feat: load dynamic settings and add identity selection page
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
next step after "2-dateselect.prompt.md":
|
||||||
|
|
||||||
|
i want to be able to define the available activities in a separate json file. for each activity, i want to define the following properties: name and icon. icon will always be a simple unicode icon. so it should be able to be treated as a character in the html
|
||||||
|
|
||||||
|
for now, i want to drop the option to select a time. the date itself should be enough
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
now i want to be able to define available dates in the same file. call the file appsettings.json instead of activities.json. the file should contain two arrays: one for activities and one for available dates. each date should be defined as a string in the format "YYYY-MM-DD".
|
||||||
|
|
||||||
|
additional to that, i want to be able to define names that can be selected for me to know who schedules the date. so the file should contain a third array called "names" with strings for each name. Add a page right after the date selection
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"activities": [
|
||||||
|
{ "name": "Essen bei Namaste", "icon": "🍛" },
|
||||||
|
{ "name": "Kinofilm", "icon": "🎬" },
|
||||||
|
{ "name": "Film zu Hause + Essen bestellen", "icon": "🛋️" },
|
||||||
|
{ "name": "Spaziergang im Wald", "icon": "🌲" },
|
||||||
|
{ "name": "Museum für Gegenwartskunst", "icon": "🖼️" },
|
||||||
|
{ "name": "Picknick auf der Wiese", "icon": "🧺" },
|
||||||
|
{ "name": "Massage zu Hause", "icon": "💆" }
|
||||||
|
],
|
||||||
|
"availableDates": [
|
||||||
|
"2026-08-15",
|
||||||
|
"2026-08-16",
|
||||||
|
"2026-08-23",
|
||||||
|
"2026-08-30",
|
||||||
|
"2026-09-05",
|
||||||
|
"2026-09-06"
|
||||||
|
],
|
||||||
|
"names": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/* ==========================================================================
|
||||||
|
Page: Namensauswahl (name.html)
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.page-name .container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-name .intro {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-name .intro p {
|
||||||
|
color: var(--color-text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 14px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 64px;
|
||||||
|
padding: 14px 20px;
|
||||||
|
background: var(--color-white);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
box-shadow: var(--shadow-soft);
|
||||||
|
cursor: pointer;
|
||||||
|
touch-action: manipulation;
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-card:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-card .icon {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-card .label {
|
||||||
|
font-family: var(--font-heading);
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-card.selected {
|
||||||
|
border-color: var(--color-rose);
|
||||||
|
background: linear-gradient(135deg, var(--color-rose-light) 0%, var(--color-white) 100%);
|
||||||
|
box-shadow: var(--shadow-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-card.selected .label {
|
||||||
|
color: var(--color-rose-dark);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
<title>Wer plant das Date? – Date-Planer</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&family=Quicksand:wght@600;700&display=swap" rel="stylesheet" />
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<link rel="stylesheet" href="name.css" />
|
||||||
|
</head>
|
||||||
|
<body class="page-name has-continue-bar">
|
||||||
|
<div class="heart-background" aria-hidden="true">
|
||||||
|
<div class="heart-shape"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<main class="container">
|
||||||
|
<a class="back-link" href="datetime.html">‹ Zurück</a>
|
||||||
|
<div class="intro">
|
||||||
|
<h1>Wer bist du? 💖</h1>
|
||||||
|
<p id="summary">Verrate mir, wer du bist.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="name-list" id="nameList"></div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="continue-bar">
|
||||||
|
<div class="container">
|
||||||
|
<button id="continueBtn" class="btn btn-primary" type="button" disabled>Weiter</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="name.js" defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
// Namensauswahl: lädt Namen aus appsettings.json, Kartenauswahl + Abschluss
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
const nameList = document.getElementById("nameList");
|
||||||
|
const summary = document.getElementById("summary");
|
||||||
|
const continueBtn = document.getElementById("continueBtn");
|
||||||
|
|
||||||
|
const selectedActivity = localStorage.getItem("selectedActivity");
|
||||||
|
const selectedDate = localStorage.getItem("selectedDate");
|
||||||
|
|
||||||
|
// Ohne Aktivität und Datum ergibt diese Seite keinen Sinn.
|
||||||
|
if (!selectedActivity) {
|
||||||
|
window.location.href = "activity.html";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!selectedDate) {
|
||||||
|
window.location.href = "datetime.html";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateLabel = new Date(`${selectedDate}T00:00:00`).toLocaleDateString("de-DE", {
|
||||||
|
weekday: "long",
|
||||||
|
day: "numeric",
|
||||||
|
month: "long",
|
||||||
|
year: "numeric",
|
||||||
|
});
|
||||||
|
summary.textContent = `${selectedActivity} am ${dateLabel} – verrate mir, wer du bist.`;
|
||||||
|
|
||||||
|
let selectedName = null;
|
||||||
|
|
||||||
|
fetch("appsettings.json")
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((settings) => renderNames(settings.names || []))
|
||||||
|
.catch(() => {
|
||||||
|
nameList.textContent = "Namen konnten nicht geladen werden.";
|
||||||
|
});
|
||||||
|
|
||||||
|
function renderNames(names) {
|
||||||
|
const options = names.length > 0 ? names : ["Mein name ist Amor 😽"];
|
||||||
|
|
||||||
|
options.forEach((name) => {
|
||||||
|
const card = document.createElement("button");
|
||||||
|
card.type = "button";
|
||||||
|
card.className = "name-card";
|
||||||
|
card.dataset.name = name;
|
||||||
|
|
||||||
|
const icon = document.createElement("span");
|
||||||
|
icon.className = "icon";
|
||||||
|
icon.setAttribute("aria-hidden", "true");
|
||||||
|
icon.textContent = "💖";
|
||||||
|
|
||||||
|
const label = document.createElement("span");
|
||||||
|
label.className = "label";
|
||||||
|
label.textContent = name;
|
||||||
|
|
||||||
|
card.append(icon, label);
|
||||||
|
card.addEventListener("click", () => {
|
||||||
|
nameList.querySelectorAll(".name-card").forEach((c) => c.classList.remove("selected"));
|
||||||
|
card.classList.add("selected");
|
||||||
|
selectedName = name;
|
||||||
|
continueBtn.disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
nameList.appendChild(card);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
continueBtn.addEventListener("click", () => {
|
||||||
|
if (!selectedName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Ablage für die spätere Anbindung an Datenbank/Storage
|
||||||
|
localStorage.setItem("selectedName", selectedName);
|
||||||
|
window.location.href = "checkout.html";
|
||||||
|
});
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user