204 lines
6.1 KiB
Svelte
204 lines
6.1 KiB
Svelte
<script lang="ts">
|
|
import { getContext } from 'svelte';
|
|
import AppLayout from '$lib/components/app-layout.svelte';
|
|
import { Button } from '$lib/components/ui/button';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardFooter,
|
|
CardHeader,
|
|
CardTitle
|
|
} from '$lib/components/ui/card';
|
|
import { Badge } from '$lib/components/ui/badge';
|
|
import { Calendar, Users, MapPin } from 'lucide-svelte';
|
|
import type { BreadcrumbItem } from '../app';
|
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
|
import type { PageProps } from './$types.js';
|
|
import { toast } from 'svelte-sonner';
|
|
import { formatDate } from '@/utils';
|
|
|
|
const breadcrumbs: BreadcrumbItem[] = [
|
|
{
|
|
title: 'Home',
|
|
href: '/'
|
|
}
|
|
];
|
|
|
|
// Get user context
|
|
const user = getContext('user');
|
|
|
|
// Get competitions data from server
|
|
let { data }: PageProps = $props();
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>Home - FlbxCup</title>
|
|
<meta name="description" content="FlbxCup - Competition Management Platform" />
|
|
</svelte:head>
|
|
|
|
<AppLayout {breadcrumbs}>
|
|
<div class="space-y-8">
|
|
<!-- Hero Section -->
|
|
<section
|
|
class="from-primary/10 via-primary/5 to-background rounded-xl bg-gradient-to-r p-8 text-center"
|
|
>
|
|
<h1 class="text-4xl font-bold tracking-tight sm:text-5xl">
|
|
Welcome to <span class="text-primary">FlbxCup</span>
|
|
</h1>
|
|
<p class="text-muted-foreground mx-auto mt-6 max-w-xl text-lg">
|
|
Your platform for managing competitions, teams, and scheduling all in one place.
|
|
</p>
|
|
{#if !user}
|
|
<div class="mt-8 flex flex-wrap justify-center gap-4">
|
|
<Button onclick={() => (window.location.href = '/auth/login')}>Sign In</Button>
|
|
<Button variant="outline">Learn More</Button>
|
|
</div>
|
|
{/if}
|
|
</section>
|
|
|
|
<!-- Competitions Section -->
|
|
<section>
|
|
<div class="flex items-center justify-between">
|
|
<h2 class="text-2xl font-semibold tracking-tight">Competitions</h2>
|
|
{#if user}
|
|
<Button size="sm" variant="outline">
|
|
<span>View All</span>
|
|
</Button>
|
|
{/if}
|
|
</div>
|
|
|
|
{#if !user}
|
|
<div class="bg-card/50 mt-6 rounded-xl border p-12 text-center">
|
|
<h3 class="text-xl font-medium">Sign in to view available competitions</h3>
|
|
<p class="text-muted-foreground mt-2">
|
|
Access all competitions, teams, and match schedules by signing in to your account.
|
|
</p>
|
|
<div class="mt-6">
|
|
<Button onclick={() => (window.location.href = '/auth/login')}>Sign In</Button>
|
|
</div>
|
|
</div>
|
|
{:else}
|
|
{#await data.competitions}
|
|
<div class="mt-6 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
{#each Array(3) as _}
|
|
<Card>
|
|
<CardHeader>
|
|
<Skeleton class="h-6 w-3/4" />
|
|
<Skeleton class="h-4 w-1/2" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div class="space-y-4">
|
|
<Skeleton class="h-4 w-full" />
|
|
<Skeleton class="h-4 w-full" />
|
|
<Skeleton class="h-4 w-3/4" />
|
|
</div>
|
|
</CardContent>
|
|
<CardFooter>
|
|
<Skeleton class="h-9 w-full" />
|
|
</CardFooter>
|
|
</Card>
|
|
{/each}
|
|
</div>
|
|
{:then competitions}
|
|
{#if data.competitions.length === 0}
|
|
<Card class="mt-6">
|
|
<CardHeader>
|
|
<p>No competitions found</p>
|
|
</CardHeader>
|
|
<CardFooter>
|
|
<Button variant="default" href="/competitions/new">Create Competition</Button>
|
|
</CardFooter>
|
|
</Card>
|
|
{:else}
|
|
<div class="mt-6 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
{#each competitions as competition}
|
|
<Card>
|
|
<CardHeader>
|
|
<div class="flex items-start justify-between">
|
|
<div>
|
|
<CardTitle>{competition.name}</CardTitle>
|
|
<CardDescription class="mt-1">ID: {competition.id}</CardDescription>
|
|
</div>
|
|
<Badge variant="outline">
|
|
{competition.teams?.length || 0} Teams
|
|
</Badge>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p class="text-muted-foreground text-sm">{competition.description}</p>
|
|
<div class="mt-4 space-y-2">
|
|
<div class="flex items-center text-sm">
|
|
<Calendar class="text-muted-foreground mr-2 h-4 w-4" />
|
|
<span>{formatDate(competition.start_date)}</span>
|
|
</div>
|
|
<div class="flex items-center text-sm">
|
|
<MapPin class="text-muted-foreground mr-2 h-4 w-4" />
|
|
<span>{competition.location}</span>
|
|
</div>
|
|
<div class="flex items-center text-sm">
|
|
<Users class="text-muted-foreground mr-2 h-4 w-4" />
|
|
<span> {competition.teams?.length || 0} teams registered max</span>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
<CardFooter>
|
|
<Button
|
|
class="w-full"
|
|
variant="default"
|
|
href={`/competitions/${competition.id}`}
|
|
>
|
|
View Details
|
|
</Button>
|
|
</CardFooter>
|
|
</Card>
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
{:catch error}
|
|
{toast(error)}
|
|
{/await}
|
|
{/if}
|
|
</section>
|
|
|
|
<!-- Features Section -->
|
|
<section class="py-8">
|
|
<h2 class="mb-6 text-2xl font-semibold tracking-tight">Platform Features</h2>
|
|
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Competition Management</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p class="text-muted-foreground text-sm">
|
|
Create and manage competitions with customizable settings, team limits, and scheduling
|
|
options.
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Team Registration</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p class="text-muted-foreground text-sm">
|
|
Streamline team registration with custom forms, roster management, and team
|
|
communication tools.
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Smart Scheduling</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p class="text-muted-foreground text-sm">
|
|
Automatically generate fair match schedules, manage fields, and handle complex
|
|
tournament formats.
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</AppLayout>
|