diff --git a/cmd/anna/theme.go b/cmd/anna/theme.go index 512182d..1ed7d24 100644 --- a/cmd/anna/theme.go +++ b/cmd/anna/theme.go @@ -12,7 +12,7 @@ import ( var ( baseURL = "https://github.com/anna-ssg/themes/releases/download" - tagVer = "v2.0" + tagVer = "v3.0" destDir = "site" ) diff --git a/cmd/anna/wizard.go b/cmd/anna/wizard.go index dd9b462..89200f4 100644 --- a/cmd/anna/wizard.go +++ b/cmd/anna/wizard.go @@ -58,7 +58,7 @@ func (ws *WizardServer) handleSubmit(w http.ResponseWriter, r *http.Request) { ws.ErrorLogger.Println("Method not allowed") return } - + // got the form data, now ask theme.go to unzip and place in current dir var config parser.LayoutConfig err := json.NewDecoder(r.Body).Decode(&config) @@ -67,6 +67,13 @@ func (ws *WizardServer) handleSubmit(w http.ResponseWriter, r *http.Request) { ws.ErrorLogger.Println(err) return } + // Call DownloadTheme function from theme.go + err = DownloadTheme(config.ThemeURL) + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + ws.ErrorLogger.Println("Error downloading and extracting theme:", err) + return + } FormSubmittedCh <- struct{}{} } diff --git a/site/static/wizard/index.html b/site/static/wizard/index.html index 9c022cf..f3aba86 100644 --- a/site/static/wizard/index.html +++ b/site/static/wizard/index.html @@ -22,15 +22,20 @@

Setup Wizard 🍚

Get started!

-
-

Name your site

-
+
+ +

Enter a domain name

-
+
+ +
-
-

Choose a Theme

-
- +
+

Choose a Theme

+
+ +
+
- -
-

Cooking your Anna site

-

Your Anna site is being cooked. This page will reload...

-
-
@@ -88,4 +89,4 @@

Cooking your Anna site

- + \ No newline at end of file diff --git a/site/static/wizard/script.js b/site/static/wizard/script.js index d11d919..357d83f 100644 --- a/site/static/wizard/script.js +++ b/site/static/wizard/script.js @@ -1,7 +1,20 @@ +document.addEventListener('DOMContentLoaded', function () { + fetch('https://raw.githubusercontent.com/anna-ssg/themes/main/themes.json') + .then(response => response.json()) + .then(data => { + const selectElement = document.getElementById('themeURL'); + data.themes.forEach(theme => { + const option = document.createElement('option'); + option.value = `${theme.name}`; + option.textContent = theme.name; + selectElement.appendChild(option); + }); + }) + .catch(error => console.error('Error fetching themes:', error)); +}); + const slides = document.querySelectorAll(".content"); let currentSlide = 0; - -// Declare global variables let author, siteTitle, baseURL, themeURL; function showSlide(index) { @@ -13,9 +26,7 @@ function showSlide(index) { function updateProgress() { const progressContainer = document.querySelector(".progress-container"); - const oldWidth = window - .getComputedStyle(progressContainer) - .getPropertyValue("--new-width"); + const oldWidth = window.getComputedStyle(progressContainer).getPropertyValue("--new-width"); const newWidth = ((currentSlide + 1) / slides.length) * 100 + "%"; progressContainer.style.setProperty("--old-width", oldWidth); progressContainer.style.setProperty("--new-width", newWidth); @@ -37,44 +48,30 @@ function checkFormValidity() { siteTitle = document.getElementById("siteTitle").value; baseURL = document.getElementById("baseURL").value; themeURL = document.getElementById("themeURL").value; - - var nameRegex = /^[a-zA-Z0-9\s]+$/; - var urlRegex = /^(https?:\/\/)([\da-z.-]+)\.([a-z.]{2,6})(\/[^\/\s]+)*$/; - - var authorButton = document.getElementById("authorButton"); - var siteTitleButton = document.getElementById("siteTitleButton"); - var baseURLButton = document.getElementById("baseURLButton"); - + const nameRegex = /^[a-zA-Z0-9\s]+$/; + const urlRegex = /^(https?:\/\/)([\da-z.-]+)\.([a-z.]{2,6})(\/[^\/\s]+)*$/; + const authorButton = document.getElementById("authorButton"); + const siteTitleButton = document.getElementById("siteTitleButton"); + const baseURLButton = document.getElementById("baseURLButton"); authorButton.disabled = !(author && author.match(nameRegex)); siteTitleButton.disabled = !(siteTitle && siteTitle.match(nameRegex)); baseURLButton.disabled = !(baseURL && baseURL.match(urlRegex)); - - // Add or remove 'valid' class based on validity - document - .getElementById("author") - .classList.toggle("valid", author && author.match(nameRegex)); - document - .getElementById("siteTitle") - .classList.toggle("valid", siteTitle && siteTitle.match(nameRegex)); - document - .getElementById("baseURL") - .classList.toggle("valid", baseURL && baseURL.match(urlRegex)); + document.getElementById("author").classList.toggle("valid", author && author.match(nameRegex)); + document.getElementById("siteTitle").classList.toggle("valid", siteTitle && siteTitle.match(nameRegex)); + document.getElementById("baseURL").classList.toggle("valid", baseURL && baseURL.match(urlRegex)); } function submitForm() { - var checkboxes = document.querySelectorAll( - '.nav-checkboxes input[type="checkbox"]', - ); - - var navbarOptions = Array.from(checkboxes) - .filter((checkbox) => checkbox.checked) - .map((checkbox) => { - navbarElementsMap = {}; + const checkboxes = document.querySelectorAll('.nav-checkboxes input[type="checkbox"]'); + const navbarOptions = Array.from(checkboxes) + .filter(checkbox => checkbox.checked) + .map(checkbox => { + let navbarElementsMap = {}; navbarElementsMap[checkbox.className] = checkbox.value; return navbarElementsMap; }); - var formData = JSON.stringify({ + const formData = JSON.stringify({ author: author, siteTitle: siteTitle, baseURL: baseURL, @@ -82,201 +79,48 @@ function submitForm() { navbar: navbarOptions, }); - console.log(formData); - - showSlide(slides.length - 1); - fetch("/submit", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: formData, - }); - - tsParticles.load({ - id: "tsparticles", - options: { - fullScreen: { - zIndex: 1, + const confettiSettings = { + particles: { + number: { + value: 10, + }, + size: { + value: 2, + }, + shape: { + type: "circle", + }, + move: { + speed: 6, }, - emitters: [ - { - position: { - x: 0, - y: 30, - }, - rate: { - quantity: 5, - delay: 0.15, - }, - particles: { - move: { - direction: "top-right", - outModes: { - top: "none", - left: "none", - default: "destroy", - }, - }, - }, - }, - { - position: { - x: 100, - y: 30, - }, - rate: { - quantity: 5, - delay: 0.15, - }, - particles: { - move: { - direction: "top-left", - outModes: { - top: "none", - right: "none", - default: "destroy", - }, - }, - }, - }, - ], - particles: { - color: { - value: ["#ffffff", "#FF0000"], - }, - move: { - decay: 0.05, - direction: "top", - enable: true, - gravity: { - enable: true, - }, - outModes: { - top: "none", - default: "destroy", - }, - speed: { - min: 10, - max: 50, - }, - }, - number: { - value: 0, - }, - opacity: { - value: 1, - }, - rotate: { - value: { - min: 0, - max: 360, - }, - direction: "random", - animation: { - enable: true, - speed: 30, - }, - }, - tilt: { - direction: "random", - enable: true, - value: { - min: 0, - max: 360, - }, - animation: { - enable: true, - speed: 30, - }, - }, - size: { - value: { - min: 0, - max: 2, - }, - animation: { - enable: true, - startValue: "min", - count: 1, - speed: 16, - sync: true, - }, - }, - roll: { - darken: { - enable: true, - value: 25, - }, - enable: true, - speed: { - min: 5, - max: 15, - }, - }, - wobble: { - distance: 30, - enable: true, - speed: { - min: -7, - max: 7, - }, - }, - shape: { - type: "emoji", - options: { - emoji: { - particles: { - size: { - value: 8, - }, - }, - value: ["🍚"], - }, - }, - }, + color: { + value: "#00FFFF", + }, + opacity: { + value: 0.8, }, }, - }); + }; tsParticles.load("confetti", confettiSettings); - currentSlide = currentSlide + 1; - updateProgress(); + showSlide(slides.length - 1); + setTimeout(() => { - window.location.href = "http://localhost:8000"; - }, 2000); + window.location.href = "http://localhost:8000"; // Change URL as needed + }, 2000); // 2 seconds delay before redirecting + + fetch("/submit", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: formData + }) } -showSlide(0); +// Initialize the wizard by showing the first slide +showSlide(currentSlide); // Add event listeners to call checkFormValidity when input fields change document.getElementById("author").addEventListener("input", checkFormValidity); -document - .getElementById("siteTitle") - .addEventListener("input", checkFormValidity); +document.getElementById("siteTitle").addEventListener("input", checkFormValidity); document.getElementById("baseURL").addEventListener("input", checkFormValidity); -document - .getElementById("themeURL") - .addEventListener("input", checkFormValidity); - -// Confetti animation -const confettiSettings = { - particles: { - number: { - value: 10, - }, - size: { - value: 2, - }, - shape: { - type: "circle", - }, - move: { - speed: 6, - }, - color: { - value: "#00FFFF", - }, - opacity: { - value: 0.8, - }, - }, -}; +document.getElementById("themeURL").addEventListener("input", checkFormValidity);