Refactor stores and types for improved data handling and schema definitions
All checks were successful
SteamWarCI Build successful

- Consolidated player fetching logic in stores.ts to utilize dataRepo.
- Introduced teams fetching logic in stores.ts.
- Updated permissions structure in stores.ts for better clarity.
- Enhanced data schemas in data.ts with new ResponseUser and ResponseTeam schemas.
- Expanded event-related schemas in event.ts to include groups, relations, and event creation/update structures.
- Improved code formatting for consistency and readability across files.
This commit is contained in:
2025-05-08 21:47:36 +02:00
parent 6377799e1b
commit 7d67ad0950
11 changed files with 2604 additions and 117 deletions

View File

@@ -18,12 +18,12 @@
-->
<script lang="ts">
import type {RouteDefinition} from "svelte-spa-router";
import type { RouteDefinition } from "svelte-spa-router";
import Router from "svelte-spa-router";
import NavLinks from "@components/moderator/layout/NavLinks.svelte";
import {Switch} from "@components/ui/switch";
import {Label} from "@components/ui/label";
import {navigate} from "astro:transitions/client";
import { Switch } from "@components/ui/switch";
import { Label } from "@components/ui/label";
import { navigate } from "astro:transitions/client";
import Players from "@components/moderator/pages/players/Players.svelte";
import Events from "@components/moderator/pages/events/Events.svelte";
import Dashboard from "@components/moderator/pages/dashboard/Dashboard.svelte";
@@ -33,19 +33,17 @@
"/": Dashboard,
"/events": Events,
"/players": Players,
"/event/:id": Event
"/event/:id": Event,
};
</script>
<div class="flex flex-col bg-background min-w-full min-h-screen">
<div class="border-b">
<div class="flex h-16 items-center px-4">
<a href="/" class="text-sm font-bold transition-colors text-primary">
SteamWar
</a>
<a href="/" class="text-sm font-bold transition-colors text-primary"> SteamWar </a>
<NavLinks />
<div class="ml-auto flex items-center space-x-4">
<Switch id="new-ui-switch" checked={true} on:click={() => navigate("/admin")} />
<Switch id="new-ui-switch" checked={true} onclick={() => navigate("/admin")} />
<Label for="new-ui-switch">New UI!</Label>
</div>
</div>
@@ -53,4 +51,4 @@
<main class="flex flex-col">
<Router {routes} />
</main>
</div>
</div>

View File

@@ -18,23 +18,13 @@
-->
<script lang="ts">
import {location} from "svelte-spa-router";
import { location } from "svelte-spa-router";
</script>
<nav class="flex items-center space-x-4 lg:space-x-6 mx-6">
<a href="#/" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted={$location !== "/"}>
Dashboard
</a>
<a href="#/events" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted={$location !== "/events"}>
Events
</a>
<a href="#/players" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted={$location !== "/players"}>
Players
</a>
<a href="#/pages" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted={$location !== "/pages"}>
Pages
</a>
<a href="#/schematics" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted={$location !== "/schematics"}>
Schematics
</a>
</nav>
<a href="#/" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted-foreground={$location !== "/"}> Dashboard </a>
<a href="#/events" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted-foreground={!$location.startsWith("/event")}> Events </a>
<a href="#/players" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted-foreground={$location !== "/players"}> Players </a>
<a href="#/pages" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted-foreground={$location !== "/pages"}> Pages </a>
<a href="#/schematics" class="hover:text-primary text-sm font-medium transition-colors" class:text-muted-foreground={$location !== "/schematics"}> Schematics </a>
</nav>

View File

@@ -28,22 +28,16 @@
const { event }: { event: ExtendedEvent } = $props();
let referees = $state(event.event.referees);
let referees = $state(event.referees);
async function addReferee(value: string) {
referees = (
await $eventRepo.updateEvent(event.event.id.toString(), {
addReferee: [value],
})
).referees;
await $eventRepo.updateReferees(event.event.id.toString(), [value]);
referees = await $eventRepo.listReferees(event.event.id.toString());
}
async function removeReferee(value: string) {
referees = (
await $eventRepo.updateEvent(event.event.id.toString(), {
removeReferee: [value],
})
).referees;
await $eventRepo.deleteReferees(event.event.id.toString(), [value]);
referees = await $eventRepo.listReferees(event.event.id.toString());
}
let playerSearch = $state("");

View File

@@ -21,14 +21,29 @@
import { Button } from "@components/ui/button";
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell, TableCaption } from "@components/ui/table";
import type { ExtendedEvent } from "@type/event.ts";
import { eventRepo } from "@repo/event";
import { Popover, PopoverContent, PopoverTrigger } from "@components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@components/ui/command";
import { teams } from "@components/stores/stores";
const { event }: { event: ExtendedEvent } = $props();
let team = $state(event.teams);
async function addTeam(value: number) {
await $eventRepo.updateTeams(event.event.id.toString(), [value]);
team = await $eventRepo.listTeams(event.event.id.toString());
}
async function removeTeam(value: number) {
await $eventRepo.deleteTeams(event.event.id.toString(), [value]);
team = await $eventRepo.listTeams(event.event.id.toString());
}
let teamSearch = $state("");
</script>
<Table>
<TableCaption>
<Button disabled>Add Team</Button>
</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Team</TableHead>
@@ -37,19 +52,42 @@
</TableRow>
</TableHeader>
<TableBody>
{#each event.teams as team (team.id)}
{#each team as t (t.id)}
<TableRow>
<TableCell>{team.kuerzel}</TableCell>
<TableCell>{team.name}</TableCell>
<TableCell>{t.kuerzel}</TableCell>
<TableCell>{t.name}</TableCell>
<TableCell>
<Button disabled>Remove</Button>
<Button onclick={() => removeTeam(t.id)}>Remove</Button>
</TableCell>
</TableRow>
{/each}
{#if event.teams.length === 0}
{#if team.length === 0}
<TableRow>
<TableCell class="text-center col-span-3">No teams available</TableCell>
</TableRow>
{/if}
</TableBody>
<Popover>
<TableCaption>
<PopoverTrigger>
<Button>Add Team</Button>
</PopoverTrigger>
</TableCaption>
<PopoverContent class="p-0">
<Command shouldFilter={false}>
<CommandInput bind:value={teamSearch} placeholder="Search teams..." />
<CommandList>
<CommandEmpty>No teams found :(</CommandEmpty>
<CommandGroup heading="Teams">
{#each $teams
.filter((v) => v.name.includes(teamSearch))
.filter((v) => !team.some((k) => k.id === v.id))
.filter((v, i) => i < 50) as t (t.id)}
<CommandItem value={t.id.toString()} onSelect={() => addTeam(t.id)} keywords={[t.name, t.kuerzel]}>{t.name}</CommandItem>
{/each}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</Table>

View File

@@ -63,7 +63,7 @@ export const columns: ColumnDef<EventFight> = [
},
{
header: "Gruppe",
accessorKey: "group",
accessorKey: "group.name",
id: "group",
},
{