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>
This commit is contained in:
97
src/routes/+error.svelte
Normal file
97
src/routes/+error.svelte
Normal file
@@ -0,0 +1,97 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import Card from '$lib/components/ui/Card.svelte';
|
||||
import { Home, ArrowLeft } from 'lucide-svelte';
|
||||
|
||||
// Get error information
|
||||
const error = $page.error;
|
||||
const status = $page.status;
|
||||
|
||||
// Determine error message
|
||||
const getErrorMessage = (status: number): string => {
|
||||
switch (status) {
|
||||
case 404:
|
||||
return "We couldn't find the page you're looking for.";
|
||||
case 500:
|
||||
return 'Something went wrong on our end. Please try again later.';
|
||||
case 503:
|
||||
return 'Service temporarily unavailable. Please check back soon.';
|
||||
default:
|
||||
return 'An unexpected error occurred.';
|
||||
}
|
||||
};
|
||||
|
||||
const getErrorTitle = (status: number): string => {
|
||||
switch (status) {
|
||||
case 404:
|
||||
return 'Page Not Found';
|
||||
case 500:
|
||||
return 'Internal Server Error';
|
||||
case 503:
|
||||
return 'Service Unavailable';
|
||||
default:
|
||||
return 'Error';
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{status} - {getErrorTitle(status)} | CS2.WTF</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="container mx-auto flex min-h-[60vh] items-center justify-center px-4 py-16">
|
||||
<Card padding="lg" class="w-full max-w-2xl">
|
||||
<div class="text-center">
|
||||
<!-- Error Code -->
|
||||
<div class="mb-4 text-8xl font-bold text-primary">
|
||||
{status}
|
||||
</div>
|
||||
|
||||
<!-- Error Title -->
|
||||
<h1 class="mb-4 text-3xl font-bold text-base-content">
|
||||
{getErrorTitle(status)}
|
||||
</h1>
|
||||
|
||||
<!-- Error Message -->
|
||||
<p class="mb-8 text-lg text-base-content/70">
|
||||
{getErrorMessage(status)}
|
||||
</p>
|
||||
|
||||
<!-- Debug Info (only in development) -->
|
||||
{#if import.meta.env?.DEV && error}
|
||||
<div class="mb-8 rounded-lg bg-base-300 p-4 text-left">
|
||||
<p class="mb-2 font-mono text-sm text-error">
|
||||
<strong>Debug Info:</strong>
|
||||
</p>
|
||||
<pre class="overflow-x-auto text-xs text-base-content/80">{JSON.stringify(
|
||||
error,
|
||||
null,
|
||||
2
|
||||
)}</pre>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="flex flex-col justify-center gap-4 sm:flex-row">
|
||||
<Button variant="secondary" href="javascript:history.back()">
|
||||
<ArrowLeft class="mr-2 h-5 w-5" />
|
||||
Go Back
|
||||
</Button>
|
||||
|
||||
<Button variant="primary" href="/">
|
||||
<Home class="mr-2 h-5 w-5" />
|
||||
Go Home
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<!-- Help Text -->
|
||||
<p class="mt-8 text-sm text-base-content/50">
|
||||
If this problem persists, please
|
||||
<a href="https://somegit.dev/CSGOWTF/csgowtf/issues" class="link-hover link text-primary">
|
||||
report it on GitHub
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
Reference in New Issue
Block a user