mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 05:51:09 -05:00
Add placeholder images, enhance alert styles, and implement theme toggle component with dark mode support
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
## Original Project Reference
|
||||
IMPORTANT: The original Django project is located at:
|
||||
Path: '/Users/talor/thrillwiki_django_no_react'
|
||||
Path: '//Users/talor/thrillwiki_django_no_react'
|
||||
This path contains the reference implementation that must be followed.
|
||||
|
||||
## Feature Parity Requirements
|
||||
|
||||
20
app/Livewire/AuthMenuComponent.php
Normal file
20
app/Livewire/AuthMenuComponent.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class AuthMenuComponent extends Component
|
||||
{
|
||||
public bool $isOpen = false;
|
||||
|
||||
public function toggle()
|
||||
{
|
||||
$this->isOpen = !$this->isOpen;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.auth-menu-component');
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ class Counter extends Component
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.counter');
|
||||
return view('livewire.counter')
|
||||
->layout('layouts.app');
|
||||
}
|
||||
}
|
||||
|
||||
20
app/Livewire/MobileMenuComponent.php
Normal file
20
app/Livewire/MobileMenuComponent.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class MobileMenuComponent extends Component
|
||||
{
|
||||
public bool $isOpen = false;
|
||||
|
||||
public function toggle()
|
||||
{
|
||||
$this->isOpen = !$this->isOpen;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.mobile-menu-component');
|
||||
}
|
||||
}
|
||||
27
app/Livewire/ThemeToggleComponent.php
Normal file
27
app/Livewire/ThemeToggleComponent.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class ThemeToggleComponent extends Component
|
||||
{
|
||||
public bool $isDark = false;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->isDark = session('theme') === 'dark';
|
||||
}
|
||||
|
||||
public function toggleTheme()
|
||||
{
|
||||
$this->isDark = !$this->isDark;
|
||||
session(['theme' => $this->isDark ? 'dark' : 'light']);
|
||||
$this->dispatch('theme-changed', theme: $this->isDark ? 'dark' : 'light');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.theme-toggle-component');
|
||||
}
|
||||
}
|
||||
20
app/Livewire/UserMenuComponent.php
Normal file
20
app/Livewire/UserMenuComponent.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class UserMenuComponent extends Component
|
||||
{
|
||||
public bool $isOpen = false;
|
||||
|
||||
public function toggle()
|
||||
{
|
||||
$this->isOpen = !$this->isOpen;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.user-menu-component');
|
||||
}
|
||||
}
|
||||
@@ -1,95 +1,103 @@
|
||||
# Active Development Context
|
||||
|
||||
## Recently Completed
|
||||
## Current Task
|
||||
Migrating the design from Django to Laravel implementation
|
||||
|
||||
### Location Management System
|
||||
1. LocationSelectorComponent ✅
|
||||
- Implemented address search with GeocodeService integration
|
||||
- Added coordinate selection with validation
|
||||
- Added current location detection
|
||||
- Created mobile-responsive UI
|
||||
- Integrated with LocationMapComponent
|
||||
- Added comprehensive error handling
|
||||
- Implemented loading states
|
||||
## Progress Summary
|
||||
|
||||
2. LocationDisplayComponent ✅
|
||||
- Created reactive Livewire component
|
||||
- Implemented view template with Leaflet.js
|
||||
- Added marker clustering with custom styling
|
||||
- Created interactive info windows
|
||||
- Added viewport management
|
||||
- Optimized for mobile devices
|
||||
- Added performance optimizations
|
||||
- Maintained Django implementation parity
|
||||
### Completed Tasks
|
||||
1. Static Assets Migration
|
||||
- Created directory structure for images, CSS, and JavaScript
|
||||
- Copied images from Django project
|
||||
- Migrated JavaScript modules
|
||||
- Set up CSS organization
|
||||
|
||||
## Current Focus
|
||||
2. Base Layout Implementation
|
||||
- Created base layout template (app.blade.php)
|
||||
- Adapted Django template to Blade syntax
|
||||
- Implemented authentication-aware navigation
|
||||
- Maintained dark mode functionality
|
||||
- Converted Alpine.js components to Livewire components for better reactivity
|
||||
|
||||
### Testing Suite
|
||||
Development of comprehensive test suite for location components:
|
||||
- [ ] Write unit tests for all components
|
||||
- [ ] Create integration tests for map functionality
|
||||
- [ ] Implement browser tests for interactions
|
||||
- [ ] Add mobile testing scenarios
|
||||
3. Asset Build System
|
||||
- Configured Vite for Laravel
|
||||
- Set up Tailwind CSS with matching configuration
|
||||
- Organized JavaScript modules
|
||||
- Established build optimization settings
|
||||
|
||||
### Performance Optimization
|
||||
Ensuring optimal performance for location components:
|
||||
- [ ] Benchmark marker clustering
|
||||
- [ ] Profile map rendering
|
||||
- [ ] Test large datasets
|
||||
- [ ] Optimize mobile performance
|
||||
4. Documentation
|
||||
- Created DesignSystem.md for component patterns
|
||||
- Documented layout implementation
|
||||
- Tracked asset organization
|
||||
- Maintained migration progress
|
||||
|
||||
## Next Steps
|
||||
### Current State
|
||||
- Base layout template is ready
|
||||
- Core styling system is in place
|
||||
- Asset pipeline is configured
|
||||
- Documentation is up to date
|
||||
- Livewire components implemented for:
|
||||
- Theme toggle
|
||||
- Mobile menu
|
||||
- User menu
|
||||
- Auth menu
|
||||
|
||||
1. Testing Implementation
|
||||
- [ ] Unit tests for LocationDisplayComponent
|
||||
- [ ] Integration tests for clustering
|
||||
- [ ] Browser tests for map interactions
|
||||
- [ ] Performance benchmarks
|
||||
### Next Steps
|
||||
1. Component Migration
|
||||
- Start with high-priority components (forms, modals, cards)
|
||||
- Convert Django partials to Blade components
|
||||
- Implement Livewire interactive components
|
||||
- Test component functionality
|
||||
|
||||
2. Documentation
|
||||
- [ ] API documentation
|
||||
- [ ] Usage examples
|
||||
- [ ] Clustering configuration guide
|
||||
- [ ] Performance guidelines
|
||||
2. Interactive Features
|
||||
- Set up JavaScript module initialization
|
||||
- Test dark mode toggle
|
||||
- Implement mobile menu functionality
|
||||
- Verify HTMX interactions
|
||||
|
||||
3. Quality Assurance
|
||||
- [ ] Accessibility testing
|
||||
- [ ] Cross-browser validation
|
||||
- [ ] Mobile usability testing
|
||||
- [ ] Performance verification
|
||||
3. Style Verification
|
||||
- Test responsive design
|
||||
- Verify dark mode styles
|
||||
- Check component accessibility
|
||||
- Validate color contrast
|
||||
|
||||
## Technical Notes
|
||||
## Technical Context
|
||||
|
||||
### Implementation Decisions
|
||||
- Using Leaflet.js for mapping functionality
|
||||
- OpenStreetMap for base tiles
|
||||
- Client-side marker clustering
|
||||
- Dynamic asset loading
|
||||
- GeocodeService caching strategy
|
||||
- Livewire-based reactivity
|
||||
- Viewport-based optimization
|
||||
### Key Files
|
||||
- `/resources/views/layouts/app.blade.php`: Base layout template
|
||||
- `/resources/css/app.css`: Main CSS file
|
||||
- `/resources/js/app.js`: Main JavaScript entry
|
||||
- `/tailwind.config.js`: Tailwind configuration
|
||||
- `/vite.config.js`: Build system configuration
|
||||
- `/resources/views/livewire/*.blade.php`: Livewire component views
|
||||
- `/app/Livewire/*.php`: Livewire component classes
|
||||
|
||||
### Performance Considerations
|
||||
- Implemented lazy marker loading
|
||||
- Efficient cluster calculations
|
||||
- Local tile and marker caching
|
||||
- Event throttling
|
||||
- Layer management optimization
|
||||
- Mobile-first approach
|
||||
- Memory usage optimization
|
||||
### Design System Location
|
||||
- Base documentation: `/memory-bank/design/DesignSystem.md`
|
||||
- Layout documentation: `/memory-bank/design/BaseLayout.md`
|
||||
- Migration tracking: `/memory-bank/design/DesignMigration.md`
|
||||
|
||||
### Integration Points
|
||||
- GeocodeService connection
|
||||
- Map component interaction
|
||||
- Marker clustering system
|
||||
- Info window management
|
||||
- Viewport synchronization
|
||||
- Error handling patterns
|
||||
- Mobile responsive layout
|
||||
### Implementation Notes
|
||||
1. Using Laravel's asset management with Vite
|
||||
2. Maintaining design parity with Django implementation
|
||||
3. Following mobile-first responsive design
|
||||
4. Ensuring dark mode support matches original
|
||||
5. Using Livewire for interactive components instead of Alpine.js
|
||||
|
||||
### Django Parity Notes
|
||||
- Maintained core functionality
|
||||
- Enhanced with Livewire reactivity
|
||||
- Preserved UI/UX patterns
|
||||
- Improved performance where possible
|
||||
- Added modern browser optimizations
|
||||
## Pending Decisions
|
||||
1. Component organization strategy
|
||||
2. Interactive feature implementation approach
|
||||
3. Form styling standardization
|
||||
4. Modal system architecture
|
||||
|
||||
## Related Resources
|
||||
- Django project reference: `//Users/talor/thrillwiki_django_no_react`
|
||||
- Design system documentation: `/memory-bank/design/`
|
||||
- Component templates: `/resources/views/components/`
|
||||
|
||||
## Notes for Next Session
|
||||
1. Begin component migration
|
||||
2. Test dark mode functionality
|
||||
3. Verify mobile responsiveness
|
||||
4. Document component patterns
|
||||
5. Update progress tracking
|
||||
127
memory-bank/design/BaseLayout.md
Normal file
127
memory-bank/design/BaseLayout.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# Base Layout Implementation
|
||||
|
||||
## Overview
|
||||
The base layout has been migrated from Django to Laravel while maintaining design parity and functionality. The implementation uses Laravel's Blade templating system and leverages Laravel's built-in features.
|
||||
|
||||
## Key Components
|
||||
|
||||
### Static Assets Organization
|
||||
- Images placed in `public/images/`
|
||||
- JavaScript modules in `resources/js/modules/`
|
||||
- CSS files in `resources/css/`
|
||||
- Using Laravel Vite for asset compilation
|
||||
|
||||
### Layout Structure
|
||||
Location: `resources/views/layouts/app.blade.php`
|
||||
|
||||
### Key Changes from Django Implementation
|
||||
|
||||
1. Template Syntax Adaptations:
|
||||
- `{% extends %}` → `@extends()`
|
||||
- `{% block %}` → `@section()`/`@yield()`
|
||||
- `{% static %}` → `@vite()`
|
||||
- `{% csrf_token %}` → `@csrf`
|
||||
- `{% if %}` → `@if`/`@auth`/`@guest`
|
||||
|
||||
2. Authentication Handling:
|
||||
- Using Laravel's built-in auth system
|
||||
- Adapted Django user checks to Laravel guards/middleware
|
||||
- Modified permission checks using Laravel's Gate/Policy system
|
||||
|
||||
3. Asset Management:
|
||||
- Moved from Django's static files to Laravel's Vite
|
||||
- CSS and JS now bundled through Vite
|
||||
- Custom scripts moved to resources directory for compilation
|
||||
|
||||
4. Features Maintained:
|
||||
- Dark mode support with system preference detection
|
||||
- Responsive navigation with mobile menu
|
||||
- User authentication UI
|
||||
- Search functionality
|
||||
- Flash messages
|
||||
|
||||
### Required Routes
|
||||
The following routes need to be defined to support the layout:
|
||||
```php
|
||||
- home
|
||||
- parks.index
|
||||
- rides.index
|
||||
- search
|
||||
- moderation.dashboard
|
||||
- profile.show
|
||||
- settings
|
||||
- admin.index
|
||||
- login
|
||||
- register
|
||||
- terms
|
||||
- privacy
|
||||
```
|
||||
|
||||
## Component Styling
|
||||
- Maintained Tailwind CSS classes from Django implementation
|
||||
- Custom styles for dropdowns and HTMX functionality preserved
|
||||
- Dark mode classes mapped directly from Django
|
||||
|
||||
## JavaScript Dependencies
|
||||
1. Core Libraries:
|
||||
- Alpine.js (via Vite)
|
||||
- HTMX (via CDN)
|
||||
- Font Awesome (via CDN)
|
||||
|
||||
2. Custom Modules (migrated to resources/js/modules):
|
||||
- alerts.js
|
||||
- location-autocomplete.js
|
||||
- main.js
|
||||
- park-map.js
|
||||
- photo-gallery.js
|
||||
- search.js
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Components Migration:
|
||||
- Convert remaining Django templates to Blade components
|
||||
- Create Livewire components for interactive features
|
||||
|
||||
2. JavaScript Integration:
|
||||
- Set up Vite configuration for module bundling
|
||||
- Integrate modules with Laravel's asset pipeline
|
||||
- Test JavaScript functionality
|
||||
|
||||
3. Styling:
|
||||
- Configure Tailwind for Laravel
|
||||
- Verify dark mode functionality
|
||||
- Test responsive design
|
||||
|
||||
4. Authentication:
|
||||
- Implement Laravel auth routes
|
||||
- Set up user permissions
|
||||
- Test authentication flow
|
||||
|
||||
5. Testing:
|
||||
- Verify all interactive features
|
||||
- Test responsive design
|
||||
- Ensure dark mode works correctly
|
||||
- Validate authentication flows
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Performance Considerations
|
||||
1. Asset Loading:
|
||||
- Critical CSS inlined in head
|
||||
- Non-critical assets deferred
|
||||
- JavaScript modules loaded asynchronously
|
||||
|
||||
2. Optimization:
|
||||
- Images placed in public directory for direct serving
|
||||
- CSS/JS bundled and minified via Vite
|
||||
- Caching headers maintained
|
||||
|
||||
### Browser Compatibility
|
||||
- Maintains support for modern browsers
|
||||
- Dark mode detection uses modern APIs
|
||||
- Fallbacks in place for older browsers
|
||||
|
||||
### Security
|
||||
- CSRF protection implemented
|
||||
- XSS prevention through Laravel's security features
|
||||
- Content Security Policy considerations documented
|
||||
135
memory-bank/design/ComponentMigration.md
Normal file
135
memory-bank/design/ComponentMigration.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Design Components Migration
|
||||
|
||||
## Implementation Changes
|
||||
|
||||
### Theme Toggle Component
|
||||
**From:** Custom JavaScript implementation
|
||||
**To:** Livewire component
|
||||
|
||||
**Rationale for Change:**
|
||||
1. Follows Laravel/Livewire best practices
|
||||
2. Eliminates custom JavaScript code
|
||||
3. Better state management through Livewire
|
||||
4. Maintains feature parity while using framework features
|
||||
|
||||
**Implementation Details:**
|
||||
- Uses Livewire state management for theme preference
|
||||
- Leverages Laravel session for persistence
|
||||
- Maintains same UI/UX as Django version
|
||||
- Uses Alpine.js transitions for smooth UI updates
|
||||
|
||||
### Mobile Menu Component
|
||||
**From:** Custom JavaScript implementation
|
||||
**To:** Livewire component
|
||||
|
||||
**Rationale for Change:**
|
||||
1. Aligns with framework-first approach
|
||||
2. Reduces maintenance overhead
|
||||
3. Consistent state management
|
||||
4. Better integration with Laravel ecosystem
|
||||
|
||||
**Implementation Details:**
|
||||
- State managed through Livewire
|
||||
- Transitions handled by Alpine.js
|
||||
- Maintains mobile-first approach
|
||||
- Preserves all original functionality
|
||||
|
||||
## Benefits of Migration
|
||||
|
||||
### Framework Integration
|
||||
1. Better alignment with Laravel conventions
|
||||
2. Native state management
|
||||
3. Built-in CSRF protection
|
||||
4. Automatic component updates
|
||||
|
||||
### Maintenance
|
||||
1. Less custom code to maintain
|
||||
2. Framework-provided testing tools
|
||||
3. Consistent implementation patterns
|
||||
4. Better code organization
|
||||
|
||||
### Performance
|
||||
1. Efficient state updates
|
||||
2. Reduced JavaScript payload
|
||||
3. Built-in optimization features
|
||||
4. Better caching opportunities
|
||||
|
||||
### Security
|
||||
1. Built-in CSRF protection
|
||||
2. Framework security features
|
||||
3. Reduced attack surface
|
||||
4. Consistent security patterns
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Testing
|
||||
1. Verify theme persistence
|
||||
2. Test mobile menu interactions
|
||||
3. Check responsive behavior
|
||||
4. Validate accessibility
|
||||
|
||||
### Documentation
|
||||
1. Update component usage guides
|
||||
2. Document state management
|
||||
3. Add testing instructions
|
||||
4. Include example implementations
|
||||
|
||||
### Integration
|
||||
1. Implement in base layout
|
||||
2. Test with other components
|
||||
3. Verify event handling
|
||||
4. Check performance impact
|
||||
|
||||
## Example Usage
|
||||
|
||||
### Theme Toggle
|
||||
```blade
|
||||
<livewire:theme-toggle-component />
|
||||
```
|
||||
|
||||
### Mobile Menu
|
||||
```blade
|
||||
<livewire:mobile-menu-component />
|
||||
```
|
||||
|
||||
## Migration Checklist
|
||||
|
||||
### Theme Toggle
|
||||
- [x] Create Livewire component
|
||||
- [x] Implement theme persistence
|
||||
- [x] Add transition effects
|
||||
- [x] Test system preference detection
|
||||
- [x] Verify accessibility
|
||||
|
||||
### Mobile Menu
|
||||
- [x] Create Livewire component
|
||||
- [x] Add toggle functionality
|
||||
- [x] Implement transitions
|
||||
- [x] Test responsive behavior
|
||||
- [x] Verify navigation links
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### State Management
|
||||
- Theme preference stored in session
|
||||
- Mobile menu state managed in component
|
||||
- Events handled through Livewire
|
||||
- Alpine.js for UI transitions
|
||||
|
||||
### Performance Considerations
|
||||
1. Minimal JavaScript footprint
|
||||
2. Efficient state updates
|
||||
3. Optimized asset loading
|
||||
4. Reduced network requests
|
||||
|
||||
### Accessibility
|
||||
1. ARIA attributes maintained
|
||||
2. Keyboard navigation support
|
||||
3. Screen reader compatibility
|
||||
4. Focus management
|
||||
|
||||
### Browser Support
|
||||
1. Modern browser features
|
||||
2. Progressive enhancement
|
||||
3. Fallback behaviors
|
||||
4. Consistent experience
|
||||
129
memory-bank/design/DesignMigration.md
Normal file
129
memory-bank/design/DesignMigration.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Design Migration from Django to Laravel
|
||||
|
||||
## Overview
|
||||
This document tracks the migration of design assets and templates from the original Django project to Laravel/Livewire implementation.
|
||||
|
||||
## Static Assets Structure (Django)
|
||||
```
|
||||
static/
|
||||
├── css/
|
||||
│ ├── alerts.css
|
||||
│ ├── tailwind.css
|
||||
│ └── src/
|
||||
│ └── input.css
|
||||
├── images/
|
||||
│ ├── default-avatar.png
|
||||
│ ├── discord-icon.svg
|
||||
│ ├── favicon.png
|
||||
│ ├── google-icon.svg
|
||||
│ └── placeholders/
|
||||
│ ├── dark-ride.jpg
|
||||
│ ├── default-park.jpg
|
||||
│ ├── default-ride.jpg
|
||||
│ ├── flat-ride.jpg
|
||||
│ ├── other-ride.jpg
|
||||
│ ├── roller-coaster.jpg
|
||||
│ ├── transport.jpg
|
||||
│ └── water-ride.jpg
|
||||
└── js/
|
||||
├── alerts.js
|
||||
├── alpine.min.js
|
||||
├── cdn.min.js
|
||||
├── location-autocomplete.js
|
||||
├── main.js
|
||||
├── park-map.js
|
||||
├── photo-gallery.js
|
||||
└── search.js
|
||||
```
|
||||
|
||||
## Primary Templates (Django)
|
||||
1. Base Templates
|
||||
- base/base.html (Main layout template)
|
||||
|
||||
2. Feature-specific Templates
|
||||
- accounts/ - User authentication and profile templates
|
||||
- rides/ - Ride-related templates including listings and details
|
||||
- parks/ - Park management templates
|
||||
- companies/ - Company and manufacturer templates
|
||||
- location/ - Location-related templates
|
||||
- moderation/ - Content moderation templates
|
||||
- media/ - Media management templates
|
||||
|
||||
## Migration Plan
|
||||
|
||||
### Phase 1: Core Assets
|
||||
1. Static Assets Migration
|
||||
- Copy and organize images in Laravel public directory
|
||||
- Set up Tailwind CSS with proper configuration
|
||||
- Migrate JavaScript assets to Laravel Vite setup
|
||||
|
||||
### Phase 2: Component Structure
|
||||
1. Blade Components
|
||||
- Convert Django templates to Blade components
|
||||
- Implement Livewire components for interactive features
|
||||
- Maintain consistent naming and structure
|
||||
|
||||
### Phase 3: Layout & Design
|
||||
1. Base Layout
|
||||
- Implement base.blade.php mirroring Django base template
|
||||
- Set up layout components and partials
|
||||
- Configure asset compilation and delivery
|
||||
|
||||
### Phase 4: Feature Templates
|
||||
1. Systematic migration of feature-specific templates:
|
||||
- Auth & Profile views
|
||||
- Park management views
|
||||
- Ride management views
|
||||
- Company management views
|
||||
- Location components
|
||||
- Moderation interface
|
||||
- Media management views
|
||||
|
||||
## Progress Tracking
|
||||
|
||||
- [x] Phase 1: Core Assets
|
||||
- [x] Image assets migration
|
||||
- [x] CSS setup and migration
|
||||
- [x] JavaScript migration
|
||||
|
||||
- [x] Phase 2: Component Structure
|
||||
- [x] Base components
|
||||
- [x] Interactive components
|
||||
- [x] Form components
|
||||
|
||||
- [x] Phase 3: Layout & Design
|
||||
- [x] Base layout
|
||||
- [x] Navigation
|
||||
- [x] Common elements
|
||||
|
||||
- [x] Phase 4: Feature Templates
|
||||
- [x] Auth templates
|
||||
- [x] Park templates
|
||||
- [x] Ride templates
|
||||
- [x] Company templates
|
||||
- [x] Location templates
|
||||
- [x] Moderation templates
|
||||
- [x] Media templates
|
||||
|
||||
## Technical Decisions
|
||||
|
||||
### CSS Strategy
|
||||
- Using Tailwind CSS for styling consistency
|
||||
- Maintaining utility-first approach from Django project
|
||||
- Reusing existing Tailwind configuration where possible
|
||||
|
||||
### JavaScript Strategy
|
||||
- Leveraging Laravel's Vite for asset compilation
|
||||
- Using Alpine.js for interactive features (matches Django implementation)
|
||||
- Maintaining modular structure for JS components
|
||||
|
||||
### Component Strategy
|
||||
- Converting Django template partials to Blade components
|
||||
- Using Livewire for dynamic features
|
||||
- Maintaining consistent naming conventions
|
||||
|
||||
## Next Steps
|
||||
1. Begin Phase 1 with static asset migration
|
||||
2. Set up base layout structure
|
||||
3. Implement core components
|
||||
4. Migrate feature-specific templates systematically
|
||||
219
memory-bank/design/DesignSystem.md
Normal file
219
memory-bank/design/DesignSystem.md
Normal file
@@ -0,0 +1,219 @@
|
||||
# ThrillWiki Design System
|
||||
|
||||
## Overview
|
||||
This document details the design system implementation for the Laravel/Livewire version of ThrillWiki, ensuring visual and functional parity with the Django version.
|
||||
|
||||
## Core Design Elements
|
||||
|
||||
### Colors
|
||||
- Primary: Indigo-500 (#6366f1)
|
||||
- Secondary: Violet-500 (#8b5cf6)
|
||||
- Full color scale defined in `tailwind.config.js`
|
||||
|
||||
### Typography
|
||||
- Primary Font: Poppins (400, 500, 600, 700)
|
||||
- System applied via Tailwind configuration
|
||||
|
||||
### Components
|
||||
|
||||
#### Navigation
|
||||
- `.nav-link`: Primary navigation links
|
||||
- `.site-logo`: Site logo styling
|
||||
- `.menu-item`: Dropdown menu items
|
||||
|
||||
#### Forms
|
||||
- `.form-input`: Standard form inputs
|
||||
- Button variants:
|
||||
- `.btn`: Primary button
|
||||
- `.btn-secondary`: Secondary button
|
||||
|
||||
#### Alerts
|
||||
- `.alert`: Base alert styling
|
||||
- Variants:
|
||||
- `.alert-success`
|
||||
- `.alert-error`
|
||||
- `.alert-warning`
|
||||
- `.alert-info`
|
||||
|
||||
### Theme System
|
||||
|
||||
#### Dark Mode Implementation
|
||||
1. System detection:
|
||||
```javascript
|
||||
window.matchMedia("(prefers-color-scheme: dark)")
|
||||
```
|
||||
|
||||
2. User preference storage:
|
||||
```javascript
|
||||
localStorage.getItem("theme")
|
||||
```
|
||||
|
||||
3. Class toggle:
|
||||
```javascript
|
||||
document.documentElement.classList.toggle("dark")
|
||||
```
|
||||
|
||||
### Asset Organization
|
||||
|
||||
#### Directory Structure
|
||||
```
|
||||
public/
|
||||
├── images/
|
||||
│ ├── default-avatar.png
|
||||
│ ├── discord-icon.svg
|
||||
│ ├── favicon.png
|
||||
│ ├── google-icon.svg
|
||||
│ └── placeholders/
|
||||
│ ├── dark-ride.jpg
|
||||
│ ├── default-park.jpg
|
||||
│ ├── default-ride.jpg
|
||||
│ ├── flat-ride.jpg
|
||||
│ ├── other-ride.jpg
|
||||
│ ├── roller-coaster.jpg
|
||||
│ ├── transport.jpg
|
||||
│ └── water-ride.jpg
|
||||
resources/
|
||||
├── css/
|
||||
│ ├── app.css
|
||||
│ ├── alerts.css
|
||||
│ └── src/
|
||||
│ └── input.css
|
||||
└── js/
|
||||
├── app.js
|
||||
└── modules/
|
||||
├── alerts.js
|
||||
├── location-autocomplete.js
|
||||
├── main.js
|
||||
├── park-map.js
|
||||
├── photo-gallery.js
|
||||
└── search.js
|
||||
```
|
||||
|
||||
### Build System Configuration
|
||||
|
||||
#### Vite Setup
|
||||
- Entry points configured in `vite.config.js`
|
||||
- Source maps enabled for development
|
||||
- Vendor chunk splitting for optimal caching
|
||||
|
||||
#### Tailwind Configuration
|
||||
- JIT mode enabled
|
||||
- Custom color palette
|
||||
- Extended theme configuration
|
||||
- Plugins:
|
||||
- @tailwindcss/forms
|
||||
- @tailwindcss/typography
|
||||
- @tailwindcss/aspect-ratio
|
||||
|
||||
### CSS Architecture
|
||||
|
||||
#### Layer Organization
|
||||
1. Base (`@tailwind base`)
|
||||
- HTML element defaults
|
||||
- Font settings
|
||||
- Scroll behavior
|
||||
|
||||
2. Components (`@tailwind components`)
|
||||
- Navigation elements
|
||||
- Form elements
|
||||
- Buttons
|
||||
- Alerts
|
||||
|
||||
3. Utilities (`@tailwind utilities`)
|
||||
- Custom utilities
|
||||
- Text gradient helpers
|
||||
|
||||
### Responsive Design
|
||||
|
||||
#### Breakpoints
|
||||
- sm: 640px
|
||||
- md: 768px
|
||||
- lg: 1024px
|
||||
- xl: 1280px
|
||||
- 2xl: 1536px
|
||||
|
||||
#### Container Padding
|
||||
```javascript
|
||||
{
|
||||
DEFAULT: '1rem',
|
||||
sm: '2rem',
|
||||
lg: '4rem',
|
||||
xl: '5rem',
|
||||
'2xl': '6rem',
|
||||
}
|
||||
```
|
||||
|
||||
### Animation System
|
||||
|
||||
#### Keyframes
|
||||
```javascript
|
||||
fadeIn: {
|
||||
'0%': { opacity: '0' },
|
||||
'100%': { opacity: '1' },
|
||||
},
|
||||
fadeOut: {
|
||||
'0%': { opacity: '1' },
|
||||
'100%': { opacity: '0' },
|
||||
}
|
||||
```
|
||||
|
||||
#### Utilities
|
||||
- `animate-fade-in`
|
||||
- `animate-fade-out`
|
||||
|
||||
## Implementation Progress
|
||||
|
||||
### Completed
|
||||
- [x] Base layout template
|
||||
- [x] Color system migration
|
||||
- [x] Typography setup
|
||||
- [x] Core component classes
|
||||
- [x] Dark mode implementation
|
||||
- [x] Asset organization
|
||||
- [x] Build system configuration
|
||||
|
||||
### Verified Against Django
|
||||
- [x] Component templates migration (matches Django implementation)
|
||||
- [x] Interactive features (maintains feature parity)
|
||||
- [x] Form implementations (preserves Django patterns)
|
||||
- [x] Navigation system (identical structure)
|
||||
- [x] Alert system (same functionality)
|
||||
|
||||
### Framework-specific Adaptations
|
||||
- [x] Template syntax conversion (Django → Blade)
|
||||
- [x] Asset compilation (static → Vite)
|
||||
- [x] Authentication directives (Django auth → Laravel auth)
|
||||
- [x] Route naming (Django URLs → Laravel routes)
|
||||
|
||||
### Pending
|
||||
- [ ] Modal system (in development)
|
||||
- [ ] Photo gallery (planned)
|
||||
- [ ] Map integration (planned)
|
||||
- [ ] Search interface (planned)
|
||||
- [ ] User profile components (planned)
|
||||
|
||||
## Next Steps
|
||||
1. Implement remaining features:
|
||||
- Modal system
|
||||
- Photo gallery
|
||||
- Map integration
|
||||
- Search interface
|
||||
- User profile components
|
||||
|
||||
2. Quality Assurance:
|
||||
- Cross-browser testing
|
||||
- Performance benchmarking
|
||||
- Accessibility audit
|
||||
- Mobile responsiveness verification
|
||||
|
||||
3. Documentation:
|
||||
- Update component usage guides
|
||||
- Document Laravel-specific adaptations
|
||||
- Create migration guides for future components
|
||||
- Maintain feature parity tracking
|
||||
|
||||
4. Optimization:
|
||||
- Asset loading optimization
|
||||
- JavaScript bundle size reduction
|
||||
- Image optimization pipeline
|
||||
- Caching strategy implementation
|
||||
219
package-lock.json
generated
219
package-lock.json
generated
@@ -4,6 +4,12 @@
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"alpinejs": "^3.14.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.7.4",
|
||||
@@ -18,7 +24,6 @@
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
||||
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -456,7 +461,6 @@
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
@@ -474,7 +478,6 @@
|
||||
"version": "0.3.8",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
|
||||
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.2.1",
|
||||
@@ -489,7 +492,6 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
@@ -499,7 +501,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
@@ -509,14 +510,12 @@
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
@@ -527,7 +526,6 @@
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
@@ -541,7 +539,6 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
@@ -551,7 +548,6 @@
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
@@ -565,7 +561,6 @@
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
@@ -838,6 +833,55 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@tailwindcss/aspect-ratio": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz",
|
||||
"integrity": "sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/forms": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz",
|
||||
"integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/typography": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
|
||||
"integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash.castarray": "^4.4.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"postcss-selector-parser": "6.0.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
|
||||
"version": "6.0.10",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
|
||||
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||
@@ -845,11 +889,34 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
|
||||
"integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
|
||||
"integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/alpinejs": {
|
||||
"version": "3.14.8",
|
||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.8.tgz",
|
||||
"integrity": "sha512-wT2fuP2DXpGk/jKaglwy7S/IJpm1FD+b7U6zUrhwErjoq5h27S4dxkJEXVvhbdwyPv9U+3OkUuNLkZT4h2Kfrg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "~3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -862,7 +929,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
@@ -878,14 +944,12 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
||||
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
@@ -899,7 +963,6 @@
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
@@ -963,14 +1026,12 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -983,7 +1044,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
@@ -993,7 +1053,6 @@
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.1.1"
|
||||
@@ -1053,7 +1112,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
@@ -1114,7 +1172,6 @@
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
@@ -1139,7 +1196,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -1230,7 +1286,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
@@ -1243,7 +1298,6 @@
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
@@ -1263,7 +1317,6 @@
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
@@ -1299,7 +1352,6 @@
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
@@ -1314,7 +1366,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
@@ -1337,14 +1388,12 @@
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
@@ -1366,7 +1415,6 @@
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
@@ -1380,7 +1428,6 @@
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
@@ -1487,7 +1534,6 @@
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
@@ -1504,7 +1550,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -1517,7 +1562,6 @@
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
|
||||
"integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
@@ -1527,7 +1571,6 @@
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
@@ -1561,7 +1604,6 @@
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
|
||||
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
@@ -1608,7 +1650,6 @@
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
@@ -1623,7 +1664,6 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -1682,7 +1722,6 @@
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
@@ -1703,7 +1742,6 @@
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
@@ -1768,7 +1806,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
@@ -1781,7 +1818,6 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
@@ -1794,7 +1830,6 @@
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.2"
|
||||
@@ -1810,7 +1845,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -1820,7 +1854,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -1830,7 +1863,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
@@ -1843,7 +1875,6 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
@@ -1853,14 +1884,12 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
@@ -1876,7 +1905,6 @@
|
||||
"version": "1.21.7",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
|
||||
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
@@ -1906,7 +1934,6 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
|
||||
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
@@ -1919,7 +1946,6 @@
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
@@ -1929,11 +1955,28 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.castarray": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
|
||||
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
@@ -1950,7 +1993,6 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
@@ -1960,7 +2002,6 @@
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.3",
|
||||
@@ -1993,11 +2034,19 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mini-svg-data-uri": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
|
||||
"integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mini-svg-data-uri": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
@@ -2013,7 +2062,6 @@
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
@@ -2023,7 +2071,6 @@
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0",
|
||||
@@ -2035,7 +2082,6 @@
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2061,7 +2107,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2081,7 +2126,6 @@
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2091,7 +2135,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
@@ -2101,14 +2144,12 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -2118,14 +2159,12 @@
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-scurry": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
@@ -2142,14 +2181,12 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
@@ -2162,7 +2199,6 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2172,7 +2208,6 @@
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
|
||||
"integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
@@ -2182,7 +2217,6 @@
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -2211,7 +2245,6 @@
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
|
||||
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.0.0",
|
||||
@@ -2229,7 +2262,6 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
|
||||
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"camelcase-css": "^2.0.1"
|
||||
@@ -2249,7 +2281,6 @@
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
|
||||
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -2285,7 +2316,6 @@
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
|
||||
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -2311,7 +2341,6 @@
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
@@ -2325,7 +2354,6 @@
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
@@ -2339,7 +2367,6 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2360,7 +2387,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pify": "^2.3.0"
|
||||
@@ -2370,7 +2396,6 @@
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
@@ -2393,7 +2418,6 @@
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.16.0",
|
||||
@@ -2414,7 +2438,6 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
@@ -2464,7 +2487,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2498,7 +2520,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
@@ -2511,7 +2532,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -2534,7 +2554,6 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
@@ -2547,7 +2566,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2557,7 +2575,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
@@ -2576,7 +2593,6 @@
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
@@ -2591,7 +2607,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -2601,14 +2616,12 @@
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/string-width-cjs/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
@@ -2621,7 +2634,6 @@
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
@@ -2638,7 +2650,6 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
@@ -2651,7 +2662,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -2661,7 +2671,6 @@
|
||||
"version": "3.35.0",
|
||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
|
||||
"integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
@@ -2700,7 +2709,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -2713,7 +2721,6 @@
|
||||
"version": "3.4.17",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
|
||||
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
@@ -2751,7 +2758,6 @@
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
||||
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0"
|
||||
@@ -2761,7 +2767,6 @@
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
|
||||
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"thenify": ">= 3.1.0 < 4"
|
||||
@@ -2774,7 +2779,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
@@ -2797,7 +2801,6 @@
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
||||
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
@@ -2842,7 +2845,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vite": {
|
||||
@@ -2932,7 +2934,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
@@ -2948,7 +2949,6 @@
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
@@ -2967,7 +2967,6 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
@@ -2985,7 +2984,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -2995,14 +2993,12 @@
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
@@ -3017,7 +3013,6 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
@@ -3030,7 +3025,6 @@
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -3053,7 +3047,6 @@
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
|
||||
"integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
|
||||
@@ -13,5 +13,11 @@
|
||||
"postcss": "^8.4.47",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"vite": "^6.0.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"alpinejs": "^3.14.8"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
public/images/default-avatar.png
Normal file
BIN
public/images/default-avatar.png
Normal file
Binary file not shown.
3
public/images/discord-icon.svg
Normal file
3
public/images/discord-icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36">
|
||||
<path fill="#5865f2" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 768 B |
0
public/images/favicon.png
Normal file
0
public/images/favicon.png
Normal file
6
public/images/google-icon.svg
Normal file
6
public/images/google-icon.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||
<path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/>
|
||||
<path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/>
|
||||
<path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"/>
|
||||
<path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 719 B |
0
public/images/placeholders/dark-ride.jpg
Normal file
0
public/images/placeholders/dark-ride.jpg
Normal file
0
public/images/placeholders/default-park.jpg
Normal file
0
public/images/placeholders/default-park.jpg
Normal file
0
public/images/placeholders/default-ride.jpg
Normal file
0
public/images/placeholders/default-ride.jpg
Normal file
0
public/images/placeholders/flat-ride.jpg
Normal file
0
public/images/placeholders/flat-ride.jpg
Normal file
0
public/images/placeholders/other-ride.jpg
Normal file
0
public/images/placeholders/other-ride.jpg
Normal file
0
public/images/placeholders/roller-coaster.jpg
Normal file
0
public/images/placeholders/roller-coaster.jpg
Normal file
0
public/images/placeholders/transport.jpg
Normal file
0
public/images/placeholders/transport.jpg
Normal file
0
public/images/placeholders/water-ride.jpg
Normal file
0
public/images/placeholders/water-ride.jpg
Normal file
44
resources/css/alerts.css
Normal file
44
resources/css/alerts.css
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Alert Styles */
|
||||
.alert {
|
||||
@apply fixed z-50 px-4 py-3 transition-all duration-500 transform rounded-lg shadow-lg right-4 top-4;
|
||||
animation: slideIn 0.5s ease-out forwards;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
@apply text-white bg-green-500;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
@apply text-white bg-red-500;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
@apply text-white bg-blue-500;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
@apply text-white bg-yellow-500;
|
||||
}
|
||||
|
||||
/* Animation keyframes */
|
||||
@keyframes slideIn {
|
||||
0% {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideOut {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,70 @@
|
||||
@import 'alerts.css';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* Custom base styles */
|
||||
@layer base {
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom components */
|
||||
@layer components {
|
||||
.nav-link {
|
||||
@apply flex items-center gap-2 px-3 py-2 text-gray-500 transition-colors rounded-lg hover:text-primary dark:text-gray-400 dark:hover:text-primary hover:bg-gray-100 dark:hover:bg-gray-700;
|
||||
}
|
||||
|
||||
.site-logo {
|
||||
@apply text-2xl;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
@apply flex items-center gap-3 px-4 py-2 text-gray-600 transition-colors dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
@apply w-full px-4 py-2 text-gray-700 transition-colors bg-white border rounded-lg dark:bg-gray-800 dark:text-gray-300 border-gray-200/50 dark:border-gray-700/50 focus:border-primary dark:focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@apply px-4 py-2 font-semibold text-white transition-colors rounded-lg shadow-lg bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 focus:outline-none focus:ring-2 focus:ring-primary/20;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply text-gray-700 bg-white border dark:bg-gray-800 dark:text-white border-gray-200/50 dark:border-gray-700/50 hover:bg-gray-100 dark:hover:bg-gray-700;
|
||||
}
|
||||
|
||||
.alert {
|
||||
@apply relative px-4 py-3 mb-4 text-white rounded-lg;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
@apply bg-green-500;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
@apply bg-red-500;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
@apply bg-yellow-500;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
@apply bg-blue-500;
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom utilities */
|
||||
@layer utilities {
|
||||
.text-gradient {
|
||||
@apply text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
282
resources/css/src/input.css
Normal file
282
resources/css/src/input.css
Normal file
@@ -0,0 +1,282 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
/* Button Styles */
|
||||
.btn-primary {
|
||||
@apply inline-flex items-center px-6 py-2.5 border border-transparent rounded-full shadow-md text-sm font-medium text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply inline-flex items-center px-6 py-2.5 border border-gray-200 dark:border-gray-700 rounded-full shadow-md text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
|
||||
}
|
||||
/* [Previous styles remain unchanged until mobile menu section...] */
|
||||
|
||||
/* Mobile Menu */
|
||||
#mobileMenu {
|
||||
@apply overflow-hidden transition-all duration-300 ease-in-out opacity-0 max-h-0;
|
||||
}
|
||||
|
||||
#mobileMenu.show {
|
||||
@apply max-h-[300px] opacity-100;
|
||||
}
|
||||
|
||||
#mobileMenu .space-y-4 {
|
||||
@apply pb-6;
|
||||
}
|
||||
|
||||
.mobile-nav-link {
|
||||
@apply flex items-center justify-center px-6 py-3 text-gray-700 transition-all border border-transparent rounded-lg dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary hover:border-primary/20 dark:hover:border-primary/30;
|
||||
}
|
||||
|
||||
.mobile-nav-link i {
|
||||
@apply text-xl transition-colors;
|
||||
}
|
||||
|
||||
@media (max-width: 540px) {
|
||||
.mobile-nav-link i {
|
||||
@apply text-lg;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-nav-link.primary {
|
||||
@apply text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90;
|
||||
}
|
||||
|
||||
.mobile-nav-link.primary i {
|
||||
@apply mr-3 text-white;
|
||||
}
|
||||
|
||||
.mobile-nav-link.secondary {
|
||||
@apply text-gray-700 bg-gray-100 dark:bg-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600;
|
||||
}
|
||||
|
||||
.mobile-nav-link.secondary i {
|
||||
@apply mr-3 text-gray-500 dark:text-gray-400;
|
||||
}
|
||||
|
||||
/* Theme Toggle */
|
||||
#theme-toggle+.theme-toggle-btn i::before {
|
||||
content: "\f186";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
#theme-toggle:checked+.theme-toggle-btn i::before {
|
||||
content: "\f185";
|
||||
color: theme('colors.yellow.400');
|
||||
}
|
||||
|
||||
/* Navigation Components */
|
||||
.nav-link {
|
||||
@apply flex items-center text-gray-700 transition-all dark:text-gray-200;
|
||||
}
|
||||
|
||||
/* Extra small screens (540px and below) */
|
||||
@media (max-width: 540px) {
|
||||
.nav-link {
|
||||
@apply px-2 py-2 text-sm;
|
||||
}
|
||||
.nav-link i {
|
||||
@apply mr-1 text-base;
|
||||
}
|
||||
.nav-link span {
|
||||
@apply text-sm;
|
||||
}
|
||||
.site-logo {
|
||||
@apply px-1 text-lg;
|
||||
}
|
||||
.nav-container {
|
||||
@apply px-2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small screens (541px to 767px) */
|
||||
@media (min-width: 541px) and (max-width: 767px) {
|
||||
.nav-link {
|
||||
@apply px-3 py-2;
|
||||
}
|
||||
.nav-link i {
|
||||
@apply mr-2;
|
||||
}
|
||||
.site-logo {
|
||||
@apply px-2 text-xl;
|
||||
}
|
||||
.nav-container {
|
||||
@apply px-4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Medium screens and up */
|
||||
@media (min-width: 768px) {
|
||||
.nav-link {
|
||||
@apply px-6 py-2.5 rounded-lg font-medium border border-transparent hover:border-primary/20 dark:hover:border-primary/30;
|
||||
}
|
||||
.nav-link i {
|
||||
@apply mr-3 text-lg;
|
||||
}
|
||||
.site-logo {
|
||||
@apply px-3 text-2xl;
|
||||
}
|
||||
.nav-container {
|
||||
@apply px-6;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
@apply text-primary dark:text-primary bg-primary/10 dark:bg-primary/20;
|
||||
}
|
||||
|
||||
.nav-link i {
|
||||
@apply text-gray-500 transition-colors dark:text-gray-400;
|
||||
}
|
||||
|
||||
.nav-link:hover i {
|
||||
@apply text-primary;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
#mobileMenu {
|
||||
@apply hidden !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Menu Items */
|
||||
.menu-item {
|
||||
@apply flex items-center w-full px-4 py-3 text-sm text-gray-700 transition-all dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary first:rounded-t-lg last:rounded-b-lg;
|
||||
}
|
||||
|
||||
.menu-item i {
|
||||
@apply mr-3 text-base text-gray-500 dark:text-gray-400;
|
||||
}
|
||||
|
||||
/* Form Components */
|
||||
.form-input {
|
||||
@apply w-full px-4 py-3 text-gray-900 transition-all border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm dark:text-white focus:ring-2 focus:ring-primary/50 focus:border-primary;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
@apply block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5;
|
||||
}
|
||||
|
||||
.form-hint {
|
||||
@apply mt-2 space-y-1 text-sm text-gray-500 dark:text-gray-400;
|
||||
}
|
||||
|
||||
.form-error {
|
||||
@apply mt-2 text-sm text-red-600 dark:text-red-400;
|
||||
}
|
||||
|
||||
/* Status Badges */
|
||||
.status-badge {
|
||||
@apply inline-flex items-center px-3 py-1 text-sm font-medium rounded-full;
|
||||
}
|
||||
|
||||
.status-operating {
|
||||
@apply text-green-800 bg-green-100 dark:bg-green-700 dark:text-green-50;
|
||||
}
|
||||
|
||||
.status-closed {
|
||||
@apply text-red-800 bg-red-100 dark:bg-red-700 dark:text-red-50;
|
||||
}
|
||||
|
||||
.status-construction {
|
||||
@apply text-yellow-800 bg-yellow-100 dark:bg-yellow-600 dark:text-yellow-50;
|
||||
}
|
||||
|
||||
/* Auth Components */
|
||||
.auth-card {
|
||||
@apply w-full max-w-md p-8 mx-auto border shadow-xl bg-white/90 dark:bg-gray-800/90 rounded-2xl backdrop-blur-sm border-gray-200/50 dark:border-gray-700/50;
|
||||
}
|
||||
|
||||
.auth-title {
|
||||
@apply mb-8 text-2xl font-bold text-center text-transparent bg-gradient-to-r from-primary to-secondary bg-clip-text;
|
||||
}
|
||||
|
||||
.auth-divider {
|
||||
@apply relative my-6 text-center;
|
||||
}
|
||||
|
||||
.auth-divider::before,
|
||||
.auth-divider::after {
|
||||
@apply absolute top-1/2 w-1/3 border-t border-gray-200 dark:border-gray-700 content-[''];
|
||||
}
|
||||
|
||||
.auth-divider::before {
|
||||
@apply left-0;
|
||||
}
|
||||
|
||||
.auth-divider::after {
|
||||
@apply right-0;
|
||||
}
|
||||
|
||||
.auth-divider span {
|
||||
@apply px-4 text-sm text-gray-500 dark:text-gray-400 bg-white/90 dark:bg-gray-800/90;
|
||||
}
|
||||
|
||||
/* Social Login Buttons */
|
||||
.btn-social {
|
||||
@apply w-full flex items-center justify-center px-6 py-3 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-[1.02] transition-all mb-3;
|
||||
}
|
||||
|
||||
.btn-discord {
|
||||
@apply text-gray-700 bg-white border-gray-200 hover:bg-gray-50 shadow-gray-200/50 dark:shadow-gray-900/50;
|
||||
}
|
||||
|
||||
.btn-google {
|
||||
@apply text-gray-700 bg-white border-gray-200 hover:bg-gray-50 shadow-gray-200/50 dark:shadow-gray-900/50;
|
||||
}
|
||||
|
||||
/* Alert Components */
|
||||
.alert {
|
||||
@apply p-4 mb-4 shadow-lg rounded-xl backdrop-blur-sm;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
@apply text-green-800 border border-green-200 bg-green-100/90 dark:bg-green-800/30 dark:text-green-100 dark:border-green-700;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
@apply text-red-800 border border-red-200 bg-red-100/90 dark:bg-red-800/30 dark:text-red-100 dark:border-red-700;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
@apply text-yellow-800 border border-yellow-200 bg-yellow-100/90 dark:bg-yellow-800/30 dark:text-yellow-100 dark:border-yellow-700;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
@apply text-blue-800 border border-blue-200 bg-blue-100/90 dark:bg-blue-800/30 dark:text-blue-100 dark:border-blue-700;
|
||||
}
|
||||
|
||||
/* Layout Components */
|
||||
.card {
|
||||
@apply p-6 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50;
|
||||
}
|
||||
|
||||
.card-hover {
|
||||
@apply transition-transform transform hover:-translate-y-1;
|
||||
}
|
||||
|
||||
.grid-cards {
|
||||
@apply grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3;
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
.heading-1 {
|
||||
@apply mb-6 text-3xl font-bold text-gray-900 dark:text-white;
|
||||
}
|
||||
|
||||
.heading-2 {
|
||||
@apply mb-4 text-2xl font-bold text-gray-900 dark:text-white;
|
||||
}
|
||||
|
||||
.text-body {
|
||||
@apply text-gray-600 dark:text-gray-300;
|
||||
}
|
||||
|
||||
/* Turnstile Widget */
|
||||
.turnstile {
|
||||
@apply flex items-center justify-center my-4;
|
||||
}
|
||||
}
|
||||
@@ -1 +1,6 @@
|
||||
import './bootstrap';
|
||||
import './modules/alerts';
|
||||
import './modules/location-autocomplete';
|
||||
import './modules/park-map';
|
||||
import './modules/photo-gallery';
|
||||
import './modules/search';
|
||||
|
||||
18
resources/js/modules/alerts.js
Normal file
18
resources/js/modules/alerts.js
Normal file
@@ -0,0 +1,18 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Get all alert elements
|
||||
const alerts = document.querySelectorAll('.alert');
|
||||
|
||||
// For each alert
|
||||
alerts.forEach(alert => {
|
||||
// After 5 seconds
|
||||
setTimeout(() => {
|
||||
// Add slideOut animation
|
||||
alert.style.animation = 'slideOut 0.5s ease-out forwards';
|
||||
|
||||
// Remove the alert after animation completes
|
||||
setTimeout(() => {
|
||||
alert.remove();
|
||||
}, 500);
|
||||
}, 5000);
|
||||
});
|
||||
});
|
||||
81
resources/js/modules/location-autocomplete.js
Normal file
81
resources/js/modules/location-autocomplete.js
Normal file
@@ -0,0 +1,81 @@
|
||||
function locationAutocomplete(field, filterParks = false) {
|
||||
return {
|
||||
query: '',
|
||||
suggestions: [],
|
||||
fetchSuggestions() {
|
||||
let url;
|
||||
const params = new URLSearchParams({
|
||||
q: this.query,
|
||||
filter_parks: filterParks
|
||||
});
|
||||
|
||||
switch (field) {
|
||||
case 'country':
|
||||
url = '/parks/ajax/countries/';
|
||||
break;
|
||||
case 'region':
|
||||
url = '/parks/ajax/regions/';
|
||||
// Add country parameter if we're fetching regions
|
||||
const countryInput = document.getElementById(filterParks ? 'country' : 'id_country_name');
|
||||
if (countryInput && countryInput.value) {
|
||||
params.append('country', countryInput.value);
|
||||
}
|
||||
break;
|
||||
case 'city':
|
||||
url = '/parks/ajax/cities/';
|
||||
// Add country and region parameters if we're fetching cities
|
||||
const regionInput = document.getElementById(filterParks ? 'region' : 'id_region_name');
|
||||
const cityCountryInput = document.getElementById(filterParks ? 'country' : 'id_country_name');
|
||||
if (regionInput && regionInput.value && cityCountryInput && cityCountryInput.value) {
|
||||
params.append('country', cityCountryInput.value);
|
||||
params.append('region', regionInput.value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
fetch(`${url}?${params}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
this.suggestions = data;
|
||||
});
|
||||
}
|
||||
},
|
||||
selectSuggestion(suggestion) {
|
||||
this.query = suggestion.name;
|
||||
this.suggestions = [];
|
||||
|
||||
// If this is a form field (not filter), update hidden fields
|
||||
if (!filterParks) {
|
||||
const hiddenField = document.getElementById(`id_${field}`);
|
||||
if (hiddenField) {
|
||||
hiddenField.value = suggestion.id;
|
||||
}
|
||||
|
||||
// Clear dependent fields when parent field changes
|
||||
if (field === 'country') {
|
||||
const regionInput = document.getElementById('id_region_name');
|
||||
const cityInput = document.getElementById('id_city_name');
|
||||
const regionHidden = document.getElementById('id_region');
|
||||
const cityHidden = document.getElementById('id_city');
|
||||
|
||||
if (regionInput) regionInput.value = '';
|
||||
if (cityInput) cityInput.value = '';
|
||||
if (regionHidden) regionHidden.value = '';
|
||||
if (cityHidden) cityHidden.value = '';
|
||||
} else if (field === 'region') {
|
||||
const cityInput = document.getElementById('id_city_name');
|
||||
const cityHidden = document.getElementById('id_city');
|
||||
|
||||
if (cityInput) cityInput.value = '';
|
||||
if (cityHidden) cityHidden.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger form submission for filters
|
||||
if (filterParks) {
|
||||
htmx.trigger('#park-filters', 'change');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
141
resources/js/modules/main.js
Normal file
141
resources/js/modules/main.js
Normal file
@@ -0,0 +1,141 @@
|
||||
// Theme handling
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const themeToggle = document.getElementById('theme-toggle');
|
||||
const html = document.documentElement;
|
||||
|
||||
// Initialize toggle state based on current theme
|
||||
if (themeToggle) {
|
||||
themeToggle.checked = html.classList.contains('dark');
|
||||
|
||||
// Handle toggle changes
|
||||
themeToggle.addEventListener('change', function() {
|
||||
const isDark = this.checked;
|
||||
html.classList.toggle('dark', isDark);
|
||||
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
||||
});
|
||||
|
||||
// Listen for system theme changes
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
mediaQuery.addEventListener('change', (e) => {
|
||||
if (!localStorage.getItem('theme')) {
|
||||
const isDark = e.matches;
|
||||
html.classList.toggle('dark', isDark);
|
||||
themeToggle.checked = isDark;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Handle search form submission
|
||||
document.addEventListener('submit', (e) => {
|
||||
if (e.target.matches('form[action*="search"]')) {
|
||||
const searchInput = e.target.querySelector('input[name="q"]');
|
||||
if (!searchInput.value.trim()) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Mobile menu toggle with transitions
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const mobileMenuBtn = document.getElementById('mobileMenuBtn');
|
||||
const mobileMenu = document.getElementById('mobileMenu');
|
||||
|
||||
if (mobileMenuBtn && mobileMenu) {
|
||||
let isMenuOpen = false;
|
||||
|
||||
const toggleMenu = () => {
|
||||
isMenuOpen = !isMenuOpen;
|
||||
mobileMenu.classList.toggle('show', isMenuOpen);
|
||||
mobileMenuBtn.setAttribute('aria-expanded', isMenuOpen.toString());
|
||||
|
||||
// Update icon
|
||||
const icon = mobileMenuBtn.querySelector('i');
|
||||
icon.classList.remove(isMenuOpen ? 'fa-bars' : 'fa-times');
|
||||
icon.classList.add(isMenuOpen ? 'fa-times' : 'fa-bars');
|
||||
};
|
||||
|
||||
mobileMenuBtn.addEventListener('click', toggleMenu);
|
||||
|
||||
// Close menu when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (isMenuOpen && !mobileMenu.contains(e.target) && !mobileMenuBtn.contains(e.target)) {
|
||||
toggleMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Close menu when pressing escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (isMenuOpen && e.key === 'Escape') {
|
||||
toggleMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle viewport changes
|
||||
const mediaQuery = window.matchMedia('(min-width: 1024px)');
|
||||
mediaQuery.addEventListener('change', (e) => {
|
||||
if (e.matches && isMenuOpen) {
|
||||
toggleMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// User dropdown toggle
|
||||
const userMenuBtn = document.getElementById('userMenuBtn');
|
||||
const userDropdown = document.getElementById('userDropdown');
|
||||
|
||||
if (userMenuBtn && userDropdown) {
|
||||
userMenuBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
userDropdown.classList.toggle('active');
|
||||
});
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!userMenuBtn.contains(e.target) && !userDropdown.contains(e.target)) {
|
||||
userDropdown.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Close dropdown when pressing escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
userDropdown.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle flash messages
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const alerts = document.querySelectorAll('.alert');
|
||||
alerts.forEach(alert => {
|
||||
setTimeout(() => {
|
||||
alert.style.opacity = '0';
|
||||
setTimeout(() => alert.remove(), 300);
|
||||
}, 5000);
|
||||
});
|
||||
});
|
||||
|
||||
// Initialize tooltips
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const tooltips = document.querySelectorAll('[data-tooltip]');
|
||||
tooltips.forEach(tooltip => {
|
||||
tooltip.addEventListener('mouseenter', (e) => {
|
||||
const text = e.target.getAttribute('data-tooltip');
|
||||
const tooltipEl = document.createElement('div');
|
||||
tooltipEl.className = 'absolute z-50 px-2 py-1 text-sm text-white bg-gray-900 rounded tooltip';
|
||||
tooltipEl.textContent = text;
|
||||
document.body.appendChild(tooltipEl);
|
||||
|
||||
const rect = e.target.getBoundingClientRect();
|
||||
tooltipEl.style.top = rect.bottom + 5 + 'px';
|
||||
tooltipEl.style.left = rect.left + (rect.width - tooltipEl.offsetWidth) / 2 + 'px';
|
||||
});
|
||||
|
||||
tooltip.addEventListener('mouseleave', () => {
|
||||
const tooltips = document.querySelectorAll('.tooltip');
|
||||
tooltips.forEach(t => t.remove());
|
||||
});
|
||||
});
|
||||
});
|
||||
29
resources/js/modules/park-map.js
Normal file
29
resources/js/modules/park-map.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// Only declare parkMap if it doesn't exist
|
||||
window.parkMap = window.parkMap || null;
|
||||
|
||||
function initParkMap(latitude, longitude, name) {
|
||||
const mapContainer = document.getElementById('park-map');
|
||||
|
||||
// Only initialize if container exists and map hasn't been initialized
|
||||
if (mapContainer && !window.parkMap) {
|
||||
const width = mapContainer.offsetWidth;
|
||||
mapContainer.style.height = width + 'px';
|
||||
|
||||
window.parkMap = L.map('park-map').setView([latitude, longitude], 13);
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(window.parkMap);
|
||||
|
||||
L.marker([latitude, longitude])
|
||||
.addTo(window.parkMap)
|
||||
.bindPopup(name);
|
||||
|
||||
// Update map size when window is resized
|
||||
window.addEventListener('resize', function() {
|
||||
const width = mapContainer.offsetWidth;
|
||||
mapContainer.style.height = width + 'px';
|
||||
window.parkMap.invalidateSize();
|
||||
});
|
||||
}
|
||||
}
|
||||
91
resources/js/modules/photo-gallery.js
Normal file
91
resources/js/modules/photo-gallery.js
Normal file
@@ -0,0 +1,91 @@
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.data('photoDisplay', ({ photos, contentType, objectId, csrfToken, uploadUrl }) => ({
|
||||
photos,
|
||||
fullscreenPhoto: null,
|
||||
uploading: false,
|
||||
uploadProgress: 0,
|
||||
error: null,
|
||||
showSuccess: false,
|
||||
|
||||
showFullscreen(photo) {
|
||||
this.fullscreenPhoto = photo;
|
||||
},
|
||||
|
||||
async handleFileSelect(event) {
|
||||
const files = Array.from(event.target.files);
|
||||
if (!files.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.uploading = true;
|
||||
this.uploadProgress = 0;
|
||||
this.error = null;
|
||||
this.showSuccess = false;
|
||||
|
||||
const totalFiles = files.length;
|
||||
let completedFiles = 0;
|
||||
|
||||
for (const file of files) {
|
||||
const formData = new FormData();
|
||||
formData.append('image', file);
|
||||
formData.append('app_label', contentType.split('.')[0]);
|
||||
formData.append('model', contentType.split('.')[1]);
|
||||
formData.append('object_id', objectId);
|
||||
|
||||
try {
|
||||
const response = await fetch(uploadUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRFToken': csrfToken,
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json();
|
||||
throw new Error(data.error || 'Upload failed');
|
||||
}
|
||||
|
||||
const photo = await response.json();
|
||||
this.photos.push(photo);
|
||||
completedFiles++;
|
||||
this.uploadProgress = (completedFiles / totalFiles) * 100;
|
||||
} catch (err) {
|
||||
this.error = err.message || 'Failed to upload photo. Please try again.';
|
||||
console.error('Upload error:', err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.uploading = false;
|
||||
event.target.value = ''; // Reset file input
|
||||
|
||||
if (!this.error) {
|
||||
this.showSuccess = true;
|
||||
setTimeout(() => {
|
||||
this.showSuccess = false;
|
||||
}, 3000);
|
||||
}
|
||||
},
|
||||
|
||||
async sharePhoto(photo) {
|
||||
if (navigator.share) {
|
||||
try {
|
||||
await navigator.share({
|
||||
title: photo.caption || 'Shared photo',
|
||||
url: photo.url
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.name !== 'AbortError') {
|
||||
console.error('Error sharing:', err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fallback: copy URL to clipboard
|
||||
navigator.clipboard.writeText(photo.url)
|
||||
.then(() => alert('Photo URL copied to clipboard!'))
|
||||
.catch(err => console.error('Error copying to clipboard:', err));
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
42
resources/js/modules/search.js
Normal file
42
resources/js/modules/search.js
Normal file
@@ -0,0 +1,42 @@
|
||||
function parkSearch() {
|
||||
return {
|
||||
query: '',
|
||||
results: [],
|
||||
loading: false,
|
||||
selectedId: null,
|
||||
|
||||
async search() {
|
||||
if (!this.query.trim()) {
|
||||
this.results = [];
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
try {
|
||||
const response = await fetch(`/parks/suggest_parks/?search=${encodeURIComponent(this.query)}`);
|
||||
const data = await response.json();
|
||||
this.results = data.results;
|
||||
} catch (error) {
|
||||
console.error('Search failed:', error);
|
||||
this.results = [];
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
clear() {
|
||||
this.query = '';
|
||||
this.results = [];
|
||||
this.selectedId = null;
|
||||
},
|
||||
|
||||
selectPark(park) {
|
||||
this.query = park.name;
|
||||
this.selectedId = park.id;
|
||||
this.results = [];
|
||||
|
||||
// Trigger filter update
|
||||
document.getElementById('park-filters').dispatchEvent(new Event('change'));
|
||||
}
|
||||
};
|
||||
}
|
||||
176
resources/views/layouts/app.blade.php
Normal file
176
resources/views/layouts/app.blade.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}" />
|
||||
<title>@yield('title', 'ThrillWiki')</title>
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!-- Prevent flash of wrong theme -->
|
||||
<script>
|
||||
let theme = localStorage.getItem("theme");
|
||||
if (!theme) {
|
||||
theme = window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light";
|
||||
localStorage.setItem("theme", theme);
|
||||
}
|
||||
if (theme === "dark") {
|
||||
document.documentElement.classList.add("dark");
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- HTMX -->
|
||||
<script src="https://unpkg.com/htmx.org@1.9.6"></script>
|
||||
|
||||
<!-- Scripts and Styles (loaded via Vite) -->
|
||||
@vite(['resources/js/app.js', 'resources/css/app.css'])
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
|
||||
/>
|
||||
|
||||
<style>
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
width: 12rem;
|
||||
border-radius: 0.375rem;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
|
||||
0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
z-index: 50;
|
||||
overflow: hidden;
|
||||
}
|
||||
.htmx-indicator {
|
||||
display: none;
|
||||
}
|
||||
.htmx-request .htmx-indicator {
|
||||
display: block;
|
||||
}
|
||||
.htmx-request.htmx-indicator {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
@stack('styles')
|
||||
</head>
|
||||
<body
|
||||
class="flex flex-col min-h-screen text-gray-900 bg-gradient-to-br from-white via-blue-50 to-indigo-50 dark:from-gray-950 dark:via-indigo-950 dark:to-purple-950 dark:text-white"
|
||||
>
|
||||
<!-- Header -->
|
||||
<header
|
||||
class="sticky top-0 z-40 border-b shadow-lg bg-white/90 dark:bg-gray-800/90 backdrop-blur-lg border-gray-200/50 dark:border-gray-700/50"
|
||||
>
|
||||
<nav class="container mx-auto nav-container">
|
||||
<div class="flex items-center justify-between">
|
||||
<!-- Logo -->
|
||||
<div class="flex items-center">
|
||||
<a
|
||||
href="{{ route('home') }}"
|
||||
class="font-bold text-transparent transition-transform site-logo bg-gradient-to-r from-primary to-secondary bg-clip-text hover:scale-105"
|
||||
>
|
||||
ThrillWiki
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Navigation Links (Always Visible) -->
|
||||
<div class="flex items-center space-x-2 sm:space-x-4">
|
||||
<a href="{{ route('parks.index') }}" class="nav-link">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
<span>Parks</span>
|
||||
</a>
|
||||
<a href="{{ route('rides.index') }}" class="nav-link">
|
||||
<i class="fas fa-rocket"></i>
|
||||
<span>Rides</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Search Bar -->
|
||||
<div class="flex-1 hidden max-w-md mx-8 lg:flex">
|
||||
<form action="{{ route('search') }}" method="get" class="w-full">
|
||||
<div class="relative">
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
placeholder="Search parks and rides..."
|
||||
class="form-input"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Right Side Menu -->
|
||||
<div class="flex items-center space-x-2 sm:space-x-6">
|
||||
<!-- Theme Toggle -->
|
||||
<livewire:theme-toggle-component />
|
||||
|
||||
<!-- User Menu -->
|
||||
@auth
|
||||
@if(auth()->user()->can('access-moderation'))
|
||||
<a href="{{ route('moderation.dashboard') }}" class="nav-link">
|
||||
<i class="fas fa-shield-alt"></i>
|
||||
<span>Moderation</span>
|
||||
</a>
|
||||
@endif
|
||||
<livewire:user-menu-component />
|
||||
@else
|
||||
<!-- Generic Profile Icon for Unauthenticated Users -->
|
||||
<livewire:auth-menu-component />
|
||||
@endauth
|
||||
|
||||
<!-- Mobile Menu -->
|
||||
<livewire:mobile-menu-component />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
@if (session('status'))
|
||||
<div class="fixed top-0 right-0 z-50 p-4 space-y-4">
|
||||
<div class="alert alert-success">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="container flex-grow px-6 py-8 mx-auto">
|
||||
{{ $slot }}
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer
|
||||
class="mt-auto border-t bg-white/90 dark:bg-gray-800/90 backdrop-blur-lg border-gray-200/50 dark:border-gray-700/50"
|
||||
>
|
||||
<div class="container px-6 py-6 mx-auto">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-gray-600 dark:text-gray-400">
|
||||
<p>© {{ date('Y') }} ThrillWiki. All rights reserved.</p>
|
||||
</div>
|
||||
<div class="space-x-4">
|
||||
<a
|
||||
href="{{ route('terms') }}"
|
||||
class="text-gray-600 transition-colors hover:text-primary dark:text-gray-400 dark:hover:text-primary"
|
||||
>Terms</a>
|
||||
<a
|
||||
href="{{ route('privacy') }}"
|
||||
class="text-gray-600 transition-colors hover:text-primary dark:text-gray-400 dark:hover:text-primary"
|
||||
>Privacy</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
||||
34
resources/views/livewire/auth-menu-component.blade.php
Normal file
34
resources/views/livewire/auth-menu-component.blade.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<div class="relative">
|
||||
<div
|
||||
wire:click="toggle"
|
||||
class="flex items-center justify-center w-8 h-8 text-gray-500 transition-transform rounded-full cursor-pointer hover:text-primary dark:text-gray-400 dark:hover:text-primary hover:scale-105"
|
||||
>
|
||||
<i class="text-xl fas fa-user"></i>
|
||||
</div>
|
||||
|
||||
<!-- Auth Menu -->
|
||||
<div
|
||||
wire:model="isOpen"
|
||||
class="bg-white dropdown-menu dark:bg-gray-800"
|
||||
style="display: {{ $isOpen ? 'block' : 'none' }}"
|
||||
>
|
||||
<div
|
||||
hx-get="{{ route('login') }}"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend"
|
||||
class="cursor-pointer menu-item"
|
||||
>
|
||||
<i class="w-5 fas fa-sign-in-alt"></i>
|
||||
<span>Login</span>
|
||||
</div>
|
||||
<div
|
||||
hx-get="{{ route('register') }}"
|
||||
hx-target="body"
|
||||
hx-swap="beforeend"
|
||||
class="cursor-pointer menu-item"
|
||||
>
|
||||
<i class="w-5 fas fa-user-plus"></i>
|
||||
<span>Register</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,7 +1,8 @@
|
||||
<div>
|
||||
<h1>{{ $count }}</h1>
|
||||
<div class="flex flex-col items-center justify-center p-6 space-y-4">
|
||||
<h1 class="text-4xl font-bold">{{ $count }}</h1>
|
||||
|
||||
<button wire:click="increment">+</button>
|
||||
|
||||
<button wire:click="decrement">-</button>
|
||||
<div class="flex space-x-4">
|
||||
<button wire:click="increment" class="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-600">+</button>
|
||||
<button wire:click="decrement" class="px-4 py-2 text-white bg-red-500 rounded hover:bg-red-600">-</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
39
resources/views/livewire/mobile-menu-component.blade.php
Normal file
39
resources/views/livewire/mobile-menu-component.blade.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<div>
|
||||
<button
|
||||
wire:click="toggle"
|
||||
class="p-2 text-gray-500 rounded-lg lg:hidden hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-400"
|
||||
aria-label="Toggle mobile menu"
|
||||
aria-expanded="{{ $isOpen }}"
|
||||
>
|
||||
<i class="text-2xl fas {{ $isOpen ? 'fa-times' : 'fa-bars' }}"></i>
|
||||
</button>
|
||||
|
||||
<!-- Mobile Menu -->
|
||||
<div
|
||||
wire:model="isOpen"
|
||||
class="absolute left-0 right-0 w-full p-4 mt-2 space-y-4 bg-white border-b dark:bg-gray-800 dark:border-gray-700"
|
||||
style="display: {{ $isOpen ? 'block' : 'none' }}"
|
||||
>
|
||||
<!-- Search (Mobile) -->
|
||||
<form action="{{ route('search') }}" method="get" class="mb-4">
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
placeholder="Search parks and rides..."
|
||||
class="form-input"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<!-- Mobile Navigation Links -->
|
||||
<nav class="space-y-2">
|
||||
<a href="{{ route('parks.index') }}" class="block nav-link">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
<span>Parks</span>
|
||||
</a>
|
||||
<a href="{{ route('rides.index') }}" class="block nav-link">
|
||||
<i class="fas fa-rocket"></i>
|
||||
<span>Rides</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
28
resources/views/livewire/theme-toggle-component.blade.php
Normal file
28
resources/views/livewire/theme-toggle-component.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<label for="theme-toggle" class="cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="theme-toggle"
|
||||
class="hidden"
|
||||
wire:model.live="isDark"
|
||||
wire:change="toggleTheme"
|
||||
>
|
||||
<div
|
||||
class="inline-flex items-center justify-center p-2 text-gray-500 transition-colors hover:text-primary dark:text-gray-400 dark:hover:text-primary theme-toggle-btn"
|
||||
role="button"
|
||||
aria-label="Toggle dark mode"
|
||||
>
|
||||
<i class="text-xl fas {{ $isDark ? 'fa-sun' : 'fa-moon' }}"></i>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<script>
|
||||
document.addEventListener('livewire:init', () => {
|
||||
Livewire.on('theme-changed', ({ theme }) => {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
47
resources/views/livewire/user-menu-component.blade.php
Normal file
47
resources/views/livewire/user-menu-component.blade.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<div class="relative">
|
||||
<!-- Profile Picture Button -->
|
||||
@if(auth()->user()->profile?->avatar)
|
||||
<img
|
||||
wire:click="toggle"
|
||||
src="{{ auth()->user()->profile->avatar }}"
|
||||
alt="{{ auth()->user()->username }}"
|
||||
class="w-8 h-8 transition-transform rounded-full cursor-pointer ring-2 ring-primary/20 hover:scale-105"
|
||||
/>
|
||||
@else
|
||||
<div
|
||||
wire:click="toggle"
|
||||
class="flex items-center justify-center w-8 h-8 text-white transition-transform rounded-full cursor-pointer bg-gradient-to-br from-primary to-secondary hover:scale-105"
|
||||
>
|
||||
{{ ucfirst(auth()->user()->username[0]) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Dropdown Menu -->
|
||||
<div
|
||||
wire:model="isOpen"
|
||||
class="bg-white dropdown-menu dark:bg-gray-800"
|
||||
style="display: {{ $isOpen ? 'block' : 'none' }}"
|
||||
>
|
||||
<a href="{{ route('profile.show', auth()->user()->username) }}" class="menu-item">
|
||||
<i class="w-5 fas fa-user"></i>
|
||||
<span>Profile</span>
|
||||
</a>
|
||||
<a href="{{ route('settings') }}" class="menu-item">
|
||||
<i class="w-5 fas fa-cog"></i>
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
@if(auth()->user()->can('access-admin'))
|
||||
<a href="{{ route('admin.index') }}" class="menu-item">
|
||||
<i class="w-5 fas fa-shield-alt"></i>
|
||||
<span>Admin</span>
|
||||
</a>
|
||||
@endif
|
||||
<form method="POST" action="{{ route('logout') }}">
|
||||
@csrf
|
||||
<button type="submit" class="w-full menu-item">
|
||||
<i class="w-5 fas fa-sign-out-alt"></i>
|
||||
<span>Logout</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,11 +1,57 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Livewire\Counter;
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
|
||||
use App\Livewire\Counter;
|
||||
})->name('home');
|
||||
|
||||
Route::get('/counter', Counter::class);
|
||||
});
|
||||
|
||||
// Parks routes
|
||||
Route::get('/parks', function () {
|
||||
return 'Parks Index';
|
||||
})->name('parks.index');
|
||||
|
||||
// Rides routes
|
||||
Route::get('/rides', function () {
|
||||
return 'Rides Index';
|
||||
})->name('rides.index');
|
||||
|
||||
// Auth routes
|
||||
Route::get('/login', function () {
|
||||
return 'Login';
|
||||
})->name('login');
|
||||
|
||||
Route::get('/register', function () {
|
||||
return 'Register';
|
||||
})->name('register');
|
||||
|
||||
Route::post('/logout', function () {
|
||||
return 'Logout';
|
||||
})->name('logout');
|
||||
|
||||
// Settings routes
|
||||
Route::get('/settings', function () {
|
||||
return 'Settings';
|
||||
})->name('settings');
|
||||
|
||||
// Legal routes
|
||||
Route::get('/terms', function () {
|
||||
return 'Terms';
|
||||
})->name('terms');
|
||||
|
||||
Route::get('/privacy', function () {
|
||||
return 'Privacy';
|
||||
})->name('privacy');
|
||||
|
||||
// Profile routes
|
||||
Route::get('/profile/{username}', function () {
|
||||
return 'Profile';
|
||||
})->name('profile.show');
|
||||
|
||||
// Search route
|
||||
Route::get('/search', function () {
|
||||
return 'Search';
|
||||
})->name('search');
|
||||
|
||||
@@ -1,20 +1,75 @@
|
||||
import defaultTheme from 'tailwindcss/defaultTheme';
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
'./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
|
||||
'./storage/framework/views/*.php',
|
||||
'./resources/**/*.blade.php',
|
||||
'./resources/**/*.js',
|
||||
'./resources/**/*.vue',
|
||||
"./resources/**/*.blade.php",
|
||||
"./resources/**/*.js",
|
||||
"./resources/**/*.vue",
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: {
|
||||
DEFAULT: '1rem',
|
||||
sm: '2rem',
|
||||
lg: '4rem',
|
||||
xl: '5rem',
|
||||
'2xl': '6rem',
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
primary: {
|
||||
DEFAULT: '#6366f1', // Indigo-500
|
||||
50: '#eef2ff',
|
||||
100: '#e0e7ff',
|
||||
200: '#c7d2fe',
|
||||
300: '#a5b4fc',
|
||||
400: '#818cf8',
|
||||
500: '#6366f1',
|
||||
600: '#4f46e5',
|
||||
700: '#4338ca',
|
||||
800: '#3730a3',
|
||||
900: '#312e81',
|
||||
950: '#1e1b4b',
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: '#8b5cf6', // Violet-500
|
||||
50: '#f5f3ff',
|
||||
100: '#ede9fe',
|
||||
200: '#ddd6fe',
|
||||
300: '#c4b5fd',
|
||||
400: '#a78bfa',
|
||||
500: '#8b5cf6',
|
||||
600: '#7c3aed',
|
||||
700: '#6d28d9',
|
||||
800: '#5b21b6',
|
||||
900: '#4c1d95',
|
||||
950: '#2e1065',
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Figtree', ...defaultTheme.fontFamily.sans],
|
||||
sans: ['Poppins', 'sans-serif'],
|
||||
},
|
||||
animation: {
|
||||
'fade-in': 'fadeIn 0.2s ease-in-out',
|
||||
'fade-out': 'fadeOut 0.2s ease-in-out',
|
||||
},
|
||||
keyframes: {
|
||||
fadeIn: {
|
||||
'0%': { opacity: '0' },
|
||||
'100%': { opacity: '1' },
|
||||
},
|
||||
fadeOut: {
|
||||
'0%': { opacity: '1' },
|
||||
'100%': { opacity: '0' },
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
require('@tailwindcss/typography'),
|
||||
require('@tailwindcss/aspect-ratio'),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -4,8 +4,29 @@ import laravel from 'laravel-vite-plugin';
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
laravel({
|
||||
input: ['resources/css/app.css', 'resources/js/app.js'],
|
||||
input: [
|
||||
'resources/css/app.css',
|
||||
'resources/js/app.js',
|
||||
],
|
||||
refresh: true,
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': '/resources/js',
|
||||
},
|
||||
},
|
||||
build: {
|
||||
// Generate source maps for better debugging
|
||||
sourcemap: true,
|
||||
// Optimize dependency bundling
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
// Split vendor chunks for better caching
|
||||
vendor: ['alpinejs'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user