Compare commits

..

2 Commits

Author SHA1 Message Date
«schmona»
6a7fbc969d clean up branch css-main 2026-03-30 00:24:37 +02:00
«schmona»
4e1b5a5495 Globales Stylesheet und clean up 2026-03-29 23:17:37 +02:00
15 changed files with 241 additions and 906 deletions

15
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -6,25 +6,6 @@
--control-min-height: 3rem;
--input-min-height: 3.5rem;
--card-min-height: 6rem;
--color-bg: var(--butter);
--color-surface: var(--white);
--color-surface-soft: var(--butter-light);
--color-text: var(--black);
--color-text-secondary: rgba(34, 33, 26, 0.8);
--color-muted: rgba(34, 33, 26, 0.68);
--color-border: rgba(102, 52, 13, 0.16);
--color-border-strong: var(--brown);
--color-divider: rgba(102, 52, 13, 0.14);
--color-primary: var(--olive);
--color-primary-hover: var(--olive-dark);
--color-progress-bg: rgba(212, 75, 36, 0.18);
--color-focus: var(--blue);
--color-error: var(--error);
--shadow-soft: 0 12px 30px rgba(102, 52, 13, 0.1);
--input-border-soft: rgba(102, 52, 13, 0.2);
--input-border-focus: rgba(107, 107, 5, 0.45);
--input-shadow-focus: 0 0 0 4px rgba(107, 107, 5, 0.12);
}
*,
@ -37,72 +18,12 @@ html {
font-size: 100%;
}
body {
margin: 0;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: var(--color-bg);
color: var(--color-text);
line-height: 1.5;
}
a,
button,
input,
textarea {
font: inherit;
}
a {
color: inherit;
text-decoration: none;
}
.site-header {
background: var(--color-bg);
border-top: 2px solid #232323;
border-bottom: 1px solid var(--color-border);
}
.site-nav {
width: min(100% - 2rem, var(--max-width));
margin: 0 auto;
min-height: var(--header-height);
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-4);
}
.site-logo {
font-size: 2rem;
font-weight: 800;
letter-spacing: 0.02em;
}
.site-nav-links {
display: flex;
align-items: center;
gap: var(--space-5);
margin: 0;
padding: 0;
list-style: none;
}
.site-nav-links a {
font-weight: 500;
}
.site-nav-links li:last-child a {
width: 2.25rem;
height: 2.25rem;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #231f20;
color: #ffffff;
font-weight: 700;
}
.event-create-page {
width: min(100% - 2rem, var(--max-width));
@ -127,10 +48,6 @@ a {
padding: var(--space-4) 0 var(--space-7);
}
.submission-success {
padding: var(--space-4) 0 var(--space-7);
}
.step--active {
display: block;
}
@ -146,7 +63,6 @@ a {
min-height: 60vh;
align-content: center;
grid-template-columns: 1fr;
gap: var(--space-7);
}
.step-copy,
@ -180,13 +96,6 @@ fieldset {
letter-spacing: 0.02em;
}
h1,
h2 {
margin: 0;
font-size: clamp(2rem, 4vw, 4rem);
line-height: 1.03;
letter-spacing: -0.03em;
}
.step-text {
margin: 0;
@ -209,22 +118,9 @@ h2 {
background: linear-gradient(135deg, var(--color-surface), var(--color-surface-soft));
}
.intro-card--image {
width: 100%;
padding: 0;
border: 0;
overflow: hidden;
background: transparent;
box-shadow: none;
}
.intro-image {
width: 100%;
aspect-ratio: 16 / 10;
display: block;
object-fit: cover;
border-radius: 1.875rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.12);
.intro-card-emoji {
font-size: 2rem;
margin-bottom: var(--space-3);
}
label,
@ -245,13 +141,11 @@ input[type="number"],
textarea {
width: 100%;
min-height: var(--input-min-height);
padding: 1rem 1.1rem;
border: 1px solid var(--input-border-soft);
border-radius: 1.125rem;
background: var(--butter-light);
padding: 0.95rem 1rem;
border: 1px solid var(--color-border);
border-radius: 1rem;
background: var(--color-surface);
color: var(--color-text);
box-shadow: 0 1px 2px rgba(102, 52, 13, 0.04);
transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}
textarea {
@ -259,30 +153,6 @@ textarea {
resize: vertical;
}
input[type="text"]:hover,
input[type="date"]:hover,
input[type="time"]:hover,
input[type="number"]:hover,
textarea:hover {
border-color: rgba(102, 52, 13, 0.28);
}
input[type="text"]:focus,
input[type="date"]:focus,
input[type="time"]:focus,
input[type="number"]:focus,
textarea:focus {
border-color: var(--input-border-focus);
box-shadow: var(--input-shadow-focus);
background: var(--butter-light);
outline: none;
}
.field-invalid {
border-color: var(--tomato) !important;
box-shadow: 0 0 0 2px rgba(212, 75, 36, 0.14);
}
.field-row {
display: grid;
gap: var(--space-4);
@ -301,8 +171,8 @@ textarea:focus {
padding: 1rem 1rem 1rem 1.05rem;
border: 1px solid var(--color-border);
border-radius: 1rem;
background: var(--butter-light);
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease, background-color 0.2s ease, color 0.2s ease;
background: var(--color-surface);
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.option-card small {
@ -310,7 +180,6 @@ textarea:focus {
}
.option-card:hover {
background: var(--olive-light);
transform: translateY(-1px);
box-shadow: var(--shadow-soft);
}
@ -323,18 +192,7 @@ textarea:focus {
}
.option-card:has(input:checked) {
border: 1px solid var(--color-primary);
background: var(--color-primary);
color: var(--white);
}
.option-card:has(input:checked) small {
color: rgba(247, 246, 230, 0.88);
}
.option-card--invalid {
border-color: var(--tomato) !important;
box-shadow: 0 0 0 2px rgba(212, 75, 36, 0.14);
border: 2px solid var(--color-border-strong);
}
.counter {
@ -356,44 +214,15 @@ textarea:focus {
.counter-button {
width: var(--control-min-height);
height: var(--control-min-height);
border: 1px solid var(--color-primary);
border: 1px solid var(--color-border);
border-radius: 50%;
background: var(--color-primary);
color: var(--white);
background: var(--color-surface);
font-size: 1.5rem;
line-height: 1;
box-shadow: 0 6px 16px rgba(107, 107, 5, 0.18);
transition: background-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.counter-button:hover {
background: var(--color-primary-hover);
transform: translateY(-1px);
}
.counter-button:focus-visible {
outline: 3px solid rgba(107, 107, 5, 0.22);
outline-offset: 3px;
}
.review-card {
display: grid;
gap: var(--space-4);
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
}
.review-card--success {
display: grid;
gap: var(--space-5);
padding: var(--space-3) 0 0;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
padding: var(--space-5);
border-radius: var(--radius-lg);
}
.review-list {
@ -404,29 +233,14 @@ textarea:focus {
.review-item {
display: grid;
gap: var(--space-2);
padding: 1rem 1.1rem;
border: 1px solid var(--input-border-soft);
border-radius: 1.125rem;
background: var(--butter-light);
box-shadow: 0 1px 2px rgba(102, 52, 13, 0.04);
cursor: pointer;
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease, background-color 0.2s ease;
gap: var(--space-1);
padding-bottom: var(--space-4);
border-bottom: 1px solid var(--color-divider);
}
.review-item:last-child {
border-bottom: 1px solid var(--input-border-soft);
}
.review-item:hover {
border-color: rgba(102, 52, 13, 0.28);
background: rgba(247, 246, 230, 0.92);
transform: translateY(-1px);
}
.review-item:focus-visible {
outline: 3px solid rgba(107, 107, 5, 0.2);
outline-offset: 3px;
border-bottom: 0;
padding-bottom: 0;
}
.review-item dt {
@ -439,29 +253,16 @@ textarea:focus {
color: var(--color-text-secondary);
}
.submission-success-actions {
display: flex;
justify-content: center;
}
.flow-footer {
position: sticky;
bottom: 0;
z-index: 5;
margin-top: auto;
background: var(--color-bg);
backdrop-filter: none;
padding-top: var(--space-4);
background: rgba(247, 247, 242, 0.96);
backdrop-filter: blur(8px);
padding-bottom: env(safe-area-inset-bottom);
}
.progress-wrap {
position: relative;
width: min(100%, var(--content-width));
margin: 0 auto;
padding-top: 4.35rem;
}
.progress {
width: 100%;
height: 0.375rem;
@ -472,50 +273,15 @@ textarea:focus {
display: block;
width: 0;
height: 100%;
background: var(--tomato);
background: var(--color-primary);
transition: width 0.25s ease;
}
.progress-marker {
position: absolute;
top: 0;
transform: translateX(-50%);
display: grid;
justify-items: center;
gap: 0.2rem;
pointer-events: none;
}
.progress-marker::after {
content: "";
width: 0.125rem;
height: 1rem;
background: var(--tomato);
border-radius: 999px;
}
.progress-marker__circle {
width: 2.9rem;
height: 2.9rem;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: var(--tomato);
color: var(--butter-light);
font-size: 1.35rem;
font-weight: 600;
line-height: 1;
box-shadow: 0 10px 24px rgba(212, 75, 36, 0.18);
}
.flow-actions {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-4);
width: min(100%, var(--content-width));
margin: 0 auto;
padding: var(--space-4) 0;
}
@ -622,10 +388,8 @@ textarea:focus-visible {
@media (min-width: 768px) {
.step-layout--intro {
width: min(100%, 56rem);
grid-template-columns: 1fr 1fr;
grid-template-columns: 1.25fr 0.8fr;
align-items: center;
gap: var(--space-8);
}
.field-row {
@ -639,4 +403,4 @@ textarea:focus-visible {
.option-grid--4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
}

View File

@ -26,11 +26,6 @@
--button-green-dark: #514c04;
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: #FFFDE3; /* butter background color from stylesheet */
}
.page-wrapper {
max-width: 1440px;
@ -184,10 +179,9 @@ body {
align-items: center;
gap: 16px;
padding: 28px 20px;
background: var(--white) !important;
border: 2px solid var(--tomato) !important;
background: #6B6B05;
border-radius: 28px;
box-shadow: 0 12px 30px rgba(212, 75, 36, 0.08);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.06);
}
.how-step__icon {
@ -226,7 +220,7 @@ body {
}
.how-step__label--brown {
color: var(--tomato);
color: #FFFDE3;
}
.how-step__label--big {
@ -247,7 +241,7 @@ body {
}
.how-step__corner-number--brown {
color: var(--tomato);
color: #FFFDE3;
}
.how-step__png {
@ -257,10 +251,10 @@ body {
}
.how-step__png--brown {
filter: brightness(0) saturate(100%) invert(39%) sepia(84%) saturate(1682%) hue-rotate(349deg) brightness(93%) contrast(86%);
}
filter: brightness(0) saturate(100%) invert(99%) sepia(6%) saturate(1200%) hue-rotate(10deg) brightness(104%) contrast(97%);
}
@media (max-width: 900px) {
.how-it-works__steps {
grid-template-columns: 1fr;
@ -378,7 +372,7 @@ body {
}
/* Center arrow removed using side arrows only */
}
@media (max-width: 900px) {
.gallery__track {

View File

@ -73,7 +73,7 @@ img {
/* Typography */
h1, h2, h3, h4, h5, h6 {
h1, h2 {
font-family: 'Bagel Fat One';
}
@ -123,8 +123,8 @@ p {
display: flex;
justify-content: space-between;
align-items: center;
min-height: 3rem;
padding: 0.1875rem 0.75rem 0.1875rem var(--space-5);
min-height: 3.625rem;
padding: 0.1875rem 0.5625rem 0.1875rem var(--space-5);
max-width: none;
width: 100%;
box-sizing: border-box;
@ -144,31 +144,10 @@ p {
display: block;
}
.nav-tab {
color: var(--black);
font-size: 1.125rem;
font-weight: 500;
letter-spacing: var(--ls-sm);
line-height: 1;
text-decoration: none;
}
.nav-tab:hover, .nav-tab:active,
.nav-tab:focus-visible {
text-decoration: underline;
text-underline-offset: 4px;
}
.button-small:hover, .button-small:active,
.button-small:focus-visible {
background: var(--olive-dark);
color: var(--black);
}
.nav-tab-links {
.button-small-links {
display: flex;
align-items: center;
gap: var(--space-5);
gap: var(--space-1);
}
@ -190,10 +169,8 @@ p {
background-color: var(--olive-dark);
}
.button-small {
background: var(--olive);
color: var(--butter-light);
color: var(--black);
font-size: 1.125rem;
font-weight: 500;
letter-spacing: var(--ls-sm);
@ -206,8 +183,22 @@ p {
.button-small:hover, .button-small:active,
.button-small:focus-visible {
background: var(--olive-dark);
background: var(--olive-light);
color: var(--black);
}
.button-login {
background: var(--olive);
color: var(--butter-light);
font-size: 1.125rem;
font-weight: 500;
letter-spacing: var(--ls-sm);
line-height: 1;
text-decoration: none;
padding: var(--space-1) var(--space-4);
border-radius: var(--radius-md);
}
.profile-pill {

View File

@ -9,24 +9,23 @@
<link rel="stylesheet" href="css/event_create.css" />
<!-- Globales Stylesheet -->
<link rel="stylesheet" href="css/stylesheet_global.css">
</head>
</head>
<body>
<!-- Top Navigation mit Seitenlinks -->
<header class="top-nav-wrap">
<div class="top-nav">
<a class="brand" href="index.html" aria-label="Zur Startseite">
<img src="assets/logo_invite.svg" alt="Invite Logo">
<img src="assets/invite-logo.svg" alt="Invite Logo">
</a>
<nav class="nav-tab-links" aria-label="Hauptnavigation">
<a class="nav-tab" href="event_overview.html">Event finden</a>
<a class="nav-tab" href="event_create.html">Event erstellen</a>
<a class="button-small" href="login.html" aria-label="Profil">Login</a>
<nav class="top-nav-links" aria-label="Hauptnavigation">
<a class="button-small" href="event_overview.html" aria-current="page">Event finden</a>
<a class="button-small:active" href="event_create.html">Event erstellen</a>
<a class="button-small" href="login.html" aria-label="Profil">M</a>
</nav>
</div>
</header>
<main class="event-create-page">
<section class="event-flow-header" aria-label="Event erstellen Aktionen">
</section>
@ -39,24 +38,16 @@
>
<div class="step-layout step-layout--intro">
<div class="step-copy">
<p class="step-kicker">Event erstellen</p>
<h1 id="intro-title">Hey <span id="username">{{username}}</span>, was hast du vor?</h1>
<h1 class="step-kicker">Event erstellen</h1>
<h2 id="intro-title">Hey <span id="username">{{username}}</span>, was hast du vor?</h2>
<p class="step-text">
Erzähl uns von deiner Idee vom Essen bis zur Stimmung. Ob Dinner, Brunch
oder etwas ganz Eigenes wir helfen dir dabei, dein Event in sieben Schritten aufzubauen.
oder etwas ganz Eigenes wir helfen dir dabei, dein Event Schritt für Schritt aufzubauen.
</p>
<button type="button" class="button button--primary button--intro" data-start-flow>
Los gehts!
</button>
</div>
<aside class="intro-card intro-card--image" aria-label="Stimmungsbild zur Event-Erstellung">
<img
class="intro-image"
src="assets/eventcreate_foodtable.jpg"
alt="Ein gedeckter Tisch mit gemeinsamem Essen"
/>
</aside>
</div>
</section>
@ -72,6 +63,11 @@
</div>
<div class="step-fields">
<div class="form-field">
<label for="eventTitle">Wie soll dein Event heissen?</label>
<input type="text" id="eventTitle" name="eventTitle" required />
</div>
<fieldset class="form-field">
<legend>Art des Essens / Eventtyp</legend>
@ -97,7 +93,47 @@
</label>
</div>
</fieldset>
</div>
</div>
</section>
<section class="step" data-step="2" aria-labelledby="step2-title">
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Schritt 2</p>
<h2 id="step2-title">Was kommt auf den Tisch?</h2>
<p class="step-text">
Mach uns neugierig. Was kochst du und wie fühlt sich dein Abend an?
Hier entsteht die Geschichte, auf die sich deine Gäste freuen.
</p>
</div>
<div class="step-fields">
<div class="form-field">
<label for="menuDescription">Was ist das Menü?</label>
<textarea id="menuDescription" name="menuDescription" rows="5" required></textarea>
</div>
<div class="form-field">
<label for="eventDescription">Beschreibung des Event-Abends</label>
<textarea id="eventDescription" name="eventDescription" rows="6" required></textarea>
</div>
</div>
</div>
</section>
<section class="step" data-step="3" aria-labelledby="step3-title">
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Schritt 3</p>
<h2 id="step3-title">Wen lädst du ein?</h2>
<p class="step-text">
Wie viele Gäste passen zu deinem Event? Und gibt es etwas, das du bei
Ernährung oder Unverträglichkeiten beachten möchtest?
</p>
</div>
<div class="step-fields">
<fieldset class="form-field">
<legend>Maximale Personenanzahl</legend>
@ -129,21 +165,7 @@
</button>
</div>
</fieldset>
</div>
</div>
</section>
<section class="step" data-step="2" aria-labelledby="step2-title">
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Schritt 2</p>
<h2 id="step2-title">Was kommt auf den Tisch?</h2>
<p class="step-text">
Mach uns neugierig. Was gibt es zu essen? Gibt es eine bestimmte Ernährungsform oder ein Motto? Je mehr du verrätst, desto besser können sich deine Gäste auf dein Event freuen.
</p>
</div>
<div class="step-fields">
<fieldset class="form-field">
<legend>Ernährungsform</legend>
@ -166,25 +188,6 @@
</div>
</fieldset>
<div class="form-field">
<label for="menuDescription">Was ist das Menü?</label>
<textarea id="menuDescription" name="menuDescription" rows="5" required></textarea>
</div>
</div>
</div>
</section>
<section class="step" data-step="3" aria-labelledby="step3-title">
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Schritt 3</p>
<h2 id="step3-title">Gibt es etwas zu beachten?</h2>
<p class="step-text">
Gibt es Allergien, Unverträglichkeiten oder andere Hinweise, die für dein Event wichtig sind? So wissen deine Gäste gleich, worauf sie sich einstellen können.
</p>
</div>
<div class="step-fields">
<fieldset class="form-field">
<legend>Allergene / Unverträglichkeiten</legend>
<p class="field-hint">Optional nur auswählen, wenn es für dein Event relevant ist.</p>
@ -205,12 +208,12 @@
<span>ohne Nüsse</span>
</label>
</div>
</fieldset>
<div class="form-field">
<label for="allergiesOther">Weitere Unverträglichkeiten oder Hinweise (optional)</label>
<textarea id="allergiesOther" name="allergiesOther" rows="3"></textarea>
</div>
<div class="form-field">
<label for="allergiesOther">Weitere Unverträglichkeiten oder Hinweise (optional)</label>
<textarea id="allergiesOther" name="allergiesOther" rows="3"></textarea>
</div>
</fieldset>
</div>
</div>
</section>
@ -221,7 +224,8 @@
<p class="step-kicker">Schritt 4</p>
<h2 id="step4-title">Wann findet dein Event statt?</h2>
<p class="step-text">
Wähle Datum und Uhrzeit für dein Event. So können deine Gäste direkt einschätzen, ob der Termin für sie passt.
Wähle Datum und Uhrzeit und sag uns, wo dein Event stattfindet.
Keine Sorge: Die genaue Adresse sehen Gäste erst nach der Buchung.
</p>
</div>
@ -237,21 +241,7 @@
<input type="time" id="eventTime" name="eventTime" required />
</div>
</div>
</div>
</div>
</section>
<section class="step" data-step="5" aria-labelledby="step5-title">
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Schritt 5</p>
<h2 id="step5-title">Wo findet dein Event statt?</h2>
<p class="step-text">
Sag uns, wo dein Event stattfindet. Keine Sorge: Die genaue Adresse sehen Gäste erst nach der Buchung.
</p>
</div>
<div class="step-fields">
<div class="form-field">
<label for="eventAddress">Adresse</label>
<input type="text" id="eventAddress" name="eventAddress" autocomplete="street-address" required />
@ -265,111 +255,81 @@
</div>
</section>
<section class="step" data-step="6" aria-labelledby="step6-title">
<section class="step" data-step="5" aria-labelledby="step5-title">
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Schritt 6</p>
<h2 id="step6-title">Gib deinem Event den letzten Schliff.</h2>
<p class="step-kicker">Schritt 5</p>
<h2 id="step5-title">Alles bereit für deine Gäste?</h2>
<p class="step-text">
Jetzt bekommt dein Event seinen Namen und die Atmosphäre, die Lust aufs Dabeisein macht.
Ein klarer Titel (z.B. "Italienische Tavolata") und ein guter Beschreibungstext (Ablauf etc.) machen den Unterschied.
</p>
</div>
<div class="step-fields">
<div class="form-field">
<label for="eventTitle">Wie soll dein Event heißen?</label>
<input type="text" id="eventTitle" name="eventTitle" required />
</div>
<div class="form-field">
<label for="eventDescription">Beschreibung des Event-Abends</label>
<textarea id="eventDescription" name="eventDescription" rows="6" required></textarea>
</div>
</div>
</div>
</section>
<section class="step" data-step="7" aria-labelledby="step7-title">
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Schritt 7</p>
<h2 id="step7-title">Dein Event auf einen Blick.</h2>
<p class="step-text">
Schau dir alle Details nochmal in Ruhe an. Wenn alles passt,
kannst du dein Event jetzt veröffentlichen und Gäste einladen.
Schau dir dein Event nochmal in Ruhe an. Passt alles?
Dann kannst du es jetzt veröffentlichen und Gäste einladen.
</p>
</div>
<div class="review-card" aria-live="polite">
<dl class="review-list">
<div class="review-item" data-edit-step="1" data-edit-field="eventType" role="button" tabindex="0" aria-label="Eventtyp bearbeiten">
<dt>Eventtyp</dt>
<dd data-review="eventType"></dd>
</div>
<div class="review-item" data-edit-step="1" data-edit-field="maxGuests" role="button" tabindex="0" aria-label="Maximale Personenanzahl bearbeiten">
<dt>Maximale Personenanzahl</dt>
<dd data-review="maxGuests"></dd>
</div>
<div class="review-item" data-edit-step="2" data-edit-field="dietType" role="button" tabindex="0" aria-label="Ernährungsform bearbeiten">
<dt>Ernährungsform</dt>
<dd data-review="dietType"></dd>
</div>
<div class="review-item" data-edit-step="2" data-edit-field="menuDescription" role="button" tabindex="0" aria-label="Menü bearbeiten">
<dt>Menü</dt>
<dd data-review="menuDescription"></dd>
</div>
<div class="review-item" data-edit-step="3" data-edit-field="allergiesOther" role="button" tabindex="0" aria-label="Allergene und Unverträglichkeiten bearbeiten">
<dt>Allergene / Unverträglichkeiten</dt>
<dd data-review="allergies">Keine Angabe</dd>
</div>
<div class="review-item" data-edit-step="4" data-edit-field="eventDate" role="button" tabindex="0" aria-label="Datum bearbeiten">
<dt>Datum</dt>
<dd data-review="eventDate"></dd>
</div>
<div class="review-item" data-edit-step="4" data-edit-field="eventTime" role="button" tabindex="0" aria-label="Uhrzeit bearbeiten">
<dt>Uhrzeit</dt>
<dd data-review="eventTime"></dd>
</div>
<div class="review-item" data-edit-step="5" data-edit-field="eventAddress" role="button" tabindex="0" aria-label="Adresse bearbeiten">
<dt>Adresse</dt>
<dd data-review="eventAddress"></dd>
</div>
<div class="review-item" data-edit-step="5" data-edit-field="eventCity" role="button" tabindex="0" aria-label="Ort bearbeiten">
<dt>Ort</dt>
<dd data-review="eventCity"></dd>
</div>
<div class="review-item" data-edit-step="6" data-edit-field="eventTitle" role="button" tabindex="0" aria-label="Eventtitel bearbeiten">
<div class="review-item">
<dt>Eventtitel</dt>
<dd data-review="eventTitle"></dd>
</div>
<div class="review-item" data-edit-step="6" data-edit-field="eventDescription" role="button" tabindex="0" aria-label="Event-Abend bearbeiten">
<div class="review-item">
<dt>Eventtyp</dt>
<dd data-review="eventType"></dd>
</div>
<div class="review-item">
<dt>Menü</dt>
<dd data-review="menuDescription"></dd>
</div>
<div class="review-item">
<dt>Event-Abend</dt>
<dd data-review="eventDescription"></dd>
</div>
<div class="review-item">
<dt>Maximale Personenanzahl</dt>
<dd data-review="maxGuests"></dd>
</div>
<div class="review-item">
<dt>Ernährungsform</dt>
<dd data-review="dietType"></dd>
</div>
<div class="review-item">
<dt>Allergene / Unverträglichkeiten</dt>
<dd data-review="allergies">Keine Angabe</dd>
</div>
<div class="review-item">
<dt>Datum</dt>
<dd data-review="eventDate"></dd>
</div>
<div class="review-item">
<dt>Uhrzeit</dt>
<dd data-review="eventTime"></dd>
</div>
<div class="review-item">
<dt>Adresse</dt>
<dd data-review="eventAddress"></dd>
</div>
<div class="review-item">
<dt>Ort</dt>
<dd data-review="eventCity"></dd>
</div>
</dl>
</div>
</div>
</section>
<div class="flow-footer" id="flowFooter" hidden>
<div class="progress-wrap" aria-hidden="true">
<div class="progress-marker" id="progressMarker">
<span class="progress-marker__circle" id="progressMarkerLabel">1</span>
</div>
<div class="progress">
<span id="progressBar" class="progress-bar"></span>
</div>
<div class="progress" aria-hidden="true">
<span id="progressBar" class="progress-bar"></span>
</div>
<div class="flow-actions">
@ -381,31 +341,6 @@
</div>
</div>
</div>
<section
id="submissionSuccess"
class="submission-success"
aria-labelledby="success-title"
aria-live="polite"
hidden
>
<div class="step-layout">
<div class="step-copy">
<p class="step-kicker">Event erstellt</p>
<h2 id="success-title">Dein Event ist ready.</h2>
<p class="step-text">
Sieht gut aus: Deine Idee ist jetzt live und bereit für Gäste.
Im Profil kannst du dein Event anschauen, verwalten oder direkt das nächste planen.
</p>
</div>
<div class="review-card review-card--success">
<div class="submission-success-actions">
<a class="button button--primary" href="event_overview.html">Weiter zu deinem Profil</a>
</div>
</div>
</div>
</section>
</form>
</main>
@ -415,4 +350,4 @@
<script src="js/event_create.js"></script>
</body>
</html>
</html>

View File

@ -4,24 +4,23 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event-Detail</title>
<!-- Stylesheet für diese Seite-->
<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=Bagel+Fat+One&family=Jost:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/event_overview.css">
<!-- Globales Stylesheet -->
<link rel="stylesheet" href="css/stylesheet_global.css">
</head>
<body>
<!-- Top Navigation mit Seitenlinks -->
<header class="top-nav-wrap">
<div class="top-nav">
<a class="brand" href="index.html" aria-label="Zur Startseite">
<img src="assets/logo_invite.svg" alt="Invite Logo">
<img src="assets/invite-logo.svg" alt="Invite Logo">
</a>
<nav class="nav-tab-links" aria-label="Hauptnavigation">
<a class="nav-tab" href="event_overview.html">Event finden</a>
<a class="nav-tab" href="event_create.html">Event erstellen</a>
<a class="button-small" href="login.html" aria-label="Profil">Login</a>
<nav class="top-nav-links" aria-label="Hauptnavigation">
<a class="nav-link active" href="event_overview.html" aria-current="page">Event finden</a>
<a class="nav-link" href="event_create.html">Event erstellen</a>
<a class="profile-pill" href="login.html" aria-label="Profil">M</a>
</nav>
</div>
</header>

View File

@ -6,22 +6,23 @@
<title>Event-Overview</title>
<!-- Stylesheet für diese Seite-->
<link rel="stylesheet" href="css/event_overview.css">
<!-- Globales Stylesheet -->
<link rel="stylesheet" href="css/stylesheet_global.css">
</head>
<!-- Globales Stylesheet -->
<link rel="stylesheet" href="stylesheet.css">
</head>
<body>
<!-- Top Navigation mit Seitenlinks -->
<header class="top-nav-wrap">
<div class="top-nav">
<a class="brand" href="index.html" aria-label="Zur Startseite">
<img src="assets/logo_invite.svg" alt="Invite Logo">
<img src="assets/invite-logo.svg" alt="Invite Logo">
</a>
<nav class="nav-tab-links" aria-label="Hauptnavigation">
<a class="nav-tab" href="event_overview.html">Event finden</a>
<a class="nav-tab" href="event_create.html">Event erstellen</a>
<a class="button-small" href="login.html" aria-label="Profil">Login</a>
<nav class="top-nav-links" aria-label="Hauptnavigation">
<a class="nav-link active" href="event_overview.html" aria-current="page">Event finden</a>
<a class="nav-link" href="event_create.html">Event erstellen</a>
<a class="profile-pill" href="login.html" aria-label="Profil">M</a>
</nav>
</div>
</header>

View File

@ -3,30 +3,20 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Invité | Events entdecken</title>
<!-- Stylesheet für diese Seite-->
<link rel="stylesheet" href="css/landingpage.css?v=2" />
<!-- Globales Stylesheet -->
<link rel="stylesheet" href="css/stylesheet_global.css?v=2">
<!-- Font Awesome
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" integrity="sha512-dU7ZrF1pFq5kVnPzlV9+04YhARzNjCX5Q5P1shgMpuN4s5I8mI8QD4981h7kYtV7sSgNldR0z5pZW5bS2ZpY3Q==" crossorigin="anonymous" referrerpolicy="no-referrer" /> -->
<title>Social Cooking Wireframe</title>
<link rel="stylesheet" href="css/landingpage.css" />
</head>
<body>
<!-- Top Navigation mit Seitenlinks -->
<header class="top-nav-wrap">
<div class="top-nav">
<a class="brand" href="index.html" aria-label="Zur Startseite">
<img src="assets/logo_invite.svg" alt="Invite Logo">
</a>
<nav class="nav-tab-links" aria-label="Hauptnavigation">
<a class="nav-tab" href="event_overview.html">Event finden</a>
<a class="nav-tab" href="event_create.html">Event erstellen</a>
<a class="button-small" href="login.html" aria-label="Profil">Login</a>
</nav>
</div>
<div class="page-wrapper">
<header class="header">
<div class="header__brand">LOGO</div>
<div class="header__actions">
<nav class="nav">
<a class="nav__link btn btn--outline" href="event_overview.html">Event finden</a>
</nav>
<a class="btn btn--outline" href="login.html">Login</a>
</div>
</header>
<main class="main-content">
@ -120,7 +110,7 @@
<div class="gallery__info">
<div class="gallery__handle" style="display: flex; align-items: center; gap: 16px;">
<img src="assets/instagram.png" alt="Instagram" class="gallery__icon--instagram" />
<img src="assets/logo_invite.svg" alt="Invité Logo" class="gallery__icon--invite" />
<img src="assets/invite-logo.svg" alt="Invité Logo" class="gallery__icon--invite" />
</div>
</div>
</section>

View File

@ -8,13 +8,9 @@ const steps = Array.from(document.querySelectorAll(".step"));
const backButton = document.getElementById("backButton");
const nextButton = document.getElementById("nextButton");
const progressBar = document.getElementById("progressBar");
const progressMarker = document.getElementById("progressMarker");
const progressMarkerLabel = document.getElementById("progressMarkerLabel");
const errorMessage = document.getElementById("errorMessage");
const usernameElement = document.getElementById("username");
const flowFooter = document.getElementById("flowFooter");
const submissionSuccess = document.getElementById("submissionSuccess");
const EVENTS_STORAGE_KEY = "socialCookingEvents";
// =============================
// STATE: aktueller Schritt im Flow
@ -31,9 +27,7 @@ const nextLabels = {
2: "Weiter",
3: "Weiter",
4: "Weiter",
5: "Weiter",
6: "Weiter",
7: "Event veröffentlichen"
5: "Event veröffentlichen"
};
// Demo-Wert: Später könnte der Name z. B. aus einem User-Profil kommen
@ -63,39 +57,6 @@ function setErrorMessage(message = "") {
errorMessage.textContent = message;
}
/**
* Entfernt alle Fehlermarkierungen innerhalb eines Schritts.
*/
function clearStepInvalidState(stepIndex) {
if (!steps[stepIndex]) return;
steps[stepIndex]
.querySelectorAll(".field-invalid, .option-card--invalid")
.forEach(element => {
element.classList.remove("field-invalid", "option-card--invalid");
});
}
/**
* Markiert ein einzelnes Feld visuell als ungültig.
*/
function markFieldInvalid(field) {
field.classList.add("field-invalid");
}
/**
* Markiert eine ganze Radio-Gruppe visuell als ungültig.
*/
function markRadioGroupInvalid(group) {
group.forEach(field => {
const card = field.closest(".option-card");
if (card) {
card.classList.add("option-card--invalid");
}
});
}
// =============================
// STEP 2: Schritt anzeigen & Oberfläche aktualisieren
@ -110,8 +71,6 @@ function markRadioGroupInvalid(group) {
*/
function showStep(index) {
currentStep = index;
submissionSuccess.hidden = true;
clearStepInvalidState(index);
// Nur der aktuelle Schritt soll sichtbar sein
steps.forEach((step, stepIndex) => {
@ -156,21 +115,12 @@ function updateFlowVisibility(stepIndex) {
*/
function updateProgressBar(stepIndex, totalStepIndex) {
let progress = 0;
let markerPosition = 0;
let markerStep = 1;
let markerTransform = "translateX(-50%)";
if (stepIndex > 0) {
progress = ((stepIndex - 1) / (totalStepIndex - 1)) * 100;
markerPosition = ((stepIndex - 1) / (totalStepIndex - 1)) * 100;
markerStep = stepIndex;
}
progressBar.style.width = `${progress}%`;
progressMarker.style.left = `${markerPosition}%`;
progressMarker.style.transform = markerTransform;
progressMarker.hidden = stepIndex === 0;
progressMarkerLabel.textContent = String(markerStep);
}
@ -275,18 +225,7 @@ function buildAllergiesReviewValue() {
* und schreibt sie gesammelt in die Review-Ansicht.
*/
function updateReview() {
const reviewValues = getReviewValues();
Object.entries(reviewValues).forEach(([key, value]) => {
updateReviewField(key, value);
});
}
/**
* Liest alle wichtigen Formularwerte gesammelt aus.
*/
function getReviewValues() {
return {
const reviewValues = {
eventTitle: getFieldValue("eventTitle"),
eventType: getFieldValue("eventType"),
menuDescription: getFieldValue("menuDescription"),
@ -299,137 +238,12 @@ function getReviewValues() {
eventAddress: getFieldValue("eventAddress"),
eventCity: getFieldValue("eventCity")
};
Object.entries(reviewValues).forEach(([key, value]) => {
updateReviewField(key, value);
});
}
/**
* Liest lokal gespeicherte Events robust aus dem Browser-Storage.
*/
function getStoredEvents() {
try {
const stored = localStorage.getItem(EVENTS_STORAGE_KEY);
return stored ? JSON.parse(stored) : [];
} catch (error) {
console.error("Lokale Events konnten nicht gelesen werden:", error);
return [];
}
}
/**
* Speichert die komplette Eventliste zurück in den Browser-Storage.
*/
function setStoredEvents(events) {
localStorage.setItem(EVENTS_STORAGE_KEY, JSON.stringify(events));
}
/**
* Formatiert ein ISO-Datum in das bestehende Eventformat der Demo-Daten.
*/
function formatDateForStorage(value) {
if (!value) return "";
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
const monthMap = {
0: "JAN",
1: "FEB",
2: "MRZ",
3: "APR",
4: "MAI",
5: "JUN",
6: "JUL",
7: "AUG",
8: "SEP",
9: "OKT",
10: "NOV",
11: "DEZ"
};
const day = String(date.getDate()).padStart(2, "0");
const month = monthMap[date.getMonth()];
const year = date.getFullYear();
return `${day}. ${month}. ${year}`;
}
/**
* Formatiert die Zeit in das bestehende Eventformat der Demo-Daten.
*/
function formatTimeForStorage(value) {
return value ? `${value} UHR` : "";
}
/**
* Zerlegt das Menü-Textarea in saubere Listenpunkte.
*/
function buildMenuItems(value) {
return value
.split("\n")
.map(item => item.replace(/^[•-]\s*/, "").trim())
.filter(Boolean);
}
/**
* Leitet den gewählten Eventtyp in die Kategorien der Übersicht über.
*/
function mapEventTypeToCategory(value) {
const categoryMap = {
Brunch: "BRUNCH",
Lunch: "LUNCH",
Dinner: "DINNER",
"Kaffee + Kuchen": "COFFEE"
};
return categoryMap[value] || value.toUpperCase();
}
/**
* Baut aus den Formulardaten ein lokal speicherbares Event-Objekt.
*/
function buildStoredEvent() {
const eventType = getFieldValue("eventType");
const dietType = getFieldValue("dietType");
const menuDescription = form.elements.menuDescription.value.trim();
const eventDescription = form.elements.eventDescription.value.trim();
const eventDate = form.elements.eventDate.value;
const eventTime = form.elements.eventTime.value;
const eventCity = form.elements.eventCity.value.trim();
return {
id: Date.now(),
title: form.elements.eventTitle.value.trim(),
location: eventCity,
address: form.elements.eventAddress.value.trim(),
date: formatDateForStorage(eventDate),
time: formatTimeForStorage(eventTime),
category: mapEventTypeToCategory(eventType),
diet: dietType,
spots: Number(form.elements.maxGuests.value),
host: {
name: usernameElement.textContent.trim() || "Host",
initial: (usernameElement.textContent.trim().charAt(0) || "H").toUpperCase()
},
hostMessage: [eventDescription],
menu: buildMenuItems(menuDescription),
specifications: getCheckboxValues("allergies") === "Keine Angabe"
? []
: getCheckboxValues("allergies").split(", ").filter(Boolean),
allergiesNote: form.elements.allergiesOther.value.trim(),
participants: [usernameElement.textContent.trim() || "Host"],
gallery: [],
createdAt: new Date().toISOString(),
source: "local"
};
}
/**
* Speichert das aktuell erstellte Event lokal im Browser.
*/
function saveCurrentEvent() {
const storedEvents = getStoredEvents();
const nextEvents = [buildStoredEvent(), ...storedEvents];
setStoredEvents(nextEvents);
}
// =============================
// STEP 5: Validierung
@ -449,7 +263,6 @@ function validateCurrentStep() {
if (currentStep === 0 || currentStep === lastStep) return true;
const fields = getStepFields(currentStep);
clearStepInvalidState(currentStep);
// Zuerst Radio-Gruppen prüfen
const radioCheck = validateRadioGroups(fields);
@ -484,7 +297,6 @@ function validateRadioGroups(fields) {
const selected = group.some(f => f.checked);
if (required && !selected) {
markRadioGroupInvalid(group);
return {
isValid: false,
message: "Bitte wähle eine Option aus."
@ -506,7 +318,6 @@ function validateRequiredFields(fields) {
if (field.type === "radio" || field.type === "checkbox") continue;
if (!field.checkValidity()) {
markFieldInvalid(field);
return {
isValid: false,
message: "Bitte fülle alle Pflichtfelder aus."
@ -563,12 +374,11 @@ function handleNextClick() {
*/
function handleFormSubmit(event) {
event.preventDefault();
saveCurrentEvent();
steps.forEach(step => step.classList.remove("step--active"));
flowFooter.hidden = true;
submissionSuccess.hidden = false;
setErrorMessage("");
window.scrollTo({ top: 0, behavior: "smooth" });
// 1. Feedback geben
alert("Dein Event wurde erfolgreich veröffentlicht!");
// 2. Weiterleiten (z. B. zur Event-Übersicht)
window.location.href = "event_overview.html";
}
@ -602,126 +412,6 @@ function updateCounterValue(input, change) {
input.value = Math.max(min, currentValue + change);
}
/**
* Macht aus "-"+Enter im Menüfeld eine einfache Bullet-Liste.
*/
function registerMenuBulletHandler() {
const menuField = document.getElementById("menuDescription");
if (!menuField) return;
menuField.addEventListener("keydown", event => {
if (event.key !== "Enter") return;
const { selectionStart, selectionEnd, value } = menuField;
const lineStart = value.lastIndexOf("\n", selectionStart - 1) + 1;
const lineEnd = value.indexOf("\n", selectionStart);
const currentLineEnd = lineEnd === -1 ? value.length : lineEnd;
const currentLine = value.slice(lineStart, currentLineEnd);
const trimmedLine = currentLine.trim();
if (trimmedLine !== "-" && !currentLine.startsWith("• ")) return;
event.preventDefault();
const isEmptyBullet = currentLine.trim() === "•";
if (isEmptyBullet) {
const beforeLine = value.slice(0, lineStart);
const afterLine = value.slice(currentLineEnd);
const separator = beforeLine.endsWith("\n") || afterLine.startsWith("\n") ? "" : "\n";
const nextValue = `${beforeLine}${separator}${afterLine}`.replace(/\n{3,}/g, "\n\n");
menuField.value = nextValue;
const caretPosition = Math.min(lineStart, nextValue.length);
menuField.setSelectionRange(caretPosition, caretPosition);
menuField.dispatchEvent(new Event("input", { bubbles: true }));
return;
}
const bulletLine = currentLine.startsWith("• ") ? currentLine : currentLine.replace("-", "•");
const updatedLine = bulletLine.startsWith("• ") ? bulletLine : `${trimmedLine.slice(1).trimStart()}`;
const beforeLine = value.slice(0, lineStart);
const afterLine = value.slice(currentLineEnd);
const nextValue = `${beforeLine}${updatedLine}\n${afterLine}`;
const caretPosition = beforeLine.length + updatedLine.length + 3;
menuField.value = nextValue;
menuField.setSelectionRange(caretPosition, caretPosition);
menuField.dispatchEvent(new Event("input", { bubbles: true }));
});
}
/**
* Springt aus der Review zurück zum passenden Schritt
* und fokussiert das gewünschte Feld für direktes Weiterbearbeiten.
*/
function registerReviewEditHandlers() {
document.querySelectorAll(".review-item[data-edit-step]").forEach(item => {
const activateEdit = () => {
const stepIndex = Number(item.dataset.editStep);
const fieldName = item.dataset.editField;
showStep(stepIndex);
focusFieldByName(fieldName);
};
item.addEventListener("click", activateEdit);
item.addEventListener("keydown", event => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
activateEdit();
}
});
});
}
/**
* Entfernt Fehlermarkierungen, sobald der User ein Feld korrigiert.
*/
function registerValidationFeedbackHandlers() {
form.querySelectorAll("input, textarea, select").forEach(field => {
const clearInvalidState = () => {
field.classList.remove("field-invalid");
if (field.type === "radio") {
const group = Array.from(form.querySelectorAll(`input[name="${field.name}"]`));
const hasSelection = group.some(item => item.checked);
if (hasSelection) {
group.forEach(item => {
const card = item.closest(".option-card");
if (card) {
card.classList.remove("option-card--invalid");
}
});
}
}
};
field.addEventListener("input", clearInvalidState);
field.addEventListener("change", clearInvalidState);
});
}
/**
* Setzt den Fokus auf ein bestimmtes Feld oder die erste Option einer Radio-Gruppe.
*/
function focusFieldByName(fieldName) {
const field = form.elements[fieldName];
if (!field) return;
const focusTarget = field instanceof RadioNodeList ? field[0] : field;
if (focusTarget && typeof focusTarget.focus === "function") {
window.setTimeout(() => {
focusTarget.focus();
}, 150);
}
}
// =============================
// STEP 9: Alles starten
@ -748,14 +438,10 @@ function initEventCreationFlow() {
// Counter aktivieren
registerCounterHandlers();
registerMenuBulletHandler();
registerValidationFeedbackHandlers();
registerReviewEditHandlers();
// Startzustand: Intro anzeigen
submissionSuccess.hidden = true;
showStep(0);
}
// Startpunkt des Skripts
initEventCreationFlow();
initEventCreationFlow();

View File

@ -1,5 +1,4 @@
document.addEventListener('DOMContentLoaded', async () => {
const EVENTS_STORAGE_KEY = 'socialCookingEvents';
// -------------------------------------------------------------
// DOM entry point and shared asset path.
// -------------------------------------------------------------
@ -15,21 +14,10 @@ document.addEventListener('DOMContentLoaded', async () => {
return;
}
function getStoredEvents() {
try {
const stored = localStorage.getItem(EVENTS_STORAGE_KEY);
return stored ? JSON.parse(stored) : [];
} catch (error) {
console.error('Lokale Events konnten nicht gelesen werden.', error);
return [];
}
}
// Fetch data source and resolve the matching event record.
try {
const response = await fetch('data/events.json');
const apiEvents = await response.json();
const allEvents = [...getStoredEvents(), ...apiEvents];
const allEvents = await response.json();
const event = allEvents.find(e => e.id === eventId);
if (event) {
@ -269,4 +257,4 @@ document.addEventListener('DOMContentLoaded', async () => {
});
}
}
});
});

View File

@ -1,5 +1,4 @@
document.addEventListener('DOMContentLoaded', () => {
const EVENTS_STORAGE_KEY = 'socialCookingEvents';
// -------------------------------------------------------------
// DOM references used throughout the page lifecycle.
// -------------------------------------------------------------
@ -15,16 +14,6 @@ document.addEventListener('DOMContentLoaded', () => {
let allEvents = [];
let activeCategory = 'ALLE';
function getStoredEvents() {
try {
const stored = localStorage.getItem(EVENTS_STORAGE_KEY);
return stored ? JSON.parse(stored) : [];
} catch (error) {
console.error('Lokale Events konnten nicht gelesen werden.', error);
return [];
}
}
// -------------------------------------------------------------
// Initial data bootstrap:
// 1) fetch JSON,
@ -35,9 +24,7 @@ document.addEventListener('DOMContentLoaded', () => {
async function fetchEvents() {
try {
const response = await fetch('data/events.json');
const apiEvents = await response.json();
const localEvents = getStoredEvents();
allEvents = [...localEvents, ...apiEvents];
allEvents = await response.json();
populateMetaFilters();
const savedCategory = sessionStorage.getItem('activeFilter') || 'ALLE';
@ -75,10 +62,6 @@ document.addEventListener('DOMContentLoaded', () => {
// Convert localized event date (e.g. 19. MÄR. 2026) into ISO format for date input comparison.
function parseEventDateToIso(dateString) {
if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
return dateString;
}
const months = {
JAN: '01',
FEB: '02',
@ -109,11 +92,6 @@ document.addEventListener('DOMContentLoaded', () => {
// Convert short month notation into full German month label for UI display.
function formatEventDate(dateString) {
if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
const [year, month, day] = dateString.split('-');
return `${Number(day)}. ${['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'][Number(month) - 1]} ${year}`;
}
const labels = {
JAN: 'Januar',
FEB: 'Februar',
@ -144,13 +122,7 @@ document.addEventListener('DOMContentLoaded', () => {
// Normalize time label from UHR to Uhr for consistent typography.
function formatEventTime(timeString) {
if (!timeString) {
return '';
}
return timeString.includes('UHR')
? timeString.replace('UHR', 'Uhr').trim()
: `${timeString} Uhr`;
return timeString.replace('UHR', 'Uhr').trim();
}
// Safely verify whether a value exists in the given select element.

View File

@ -17,12 +17,12 @@
<header class="top-nav-wrap">
<div class="top-nav">
<a class="brand" href="index.html" aria-label="Zur Startseite">
<img src="assets/logo_invite.svg" alt="Invite Logo">
<img src="assets/invite-logo.svg" alt="Invite Logo">
</a>
<nav class="nav-tab-links" aria-label="Hauptnavigation">
<a class="nav-tab" href="event_overview.html">Event finden</a>
<a class="nav-tab" href="event_create.html">Event erstellen</a>
<a class="button-small" href="login.html" aria-label="Profil">Login</a>
<nav class="button-small-links" aria-label="Hauptnavigation">
<a class="button-small" href="event_overview.html">Event finden</a>
<a class="button-small" href="event_create.html">Event erstellen</a>
<a class="button-login" href="login.html" aria-label="Profil">Login</a>
</nav>
</div>
</header>

View File

@ -9,19 +9,19 @@
<link rel="stylesheet" href="css/login_signup.css">
<!-- Globales Stylesheet -->
<link rel="stylesheet" href="css/stylesheet_global.css">
</head>
</head>
<body>
<!-- Top Navigation mit Seitenlinks -->
<header class="top-nav-wrap">
<div class="top-nav">
<a class="brand" href="index.html" aria-label="Zur Startseite">
<img src="assets/logo_invite.svg" alt="Invite Logo">
<img src="assets/invite-logo.svg" alt="Invite Logo">
</a>
<nav class="nav-tab-links" aria-label="Hauptnavigation">
<a class="nav-tab" href="event_overview.html">Event finden</a>
<a class="nav-tab" href="event_create.html">Event erstellen</a>
<a class="button-small" href="login.html" aria-label="Profil">Login</a>
<nav class="button-small-links" aria-label="Hauptnavigation">
<a class="button-small" href="event_overview.html">Event finden</a>
<a class="button-small" href="event_create.html">Event erstellen</a>
<a class="button-login" href="login.html" aria-label="Profil">Login</a>
</nav>
</div>
</header>