mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 13:51:09 -05:00
- Implemented park detail page with dynamic content loading for rides and weather. - Created park list page with filters and search functionality. - Developed ride detail page showcasing ride stats, reviews, and similar rides. - Added ride list page with filtering options and dynamic loading. - Introduced search results page with tabs for parks, rides, and users. - Added HTMX tests for global search functionality.
112 lines
3.0 KiB
JavaScript
112 lines
3.0 KiB
JavaScript
document.addEventListener('alpine:init', () => {
|
|
// Authentication Store
|
|
Alpine.store('auth', {
|
|
user: null,
|
|
isAuthenticated: false,
|
|
permissions: [],
|
|
|
|
init() {
|
|
// Initialize from server-rendered data
|
|
if (window.__AUTH_USER__) {
|
|
this.user = window.__AUTH_USER__;
|
|
this.isAuthenticated = true;
|
|
this.permissions = window.__AUTH_PERMISSIONS__ || [];
|
|
}
|
|
},
|
|
|
|
hasPermission(permission) {
|
|
return this.permissions.includes(permission);
|
|
}
|
|
});
|
|
|
|
// Theme Store
|
|
Alpine.store('theme', {
|
|
isDark: false,
|
|
|
|
init() {
|
|
this.isDark = localStorage.getItem('theme') === 'dark' ||
|
|
(!localStorage.getItem('theme') &&
|
|
window.matchMedia('(prefers-color-scheme: dark)').matches);
|
|
this.apply();
|
|
},
|
|
|
|
toggle() {
|
|
this.isDark = !this.isDark;
|
|
this.apply();
|
|
},
|
|
|
|
apply() {
|
|
document.documentElement.classList.toggle('dark', this.isDark);
|
|
localStorage.setItem('theme', this.isDark ? 'dark' : 'light');
|
|
}
|
|
});
|
|
|
|
// Search Store
|
|
Alpine.store('search', {
|
|
query: '',
|
|
results: [],
|
|
isOpen: false,
|
|
isLoading: false,
|
|
filters: {},
|
|
|
|
toggle() {
|
|
this.isOpen = !this.isOpen;
|
|
if (this.isOpen) {
|
|
// Focus search input logic would go here
|
|
}
|
|
},
|
|
|
|
close() {
|
|
this.isOpen = false;
|
|
},
|
|
|
|
clearSearch() {
|
|
this.query = '';
|
|
this.results = [];
|
|
}
|
|
});
|
|
|
|
// Toast/Notification Store
|
|
Alpine.store('toast', {
|
|
toasts: [],
|
|
|
|
show(message, type = 'info', duration = 5000) {
|
|
const id = Date.now();
|
|
this.toasts.push({ id, message, type, duration });
|
|
if (duration > 0) {
|
|
setTimeout(() => this.dismiss(id), duration);
|
|
}
|
|
return id;
|
|
},
|
|
|
|
dismiss(id) {
|
|
this.toasts = this.toasts.filter(t => t.id !== id);
|
|
},
|
|
|
|
success(message) { return this.show(message, 'success'); },
|
|
error(message) { return this.show(message, 'error'); },
|
|
warning(message) { return this.show(message, 'warning'); },
|
|
info(message) { return this.show(message, 'info'); }
|
|
});
|
|
|
|
// UI State Store
|
|
Alpine.store('ui', {
|
|
sidebarOpen: false,
|
|
modalStack: [],
|
|
|
|
openModal(id) {
|
|
if (!this.modalStack.includes(id)) {
|
|
this.modalStack.push(id);
|
|
}
|
|
},
|
|
closeModal(id) {
|
|
this.modalStack = this.modalStack.filter(m => m !== id);
|
|
},
|
|
isModalOpen(id) { return this.modalStack.includes(id); },
|
|
|
|
toggleSidebar() {
|
|
this.sidebarOpen = !this.sidebarOpen;
|
|
}
|
|
});
|
|
});
|