Add custom activity support and clear booking data on submission
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
i want you to add a custom-activity (Sonstiges) with an appropriate icon. The custom activity always appears last in the list of activities. The custom activity should be available for selection in the booking process, and when selected, it should allow the user to enter a description of the activity. The entered description should be stored along with the booking information. The custom activity can not be paired with any other activity, and if selected, it should be the only activity in the booking. Custom activity don't need to be stored for later but included in the information mail and the created ics file
|
||||||
@@ -17,6 +17,7 @@ type Activity struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
CustomDescription string `json:"customDescription,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SurveyPayload struct {
|
type SurveyPayload struct {
|
||||||
@@ -233,12 +234,19 @@ func sendEmail(payload SurveyPayload) error {
|
|||||||
bodyBuilder.WriteString("Es gibt eine neue Date-Reservierung über deinen Date-Planer:\r\n\r\n")
|
bodyBuilder.WriteString("Es gibt eine neue Date-Reservierung über deinen Date-Planer:\r\n\r\n")
|
||||||
bodyBuilder.WriteString(fmt.Sprintf("👤 Name: %s\r\n", payload.Name))
|
bodyBuilder.WriteString(fmt.Sprintf("👤 Name: %s\r\n", payload.Name))
|
||||||
bodyBuilder.WriteString(fmt.Sprintf("📅 Datum: %s (%s)\r\n", payload.Date, payload.DateType))
|
bodyBuilder.WriteString(fmt.Sprintf("📅 Datum: %s (%s)\r\n", payload.Date, payload.DateType))
|
||||||
bodyBuilder.WriteString(fmt.Sprintf("💌 Aktivität(en): %s\r\n\r\n", payload.Activity))
|
bodyBuilder.WriteString(fmt.Sprintf("💌 Aktivität(en): %s\r\n\r\n", cleanActivityName(payload.Activity)))
|
||||||
|
|
||||||
if len(payload.Activities) > 0 {
|
if len(payload.Activities) > 0 {
|
||||||
bodyBuilder.WriteString("Details der Aktivitäten:\r\n")
|
bodyBuilder.WriteString("Details der Aktivitäten:\r\n")
|
||||||
for _, act := range payload.Activities {
|
for _, act := range payload.Activities {
|
||||||
bodyBuilder.WriteString(fmt.Sprintf(" - %s %s (%s)\r\n", act.Icon, act.Name, act.Type))
|
actName := cleanActivityName(act.Name)
|
||||||
|
if act.CustomDescription != "" {
|
||||||
|
cleanDesc := cleanActivityName(act.CustomDescription)
|
||||||
|
if !strings.Contains(actName, cleanDesc) {
|
||||||
|
actName = cleanDesc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bodyBuilder.WriteString(fmt.Sprintf(" - %s %s (%s)\r\n", act.Icon, actName, act.Type))
|
||||||
}
|
}
|
||||||
bodyBuilder.WriteString("\r\n")
|
bodyBuilder.WriteString("\r\n")
|
||||||
}
|
}
|
||||||
@@ -263,6 +271,14 @@ func sendEmail(payload SurveyPayload) error {
|
|||||||
return smtp.SendMail(addr, auth, fromEmail, []string{toEmail}, bodyBuilder.Bytes())
|
return smtp.SendMail(addr, auth, fromEmail, []string{toEmail}, bodyBuilder.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cleanActivityName(s string) string {
|
||||||
|
s = strings.TrimPrefix(s, "Etwas eigenes: ")
|
||||||
|
s = strings.TrimPrefix(s, "Etwas eigenes:")
|
||||||
|
s = strings.TrimPrefix(s, "Sonstiges: ")
|
||||||
|
s = strings.TrimPrefix(s, "Sonstiges:")
|
||||||
|
return strings.TrimSpace(s)
|
||||||
|
}
|
||||||
|
|
||||||
func generateICS(payload SurveyPayload) string {
|
func generateICS(payload SurveyPayload) string {
|
||||||
parsedDate, err := time.Parse("2006-01-02", payload.Date)
|
parsedDate, err := time.Parse("2006-01-02", payload.Date)
|
||||||
dtStart := strings.ReplaceAll(payload.Date, "-", "")
|
dtStart := strings.ReplaceAll(payload.Date, "-", "")
|
||||||
@@ -275,8 +291,18 @@ func generateICS(payload SurveyPayload) string {
|
|||||||
dtStamp := time.Now().UTC().Format("20060102T150405Z")
|
dtStamp := time.Now().UTC().Format("20060102T150405Z")
|
||||||
uid := fmt.Sprintf("date-wizard-%s-%d@date-wizard", dtStart, time.Now().UnixNano())
|
uid := fmt.Sprintf("date-wizard-%s-%d@date-wizard", dtStart, time.Now().UnixNano())
|
||||||
|
|
||||||
summary := fmt.Sprintf("Date: %s", payload.Activity)
|
activityText := cleanActivityName(payload.Activity)
|
||||||
description := fmt.Sprintf("Date mit %s\\nAktivität(en): %s", payload.Name, payload.Activity)
|
for _, act := range payload.Activities {
|
||||||
|
if act.CustomDescription != "" {
|
||||||
|
cleanDesc := cleanActivityName(act.CustomDescription)
|
||||||
|
if !strings.Contains(activityText, cleanDesc) {
|
||||||
|
activityText = cleanDesc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary := fmt.Sprintf("Date: %s", activityText)
|
||||||
|
description := fmt.Sprintf("Date mit %s\\nAktivität(en): %s", payload.Name, activityText)
|
||||||
|
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
sb.WriteString("BEGIN:VCALENDAR\r\n")
|
sb.WriteString("BEGIN:VCALENDAR\r\n")
|
||||||
|
|||||||
@@ -96,6 +96,43 @@
|
|||||||
animation: fadeIn 0.3s ease;
|
animation: fadeIn 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-activity-section {
|
||||||
|
margin-top: 16px;
|
||||||
|
background: var(--color-white);
|
||||||
|
border: 2px solid var(--color-rose);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
padding: 16px;
|
||||||
|
box-shadow: var(--shadow-soft);
|
||||||
|
animation: fadeIn 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-activity-label {
|
||||||
|
display: block;
|
||||||
|
font-family: var(--font-heading);
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--color-rose-dark);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-activity-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 14px;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-bg);
|
||||||
|
border: 2px solid var(--color-peach);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-activity-input:focus {
|
||||||
|
border-color: var(--color-rose);
|
||||||
|
box-shadow: 0 0 0 3px rgba(224, 87, 126, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="activity-grid" id="activityGrid"></div>
|
<div class="activity-grid" id="activityGrid"></div>
|
||||||
|
|
||||||
|
<div id="customActivitySection" class="custom-activity-section hidden">
|
||||||
|
<label for="customActivityInput" class="custom-activity-label">Was möchtest du unternehmen? ✏️</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="customActivityInput"
|
||||||
|
class="custom-activity-input"
|
||||||
|
placeholder="Beschreibung der Aktivität eingeben..."
|
||||||
|
maxlength="150"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div class="continue-bar">
|
<div class="continue-bar">
|
||||||
|
|||||||
+123
-10
@@ -5,6 +5,8 @@
|
|||||||
const dateSummary = document.getElementById("dateSummary");
|
const dateSummary = document.getElementById("dateSummary");
|
||||||
const timeNotice = document.getElementById("timeNotice");
|
const timeNotice = document.getElementById("timeNotice");
|
||||||
const continueBtn = document.getElementById("continueBtn");
|
const continueBtn = document.getElementById("continueBtn");
|
||||||
|
const customActivitySection = document.getElementById("customActivitySection");
|
||||||
|
const customActivityInput = document.getElementById("customActivityInput");
|
||||||
|
|
||||||
const selectedDate = localStorage.getItem("selectedDate");
|
const selectedDate = localStorage.getItem("selectedDate");
|
||||||
const selectedDateType = localStorage.getItem("selectedDateType") || "long";
|
const selectedDateType = localStorage.getItem("selectedDateType") || "long";
|
||||||
@@ -26,15 +28,59 @@
|
|||||||
let availableActivities = [];
|
let availableActivities = [];
|
||||||
let selectedList = [];
|
let selectedList = [];
|
||||||
|
|
||||||
|
function isCustomActivity(act) {
|
||||||
|
return act && (act.name === "Etwas eigenes" || act.name === "Sonstiges" || act.type === "custom");
|
||||||
|
}
|
||||||
|
|
||||||
fetch("appsettings.json")
|
fetch("appsettings.json")
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((settings) => {
|
.then((settings) => {
|
||||||
const allActivities = settings.activities || [];
|
const allActivities = settings.activities || [];
|
||||||
|
|
||||||
|
const customAct = allActivities.find((a) => a.name === "Etwas eigenes" || a.name === "Sonstiges") || {
|
||||||
|
name: "Etwas eigenes",
|
||||||
|
icon: "✏️",
|
||||||
|
type: "custom",
|
||||||
|
};
|
||||||
|
|
||||||
|
let otherActivities = allActivities.filter((a) => a.name !== "Etwas eigenes" && a.name !== "Sonstiges");
|
||||||
if (selectedDateType === "short") {
|
if (selectedDateType === "short") {
|
||||||
availableActivities = allActivities.filter((a) => a.type === "short");
|
otherActivities = otherActivities.filter((a) => a.type === "short");
|
||||||
} else {
|
|
||||||
availableActivities = allActivities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "Etwas eigenes" erscheint IMMER an letzter Stelle
|
||||||
|
availableActivities = [...otherActivities, customAct];
|
||||||
|
|
||||||
|
// Vorherige Auswahl wiederherstellen, falls vorhanden
|
||||||
|
try {
|
||||||
|
const stored = JSON.parse(localStorage.getItem("selectedActivities") || "[]");
|
||||||
|
if (stored && stored.length > 0) {
|
||||||
|
const isStoredCustom = stored.some(
|
||||||
|
(a) => a.type === "custom" || (a.name && (a.name.startsWith("Etwas eigenes") || a.name.startsWith("Sonstiges")))
|
||||||
|
);
|
||||||
|
if (isStoredCustom) {
|
||||||
|
const storedCustom = stored.find(
|
||||||
|
(a) => a.type === "custom" || (a.name && (a.name.startsWith("Etwas eigenes") || a.name.startsWith("Sonstiges")))
|
||||||
|
);
|
||||||
|
selectedList = [customAct];
|
||||||
|
if (storedCustom) {
|
||||||
|
const desc =
|
||||||
|
storedCustom.customDescription ||
|
||||||
|
(storedCustom.name.includes(":")
|
||||||
|
? storedCustom.name.split(":").slice(1).join(":").trim()
|
||||||
|
: "");
|
||||||
|
if (customActivityInput) {
|
||||||
|
customActivityInput.value = desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedList = stored.filter((s) =>
|
||||||
|
availableActivities.some((a) => a.name === s.name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
renderActivities();
|
renderActivities();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@@ -43,20 +89,35 @@
|
|||||||
|
|
||||||
function renderActivities() {
|
function renderActivities() {
|
||||||
activityGrid.innerHTML = "";
|
activityGrid.innerHTML = "";
|
||||||
|
const hasCustomSelected = selectedList.some(isCustomActivity);
|
||||||
const hasShortSelected = selectedList.some((a) => a.type === "short");
|
const hasShortSelected = selectedList.some((a) => a.type === "short");
|
||||||
|
|
||||||
|
if (hasCustomSelected) {
|
||||||
|
if (customActivitySection) {
|
||||||
|
customActivitySection.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (customActivitySection) {
|
||||||
|
customActivitySection.classList.add("hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
availableActivities.forEach((activity) => {
|
availableActivities.forEach((activity) => {
|
||||||
const card = document.createElement("button");
|
const card = document.createElement("button");
|
||||||
card.type = "button";
|
card.type = "button";
|
||||||
card.className = "activity-card";
|
card.className = "activity-card";
|
||||||
card.dataset.activity = activity.name;
|
card.dataset.activity = activity.name;
|
||||||
|
|
||||||
const isSelected = selectedList.some((a) => a.name === activity.name);
|
const isCustom = isCustomActivity(activity);
|
||||||
|
const isSelected = isCustom
|
||||||
|
? hasCustomSelected
|
||||||
|
: selectedList.some((a) => a.name === activity.name);
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
card.classList.add("selected");
|
card.classList.add("selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
const isLongDisabled = hasShortSelected && activity.type === "long";
|
const isLongDisabled = !isCustom && hasShortSelected && activity.type === "long";
|
||||||
if (isLongDisabled) {
|
if (isLongDisabled) {
|
||||||
card.classList.add("is-disabled");
|
card.classList.add("is-disabled");
|
||||||
card.disabled = true;
|
card.disabled = true;
|
||||||
@@ -84,6 +145,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleCardClick(activity) {
|
function handleCardClick(activity) {
|
||||||
|
const isCustom = isCustomActivity(activity);
|
||||||
|
const hasCustomSelected = selectedList.some(isCustomActivity);
|
||||||
|
|
||||||
|
if (isCustom) {
|
||||||
|
if (hasCustomSelected) {
|
||||||
|
selectedList = [];
|
||||||
|
} else {
|
||||||
|
// Custom-Aktivität darf mit keiner anderen Aktivität kombiniert werden!
|
||||||
|
selectedList = [activity];
|
||||||
|
setTimeout(() => {
|
||||||
|
if (customActivityInput) {
|
||||||
|
customActivityInput.focus();
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hasCustomSelected) {
|
||||||
|
selectedList = [];
|
||||||
|
}
|
||||||
|
|
||||||
const isAlreadySelected = selectedList.some((a) => a.name === activity.name);
|
const isAlreadySelected = selectedList.some((a) => a.name === activity.name);
|
||||||
|
|
||||||
if (activity.type === "long") {
|
if (activity.type === "long") {
|
||||||
@@ -93,33 +174,41 @@
|
|||||||
selectedList = [activity];
|
selectedList = [activity];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Short activity
|
|
||||||
if (isAlreadySelected) {
|
if (isAlreadySelected) {
|
||||||
selectedList = selectedList.filter((a) => a.name !== activity.name);
|
selectedList = selectedList.filter((a) => a.name !== activity.name);
|
||||||
} else if (selectedDateType === "short") {
|
} else if (selectedDateType === "short") {
|
||||||
// An kurzen Tagen ist nur maximal eine kurze Aktivität erlaubt
|
|
||||||
selectedList = [activity];
|
selectedList = [activity];
|
||||||
} else {
|
} else {
|
||||||
// An langen Tagen:
|
|
||||||
// Falls vorher eine lange Aktivität gewählt war, ersetzen
|
|
||||||
if (selectedList.some((a) => a.type === "long")) {
|
if (selectedList.some((a) => a.type === "long")) {
|
||||||
selectedList = [activity];
|
selectedList = [activity];
|
||||||
} else if (selectedList.length >= 2) {
|
} else if (selectedList.length >= 2) {
|
||||||
// Maximal 2 kurze Aktivitäten, die zweite ersetzen
|
|
||||||
selectedList = [selectedList[0], activity];
|
selectedList = [selectedList[0], activity];
|
||||||
} else {
|
} else {
|
||||||
selectedList.push(activity);
|
selectedList.push(activity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderActivities();
|
renderActivities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (customActivityInput) {
|
||||||
|
customActivityInput.addEventListener("input", () => {
|
||||||
|
updateNoticeAndContinue();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateNoticeAndContinue() {
|
function updateNoticeAndContinue() {
|
||||||
|
const hasCustomSelected = selectedList.some(isCustomActivity);
|
||||||
const shortCount = selectedList.filter((a) => a.type === "short").length;
|
const shortCount = selectedList.filter((a) => a.type === "short").length;
|
||||||
const hasLong = selectedList.some((a) => a.type === "long");
|
const hasLong = selectedList.some((a) => a.type === "long");
|
||||||
|
|
||||||
|
if (hasCustomSelected) {
|
||||||
|
timeNotice.classList.add("hidden");
|
||||||
|
const desc = customActivityInput ? customActivityInput.value.trim() : "";
|
||||||
|
continueBtn.disabled = desc.length === 0;
|
||||||
|
} else {
|
||||||
if (selectedDateType === "long" && shortCount === 1 && !hasLong) {
|
if (selectedDateType === "long" && shortCount === 1 && !hasLong) {
|
||||||
timeNotice.textContent =
|
timeNotice.textContent =
|
||||||
"💡 An diesem Tag haben wir reichlich Zeit! Wenn du möchtest, kannst du noch eine zweite kurze Aktivität auswählen.";
|
"💡 An diesem Tag haben wir reichlich Zeit! Wenn du möchtest, kannst du noch eine zweite kurze Aktivität auswählen.";
|
||||||
@@ -133,13 +222,37 @@
|
|||||||
|
|
||||||
continueBtn.disabled = selectedList.length === 0;
|
continueBtn.disabled = selectedList.length === 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
continueBtn.addEventListener("click", () => {
|
continueBtn.addEventListener("click", () => {
|
||||||
if (selectedList.length === 0) {
|
if (selectedList.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hasCustomSelected = selectedList.some(isCustomActivity);
|
||||||
|
|
||||||
|
if (hasCustomSelected) {
|
||||||
|
const customDesc = customActivityInput ? customActivityInput.value.trim() : "";
|
||||||
|
if (!customDesc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const customAct = selectedList.find(isCustomActivity);
|
||||||
|
|
||||||
|
const savedCustomAct = {
|
||||||
|
name: customDesc,
|
||||||
|
icon: customAct.icon || "✏️",
|
||||||
|
type: "custom",
|
||||||
|
customDescription: customDesc,
|
||||||
|
};
|
||||||
|
|
||||||
|
localStorage.setItem("selectedActivities", JSON.stringify([savedCustomAct]));
|
||||||
|
localStorage.setItem("selectedActivity", customDesc);
|
||||||
|
} else {
|
||||||
localStorage.setItem("selectedActivities", JSON.stringify(selectedList));
|
localStorage.setItem("selectedActivities", JSON.stringify(selectedList));
|
||||||
localStorage.setItem("selectedActivity", selectedList.map((a) => a.name).join(" + "));
|
localStorage.setItem("selectedActivity", selectedList.map((a) => a.name).join(" + "));
|
||||||
|
}
|
||||||
|
|
||||||
window.location.href = "name.html";
|
window.location.href = "name.html";
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
{ "name": "Squash spielen", "icon": "🏸", "type": "short" },
|
{ "name": "Squash spielen", "icon": "🏸", "type": "short" },
|
||||||
{ "name": "Essen im Namaste", "icon": "🍛", "type": "short" },
|
{ "name": "Essen im Namaste", "icon": "🍛", "type": "short" },
|
||||||
{ "name": "Museum für Gegenwartskunst", "icon": "🖼️", "type": "short" },
|
{ "name": "Museum für Gegenwartskunst", "icon": "🖼️", "type": "short" },
|
||||||
{ "name": "Playstation Co-Op", "icon": "🎮", "type": "short" }
|
{ "name": "Playstation Co-Op", "icon": "🎮", "type": "short" },
|
||||||
|
{ "name": "Etwas eigenes", "icon": "✏️", "type": "custom" }
|
||||||
],
|
],
|
||||||
"availableDates": [
|
"availableDates": [
|
||||||
{ "date": "2026-08-11", "type": "short" },
|
{ "date": "2026-08-11", "type": "short" },
|
||||||
|
|||||||
+15
-10
@@ -10,7 +10,12 @@
|
|||||||
const activityIcon = document.getElementById("activityIcon");
|
const activityIcon = document.getElementById("activityIcon");
|
||||||
const checkoutBtn = document.getElementById("checkoutBtn");
|
const checkoutBtn = document.getElementById("checkoutBtn");
|
||||||
|
|
||||||
const selectedActivity = localStorage.getItem("selectedActivity");
|
function cleanPrefix(str) {
|
||||||
|
if (!str) return "";
|
||||||
|
return str.replace(/^(Etwas eigenes|Sonstiges):\s*/i, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedActivity = cleanPrefix(localStorage.getItem("selectedActivity"));
|
||||||
const selectedDate = localStorage.getItem("selectedDate");
|
const selectedDate = localStorage.getItem("selectedDate");
|
||||||
const selectedName = localStorage.getItem("selectedName");
|
const selectedName = localStorage.getItem("selectedName");
|
||||||
|
|
||||||
@@ -57,8 +62,12 @@
|
|||||||
checkoutBtn.textContent = "Wird übermittelt... 💌";
|
checkoutBtn.textContent = "Wird übermittelt... 💌";
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
activity: selectedActivity,
|
activity: cleanPrefix(selectedActivity),
|
||||||
activities: storedActivities,
|
activities: storedActivities.map((a) => ({
|
||||||
|
...a,
|
||||||
|
name: cleanPrefix(a.name),
|
||||||
|
customDescription: cleanPrefix(a.customDescription || a.name),
|
||||||
|
})),
|
||||||
date: selectedDate,
|
date: selectedDate,
|
||||||
dateType: localStorage.getItem("selectedDateType") || "long",
|
dateType: localStorage.getItem("selectedDateType") || "long",
|
||||||
name: selectedName,
|
name: selectedName,
|
||||||
@@ -79,13 +88,9 @@
|
|||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
try {
|
// Alle lokal gespeicherten Daten (inkl. bookedDates und ausgewählter Werte) leeren,
|
||||||
const localBooked = JSON.parse(localStorage.getItem("bookedDates") || "[]");
|
// damit bei der nächsten Buchung alles frisch geladen / neu ausgewählt wird.
|
||||||
if (!localBooked.includes(selectedDate)) {
|
localStorage.clear();
|
||||||
localBooked.push(selectedDate);
|
|
||||||
localStorage.setItem("bookedDates", JSON.stringify(localBooked));
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
summarySection.classList.add("hidden");
|
summarySection.classList.add("hidden");
|
||||||
if (backLink) {
|
if (backLink) {
|
||||||
|
|||||||
Reference in New Issue
Block a user