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
+49
View File
@@ -0,0 +1,49 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html {
@apply scroll-smooth;
}
body {
@apply bg-gray-50 text-gray-900 antialiased;
}
}
@layer components {
.btn {
@apply px-4 py-2 rounded-lg font-medium transition-all duration-200 inline-flex items-center justify-center;
}
.btn-primary {
@apply bg-primary-500 text-white hover:bg-primary-600 active:bg-primary-700;
}
.btn-secondary {
@apply bg-gray-200 text-gray-800 hover:bg-gray-300 active:bg-gray-400;
}
.card {
@apply bg-white rounded-xl shadow-md p-6 transition-shadow hover:shadow-lg;
}
.input-field {
@apply w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent;
}
.badge {
@apply inline-flex items-center px-3 py-1 rounded-full text-sm font-medium;
}
.badge-yellow {
@apply bg-accent-100 text-accent-800;
}
}
@layer utilities {
.text-balance {
text-wrap: balance;
}
}
+99
View File
@@ -0,0 +1,99 @@
import Alpine from 'alpinejs';
// Make Alpine available globally
window.Alpine = Alpine;
// Alpine Components
Alpine.data('searchBands', () => ({
query: '',
filters: {
genre: '',
location: '',
priceMin: '',
priceMax: '',
},
results: [],
loading: false,
init() {
console.log('Search component initialized');
},
async search() {
this.loading = true;
try {
const params = new URLSearchParams({
q: this.query,
...this.filters
});
const response = await fetch(`/api/bands/search?${params}`);
this.results = await response.json();
} catch (error) {
console.error('Search error:', error);
} finally {
this.loading = false;
}
}
}));
Alpine.data('bookingForm', () => ({
formData: {
bandId: '',
eventDate: '',
location: '',
budget: '',
eventType: '',
message: ''
},
submitting: false,
async submit() {
this.submitting = true;
try {
const response = await fetch('/api/bookings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(this.formData)
});
if (response.ok) {
alert('Buchungsanfrage erfolgreich gesendet!');
this.reset();
}
} catch (error) {
console.error('Booking error:', error);
alert('Es gab einen Fehler. Bitte versuchen Sie es erneut.');
} finally {
this.submitting = false;
}
},
reset() {
this.formData = {
bandId: '',
eventDate: '',
location: '',
budget: '',
eventType: '',
message: ''
};
}
}));
// Initialize Alpine
Alpine.start();
// Smooth scroll for anchor links
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth' });
}
});
});
});