Files
csgowtf/src/lib/components/ui/Toast.svelte
vikingowl 24b990ac62 feat: Implement Phase 4 - Application Architecture & Routing
Phase 4 establishes the core application structure with SvelteKit routing,
data loading, error handling, and state management.

## Routing & Data Loading
- Created root layout load function (+layout.ts) with app version and feature flags
- Implemented comprehensive error boundary (+error.svelte) with status-based messages
- Added page loaders for homepage, matches, players, and about routes
- Homepage loader fetches featured matches via API with error fallback
- Matches loader supports URL query parameters (map, player_id, limit)

## State Management (Svelte Stores)
- preferences.ts: User settings with localStorage persistence
  * Theme selection (cs2dark, cs2light, auto)
  * Favorite players tracking
  * Advanced stats toggle, date format preferences
- search.ts: Search state with recent searches (localStorage)
- toast.ts: Toast notification system with auto-dismiss
  * Success, error, warning, info types
  * Configurable duration and dismissibility

## UI Components
- Toast.svelte: Individual notification with Lucide icons
- ToastContainer.svelte: Fixed top-right toast display
- Integrated ToastContainer into root layout

## Fixes
- Fixed Svelte 5 deprecation warnings (removed <svelte:component> in runes mode)
- Updated homepage to use PageData from loader
- Added proper type safety across all load functions

## Testing
- Type check: 0 errors, 0 warnings
- Production build: Successful
- All Phase 4 core objectives completed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 20:47:49 +01:00

50 lines
1.0 KiB
Svelte

<script lang="ts">
import { fly } from 'svelte/transition';
import { CheckCircle, XCircle, AlertTriangle, Info, X } from 'lucide-svelte';
import type { Toast } from '$lib/stores';
interface Props {
toast: Toast;
onDismiss: (id: string) => void;
}
let { toast, onDismiss }: Props = $props();
// Icon mapping
const icons = {
success: CheckCircle,
error: XCircle,
warning: AlertTriangle,
info: Info
};
// Color mapping for DaisyUI
const alertClasses = {
success: 'alert-success',
error: 'alert-error',
warning: 'alert-warning',
info: 'alert-info'
};
const IconComponent = icons[toast.type];
</script>
<div
role="alert"
class="alert {alertClasses[toast.type]} shadow-lg"
transition:fly={{ y: -20, duration: 300 }}
>
<IconComponent class="h-6 w-6" />
<span>{toast.message}</span>
{#if toast.dismissible}
<button
class="btn btn-circle btn-ghost btn-sm"
onclick={() => onDismiss(toast.id)}
aria-label="Dismiss notification"
>
<X class="h-4 w-4" />
</button>
{/if}
</div>