Update
This commit is contained in:
@@ -30,26 +30,30 @@
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
export let data: ExtendedEvent;
|
||||
let event = data.event;
|
||||
let name = event.name;
|
||||
let deadline = dayjs(event.deadline).utc(true).toISOString().slice(0, -1);
|
||||
let start = dayjs(event.start).utc(true).toISOString().slice(0, -1);
|
||||
let end = dayjs(event.end).utc(true).toISOString().slice(0, -1);
|
||||
let member = event.maxTeamMembers;
|
||||
let schemType = event.schemType;
|
||||
let publicOnly = event.publicSchemsOnly;
|
||||
interface Props {
|
||||
data: ExtendedEvent;
|
||||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
let event = $state(data.event);
|
||||
let name = $state(event.name);
|
||||
let deadline = $state(dayjs(event.deadline).utc(true).toISOString().slice(0, -1));
|
||||
let start = $state(dayjs(event.start).utc(true).toISOString().slice(0, -1));
|
||||
let end = $state(dayjs(event.end).utc(true).toISOString().slice(0, -1));
|
||||
let member = $state(event.maxTeamMembers);
|
||||
let schemType = $state(event.schemType);
|
||||
let publicOnly = $state(event.publicSchemsOnly);
|
||||
let addReferee: {name: string, id: number}[] = [];
|
||||
let removeReferee: {name: string, id: number}[] = [];
|
||||
|
||||
let errorOpen = false;
|
||||
let error: any = undefined;
|
||||
let deleteOpen = false;
|
||||
let errorOpen = $state(false);
|
||||
let error: any = $state(undefined);
|
||||
let deleteOpen = $state(false);
|
||||
|
||||
$: deadlineDate = dayjs(deadline);
|
||||
$: startDate = dayjs(start);
|
||||
$: endDate = dayjs(end);
|
||||
$: selectTypes = [{
|
||||
let deadlineDate = $derived(dayjs(deadline));
|
||||
let startDate = $derived(dayjs(start));
|
||||
let endDate = $derived(dayjs(end));
|
||||
let selectTypes = $derived([{
|
||||
value: null,
|
||||
name: "None"
|
||||
}, ...$schemTypes.map((type) => {
|
||||
@@ -57,9 +61,9 @@
|
||||
value: type.db,
|
||||
name: type.name
|
||||
};
|
||||
})];
|
||||
})]);
|
||||
|
||||
$: changed = name !== event.name ||
|
||||
let changed = $derived(name !== event.name ||
|
||||
deadlineDate.diff(dayjs(event.deadline)) !== 0 ||
|
||||
startDate.diff(dayjs(event.start)) !== 0 ||
|
||||
endDate.diff(dayjs(event.end)) !== 0 ||
|
||||
@@ -67,7 +71,7 @@
|
||||
schemType != event.schemType ||
|
||||
publicOnly !== event.publicSchemsOnly ||
|
||||
addReferee.length > 0 ||
|
||||
removeReferee.length > 0;
|
||||
removeReferee.length > 0);
|
||||
|
||||
|
||||
async function del() {
|
||||
@@ -80,7 +84,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
let successToast: boolean = false;
|
||||
let successToast: boolean = $state(false);
|
||||
|
||||
async function update() {
|
||||
let ev: UpdateEvent = {
|
||||
@@ -117,20 +121,26 @@
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<Label for="event-deadline">Deadline</Label>
|
||||
<Input id="event-deadline" bind:value={name} class="w-80" let:props size="lg">
|
||||
<Input id="event-deadline" bind:value={name} class="w-80" size="lg">
|
||||
{#snippet children({ props })}
|
||||
<input type="datetime-local" {...props} bind:value={deadline}/>
|
||||
{/snippet}
|
||||
</Input>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<Label for="event-start">Start</Label>
|
||||
<Input id="event-start" bind:value={name} class="w-80" let:props size="lg">
|
||||
<Input id="event-start" bind:value={name} class="w-80" size="lg">
|
||||
{#snippet children({ props })}
|
||||
<input type="datetime-local" {...props} bind:value={start}/>
|
||||
{/snippet}
|
||||
</Input>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<Label for="event-end">End</Label>
|
||||
<Input id="event-end" bind:value={name} class="w-80" let:props size="lg">
|
||||
<Input id="event-end" bind:value={name} class="w-80" size="lg">
|
||||
{#snippet children({ props })}
|
||||
<input type="datetime-local" {...props} bind:value={end}/>
|
||||
{/snippet}
|
||||
</Input>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
@@ -159,6 +169,8 @@
|
||||
</Modal>
|
||||
|
||||
<Toast bind:open={successToast} position="bottom-left" color="green">
|
||||
<CheckCircleOutline slot="icon"/>
|
||||
{#snippet icon()}
|
||||
<CheckCircleOutline />
|
||||
{/snippet}
|
||||
Updated Successfully
|
||||
</Toast>
|
||||
|
||||
@@ -26,14 +26,24 @@
|
||||
import {isWide} from "@stores/stores.ts";
|
||||
import {fightRepo} from "@repo/fight.ts";
|
||||
|
||||
export let fight: EventFight;
|
||||
export let data: ExtendedEvent;
|
||||
export let i: number;
|
||||
export let selected: boolean = false;
|
||||
export let hideEdit: boolean = false;
|
||||
interface Props {
|
||||
fight: EventFight;
|
||||
data: ExtendedEvent;
|
||||
i: number;
|
||||
selected?: boolean;
|
||||
hideEdit?: boolean;
|
||||
}
|
||||
|
||||
let deleteOpen = false;
|
||||
let editOpen = false;
|
||||
let {
|
||||
fight,
|
||||
data = $bindable(),
|
||||
i,
|
||||
selected = false,
|
||||
hideEdit = false
|
||||
}: Props = $props();
|
||||
|
||||
let deleteOpen = $state(false);
|
||||
let editOpen = $state(false);
|
||||
|
||||
let dispatcher = createEventDispatcher();
|
||||
|
||||
@@ -52,7 +62,7 @@
|
||||
</script>
|
||||
|
||||
<div class="flex h-16 {i % 2 === 0 ? 'bg-gray-800' : ''} mx-4 mt-6 rounded border {selected ? 'border-orange-700' : 'border-gray-700'} p-2 hover:bg-gray-700 transition justify-between shadow-lg cursor-pointer"
|
||||
on:click={dispatchSelect} on:keypress={dispatchSelect} role="checkbox" aria-checked={selected} tabindex="0"
|
||||
onclick={dispatchSelect} onkeypress={dispatchSelect} role="checkbox" aria-checked={selected} tabindex="0"
|
||||
>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col">
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
Tooltip
|
||||
} from "flowbite-svelte";
|
||||
import {
|
||||
ArrowsRepeatSolid, CalendarWeekOutline,
|
||||
PlusSolid, ProfileCardOutline, TrashBinOutline, UsersGroupOutline,
|
||||
ArrowsRepeatOutline, CalendarWeekOutline,
|
||||
PlusOutline, ProfileCardOutline, TrashBinOutline, UsersGroupOutline,
|
||||
} from "flowbite-svelte-icons";
|
||||
import FightCard from "./FightCard.svelte";
|
||||
import CreateFightModal from "./modals/CreateFightModal.svelte";
|
||||
@@ -44,19 +44,23 @@
|
||||
|
||||
dayjs.extend(duration);
|
||||
|
||||
export let data: ExtendedEvent;
|
||||
interface Props {
|
||||
data: ExtendedEvent;
|
||||
}
|
||||
|
||||
let createOpen = false;
|
||||
let fights = data.fights;
|
||||
let selectedFights: Set<EventFight> = new Set();
|
||||
let { data = $bindable() }: Props = $props();
|
||||
|
||||
$: groupsMap = new Set(fights.map(fight => fight.group));
|
||||
$: groupedFights = Array.from(groupsMap).map(group => {
|
||||
let createOpen = $state(false);
|
||||
let fights = $state(data.fights);
|
||||
let selectedFights: Set<EventFight> = $state(new Set());
|
||||
|
||||
let groupsMap = $derived(new Set(fights.map(fight => fight.group)));
|
||||
let groupedFights = $derived(Array.from(groupsMap).map(group => {
|
||||
return {
|
||||
group: group,
|
||||
fights: fights.filter(fight => fight.group === group)
|
||||
};
|
||||
});
|
||||
}));
|
||||
|
||||
function cycleSelect() {
|
||||
if (selectedFights.size === fights.length) {
|
||||
@@ -81,7 +85,7 @@
|
||||
selectedFights = selectedFights;
|
||||
}
|
||||
|
||||
let deleteOpen = false;
|
||||
let deleteOpen = $state(false);
|
||||
|
||||
async function deleteFights() {
|
||||
for (const fight of selectedFights) {
|
||||
@@ -92,14 +96,14 @@
|
||||
deleteOpen = false;
|
||||
}
|
||||
|
||||
let spectatePortOpen = false;
|
||||
$: selectPlayers = $players.map(player => {
|
||||
let spectatePortOpen = $state(false);
|
||||
let selectPlayers = $derived($players.map(player => {
|
||||
return {
|
||||
name: player.name,
|
||||
value: player.uuid
|
||||
};
|
||||
}).sort((a, b) => a.name.localeCompare(b.name));
|
||||
let spectatePort = "";
|
||||
}).sort((a, b) => a.name.localeCompare(b.name)));
|
||||
let spectatePort = $state("");
|
||||
|
||||
async function updateSpectatePort() {
|
||||
for (const fight of selectedFights) {
|
||||
@@ -120,11 +124,11 @@
|
||||
spectatePortOpen = false;
|
||||
}
|
||||
|
||||
let groupChangeOpen = false;
|
||||
let group = "";
|
||||
let groupSearch = "";
|
||||
let groupChangeOpen = $state(false);
|
||||
let group = $state("");
|
||||
let groupSearch = $state("");
|
||||
|
||||
$: selectableGroups = [{
|
||||
let selectableGroups = $derived([{
|
||||
name: "Keine",
|
||||
value: ""
|
||||
}, {
|
||||
@@ -135,7 +139,7 @@
|
||||
name: group,
|
||||
value: group
|
||||
};
|
||||
}).sort((a, b) => a.name.localeCompare(b.name))];
|
||||
}).sort((a, b) => a.name.localeCompare(b.name))]);
|
||||
|
||||
async function updateGroup() {
|
||||
for (const fight of selectedFights) {
|
||||
@@ -157,11 +161,11 @@
|
||||
groupChangeOpen = false;
|
||||
}
|
||||
|
||||
$: minTime = dayjs(Math.min(...fights.map(fight => fight.start))).utc(true);
|
||||
let changeTimeOpen = false;
|
||||
let changedTime = fights.length != 0 ? dayjs(Math.min(...fights.map(fight => fight.start)))?.utc(true)?.toISOString()?.slice(0, -1) : undefined;
|
||||
let minTime = $derived(dayjs(Math.min(...fights.map(fight => fight.start))).utc(true));
|
||||
let changeTimeOpen = $state(false);
|
||||
let changedTime = $state(fights.length != 0 ? dayjs(Math.min(...fights.map(fight => fight.start)))?.utc(true)?.toISOString()?.slice(0, -1) : undefined);
|
||||
|
||||
$: deltaTime = dayjs.duration(dayjs(changedTime).utc(true).diff(minTime));
|
||||
let deltaTime = $derived(dayjs.duration(dayjs(changedTime).utc(true).diff(minTime)));
|
||||
|
||||
async function updateStartTime() {
|
||||
for (const fight of selectedFights) {
|
||||
@@ -243,10 +247,12 @@
|
||||
|
||||
<Modal bind:open={deleteOpen} title="Delete {selectedFights.size} Fights" autoclose size="sm">
|
||||
<p>Are you sure you want to delete {selectedFights.size} fights?</p>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button color="red" class="ml-auto" on:click={deleteFights}>Delete</Button>
|
||||
<Button on:click={() => deleteOpen = false} color="alternative">Cancel</Button>
|
||||
</svelte:fragment>
|
||||
{#snippet footer()}
|
||||
|
||||
<Button color="red" class="ml-auto" on:click={deleteFights}>Delete</Button>
|
||||
<Button on:click={() => deleteOpen = false} color="alternative">Cancel</Button>
|
||||
|
||||
{/snippet}
|
||||
</Modal>
|
||||
|
||||
<Modal bind:open={spectatePortOpen} title="Change Kampfleiter" size="sm">
|
||||
@@ -254,10 +260,12 @@
|
||||
<Label for="fight-kampf">Kampfleiter</Label>
|
||||
<TypeAheadSearch items={selectPlayers} bind:selected={spectatePort}></TypeAheadSearch>
|
||||
</div>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button class="ml-auto" on:click={updateSpectatePort}>Change</Button>
|
||||
<Button on:click={() => spectatePortOpen = false} color="alternative">Cancel</Button>
|
||||
</svelte:fragment>
|
||||
{#snippet footer()}
|
||||
|
||||
<Button class="ml-auto" on:click={updateSpectatePort}>Change</Button>
|
||||
<Button on:click={() => spectatePortOpen = false} color="alternative">Cancel</Button>
|
||||
|
||||
{/snippet}
|
||||
</Modal>
|
||||
|
||||
<Modal bind:open={groupChangeOpen} title="Change Group" size="sm">
|
||||
@@ -266,32 +274,38 @@
|
||||
<TypeAheadSearch items={selectableGroups} bind:selected={group} bind:searchValue={groupSearch}
|
||||
all></TypeAheadSearch>
|
||||
</div>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button class="ml-auto" on:click={updateGroup}>Change</Button>
|
||||
<Button on:click={() => groupChangeOpen = false} color="alternative">Cancel</Button>
|
||||
</svelte:fragment>
|
||||
{#snippet footer()}
|
||||
|
||||
<Button class="ml-auto" on:click={updateGroup}>Change</Button>
|
||||
<Button on:click={() => groupChangeOpen = false} color="alternative">Cancel</Button>
|
||||
|
||||
{/snippet}
|
||||
</Modal>
|
||||
|
||||
<Modal bind:open={changeTimeOpen} title="Change Start Time" size="sm">
|
||||
<div class="m-2">
|
||||
<Label for="fight-start">New Start Time:</Label>
|
||||
<Input id="fight-start" bind:value={changedTime} let:props>
|
||||
<Input id="fight-start" bind:value={changedTime} >
|
||||
{#snippet children({ props })}
|
||||
<input type="datetime-local" {...props} bind:value={changedTime}/>
|
||||
{/snippet}
|
||||
</Input>
|
||||
</div>
|
||||
<p>{deltaTime.asMilliseconds() < 0 ? '' : '+'}{("0" + deltaTime.hours()).slice(-2)}
|
||||
:{("0" + deltaTime.minutes()).slice(-2)}</p>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button class="ml-auto" on:click={updateStartTime}>Update</Button>
|
||||
<Button on:click={() => changeTimeOpen = false} color="alternative">Cancel</Button>
|
||||
</svelte:fragment>
|
||||
{#snippet footer()}
|
||||
|
||||
<Button class="ml-auto" on:click={updateStartTime}>Update</Button>
|
||||
<Button on:click={() => changeTimeOpen = false} color="alternative">Cancel</Button>
|
||||
|
||||
{/snippet}
|
||||
</Modal>
|
||||
|
||||
<SpeedDial>
|
||||
<SpeedDialButton name="Add" on:click={() => createOpen = true}>
|
||||
<PlusSolid/>
|
||||
<PlusOutline/>
|
||||
</SpeedDialButton>
|
||||
<SpeedDialButton name="Generate" href="#/event/{data.event.id}/generate">
|
||||
<ArrowsRepeatSolid/>
|
||||
<ArrowsRepeatOutline/>
|
||||
</SpeedDialButton>
|
||||
</SpeedDial>
|
||||
|
||||
@@ -20,21 +20,25 @@
|
||||
<script lang="ts">
|
||||
import type {ExtendedEvent} from "@type/event.ts";
|
||||
import {Button} from "flowbite-svelte";
|
||||
import {PlusSolid} from "flowbite-svelte-icons";
|
||||
import {PlusOutline} from "flowbite-svelte-icons";
|
||||
import SWModal from "@components/styled/SWModal.svelte";
|
||||
import SWButton from "@components/styled/SWButton.svelte";
|
||||
import TypeAheadSearch from "@components/admin/components/TypeAheadSearch.svelte";
|
||||
import {players} from "@stores/stores.ts";
|
||||
import {eventRepo} from "@repo/event.ts";
|
||||
|
||||
export let data: ExtendedEvent;
|
||||
interface Props {
|
||||
data: ExtendedEvent;
|
||||
}
|
||||
|
||||
let searchValue = "";
|
||||
let selectedPlayer: string | null = null;
|
||||
let { data }: Props = $props();
|
||||
|
||||
let referees = data.event.referees;
|
||||
let searchValue = $state("");
|
||||
let selectedPlayer: string | null = $state(null);
|
||||
|
||||
let showAdd = false;
|
||||
let referees = $state(data.event.referees);
|
||||
|
||||
let showAdd = $state(false);
|
||||
|
||||
async function addReferee() {
|
||||
if (selectedPlayer) {
|
||||
@@ -76,7 +80,7 @@
|
||||
</ul>
|
||||
|
||||
<Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" on:click={() => showAdd = true}>
|
||||
<PlusSolid/>
|
||||
<PlusOutline/>
|
||||
</Button>
|
||||
|
||||
<SWModal title="Schiedsrichter hinzufügen" bind:open={showAdd}>
|
||||
@@ -86,10 +90,12 @@
|
||||
items={$players.map(v => ({ name: v.name, value: v.uuid }))}/>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="flex flex-grow justify-end">
|
||||
<SWButton on:click={reset} type="gray">Abbrechen</SWButton>
|
||||
<SWButton on:click={addReferee}>Hinzufügen</SWButton>
|
||||
</div>
|
||||
{#snippet footer()}
|
||||
<div class="flex flex-grow justify-end">
|
||||
<SWButton on:click={reset} type="gray">Abbrechen</SWButton>
|
||||
<SWButton on:click={addReferee}>Hinzufügen</SWButton>
|
||||
</div>
|
||||
{/snippet}
|
||||
</SWModal>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
import {Avatar} from "flowbite-svelte";
|
||||
import type {ExtendedEvent} from "@type/event.ts";
|
||||
|
||||
export let data: ExtendedEvent;
|
||||
interface Props {
|
||||
data: ExtendedEvent;
|
||||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
</script>
|
||||
<div class="m-4">
|
||||
{#each data.teams as team (team.id)}
|
||||
|
||||
@@ -28,25 +28,29 @@
|
||||
|
||||
let dispatch = createEventDispatcher();
|
||||
|
||||
export let open: boolean = false;
|
||||
export let data: ExtendedEvent;
|
||||
interface Props {
|
||||
open?: boolean;
|
||||
data: ExtendedEvent;
|
||||
}
|
||||
|
||||
let blueTeam: string = "";
|
||||
let redTeam: string = "";
|
||||
let { open = $bindable(false), data }: Props = $props();
|
||||
|
||||
let start: string = "";
|
||||
let blueTeam: string = $state("");
|
||||
let redTeam: string = $state("");
|
||||
|
||||
let gamemode: string = "";
|
||||
let map: string = "";
|
||||
let start: string = $state("");
|
||||
|
||||
let spectatePort: string | null = null;
|
||||
let group: string | null = null;
|
||||
let groupSearch = "";
|
||||
let gamemode: string = $state("");
|
||||
let map: string = $state("");
|
||||
|
||||
let errorOpen = false;
|
||||
let error: any = undefined;
|
||||
let spectatePort: string | null = $state(null);
|
||||
let group: string | null = $state(null);
|
||||
let groupSearch = $state("");
|
||||
|
||||
$: canCreate = blueTeam !== "" && redTeam !== "" && start !== "" && gamemode !== "" && map !== "";
|
||||
let errorOpen = $state(false);
|
||||
let error: any = $state(undefined);
|
||||
|
||||
let canCreate = $derived(blueTeam !== "" && redTeam !== "" && start !== "" && gamemode !== "" && map !== "");
|
||||
|
||||
async function create() {
|
||||
try {
|
||||
@@ -96,10 +100,12 @@
|
||||
teams={data.teams}
|
||||
/>
|
||||
</div>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button on:click={create} class="mr-auto" disabled={!canCreate}>Create</Button>
|
||||
<Button color="light" on:click={() => open = false}>Cancel</Button>
|
||||
</svelte:fragment>
|
||||
{#snippet footer()}
|
||||
|
||||
<Button on:click={create} class="mr-auto" disabled={!canCreate}>Create</Button>
|
||||
<Button color="light" on:click={() => open = false}>Cancel</Button>
|
||||
|
||||
{/snippet}
|
||||
</Modal>
|
||||
|
||||
<ErrorModal bind:open={errorOpen} bind:error={error} on:close={() => errorOpen = false}/>
|
||||
|
||||
@@ -29,21 +29,25 @@
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
export let fight: EventFight;
|
||||
export let data: ExtendedEvent;
|
||||
export let open = false;
|
||||
interface Props {
|
||||
fight: EventFight;
|
||||
data: ExtendedEvent;
|
||||
open?: boolean;
|
||||
}
|
||||
|
||||
let redTeam = fight.redTeam.id.toString();
|
||||
let blueTeam = fight.blueTeam.id.toString();
|
||||
let start = dayjs(fight.start).utc(true).toISOString().slice(0, -1);
|
||||
let spectatePort = fight.spectatePort?.toString() ?? null;
|
||||
let gamemode = fight.spielmodus;
|
||||
let map = fight.map;
|
||||
let group = fight.group;
|
||||
let groupSearch = fight.group ?? "";
|
||||
let { fight = $bindable(), data, open = $bindable(false) }: Props = $props();
|
||||
|
||||
let errorOpen = false;
|
||||
let error: any = undefined;
|
||||
let redTeam = $state(fight.redTeam.id.toString());
|
||||
let blueTeam = $state(fight.blueTeam.id.toString());
|
||||
let start = $state(dayjs(fight.start).utc(true).toISOString().slice(0, -1));
|
||||
let spectatePort = $state(fight.spectatePort?.toString() ?? null);
|
||||
let gamemode = $state(fight.spielmodus);
|
||||
let map = $state(fight.map);
|
||||
let group = $state(fight.group);
|
||||
let groupSearch = $state(fight.group ?? "");
|
||||
|
||||
let errorOpen = $state(false);
|
||||
let error: any = $state(undefined);
|
||||
|
||||
let dispatch = createEventDispatcher();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user