| @@ -1,8 +1,35 @@ | ||
| 1 | 1 | document.addEventListener("DOMContentLoaded", () => { |
| 2 | 2 | const form = document.getElementById("aibui-settings-form"); |
| 3 | 3 | const toast = document.getElementById("aibui-settings-toast"); |
| 4 | 4 | |
| 5 | + // Descriptions for Design Style options | |
| 6 | + const designStyleDescriptions = { | |
| 7 | + minimalist: "Priority on white space and readability. Few graphic elements, very airy and quiet design.", | |
| 8 | + "tech-modern": "A 'Startup' style with soft drop shadows, subtle gradients, and a very clean appearance.", | |
| 9 | + corporate: "A structured and reassuring design, ideal for B2B companies, firms, and consultants.", | |
| 10 | + brutalist: "Strong contrasts, bold typography, thick black borders. A style that dares and stands out.", | |
| 11 | + luxury: "Sophisticated, monochrome or gold palettes, often associated with serif fonts.", | |
| 12 | + organic: "Pastel colors, natural shapes, no pure black, for a wellness or nature ambiance.", | |
| 13 | + }; | |
| 14 | + | |
| 15 | + // Descriptions for Block Shapes options | |
| 16 | + const blockShapesDescriptions = { | |
| 17 | + sharp: "Right angles (0px). Gives a rigorous, solid, and technical look.", | |
| 18 | + soft: "Soft angles (4px - 8px). The current web standard, neutral and pleasant.", | |
| 19 | + rounded: "Pronounced curves (12px - 20px). Brings modernity and fluidity.", | |
| 20 | + pill: "Very rounded buttons and cards (Full radius). Friendly, young, and playful style.", | |
| 21 | + }; | |
| 22 | + | |
| 23 | + // Descriptions for Copywriting Tone options | |
| 24 | + const copywritingToneDescriptions = { | |
| 25 | + professional: "An expert tone, formal address, precise vocabulary. Inspires trust and authority.", | |
| 26 | + friendly: "A conversational, warm tone, close to the reader. Ideal for blogs or lifestyle brands.", | |
| 27 | + persuasive: "Short sentences, action-oriented (CTA), focused on customer benefits. For selling.", | |
| 28 | + educational: "A neutral, pedagogical, and detailed tone. Perfect for explaining complex services.", | |
| 29 | + enthusiastic: "Many positive adjectives, exclamation points, dynamic style to motivate.", | |
| 30 | + }; | |
| 31 | + | |
| 5 | 32 | function showToast(message, isError = false) { |
| 6 | 33 | if (!toast) return; |
| 7 | 34 | toast.textContent = message; |
| 8 | 35 | toast.style.display = "block"; |
| @@ -14,8 +41,45 @@ | ||
| 14 | 41 | toast.style.display = "none"; |
| 15 | 42 | }, 4000); |
| 16 | 43 | } |
| 17 | 44 | |
| 45 | + // Limite et compteur pour "Site description & context" | |
| 46 | + const SITE_DESCRIPTION_MAX = 1000; | |
| 47 | + const siteDescriptionTextarea = document.getElementById("siteDescription"); | |
| 48 | + const siteDescriptionCounter = document.getElementById("siteDescription-counter"); | |
| 49 | + | |
| 50 | + function updateSiteDescriptionCounter() { | |
| 51 | + if (!siteDescriptionTextarea || !siteDescriptionCounter) return; | |
| 52 | + let value = siteDescriptionTextarea.value || ""; | |
| 53 | + if (value.length > SITE_DESCRIPTION_MAX) { | |
| 54 | + value = value.slice(0, SITE_DESCRIPTION_MAX); | |
| 55 | + siteDescriptionTextarea.value = value; | |
| 56 | + } | |
| 57 | + siteDescriptionCounter.textContent = `${value.length}/${SITE_DESCRIPTION_MAX}`; | |
| 58 | + } | |
| 59 | + | |
| 60 | + if (siteDescriptionTextarea && siteDescriptionCounter) { | |
| 61 | + siteDescriptionTextarea.addEventListener("input", updateSiteDescriptionCounter); | |
| 62 | + // Initialiser l'affichage au chargement | |
| 63 | + updateSiteDescriptionCounter(); | |
| 64 | + } | |
| 65 | + | |
| 66 | + // Update description when select changes | |
| 67 | + function updateDescription(selectId, descriptions) { | |
| 68 | + const select = document.getElementById(selectId); | |
| 69 | + const descriptionEl = document.getElementById(selectId + "-description"); | |
| 70 | + if (!select || !descriptionEl) return; | |
| 71 | + | |
| 72 | + select.addEventListener("change", () => { | |
| 73 | + const value = select.value; | |
| 74 | + descriptionEl.textContent = descriptions[value] || ""; | |
| 75 | + }); | |
| 76 | + | |
| 77 | + // Set initial description | |
| 78 | + const initialValue = select.value; | |
| 79 | + descriptionEl.textContent = descriptions[initialValue] || ""; | |
| 80 | + } | |
| 81 | + | |
| 18 | 82 | async function getJwtToken() { |
| 19 | 83 | const res = await fetch(aiBuilderVars.ajaxurl, { |
| 20 | 84 | method: "POST", |
| 21 | 85 | headers: { "Content-Type": "application/x-www-form-urlencoded" }, |
| @@ -35,30 +99,52 @@ | ||
| 35 | 99 | }); |
| 36 | 100 | if (!res.ok) throw new Error("Failed to load settings"); |
| 37 | 101 | const data = await res.json(); |
| 38 | 102 | |
| 39 | - // Expect shape: { primaryColor, secondaryColor, siteName, siteDescription, nativeFont } | |
| 103 | + // Expect shape: { primaryColor, secondaryColor, siteName, siteDescription, designStyle, blockShapes, copywritingTone } | |
| 40 | 104 | const { |
| 41 | 105 | primaryColor = "#2f80ed", |
| 42 | 106 | secondaryColor = "#00b87c", |
| 43 | 107 | siteName = "", |
| 44 | 108 | siteDescription = "", |
| 45 | - // nativeFont = "system-ui", | |
| 109 | + designStyle = "", | |
| 110 | + blockShapes = "", | |
| 111 | + copywritingTone = "", | |
| 46 | 112 | } = data || {}; |
| 47 | 113 | |
| 48 | 114 | document.getElementById("primaryColor").value = primaryColor; |
| 49 | - console.log("a"); | |
| 50 | 115 | document.getElementById("secondaryColor").value = secondaryColor; |
| 51 | - console.log("b"); | |
| 52 | 116 | document.getElementById("siteName").value = siteName; |
| 53 | - console.log("d"); | |
| 54 | - document.getElementById("siteDescription").value = siteDescription; | |
| 55 | - console.log("e"); | |
| 56 | - // document.getElementById("nativeFont").value = nativeFont; | |
| 57 | - console.log("f"); | |
| 117 | + const siteDescriptionEl = document.getElementById("siteDescription"); | |
| 118 | + if (siteDescriptionEl) { | |
| 119 | + siteDescriptionEl.value = siteDescription; | |
| 120 | + // Mettre à jour le compteur si déjà chargé | |
| 121 | + if (typeof updateSiteDescriptionCounter === "function") { | |
| 122 | + updateSiteDescriptionCounter(); | |
| 123 | + } | |
| 124 | + } | |
| 125 | + | |
| 126 | + if (designStyle) { | |
| 127 | + document.getElementById("designStyle").value = designStyle; | |
| 128 | + } | |
| 129 | + if (blockShapes) { | |
| 130 | + document.getElementById("blockShapes").value = blockShapes; | |
| 131 | + } | |
| 132 | + if (copywritingTone) { | |
| 133 | + document.getElementById("copywritingTone").value = copywritingTone; | |
| 134 | + } | |
| 135 | + | |
| 136 | + // Update descriptions for loaded values | |
| 137 | + updateDescription("designStyle", designStyleDescriptions); | |
| 138 | + updateDescription("blockShapes", blockShapesDescriptions); | |
| 139 | + updateDescription("copywritingTone", copywritingToneDescriptions); | |
| 58 | 140 | } catch (e) { |
| 59 | 141 | // Silent load error; user can still save |
| 60 | 142 | console.warn("AI Builder Settings: load failed", e); |
| 143 | + // Still initialize description handlers even if load fails | |
| 144 | + updateDescription("designStyle", designStyleDescriptions); | |
| 145 | + updateDescription("blockShapes", blockShapesDescriptions); | |
| 146 | + updateDescription("copywritingTone", copywritingToneDescriptions); | |
| 61 | 147 | } |
| 62 | 148 | } |
| 63 | 149 | |
| 64 | 150 | form?.addEventListener("submit", async (e) => { |
| @@ -71,9 +157,11 @@ | ||
| 71 | 157 | siteName: document.getElementById("siteName").value.trim(), |
| 72 | 158 | siteDescription: document |
| 73 | 159 | .getElementById("siteDescription") |
| 74 | 160 | .value.trim(), |
| 75 | - // nativeFont: document.getElementById("nativeFont").value, | |
| 161 | + designStyle: document.getElementById("designStyle").value, | |
| 162 | + blockShapes: document.getElementById("blockShapes").value, | |
| 163 | + copywritingTone: document.getElementById("copywritingTone").value, | |
| 76 | 164 | }; |
| 77 | 165 | |
| 78 | 166 | const res = await fetch(window.config.apiUrl + "/settings", { |
| 79 | 167 | method: "POST", |