feat: Enhance event management with FightEdit and GroupEdit components, including improved data handling and new functionalities

This commit is contained in:
2025-05-22 19:41:49 +02:00
parent 1da279bb24
commit 5277c9a3fc
9 changed files with 371 additions and 112 deletions

View File

@@ -22,25 +22,29 @@
import GroupEditRow from "./GroupEditRow.svelte";
import type { ExtendedEvent } from "@type/event";
import type { EventFightEdit, ExtendedEvent } from "@type/event";
import { createSvelteTable, FlexRender } from "@components/ui/data-table";
import { type ColumnFiltersState, getCoreRowModel, getFilteredRowModel, getGroupedRowModel, getSortedRowModel, type RowSelectionState, type SortingState } from "@tanstack/table-core";
import { columns } from "./columns";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@components/ui/table";
import { Checkbox } from "@components/ui/checkbox";
import { Menubar, MenubarContent, MenubarItem, MenubarGroup, MenubarGroupHeading, MenubarMenu, MenubarSeparator, MenubarTrigger } from "@components/ui/menubar";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@components/ui/dialog";
import FightEdit from "@components/moderator/components/FightEdit.svelte";
import { Button } from "@components/ui/button";
import { MenuIcon } from "lucide-svelte";
import { eventRepo } from "@components/repo/event";
let { data = $bindable() }: { data: ExtendedEvent } = $props();
let fights = $state(data.fights);
let sorting = $state<SortingState>([]);
let columnFilters = $state<ColumnFiltersState>([]);
let selection = $state<RowSelectionState>({});
const table = createSvelteTable({
get data() {
return data.fights;
return fights;
},
initialState: {
columnOrder: ["auswahl", "begegnung", "group"],
@@ -88,30 +92,58 @@
groupedColumnMode: "remove",
getRowId: (row) => row.id.toString(),
});
let createOpen = $state(false);
async function handleSave(fight: EventFightEdit) {
await $eventRepo.createFight(data.event.id.toString(), {
...fight,
blueTeam: fight.blueTeam.id,
redTeam: fight.redTeam.id,
});
fights = await $eventRepo.listFights(data.event.id.toString());
createOpen = false;
}
</script>
<div class="w-fit">
<Menubar>
<MenubarMenu>
<MenubarTrigger>Mehrfach Bearbeiten</MenubarTrigger>
<MenubarContent>
<MenubarItem disabled>Gruppe Ändern</MenubarItem>
<MenubarItem disabled>Startzeit Verschieben</MenubarItem>
<MenubarItem disabled>Spectate Port Ändern</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu>
<MenubarTrigger>Erstellen</MenubarTrigger>
<MenubarContent>
<MenubarItem disabled>Fight Erstellen</MenubarItem>
<MenubarGroup>
<MenubarGroupHeading>Generatoren</MenubarGroupHeading>
<MenubarItem disabled>Gruppenphase</MenubarItem>
<MenubarItem disabled>K.O. Phase</MenubarItem>
</MenubarGroup>
</MenubarContent>
</MenubarMenu>
</Menubar>
<Dialog bind:open={createOpen}>
<Menubar>
<MenubarMenu>
<MenubarTrigger>Mehrfach Bearbeiten</MenubarTrigger>
<MenubarContent>
<MenubarItem disabled>Gruppe Ändern</MenubarItem>
<MenubarItem disabled>Startzeit Verschieben</MenubarItem>
<MenubarItem disabled>Spectate Port Ändern</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu>
<MenubarTrigger>Erstellen</MenubarTrigger>
<MenubarContent>
<MenubarItem onclick={() => (createOpen = true)}>Fight Erstellen</MenubarItem>
<MenubarGroup>
<MenubarGroupHeading>Generatoren</MenubarGroupHeading>
<MenubarItem disabled>Gruppenphase</MenubarItem>
<MenubarItem disabled>K.O. Phase</MenubarItem>
</MenubarGroup>
</MenubarContent>
</MenubarMenu>
</Menubar>
<DialogContent>
<DialogHeader>
<DialogTitle>Fight Erstellen</DialogTitle>
<DialogDescription>Hier kannst du einen neuen Fight erstellen</DialogDescription>
</DialogHeader>
<FightEdit fight={null} teams={data.teams} event={data.event} groups={data.groups} onSave={handleSave}>
{#snippet actions(dirty, submit)}
<DialogFooter>
<Button disabled={!dirty} onclick={submit}>Speichern</Button>
</DialogFooter>
{/snippet}
</FightEdit>
</DialogContent>
</Dialog>
</div>
<Table>
@@ -131,7 +163,7 @@
<TableBody>
{#each table.getRowModel().rows as groupRow (groupRow.id)}
{#if groupRow.getIsGrouped()}
<TableRow class="bg-muted font-bold">
<TableRow class="font-bold">
<TableCell colspan={columns.length - 1}>
<Checkbox
checked={groupRow.getIsSelected()}
@@ -155,7 +187,13 @@
</TableCell>
{/each}
<TableCell class="text-right">
<FightEditRow fight={row.original} teams={data.teams}></FightEditRow>
<FightEditRow
fight={row.original}
teams={data.teams}
groups={data.groups}
event={data.event}
onupdate={(update) => (fights = fights.map((v) => (v.id === update.id ? update : v)))}
></FightEditRow>
</TableCell>
</TableRow>
{/each}

View File

@@ -24,7 +24,7 @@
import RefereesList from "@components/moderator/pages/event/RefereesList.svelte";
import TeamTable from "@components/moderator/pages/event/TeamTable.svelte";
let { event }: { event: ExtendedEvent } = $props();
let { event = $bindable() }: { event: ExtendedEvent } = $props();
</script>
<div class="flex flex-col m-4 p-4 rounded-md border gap-4">

View File

@@ -1,21 +1,32 @@
<script lang="ts">
import type { EventFight } from "@type/event";
import type { EventFight, EventFightEdit, ResponseGroups, SWEvent } from "@type/event";
import { Button } from "@components/ui/button";
import { EditIcon, MenuIcon } from "lucide-svelte";
import { EditIcon, MenuIcon, GroupIcon } from "lucide-svelte";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@components/ui/dialog";
import FightEdit from "@components/moderator/components/FightEdit.svelte";
import type { Team } from "@components/types/team";
import { fightRepo } from "@components/repo/fight";
const { fight, teams }: { fight: EventFight; teams: Team[] } = $props();
let { fight, teams, groups, event, onupdate }: { fight: EventFight; teams: Team[]; groups: ResponseGroups[]; event: SWEvent; onupdate: (update: EventFight) => void } = $props();
function handleSave(fightData) {
// Handle the save action here
console.log("Fight data saved:", fightData);
let editOpen = $state(false);
async function handleSave(fightData: EventFightEdit) {
let f = await $fightRepo.updateFight(event.id, fight.id, {
...fightData,
blueTeam: fightData.blueTeam.id,
redTeam: fightData.redTeam.id,
group: fightData.group ?? -1,
});
onupdate(f);
editOpen = false;
}
</script>
<div>
<Dialog>
<Dialog bind:open={editOpen}>
<DialogTrigger>
<Button variant="ghost" size="icon">
<EditIcon />
@@ -26,7 +37,7 @@
<DialogTitle>Fight bearbeiten</DialogTitle>
<DialogDescription>Hier kannst du die Daten des Kampfes bearbeiten.</DialogDescription>
</DialogHeader>
<FightEdit {fight} {teams} onSave={handleSave}>
<FightEdit {fight} {teams} {groups} {event} onSave={handleSave}>
{#snippet actions(dirty, submit)}
<DialogFooter>
<Button disabled={!dirty} onclick={submit}>Speichern</Button>
@@ -35,7 +46,4 @@
</FightEdit>
</DialogContent>
</Dialog>
<Button variant="ghost" size="icon">
<MenuIcon />
</Button>
</div>

View File

@@ -77,4 +77,28 @@ export const columns: ColumnDef<EventFight> = [
});
},
},
{
header: "Spielmodus",
accessorKey: "spielmodus",
},
{
header: "Map",
accessorKey: "map",
},
{
header: "Ergebnis",
accessorKey: "ergebnis",
cell: ({ row }) => {
const fight = row.original;
if (fight.ergebnis === 0 && fight.start > Date.now()) {
return "Noch nicht gespielt";
} else if (fight.ergebnis === 1) {
return fight.blueTeam.name + " hat gewonnen";
} else if (fight.ergebnis === 2) {
return fight.redTeam.name + " hat gewonnen";
} else {
return "Unentschieden";
}
},
},
];