Set up modern PHP MVC project structure for GetYourBand platform

- Implemented clean MVC architecture with Router, Controller, and Model base classes
- Created database migrations for users, bands, bookings, reviews, and availability
- Set up Tailwind CSS with yellow color scheme and modern design
- Added Alpine.js for reactive JavaScript components
- Configured Vite for asset building and hot module replacement
- Created authentication and role-based middleware
- Implemented helper functions and configuration system
- Added comprehensive README with setup instructions
- Configured Apache with proper rewrite rules and security headers
- Set up Composer and npm package management with modern dependencies
This commit is contained in:
Claude
2025-12-02 21:31:08 +00:00
parent 798a2785e7
commit 143fe3d488
37 changed files with 2015 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
<?php ob_start(); ?>
<!-- Hero Section -->
<section class="bg-gradient-to-br from-primary-500 via-accent-500 to-primary-600 text-white py-20">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h1 class="text-5xl md:text-6xl font-display font-bold mb-6 text-balance">
Finde die perfekte Band für dein Event
</h1>
<p class="text-xl md:text-2xl mb-8 text-primary-50 max-w-3xl mx-auto text-balance">
Professionelle Live-Bands in der ganzen Schweiz. Einfach buchen, perfekt performen.
</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a href="/bands" class="btn bg-white text-primary-600 hover:bg-gray-100 text-lg px-8 py-3">
Bands entdecken
</a>
<a href="/register" class="btn bg-primary-700 text-white hover:bg-primary-800 text-lg px-8 py-3">
Als Band registrieren
</a>
</div>
</div>
</section>
<!-- Search Section -->
<section class="py-16 bg-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="bg-gray-50 rounded-2xl shadow-lg p-8" x-data="searchBands">
<h2 class="text-3xl font-display font-bold text-center mb-8">Suche deine Band</h2>
<form @submit.prevent="search" class="grid grid-cols-1 md:grid-cols-4 gap-4">
<input
type="text"
x-model="query"
placeholder="Band, Genre, Stil..."
class="input-field"
>
<input
type="text"
x-model="filters.location"
placeholder="Ort oder PLZ"
class="input-field"
>
<select x-model="filters.genre" class="input-field">
<option value="">Alle Genres</option>
<option value="Rock">Rock</option>
<option value="Pop">Pop</option>
<option value="Jazz">Jazz</option>
<option value="Blues">Blues</option>
<option value="Funk">Funk</option>
<option value="Cover">Cover</option>
</select>
<button type="submit" class="btn btn-primary">
Suchen
</button>
</form>
</div>
</div>
</section>
<!-- Featured Bands -->
<section class="py-16 bg-gray-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h2 class="text-4xl font-display font-bold text-center mb-12">Top bewertete Bands</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<?php foreach ($featuredBands ?? [] as $band): ?>
<div class="card group hover:scale-105 transition-transform">
<div class="aspect-video bg-gray-200 rounded-lg mb-4 overflow-hidden">
<?php if ($band['cover_image']): ?>
<img src="<?= $band['cover_image'] ?>" alt="<?= $band['name'] ?>" class="w-full h-full object-cover">
<?php endif; ?>
</div>
<div class="flex items-start justify-between mb-2">
<h3 class="text-xl font-bold text-gray-900"><?= htmlspecialchars($band['name']) ?></h3>
<span class="badge badge-yellow"><?= htmlspecialchars($band['genre']) ?></span>
</div>
<p class="text-gray-600 mb-4 line-clamp-2"><?= htmlspecialchars($band['description']) ?></p>
<div class="flex items-center justify-between">
<div class="flex items-center">
<span class="text-yellow-500 mr-1">⭐</span>
<span class="font-semibold"><?= number_format($band['average_rating'], 1) ?></span>
<span class="text-gray-500 text-sm ml-1">(<?= $band['total_reviews'] ?>)</span>
</div>
<a href="/bands/<?= $band['slug'] ?>" class="text-primary-600 hover:text-primary-700 font-medium">
Details →
</a>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<!-- How it Works -->
<section class="py-16 bg-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h2 class="text-4xl font-display font-bold text-center mb-12">So funktioniert's</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-12">
<div class="text-center">
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
<span class="text-3xl">🔍</span>
</div>
<h3 class="text-xl font-bold mb-2">1. Suchen</h3>
<p class="text-gray-600">Finde die perfekte Band für dein Event mit unseren Suchfiltern.</p>
</div>
<div class="text-center">
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
<span class="text-3xl">📧</span>
</div>
<h3 class="text-xl font-bold mb-2">2. Anfragen</h3>
<p class="text-gray-600">Sende eine unverbindliche Anfrage mit deinen Event-Details.</p>
</div>
<div class="text-center">
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
<span class="text-3xl">🎉</span>
</div>
<h3 class="text-xl font-bold mb-2">3. Buchen</h3>
<p class="text-gray-600">Bestätige die Buchung und freue dich auf ein unvergessliches Event!</p>
</div>
</div>
</div>
</section>
<?php $content = ob_get_clean(); ?>
<?php $title = 'Home'; ?>
<?php include __DIR__ . '/layouts/app.php'; ?>
+104
View File
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="de" class="h-full">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title><?= $title ?? 'GetYourBand' ?> - Bandvermittlung Schweiz</title>
<!-- Fonts -->
<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=Inter:wght@300;400;500;600;700&family=Poppins:wght@600;700;800&display=swap" rel="stylesheet">
<!-- Styles -->
<link rel="stylesheet" href="/dist/css/app.css">
<!-- Alpine.js -->
<script defer src="/dist/js/app.js"></script>
</head>
<body class="h-full">
<!-- Navigation -->
<nav class="bg-white shadow-sm sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<div class="flex items-center">
<a href="/" class="text-2xl font-display font-bold text-primary-600">
🎸 GetYourBand
</a>
</div>
<div class="hidden md:flex items-center space-x-8">
<a href="/" class="text-gray-700 hover:text-primary-600 transition">Home</a>
<a href="/bands" class="text-gray-700 hover:text-primary-600 transition">Bands</a>
<?php if (isset($_SESSION['user'])): ?>
<a href="/profile" class="text-gray-700 hover:text-primary-600 transition">Profil</a>
<form action="/logout" method="POST" class="inline">
<?= csrf_field() ?>
<button type="submit" class="btn btn-secondary">Logout</button>
</form>
<?php else: ?>
<a href="/login" class="text-gray-700 hover:text-primary-600 transition">Login</a>
<a href="/register" class="btn btn-primary">Registrieren</a>
<?php endif; ?>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<main>
<?php if (isset($_SESSION['success'])): ?>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4">
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded">
<?= $_SESSION['success'] ?>
<?php unset($_SESSION['success']); ?>
</div>
</div>
<?php endif; ?>
<?php if (isset($_SESSION['error'])): ?>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4">
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
<?= $_SESSION['error'] ?>
<?php unset($_SESSION['error']); ?>
</div>
</div>
<?php endif; ?>
<?= $content ?? '' ?>
</main>
<!-- Footer -->
<footer class="bg-gray-900 text-white mt-20">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div>
<h3 class="text-xl font-display font-bold text-primary-400 mb-4">GetYourBand</h3>
<p class="text-gray-400">Die Plattform für professionelle Bandvermittlung in der Schweiz.</p>
</div>
<div>
<h4 class="font-semibold mb-4">Links</h4>
<ul class="space-y-2">
<li><a href="/" class="text-gray-400 hover:text-white transition">Home</a></li>
<li><a href="/bands" class="text-gray-400 hover:text-white transition">Bands</a></li>
<li><a href="/register" class="text-gray-400 hover:text-white transition">Als Band registrieren</a></li>
</ul>
</div>
<div>
<h4 class="font-semibold mb-4">Rechtliches</h4>
<ul class="space-y-2">
<li><a href="/impressum" class="text-gray-400 hover:text-white transition">Impressum</a></li>
<li><a href="/datenschutz" class="text-gray-400 hover:text-white transition">Datenschutz</a></li>
<li><a href="/agb" class="text-gray-400 hover:text-white transition">AGB</a></li>
</ul>
</div>
</div>
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
<p>&copy; <?= date('Y') ?> GetYourBand. Alle Rechte vorbehalten.</p>
</div>
</div>
</footer>
</body>
</html>