Files
thrillwiki_django_no_react/static/js/stores/index.js
pacnpal b9063ff4f8 feat: Add detailed park and ride pages with HTMX integration
- 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.
2025-12-19 19:53:20 -05:00

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;
}
});
});