Vibecoded basic filter system based on wireframe layout using json and js. rearragend folder strcuture in this branch.
This commit is contained in:
parent
7cebec338e
commit
4da3c0741a
54
css/event_overview_stylesheet.css
Normal file
54
css/event_overview_stylesheet.css
Normal file
@ -0,0 +1,54 @@
|
||||
:root {
|
||||
--black: #000;
|
||||
--white: #fff;
|
||||
--gray-bg: #f4f4f4;
|
||||
--border: 1px solid #000;
|
||||
}
|
||||
|
||||
body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
|
||||
.container { max-width: 1100px; margin: 0 auto; padding: 20px; }
|
||||
|
||||
/* Navbar & Filter */
|
||||
.navbar { display: flex; justify-content: space-between; padding: 20px 5%; border-bottom: var(--border); }
|
||||
.category-group { display: flex; gap: 20px; margin-bottom: 40px; flex-wrap: wrap; }
|
||||
.category-item { cursor: pointer; text-align: center; font-size: 11px; font-weight: bold; }
|
||||
.square { width: 50px; height: 50px; border: var(--border); margin-bottom: 5px; }
|
||||
.category-item.active .square { background: var(--black); }
|
||||
|
||||
/* Event Cards */
|
||||
.event-list { display: flex; flex-direction: column; gap: 20px; }
|
||||
.event-card {
|
||||
display: grid;
|
||||
grid-template-columns: 200px 1fr 150px 150px 50px;
|
||||
border: var(--border);
|
||||
align-items: center;
|
||||
}
|
||||
.event-image { height: 150px; background-size: cover; background-position: center; border-right: var(--border); }
|
||||
.event-content, .event-info, .event-cta { padding: 15px; }
|
||||
.tag { border: var(--border); padding: 3px 10px; border-radius: 15px; font-size: 10px; margin-right: 5px; }
|
||||
.btn-primary { background: var(--black); color: var(--white); border: none; padding: 10px; width: 100%; cursor: pointer; font-weight: bold; }
|
||||
|
||||
/* Empty State Style */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 50px 20px;
|
||||
border: 2px dashed #ccc;
|
||||
background: var(--gray-bg);
|
||||
margin-top: 20px;
|
||||
}
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
border: 2px solid var(--black);
|
||||
padding: 12px 25px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
margin-top: 15px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
.btn-outline:hover { background: var(--black); color: var(--white); }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 850px) {
|
||||
.event-card { grid-template-columns: 1fr; }
|
||||
.event-image { border-right: none; border-bottom: var(--border); width: 100%; }
|
||||
}
|
||||
38
data/events.json
Normal file
38
data/events.json
Normal file
@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Italienische Tavolata",
|
||||
"location": "LUZERN",
|
||||
"date": "19. MÄR. 2026",
|
||||
"time": "18:30 UHR",
|
||||
"category": "DINNER",
|
||||
"cuisine": "ITALIENISCH",
|
||||
"diet": "VEGGIE",
|
||||
"spots": 4,
|
||||
"image": "https://via.placeholder.com/300x200"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "Noche Peruana",
|
||||
"location": "LUZERN",
|
||||
"date": "11. APR. 2026",
|
||||
"time": "19:00 UHR",
|
||||
"category": "DINNER",
|
||||
"cuisine": "PERUANISCH",
|
||||
"diet": "FLEISCH",
|
||||
"spots": 2,
|
||||
"image": "https://via.placeholder.com/300x200"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "Japanese Delight",
|
||||
"location": "ZÜRICH",
|
||||
"date": "02. MAI. 2026",
|
||||
"time": "12:30 UHR",
|
||||
"category": "LUNCH",
|
||||
"cuisine": "JAPANISCH",
|
||||
"diet": "FISCH",
|
||||
"spots": 8,
|
||||
"image": "https://via.placeholder.com/300x200"
|
||||
}
|
||||
]
|
||||
36
event_overview.html
Normal file
36
event_overview.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Event_Overview</title>
|
||||
<link rel="stylesheet" href="css/event_overview_stylesheet.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="navbar">
|
||||
<div class="logo">SOCIAL COOKING</div>
|
||||
<nav>
|
||||
<span>Events</span>
|
||||
<div class="user-profile">M</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Invité Events</h1>
|
||||
|
||||
<section class="filter-section">
|
||||
<p class="filter-label">WORAUF HAST DU LUST</p>
|
||||
<div class="category-group">
|
||||
<div class="category-item" data-cat="BRUNCH"><div class="square"></div><span>BRUNCH</span></div>
|
||||
<div class="category-item" data-cat="LUNCH"><div class="square"></div><span>LUNCH</span></div>
|
||||
<div class="category-item" data-cat="DINNER"><div class="square"></div><span>DINNER</span></div>
|
||||
<div class="category-item" data-cat="COFFEE"><div class="square"></div><span>COFFEE</span></div>
|
||||
<div class="category-item active" data-cat="ALLE"><div class="square"></div><span>ALLE</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="event-grid" class="event-list"></section>
|
||||
</main>
|
||||
<script src="js/event_overview_script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
81
js/event_overview_script.js
Normal file
81
js/event_overview_script.js
Normal file
@ -0,0 +1,81 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const eventGrid = document.getElementById('event-grid');
|
||||
const filterButtons = document.querySelectorAll('.category-item');
|
||||
let allEvents = [];
|
||||
|
||||
// 1. Daten laden
|
||||
async function fetchEvents() {
|
||||
try {
|
||||
// Pfad an deine Ordnerstruktur angepasst
|
||||
const response = await fetch('data/events.json');
|
||||
allEvents = await response.json();
|
||||
renderEvents(allEvents);
|
||||
} catch (error) {
|
||||
console.error("Fehler:", error);
|
||||
eventGrid.innerHTML = "<p>Events konnten nicht geladen werden.</p>";
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Events rendern + "Empty State" Logik
|
||||
function renderEvents(events) {
|
||||
eventGrid.innerHTML = '';
|
||||
|
||||
// PRÜFUNG: Wenn keine Events vorhanden sind
|
||||
if (events.length === 0) {
|
||||
eventGrid.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<h3>Schade! Aktuell gibt es hier keine Events.</h3>
|
||||
<p>Möchtest du vielleicht selbst Gastgeber sein?</p>
|
||||
<button class="btn-outline" onclick="alert('Hier gehts zum Formular!')">Eigenes Event erstellen</button>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
// Wenn Events da sind, Karten bauen
|
||||
events.forEach(event => {
|
||||
const card = document.createElement('article');
|
||||
card.className = 'event-card';
|
||||
card.innerHTML = `
|
||||
<div class="event-image" style="background-image: url('${event.image}')"></div>
|
||||
<div class="event-content">
|
||||
<small>📍 ${event.location}</small>
|
||||
<h2 style="margin: 5px 0;">${event.title}</h2>
|
||||
<div>
|
||||
<span class="tag">${event.cuisine}</span>
|
||||
<span class="tag">${event.category}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="event-info">
|
||||
<strong>${event.date}</strong><br>
|
||||
<span>🕒 ${event.time}</span>
|
||||
</div>
|
||||
<div class="event-cta">
|
||||
<div style="font-size: 12px; margin-bottom: 8px;">🥗 ${event.diet}</div>
|
||||
<button class="btn-primary">Anmelden</button>
|
||||
<p style="font-size: 10px; margin-top: 8px;">${event.spots} PLÄTZE FREI</p>
|
||||
</div>
|
||||
<div style="text-align: center;">❤️</div>
|
||||
`;
|
||||
eventGrid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Filter-Logik
|
||||
filterButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
filterButtons.forEach(btn => btn.classList.remove('active'));
|
||||
button.classList.add('active');
|
||||
|
||||
const selectedCat = button.getAttribute('data-cat');
|
||||
|
||||
const filtered = selectedCat === 'ALLE'
|
||||
? allEvents
|
||||
: allEvents.filter(e => e.category === selectedCat);
|
||||
|
||||
renderEvents(filtered);
|
||||
});
|
||||
});
|
||||
|
||||
fetchEvents();
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user