Theme editor UI refinement
This commit is contained in:
		@@ -96,8 +96,8 @@ function renderLocalFonts(fonts) {
 | 
			
		||||
  fonts.forEach(font => {
 | 
			
		||||
    listDiv.innerHTML += `
 | 
			
		||||
      <div class="font-item">
 | 
			
		||||
        <span>${font}</span>
 | 
			
		||||
        <button type="button" class="remove-font-btn danger" data-font="${font}">Remove</button>
 | 
			
		||||
        <span class="font-name">${font}</span>
 | 
			
		||||
        <button type="button" class="remove-font-btn danger remove-btn" data-font="${font}">🗑️</button>
 | 
			
		||||
      </div>
 | 
			
		||||
    `;
 | 
			
		||||
  });
 | 
			
		||||
@@ -170,30 +170,28 @@ document.addEventListener("DOMContentLoaded", async () => {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (fontUploadInput) {
 | 
			
		||||
    fontUploadInput.addEventListener("change", async (e) => {
 | 
			
		||||
      const file = e.target.files[0];
 | 
			
		||||
      if (!file) return;
 | 
			
		||||
      const ext = file.name.split('.').pop().toLowerCase();
 | 
			
		||||
      if (!["woff", "woff2"].includes(ext)) {
 | 
			
		||||
        fontUploadStatus.textContent = "Only .woff and .woff2 fonts are allowed.";
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      const formData = new FormData();
 | 
			
		||||
      formData.append("file", file);
 | 
			
		||||
      formData.append("theme", themeInfo.theme_name);
 | 
			
		||||
      const res = await fetch("/api/font/upload", { method: "POST", body: formData });
 | 
			
		||||
      const result = await res.json();
 | 
			
		||||
      if (result.status === "ok") {
 | 
			
		||||
        fontUploadStatus.textContent = "Font uploaded!";
 | 
			
		||||
        showToast("Font uploaded!", "success");
 | 
			
		||||
        localFonts = await fetchLocalFonts(themeInfo.theme_name);
 | 
			
		||||
        refreshLocalFonts();
 | 
			
		||||
      } else {
 | 
			
		||||
        fontUploadStatus.textContent = "Error uploading font.";
 | 
			
		||||
        showToast("Error uploading font.", "error");
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  fontUploadInput.addEventListener("change", async (e) => {
 | 
			
		||||
    const file = e.target.files[0];
 | 
			
		||||
    if (!file) return;
 | 
			
		||||
    const ext = file.name.split('.').pop().toLowerCase();
 | 
			
		||||
    if (!["woff", "woff2"].includes(ext)) {
 | 
			
		||||
      showToast("Only .woff and .woff2 fonts are allowed.", "error");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    const formData = new FormData();
 | 
			
		||||
    formData.append("file", file);
 | 
			
		||||
    formData.append("theme", themeInfo.theme_name);
 | 
			
		||||
    const res = await fetch("/api/font/upload", { method: "POST", body: formData });
 | 
			
		||||
    const result = await res.json();
 | 
			
		||||
    if (result.status === "ok") {
 | 
			
		||||
      showToast("✅ Font uploaded!", "success");
 | 
			
		||||
      localFonts = await fetchLocalFonts(themeInfo.theme_name);
 | 
			
		||||
      refreshLocalFonts();
 | 
			
		||||
    } else {
 | 
			
		||||
      showToast("Error uploading font.", "error");
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  // Remove font button triggers modal
 | 
			
		||||
  if (localFontsList) {
 | 
			
		||||
@@ -223,7 +221,7 @@ document.addEventListener("DOMContentLoaded", async () => {
 | 
			
		||||
      if (!fontToDelete) return;
 | 
			
		||||
      const result = await removeFont(themeInfo.theme_name, fontToDelete);
 | 
			
		||||
      if (result.status === "ok") {
 | 
			
		||||
        showToast("Font removed!", "success");
 | 
			
		||||
        showToast("Font removed!", "✅ success");
 | 
			
		||||
        localFonts = await fetchLocalFonts(themeInfo.theme_name);
 | 
			
		||||
        refreshLocalFonts();
 | 
			
		||||
      } else {
 | 
			
		||||
@@ -282,7 +280,7 @@ document.addEventListener("DOMContentLoaded", async () => {
 | 
			
		||||
      if (result.status === "ok") {
 | 
			
		||||
        faviconInput.value = result.filename;
 | 
			
		||||
        updateFaviconPreview(`/themes/${themeInfo.theme_name}/${result.filename}?t=${Date.now()}`);
 | 
			
		||||
        showToast("Favicon uploaded!", "success");
 | 
			
		||||
        showToast("✅ Favicon uploaded!", "success");
 | 
			
		||||
      } else {
 | 
			
		||||
        showToast("Error uploading favicon", "error");
 | 
			
		||||
      }
 | 
			
		||||
@@ -314,7 +312,7 @@ document.addEventListener("DOMContentLoaded", async () => {
 | 
			
		||||
      if (result.status === "ok") {
 | 
			
		||||
        faviconInput.value = "";
 | 
			
		||||
        updateFaviconPreview("");
 | 
			
		||||
        showToast("Favicon removed!", "success");
 | 
			
		||||
        showToast("✅ Favicon removed!", "success");
 | 
			
		||||
      } else {
 | 
			
		||||
        showToast("Error removing favicon", "error");
 | 
			
		||||
      }
 | 
			
		||||
@@ -393,7 +391,7 @@ document.addEventListener("DOMContentLoaded", async () => {
 | 
			
		||||
      body: JSON.stringify({ theme_name: themeInfo.theme_name, theme_yaml: data })
 | 
			
		||||
    });
 | 
			
		||||
    if (res.ok) {
 | 
			
		||||
      showToast("Theme saved!", "success");
 | 
			
		||||
      showToast("✅ Theme saved!", "success");
 | 
			
		||||
    } else {
 | 
			
		||||
      showToast("Error saving theme.", "error");
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -693,3 +693,28 @@ input[type="color"].color-input {
 | 
			
		||||
  top:0;
 | 
			
		||||
  opacity:0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fieldset p {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
    color: #b3b3b3;
 | 
			
		||||
    margin-top: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.font-name {
 | 
			
		||||
  background: #1f2223;
 | 
			
		||||
  color: #b3b3b3;
 | 
			
		||||
  border: 1px solid #585858;
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
  font-size: 15px;
 | 
			
		||||
  font-weight: 400;
 | 
			
		||||
  padding: 10px 14px;
 | 
			
		||||
  margin-bottom: 4px;
 | 
			
		||||
  outline: none;
 | 
			
		||||
  transition: border-color 0.2s, background 0.2s;
 | 
			
		||||
  box-shadow: 0 2px 8px rgba(0,0,0,0.07);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#theme-editor-form button[type="button"]#choose-font-btn {
 | 
			
		||||
  margin-top: 16px;
 | 
			
		||||
}
 | 
			
		||||
@@ -50,6 +50,7 @@
 | 
			
		||||
      <!-- Colors Section -->
 | 
			
		||||
      <fieldset>
 | 
			
		||||
        <h2>Colors</h2>
 | 
			
		||||
        <p>Set the color values for your theme</p>
 | 
			
		||||
        <div class="fields">
 | 
			
		||||
          <!-- Example for one color field, repeat for all -->
 | 
			
		||||
          <div class="input-field">
 | 
			
		||||
@@ -113,6 +114,7 @@
 | 
			
		||||
      <!-- Google Fonts Section -->
 | 
			
		||||
      <fieldset>
 | 
			
		||||
        <h2>Google Fonts</h2>
 | 
			
		||||
        <p>Add Google Fonts to your theme</p>
 | 
			
		||||
        <div class="fields" id="google-fonts-fields">
 | 
			
		||||
          <!-- JS will render font family and weights inputs here -->
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -120,17 +122,16 @@
 | 
			
		||||
      </fieldset>
 | 
			
		||||
      <!-- Custom Font Upload Section -->
 | 
			
		||||
      <fieldset>
 | 
			
		||||
        <h2>Upload Custom Font (.woff, .woff2)</h2>
 | 
			
		||||
        <div class="fields">
 | 
			
		||||
        <h2>Upload Custom Font</h2>
 | 
			
		||||
        <p>Supported formats: .woff, .woff2</p>
 | 
			
		||||
          <input type="file" id="font-upload" accept=".woff,.woff2" style="display:none;">
 | 
			
		||||
          <button type="button" id="choose-font-btn" class="up-btn">🖋️ Upload font</button>
 | 
			
		||||
          <div id="local-fonts-list" class="font-list"></div>
 | 
			
		||||
          <span id="font-upload-status"></span>
 | 
			
		||||
        </div>
 | 
			
		||||
          <button type="button" id="choose-font-btn" class="up-btn">🖋️ Upload font</button>
 | 
			
		||||
      </fieldset>
 | 
			
		||||
      <!-- Fonts Section -->
 | 
			
		||||
      <fieldset>
 | 
			
		||||
        <h2>Fonts</h2>
 | 
			
		||||
        <p>Select where to apply your fonts</p>
 | 
			
		||||
        <div class="fields">
 | 
			
		||||
          <div class="input-field">
 | 
			
		||||
            <label>Primary Font</label>
 | 
			
		||||
@@ -155,6 +156,7 @@
 | 
			
		||||
      <!-- Favicon Section -->
 | 
			
		||||
      <fieldset>
 | 
			
		||||
        <h2>Favicon</h2>
 | 
			
		||||
        <p>Supported formats: .png, .jpg, .jpeg</p>
 | 
			
		||||
        <div class="fields">
 | 
			
		||||
          <div class="input-field">
 | 
			
		||||
            <label>Favicon Path</label>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user