homepage and logo
This commit is contained in:
parent
c9d982669a
commit
ef6dadb148
12 changed files with 359 additions and 242 deletions
|
@ -3,13 +3,13 @@
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Competition;
|
use App\Models\Competition;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
class CompetitionController extends Controller
|
class CompetitionController extends Controller
|
||||||
{
|
{
|
||||||
|
public static function getPublics(int $skip = 0, int $take = 10): JsonResponse
|
||||||
public static function getPublicCompetitions(int $skip = 0, int $take = 10): JsonResponse
|
|
||||||
{
|
{
|
||||||
if ($skip < 0) {
|
if ($skip < 0) {
|
||||||
$skip = 0;
|
$skip = 0;
|
||||||
|
@ -37,6 +37,35 @@ class CompetitionController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getUser(User $user, int $skip = 0, int $take = 10): JsonResponse
|
||||||
|
{
|
||||||
|
if ($skip < 0) {
|
||||||
|
$skip = 0;
|
||||||
|
}
|
||||||
|
if ($take < 1 || $take > 100) {
|
||||||
|
$take = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = Competition::where('owner', $user->id);
|
||||||
|
|
||||||
|
$competitions = $query->orderBy('start_date', 'desc')
|
||||||
|
->skip($skip)
|
||||||
|
->take($take)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$total = $query->count();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'data' => $competitions,
|
||||||
|
'meta' => [
|
||||||
|
'skip' => $skip,
|
||||||
|
'take' => $take,
|
||||||
|
'total' => $total,
|
||||||
|
'hasMore' => ($skip + $take) < $total
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all public competitions/tournaments with pagination.
|
* Get all public competitions/tournaments with pagination.
|
||||||
*
|
*
|
||||||
|
|
|
@ -25,6 +25,7 @@ class Competition extends Model
|
||||||
'location',
|
'location',
|
||||||
'max_teams',
|
'max_teams',
|
||||||
'current_scheduling_mode_id',
|
'current_scheduling_mode_id',
|
||||||
|
'owner',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,6 +22,7 @@ return new class extends Migration
|
||||||
$table->string('location')->nullable();
|
$table->string('location')->nullable();
|
||||||
$table->integer('max_teams')->default(0);
|
$table->integer('max_teams')->default(0);
|
||||||
$table->integer('current_scheduling_mode_id')->nullable();
|
$table->integer('current_scheduling_mode_id')->nullable();
|
||||||
|
$table->uuid('owner')->nullable();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
BIN
public/logo.png
Normal file
BIN
public/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 13 KiB |
|
@ -42,11 +42,6 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
const rightNavItems: NavItem[] = [
|
const rightNavItems: NavItem[] = [
|
||||||
{
|
|
||||||
title: 'Repository',
|
|
||||||
href: 'https://github.com/oseughu/svelte-starter-kit',
|
|
||||||
icon: Folder,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'Documentation',
|
title: 'Documentation',
|
||||||
href: 'https://laravel.com/docs/starter-kits',
|
href: 'https://laravel.com/docs/starter-kits',
|
||||||
|
@ -101,9 +96,7 @@
|
||||||
</Sheet>
|
</Sheet>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link href={route('dashboard')} class="flex items-center gap-x-2">
|
|
||||||
<AppLogo />
|
<AppLogo />
|
||||||
</Link>
|
|
||||||
|
|
||||||
<!-- Desktop Menu -->
|
<!-- Desktop Menu -->
|
||||||
<div class="hidden h-full lg:flex lg:flex-1">
|
<div class="hidden h-full lg:flex lg:flex-1">
|
||||||
|
|
|
@ -1,12 +1,45 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import AppLogoIcon from '@/components/AppLogoIcon.svelte';
|
import AppLogoIcon from '@/components/AppLogoIcon.svelte';
|
||||||
|
import { type Appearance, useAppearance } from '@/hooks/useAppearance.svelte';
|
||||||
|
import { MonitorIcon, Moon, Sun } from 'lucide-svelte';
|
||||||
|
import Button from './ui/button/button.svelte';
|
||||||
|
import { Link } from '@inertiajs/svelte';
|
||||||
|
|
||||||
|
const appearanceManager = useAppearance();
|
||||||
|
// Create a local reactive variable that tracks the hook's value
|
||||||
|
let currentAppearance = $state(appearanceManager.appearance);
|
||||||
|
|
||||||
|
function handleUpdateAppearance(value: Appearance) {
|
||||||
|
appearanceManager.updateAppearance(value);
|
||||||
|
// Immediately update local state to ensure UI reflects the change
|
||||||
|
currentAppearance = value;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="inline-flex items-center gap-3">
|
<div class="inline-flex w-full justify-around">
|
||||||
<div class="flex aspect-square size-8 shrink-0 items-center justify-center rounded-md bg-sidebar-primary">
|
<div class="inline-flex items-center gap-3">
|
||||||
<AppLogoIcon class="size-5 fill-current text-white! dark:text-black!" />
|
<div class="flex aspect-square size-8 shrink-0 items-center justify-center rounded-md">
|
||||||
|
<AppLogoIcon class="size-5 object-cover" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span class="truncate text-sm font-semibold">Laravel Starter Kit</span>
|
<Link href={route('home')} class="flex items-center gap-x-2">
|
||||||
|
<span class="truncate text-sm font-semibold">FlbxCup</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
{#if currentAppearance === 'light'}
|
||||||
|
<Button onclick={() => handleUpdateAppearance('dark')}>
|
||||||
|
<Sun class="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
{:else if currentAppearance === 'dark'}
|
||||||
|
<Button onclick={() => handleUpdateAppearance('system')}>
|
||||||
|
<Moon class="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
{:else}
|
||||||
|
<Button onclick={() => handleUpdateAppearance('light')}>
|
||||||
|
<MonitorIcon class="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,9 +4,10 @@
|
||||||
import NavUser from '@/components/NavUser.svelte';
|
import NavUser from '@/components/NavUser.svelte';
|
||||||
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar';
|
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar';
|
||||||
import { type NavItem } from '@/types';
|
import { type NavItem } from '@/types';
|
||||||
import { Link } from '@inertiajs/svelte';
|
import { Link, page } from '@inertiajs/svelte';
|
||||||
import { BookOpen, Folder, LayoutGrid } from 'lucide-svelte';
|
import { BookOpen, Folder, LayoutGrid } from 'lucide-svelte';
|
||||||
import AppLogo from './AppLogo.svelte';
|
import AppLogo from './AppLogo.svelte';
|
||||||
|
import Button from './ui/button/button.svelte';
|
||||||
|
|
||||||
const mainNavItems: NavItem[] = [
|
const mainNavItems: NavItem[] = [
|
||||||
{
|
{
|
||||||
|
@ -17,11 +18,6 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
const footerNavItems: NavItem[] = [
|
const footerNavItems: NavItem[] = [
|
||||||
{
|
|
||||||
title: 'Repository',
|
|
||||||
href: 'https://github.com/oseughu/svelte-starter-kit',
|
|
||||||
icon: Folder,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'Admin Dashboard',
|
title: 'Admin Dashboard',
|
||||||
href: '/admin',
|
href: '/admin',
|
||||||
|
@ -36,9 +32,7 @@
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton size="lg">
|
<SidebarMenuButton size="lg">
|
||||||
<Link href={route('dashboard')}>
|
|
||||||
<AppLogo />
|
<AppLogo />
|
||||||
</Link>
|
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
|
@ -50,6 +44,12 @@
|
||||||
|
|
||||||
<SidebarFooter>
|
<SidebarFooter>
|
||||||
<NavFooter items={footerNavItems} class="mt-auto" />
|
<NavFooter items={footerNavItems} class="mt-auto" />
|
||||||
|
{#if $page.props.auth.user}
|
||||||
<NavUser />
|
<NavUser />
|
||||||
|
{:else}
|
||||||
|
<Button>
|
||||||
|
<a href={route('auth.redirect')} class="flex items-center gap-2">Login</a>
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
</SidebarFooter>
|
</SidebarFooter>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import type { User } from '@/types';
|
import type { User } from '@/types';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user: User;
|
user?: User;
|
||||||
showEmail?: boolean;
|
showEmail?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,11 @@
|
||||||
|
|
||||||
const { getInitials } = useInitials();
|
const { getInitials } = useInitials();
|
||||||
|
|
||||||
let showAvatar = $derived(user.avatar && user.avatar !== '');
|
let showAvatar = $derived(user?.avatar && user?.avatar !== '');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Avatar class="h-8 w-8 overflow-hidden rounded-full">
|
{#if user}
|
||||||
|
<Avatar class="h-8 w-8 overflow-hidden rounded-full">
|
||||||
{#if showAvatar}
|
{#if showAvatar}
|
||||||
<AvatarImage src={user.avatar} alt={user.name} />
|
<AvatarImage src={user.avatar} alt={user.name} />
|
||||||
{:else}
|
{:else}
|
||||||
|
@ -23,12 +24,13 @@
|
||||||
{getInitials(user.name)}
|
{getInitials(user.name)}
|
||||||
</AvatarFallback>
|
</AvatarFallback>
|
||||||
{/if}
|
{/if}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
|
|
||||||
<div class="grid flex-1 text-left text-sm leading-tight">
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
<span class="truncate font-medium">{user.name}</span>
|
<span class="truncate font-medium">{user.name}</span>
|
||||||
|
|
||||||
{#if showEmail}
|
{#if showEmail}
|
||||||
<span class="truncate text-xs text-muted-foreground">{user.email}</span>
|
<span class="truncate text-xs text-muted-foreground">{user.email}</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Link, page } from '@inertiajs/svelte';
|
import { Deferred, Link, page } from '@inertiajs/svelte';
|
||||||
import AppLayout from '@/layouts/AppLayout.svelte';
|
import AppLayout from '@/layouts/AppLayout.svelte';
|
||||||
import { type BreadcrumbItem } from '@/types';
|
import { type BreadcrumbItem } from '@/types';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
@ -7,54 +7,7 @@
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||||
import { Trophy, Users, Calendar, User } from 'lucide-svelte';
|
import { Trophy, Users, Calendar, User } from 'lucide-svelte';
|
||||||
|
|
||||||
// Mock data for tournaments - replace with API calls when backend is ready
|
let { publicTournaments, userTournaments } = $props();
|
||||||
const publicTournaments = [
|
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
name: 'Summer Championship 2024',
|
|
||||||
description: 'Annual summer championship with multiple categories',
|
|
||||||
date: '2024-07-15',
|
|
||||||
participantsCount: 48,
|
|
||||||
isPublic: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
name: 'Regional Qualifiers',
|
|
||||||
description: 'Regional qualifiers for the national tournament',
|
|
||||||
date: '2024-06-05',
|
|
||||||
participantsCount: 32,
|
|
||||||
isPublic: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3',
|
|
||||||
name: 'Friendly Tournament',
|
|
||||||
description: 'Casual tournament for all skill levels',
|
|
||||||
date: '2024-05-20',
|
|
||||||
participantsCount: 16,
|
|
||||||
isPublic: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// User tournaments - only displayed when logged in
|
|
||||||
const userTournaments = [
|
|
||||||
{
|
|
||||||
id: '4',
|
|
||||||
name: 'My Club Championship',
|
|
||||||
description: 'Internal club championship tournament',
|
|
||||||
date: '2024-06-18',
|
|
||||||
participantsCount: 12,
|
|
||||||
isPublic: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5',
|
|
||||||
name: 'Training Tournament',
|
|
||||||
description: 'Practice tournament for team members',
|
|
||||||
date: '2024-05-10',
|
|
||||||
participantsCount: 8,
|
|
||||||
isPublic: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const breadcrumbs: BreadcrumbItem[] = [
|
const breadcrumbs: BreadcrumbItem[] = [
|
||||||
{
|
{
|
||||||
title: 'Home',
|
title: 'Home',
|
||||||
|
@ -80,7 +33,13 @@
|
||||||
<title>Home - FlbxCup</title>
|
<title>Home - FlbxCup</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<AppLayout {breadcrumbs}>
|
<Deferred data="publicTournaments">
|
||||||
|
{#snippet fallback()}
|
||||||
|
<AppLayout {breadcrumbs}>
|
||||||
|
<div>Loading...</div>
|
||||||
|
</AppLayout>
|
||||||
|
{/snippet}
|
||||||
|
<AppLayout {breadcrumbs}>
|
||||||
<div class="space-y-8 px-4 py-6 md:px-8">
|
<div class="space-y-8 px-4 py-6 md:px-8">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
|
@ -97,28 +56,6 @@
|
||||||
<p class="text-lg text-muted-foreground">Discover and manage tournaments with ease</p>
|
<p class="text-lg text-muted-foreground">Discover and manage tournaments with ease</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !isAuthenticated}
|
|
||||||
<Card>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>Join FlbxCup</CardTitle>
|
|
||||||
<CardDescription>Create an account to create and manage your own tournaments</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<div class="flex flex-col gap-4 sm:flex-row">
|
|
||||||
<Button>
|
|
||||||
<Link href={route('login')} class="flex items-center gap-2">Login</Link>
|
|
||||||
</Button>
|
|
||||||
<Button variant="outline">
|
|
||||||
<Link href={route('register')} class="flex items-center gap-2">Register</Link>
|
|
||||||
</Button>
|
|
||||||
<Button variant="outline">
|
|
||||||
<Link href={route('auth.redirect')} class="flex items-center gap-2">Login with SSO</Link>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if isAuthenticated}
|
{#if isAuthenticated}
|
||||||
<Tabs value="public" class="w-full">
|
<Tabs value="public" class="w-full">
|
||||||
<TabsList>
|
<TabsList>
|
||||||
|
@ -127,7 +64,17 @@
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value="public" class="mt-6">
|
<TabsContent value="public" class="mt-6">
|
||||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
{#each publicTournaments as tournament (tournament.id)}
|
{#if !publicTournaments.original.data || publicTournaments.original.data.length === 0}
|
||||||
|
<div class="flex flex-col items-center justify-center rounded-lg border border-dashed p-8 text-center">
|
||||||
|
<Trophy class="h-10 w-10 text-muted-foreground" />
|
||||||
|
<h3 class="mt-4 text-lg font-semibold">No Tournaments Yet</h3>
|
||||||
|
<p class="mt-2 text-sm text-muted-foreground">You haven't created any tournaments yet.</p>
|
||||||
|
<Button class="mt-4">
|
||||||
|
<Link href="/tournaments/create" class="flex items-center gap-2">Create Your First Tournament</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#each publicTournaments.original.data as tournament (tournament.id)}
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle class="flex items-center gap-2">
|
<CardTitle class="flex items-center gap-2">
|
||||||
|
@ -160,7 +107,8 @@
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="my" class="mt-6">
|
<TabsContent value="my" class="mt-6">
|
||||||
{#if userTournaments.length === 0}
|
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{#if !userTournaments.original.data || userTournaments.original.data.length === 0}
|
||||||
<div class="flex flex-col items-center justify-center rounded-lg border border-dashed p-8 text-center">
|
<div class="flex flex-col items-center justify-center rounded-lg border border-dashed p-8 text-center">
|
||||||
<Trophy class="h-10 w-10 text-muted-foreground" />
|
<Trophy class="h-10 w-10 text-muted-foreground" />
|
||||||
<h3 class="mt-4 text-lg font-semibold">No Tournaments Yet</h3>
|
<h3 class="mt-4 text-lg font-semibold">No Tournaments Yet</h3>
|
||||||
|
@ -171,7 +119,7 @@
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
{#each userTournaments as tournament (tournament.id)}
|
{#each userTournaments.original.data as tournament (tournament.id)}
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle class="flex items-center gap-2">
|
<CardTitle class="flex items-center gap-2">
|
||||||
|
@ -198,7 +146,9 @@
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter class="flex gap-2">
|
<CardFooter class="flex gap-2">
|
||||||
<Button variant="outline" class="flex-1">
|
<Button variant="outline" class="flex-1">
|
||||||
<Link href={`/tournaments/${tournament.id}`} class="flex items-center justify-center w-full">View</Link>
|
<Link href={`/tournaments/${tournament.id}`} class="flex items-center justify-center w-full"
|
||||||
|
>View</Link
|
||||||
|
>
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" class="flex-1">
|
<Button variant="secondary" class="flex-1">
|
||||||
<Link href={`/tournaments/${tournament.id}/edit`} class="flex items-center justify-center w-full">
|
<Link href={`/tournaments/${tournament.id}/edit`} class="flex items-center justify-center w-full">
|
||||||
|
@ -210,13 +160,37 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
{:else}
|
{:else}
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Join FlbxCup</CardTitle>
|
||||||
|
<CardDescription>Create an account to create and manage your own tournaments</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div class="flex flex-col gap-4 sm:flex-row">
|
||||||
|
<Button>
|
||||||
|
<a href={route('auth.redirect')} class="flex items-center gap-2">Login with SSO</a>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<h2 class="text-2xl font-semibold tracking-tight">Public Tournaments</h2>
|
<h2 class="text-2xl font-semibold tracking-tight">Public Tournaments</h2>
|
||||||
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
{#each publicTournaments as tournament (tournament.id)}
|
{#if !publicTournaments.original.data || publicTournaments.original.data.length === 0}
|
||||||
|
<div class="flex flex-col items-center justify-center rounded-lg border border-dashed p-8 text-center">
|
||||||
|
<Trophy class="h-10 w-10 text-muted-foreground" />
|
||||||
|
<h3 class="mt-4 text-lg font-semibold">No Tournaments Yet</h3>
|
||||||
|
<p class="mt-2 text-sm text-muted-foreground">You haven't created any tournaments yet.</p>
|
||||||
|
<Button class="mt-4">
|
||||||
|
<Link href="/tournaments/create" class="flex items-center gap-2">Create Your First Tournament</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#each publicTournaments.original.data as tournament (tournament.id)}
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle class="flex items-center gap-2">
|
<CardTitle class="flex items-center gap-2">
|
||||||
|
@ -239,7 +213,9 @@
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter>
|
<CardFooter>
|
||||||
<Button variant="outline" class="w-full">
|
<Button variant="outline" class="w-full">
|
||||||
<Link href={`/tournaments/${tournament.id}`} class="flex items-center justify-center w-full">View Details</Link>
|
<Link href={`/tournaments/${tournament.id}`} class="flex items-center justify-center w-full"
|
||||||
|
>View Details</Link
|
||||||
|
>
|
||||||
</Button>
|
</Button>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -248,4 +224,5 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
|
</Deferred>
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\CompetitionController;
|
use App\Http\Controllers\CompetitionController;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
|
// get user if it exists
|
||||||
|
$user = Auth::user();
|
||||||
|
$userTournaments = [];
|
||||||
|
if ($user) {
|
||||||
|
$userTournaments = Inertia::defer(fn() => CompetitionController::getUser($user, 1, 10));
|
||||||
|
}
|
||||||
return Inertia::render('Home', [
|
return Inertia::render('Home', [
|
||||||
'publicTournaments' => Inertia::defer(fn() => CompetitionController::getPublicCompetitions(1, 10))
|
'publicTournaments' => Inertia::defer(fn() => CompetitionController::getPublics(1, 10)),
|
||||||
|
'userTournaments' => $userTournaments,
|
||||||
]);
|
]);
|
||||||
})->name('home');
|
})->name('home');
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue