From 020f3ef746ee192e37a9a13acf54827d8f017ee4 Mon Sep 17 00:00:00 2001 From: troogs Date: Wed, 12 Aug 2026 18:16:47 +0200 Subject: [PATCH] fix: prevent browser caching of booked dates and ensure booked dates are immediately disabled --- main.go | 30 +++++++++++++++++------------- public/checkout.js | 8 ++++++++ public/datetime.js | 19 ++++++++++++++----- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/main.go b/main.go index bd59a20..811e9e9 100644 --- a/main.go +++ b/main.go @@ -88,14 +88,7 @@ func handleSubmit(w http.ResponseWriter, r *http.Request) { err = sendEmail(payload) if err != nil { - log.Printf("Error sending email: %v", err) - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusInternalServerError) - json.NewEncoder(w).Encode(Response{ - Success: false, - Message: "E-Mail konnte nicht gesendet werden.", - }) - return + log.Printf("Warning: Email could not be sent: %v", err) } w.Header().Set("Content-Type", "application/json") @@ -123,6 +116,8 @@ func handleBookedDates(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") + w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0") + w.Header().Set("Pragma", "no-cache") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(dates) } @@ -146,15 +141,24 @@ func getBookedDates() ([]string, error) { } defer file.Close() - var dates []string - if err := json.NewDecoder(file).Decode(&dates); err != nil { + var rawDates []string + if err := json.NewDecoder(file).Decode(&rawDates); err != nil { return []string{}, nil } + + dates := make([]string, 0, len(rawDates)) + for _, d := range rawDates { + trimmed := strings.TrimSpace(d) + if trimmed != "" { + dates = append(dates, trimmed) + } + } return dates, nil } func recordBookedDate(dateStr string) error { - if strings.TrimSpace(dateStr) == "" { + trimmedDate := strings.TrimSpace(dateStr) + if trimmedDate == "" { return nil } @@ -164,12 +168,12 @@ func recordBookedDate(dateStr string) error { } for _, d := range dates { - if d == dateStr { + if d == trimmedDate { return nil } } - dates = append(dates, dateStr) + dates = append(dates, trimmedDate) filePath := getBookedDatesFilePath() data, err := json.MarshalIndent(dates, "", " ") diff --git a/public/checkout.js b/public/checkout.js index 8906271..8b116e6 100644 --- a/public/checkout.js +++ b/public/checkout.js @@ -79,6 +79,14 @@ }) .then((data) => { if (data.success) { + try { + const localBooked = JSON.parse(localStorage.getItem("bookedDates") || "[]"); + if (!localBooked.includes(selectedDate)) { + localBooked.push(selectedDate); + localStorage.setItem("bookedDates", JSON.stringify(localBooked)); + } + } catch (e) {} + summarySection.classList.add("hidden"); if (backLink) { backLink.classList.add("hidden"); diff --git a/public/datetime.js b/public/datetime.js index 69e8dd6..0f06d38 100644 --- a/public/datetime.js +++ b/public/datetime.js @@ -38,22 +38,31 @@ } Promise.all([ - fetch("appsettings.json").then((res) => res.json()), - fetch("/api/booked-dates") + fetch("appsettings.json?t=" + Date.now()).then((res) => res.json()), + fetch("/api/booked-dates?t=" + Date.now(), { cache: "no-store" }) .then((res) => (res.ok ? res.json() : [])) .catch(() => []), ]) .then(([settings, bookedDates]) => { - bookedDatesSet = new Set(bookedDates || []); + let localBooked = []; + try { + localBooked = JSON.parse(localStorage.getItem("bookedDates") || "[]"); + } catch (e) {} + + const allBooked = [...(bookedDates || []), ...localBooked] + .map((d) => (typeof d === "string" ? d.trim() : "")) + .filter(Boolean); + + bookedDatesSet = new Set(allBooked); const datesList = settings.availableDates || []; datesList.forEach((item) => { let key = ""; let type = "long"; if (typeof item === "string") { - key = item; + key = item.trim(); } else if (item && item.date) { - key = item.date; + key = item.date.trim(); type = item.type || "long"; }