Changes
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
<script lang="ts">
|
||||
import type {ExtendedEvent} from "../../types/event.js";
|
||||
import {Button, Heading, Input, Label, Modal, Range, Select, Toast, Toggle} from "flowbite-svelte";
|
||||
import {schemTypes} from "../../stores/stores.js";
|
||||
import moment from "moment/moment.js";
|
||||
import type {UpdateEvent} from "../../repo/event.js";
|
||||
import {eventRepo} from "../../repo/repo.js";
|
||||
import ErrorModal from "../../components/ErrorModal.svelte";
|
||||
import {replace} from "svelte-spa-router";
|
||||
import {CheckCircleOutline} from "flowbite-svelte-icons";
|
||||
|
||||
export let data: ExtendedEvent;
|
||||
let event = data.event;
|
||||
let name = event.name;
|
||||
let deadline = moment(event.deadline).utc(true).toISOString().slice(0, -1);
|
||||
let start = moment(event.start).utc(true).toISOString().slice(0, -1);
|
||||
let end = moment(event.end).utc(true).toISOString().slice(0, -1);
|
||||
let member = event.maxTeamMembers;
|
||||
let schemType = event.schemType;
|
||||
let publicOnly = event.publicSchemsOnly;
|
||||
let spectateSystem = event.spectateSystem;
|
||||
|
||||
let errorOpen = false;
|
||||
let error: Error = undefined;
|
||||
let deleteOpen = false;
|
||||
|
||||
$: deadlineDate = moment(deadline);
|
||||
$: startDate = moment(start);
|
||||
$: endDate = moment(end);
|
||||
$: selectTypes = [{
|
||||
value: null,
|
||||
name: "None"
|
||||
}, ...$schemTypes.map((type) => {
|
||||
return {
|
||||
value: type.db,
|
||||
name: type.name
|
||||
}
|
||||
})];
|
||||
|
||||
$: changed = name !== event.name ||
|
||||
deadlineDate.diff(moment(event.deadline)) !== 0 ||
|
||||
startDate.diff(moment(event.start)) !== 0 ||
|
||||
endDate.diff(moment(event.end)) !== 0 ||
|
||||
member !== event.maxTeamMembers ||
|
||||
schemType != event.schemType ||
|
||||
publicOnly !== event.publicSchemsOnly ||
|
||||
spectateSystem !== event.spectateSystem;
|
||||
|
||||
async function del() {
|
||||
try {
|
||||
await $eventRepo.deleteEvent(event.id.toString());
|
||||
await replace("/")
|
||||
} catch (e) {
|
||||
error = e;
|
||||
errorOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
let successToast: boolean = false;
|
||||
|
||||
async function update() {
|
||||
let ev: UpdateEvent = {
|
||||
deadline: deadlineDate,
|
||||
end: endDate,
|
||||
maxTeamMembers: member,
|
||||
name: name,
|
||||
publicSchemsOnly: publicOnly,
|
||||
schemType: schemType ?? 'null',
|
||||
spectateSystem: spectateSystem,
|
||||
start: startDate
|
||||
};
|
||||
|
||||
try {
|
||||
event = await $eventRepo.updateEvent(event.id.toString(), ev);
|
||||
successToast = true;
|
||||
setTimeout(() => successToast = false, 5000);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
errorOpen = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{event.name} - Edit</title>
|
||||
</svelte:head>
|
||||
|
||||
<form class="m-4">
|
||||
<div class="mt-4">
|
||||
<Label for="event-name">Name</Label>
|
||||
<Input type="text" id="event-name" bind:value={name} class="w-80" size="lg"></Input>
|
||||
</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 type="datetime-local" {...props} bind:value={deadline}/>
|
||||
</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 type="datetime-local" {...props} bind:value={start}/>
|
||||
</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 type="datetime-local" {...props} bind:value={end}/>
|
||||
</Input>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<Label for="event-member">Member: {member}</Label>
|
||||
<Range id="event-member" bind:value={member} step="1" min="1" max="30"/>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<Label for="event-type">Schematic Type:</Label>
|
||||
<Select bind:value={schemType} items={selectTypes}/>
|
||||
</div>
|
||||
<Toggle bind:checked={publicOnly} class="mt-4">Public Schematics Only</Toggle>
|
||||
<Toggle bind:checked={spectateSystem} class="mt-4">Spectate System</Toggle>
|
||||
<div class="flex mt-4">
|
||||
<Button disabled={!changed} on:click={update}>Update</Button>
|
||||
<Button class="ml-4" color="red" on:click={() => deleteOpen = true}>Delete</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ErrorModal bind:open={errorOpen} bind:error={error}/>
|
||||
|
||||
<Modal bind:open={deleteOpen} outsideclose title="Delete {event.name}?">
|
||||
<p>Are you sure you want to delete {event.name}?</p>
|
||||
<div class="flex justify-end">
|
||||
<Button on:click={() => deleteOpen = false}>Cancel</Button>
|
||||
<Button class="ml-4" color="red" on:click={del}>Delete</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Toast bind:open={successToast} position="bottom-left" color="green">
|
||||
<CheckCircleOutline slot="icon"/>
|
||||
Updated Successfully
|
||||
</Toast>
|
||||
@@ -0,0 +1,96 @@
|
||||
<script lang="ts">
|
||||
import {EditOutline, InboxSolid, TrashBinOutline} from "flowbite-svelte-icons";
|
||||
import {Button, Checkbox, Modal, Toolbar, ToolbarButton} from "flowbite-svelte";
|
||||
import type {EventFight, ExtendedEvent} from "../../types/event.js";
|
||||
import FightEditModal from "./modals/FightEditModal.svelte";
|
||||
import {createEventDispatcher, onMount} from "svelte";
|
||||
import {fightRepo} from "../../repo/repo.js";
|
||||
import {isWide} from "../../stores/stores.js";
|
||||
|
||||
export let fight: EventFight;
|
||||
export let data: ExtendedEvent;
|
||||
export let i: number;
|
||||
export let selected: boolean = false;
|
||||
export let hideEdit: boolean = false;
|
||||
|
||||
let deleteOpen = false;
|
||||
let editOpen = false;
|
||||
|
||||
let dispatcher = createEventDispatcher();
|
||||
|
||||
function dispatchSelect() {
|
||||
setTimeout(() => {
|
||||
if (!deleteOpen && !editOpen) {
|
||||
dispatcher('select');
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
async function deleteFight() {
|
||||
await $fightRepo.deleteFight(fight.id);
|
||||
dispatcher('update');
|
||||
}
|
||||
</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"
|
||||
>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col">
|
||||
<div>
|
||||
<span>{$isWide ? fight.blueTeam.name : fight.blueTeam.kuerzel}</span>
|
||||
vs.
|
||||
<span>{$isWide ? fight.redTeam.name : fight.redTeam.kuerzel}</span>
|
||||
</div>
|
||||
{#if (fight.ergebnis === 3)}
|
||||
<span class="ml-2">Unentschieden</span>
|
||||
{:else if (fight.ergebnis !== 0)}
|
||||
<span class="ml-2">{fight.ergebnis === 1 ? 'Sieger: ' + ($isWide ? fight.blueTeam.name : fight.blueTeam.kuerzel) : 'Sieger: ' + ($isWide ? fight.redTeam.name : fight.redTeam.kuerzel)}</span>
|
||||
{:else}
|
||||
<span class="ml-2">{$isWide ? 'Noch nicht gespielt' : 'kommend'}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<div class="mr-2 flex flex-col">
|
||||
<span>
|
||||
{new Intl.DateTimeFormat(Intl.Locale.name, {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
}).format(fight.start)}
|
||||
</span>
|
||||
<span>
|
||||
{new Intl.DateTimeFormat(Intl.Locale.name, {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: '2-digit'
|
||||
}).format(fight.start)}
|
||||
</span>
|
||||
</div>
|
||||
{#if !hideEdit}
|
||||
<Toolbar embedded>
|
||||
<ToolbarButton on:click={() => editOpen = true}>
|
||||
<EditOutline/>
|
||||
</ToolbarButton>
|
||||
<ToolbarButton color="red" on:click={() => deleteOpen = true}>
|
||||
<TrashBinOutline />
|
||||
</ToolbarButton>
|
||||
</Toolbar>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal title="Delete {fight.blueTeam.name} vs. {fight.redTeam.name}" bind:open={deleteOpen} autoclose outsideclose size="xs">
|
||||
<div class="text-center">
|
||||
<p class="mb-5">
|
||||
Are you sure you want to delete this fight?
|
||||
</p>
|
||||
<Button color="red" on:click={deleteFight}>Delete Fight</Button>
|
||||
<Button color="alternative">Cancel</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
{#if (editOpen)}
|
||||
<FightEditModal {fight} bind:data bind:open={editOpen} on:update/>
|
||||
{/if}
|
||||
@@ -0,0 +1,267 @@
|
||||
<script lang="ts">
|
||||
import type {EventFight, ExtendedEvent} from "../../types/event.js";
|
||||
import {
|
||||
Button,
|
||||
Checkbox, Input, Label,
|
||||
Modal,
|
||||
SpeedDial,
|
||||
SpeedDialButton,
|
||||
Toolbar,
|
||||
ToolbarButton,
|
||||
ToolbarGroup,
|
||||
Tooltip
|
||||
} from "flowbite-svelte";
|
||||
import {
|
||||
ArrowsRepeatSolid, CalendarWeekOutline,
|
||||
PlusSolid, ProfileCardOutline, TrashBinOutline, UsersGroupOutline,
|
||||
} from "flowbite-svelte-icons";
|
||||
import FightCard from "./FightCard.svelte";
|
||||
import CreateFightModal from "./modals/CreateFightModal.svelte";
|
||||
import {fightRepo} from "../../repo/repo.js";
|
||||
import {groups, players} from "../../stores/stores.js";
|
||||
import TypeAheadSearch from "../../components/TypeAheadSearch.svelte";
|
||||
import type {UpdateFight} from "../../repo/fight.js";
|
||||
import moment from "moment";
|
||||
|
||||
export let data: ExtendedEvent;
|
||||
|
||||
let createOpen = false;
|
||||
let fights = data.fights;
|
||||
let selectedFights: Set<EventFight> = new Set();
|
||||
|
||||
$: groupsMap = new Set(fights.map(fight => fight.group));
|
||||
$: groupedFights = Array.from(groupsMap).map(group => {
|
||||
return {
|
||||
group: group,
|
||||
fights: fights.filter(fight => fight.group === group)
|
||||
}
|
||||
});
|
||||
|
||||
function cycleSelect() {
|
||||
if (selectedFights.size === fights.length) {
|
||||
selectedFights = new Set();
|
||||
} else if(selectedFights.size === 0){
|
||||
selectedFights = new Set(fights.filter(fight => fight.start > Date.now()));
|
||||
|
||||
if (selectedFights.size === 0) {
|
||||
selectedFights = new Set(fights);
|
||||
}
|
||||
} else {
|
||||
selectedFights = new Set(fights);
|
||||
}
|
||||
}
|
||||
|
||||
function cycleGroup(groupFights: EventFight[]) {
|
||||
if(groupFights.every(gf => selectedFights.has(gf))) {
|
||||
groupFights.forEach(fight => selectedFights.delete(fight));
|
||||
} else {
|
||||
groupFights.forEach(fight => selectedFights.add(fight));
|
||||
}
|
||||
selectedFights = selectedFights;
|
||||
}
|
||||
|
||||
let deleteOpen = false;
|
||||
async function deleteFights() {
|
||||
for (const fight of selectedFights) {
|
||||
await $fightRepo.deleteFight(fight.id);
|
||||
}
|
||||
fights = await $fightRepo.listFights(data.event.id);
|
||||
selectedFights = new Set();
|
||||
deleteOpen = false;
|
||||
}
|
||||
|
||||
let kampfleiterOpen = false;
|
||||
$: selectPlayers = $players.map(player => {
|
||||
return {
|
||||
name: player.name,
|
||||
value: player.id.toString()
|
||||
}
|
||||
}).sort((a, b) => a.name.localeCompare(b.name));
|
||||
let kampfleiter = "";
|
||||
async function updateKampfleiter() {
|
||||
for (const fight of selectedFights) {
|
||||
let f: UpdateFight = {
|
||||
blueTeam: null,
|
||||
group: null,
|
||||
kampfleiter: Number.parseInt(kampfleiter),
|
||||
map: null,
|
||||
redTeam: null,
|
||||
spielmodus: null,
|
||||
start: null
|
||||
};
|
||||
await $fightRepo.updateFight(fight.id, f);
|
||||
}
|
||||
fights = await $fightRepo.listFights(data.event.id);
|
||||
selectedFights = new Set();
|
||||
kampfleiter = "";
|
||||
kampfleiterOpen = false;
|
||||
}
|
||||
|
||||
let groupChangeOpen = false;
|
||||
let group = "";
|
||||
let groupSearch = "";
|
||||
|
||||
$: selectableGroups = [{
|
||||
name: 'None',
|
||||
value: ''
|
||||
}, {
|
||||
value: groupSearch,
|
||||
name: `Create: '${groupSearch}'`
|
||||
}, ...$groups.map(group => {
|
||||
return {
|
||||
name: group,
|
||||
value: group
|
||||
}
|
||||
}).sort((a, b) => a.name.localeCompare(b.name))];
|
||||
async function updateGroup() {
|
||||
for (const fight of selectedFights) {
|
||||
let f: UpdateFight = {
|
||||
blueTeam: null,
|
||||
group: group,
|
||||
kampfleiter: null,
|
||||
map: null,
|
||||
redTeam: null,
|
||||
spielmodus: null,
|
||||
start: null
|
||||
};
|
||||
await $fightRepo.updateFight(fight.id, f);
|
||||
}
|
||||
fights = await $fightRepo.listFights(data.event.id);
|
||||
selectedFights = new Set();
|
||||
group = "";
|
||||
groupSearch = "";
|
||||
groupChangeOpen = false;
|
||||
}
|
||||
|
||||
$: minTime = moment(Math.min(...fights.map(fight => fight.start))).utc(true);
|
||||
let changeTimeOpen = false;
|
||||
let changedTime = moment(Math.min(...fights.map(fight => fight.start)))?.utc(true)?.toISOString()?.slice(0, -1);
|
||||
|
||||
$: deltaTime = moment.duration(moment(changedTime).utc(true).diff(minTime))
|
||||
|
||||
async function updateStartTime() {
|
||||
for (const fight of selectedFights) {
|
||||
let f: UpdateFight = {
|
||||
blueTeam: null,
|
||||
group: null,
|
||||
kampfleiter: null,
|
||||
map: null,
|
||||
redTeam: null,
|
||||
spielmodus: null,
|
||||
start: moment(fight.start).add(deltaTime.asMilliseconds(), 'millisecond')
|
||||
};
|
||||
await $fightRepo.updateFight(fight.id, f);
|
||||
}
|
||||
fights = await $fightRepo.listFights(data.event.id);
|
||||
changedTime = minTime.toISOString().slice(0, -1);
|
||||
selectedFights = new Set();
|
||||
changeTimeOpen = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{data.event.name} - Fights</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="pb-28">
|
||||
<Toolbar class="mx-4 mt-2 w-fit">
|
||||
<ToolbarGroup>
|
||||
<Checkbox class="ml-2" checked={selectedFights.size === fights.length} on:click={cycleSelect}/>
|
||||
<Tooltip>Select Upcoming</Tooltip>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup>
|
||||
<ToolbarButton on:click={() => selectedFights.size > 0 ? changeTimeOpen = true : changeTimeOpen = false}>
|
||||
<CalendarWeekOutline/>
|
||||
</ToolbarButton>
|
||||
<Tooltip>Reschedule Fights</Tooltip>
|
||||
<ToolbarButton on:click={() => selectedFights.size > 0 ? kampfleiterOpen = true : kampfleiterOpen = false}>
|
||||
<ProfileCardOutline/>
|
||||
</ToolbarButton>
|
||||
<Tooltip>Change Kampfleiter</Tooltip>
|
||||
<ToolbarButton on:click={() => selectedFights.size > 0 ? groupChangeOpen = true : groupChangeOpen = false}>
|
||||
<UsersGroupOutline/>
|
||||
</ToolbarButton>
|
||||
<Tooltip>Change Group</Tooltip>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup>
|
||||
<ToolbarButton color="red" on:click={() => selectedFights.size > 0 ? deleteOpen = true : deleteOpen = false}>
|
||||
<TrashBinOutline/>
|
||||
</ToolbarButton>
|
||||
<Tooltip>Delete</Tooltip>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
{#each groupedFights as group}
|
||||
<div class="flex mt-4">
|
||||
<Checkbox class="ml-2 text-center" checked={group.fights.every(gf => selectedFights.has(gf))} on:click={() => cycleGroup(group.fights)}/>
|
||||
<h1 class="ml-4 text-2xl">{group.group ?? "Ungrouped"}</h1>
|
||||
</div>
|
||||
{#each group.fights.sort((a, b) => a.start - b.start) as fight, i}
|
||||
<FightCard {fight} {i} {data} selected={selectedFights.has(fight)}
|
||||
on:select={() => {
|
||||
if (selectedFights.has(fight)) {
|
||||
selectedFights.delete(fight);
|
||||
} else {
|
||||
selectedFights.add(fight);
|
||||
}
|
||||
selectedFights = selectedFights;
|
||||
}}
|
||||
on:update={async () => fights = await $fightRepo.listFights(data.event.id)}
|
||||
/>
|
||||
{/each}
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<CreateFightModal {data} bind:open={createOpen} on:create={async () => data.fights = await $fightRepo.listFights(data.event.id)}></CreateFightModal>
|
||||
|
||||
<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>
|
||||
</Modal>
|
||||
|
||||
<Modal bind:open={kampfleiterOpen} title="Change Kampfleiter" size="sm">
|
||||
<div class="m-2">
|
||||
<Label for="fight-kampf">Kampfleiter</Label>
|
||||
<TypeAheadSearch items={selectPlayers} bind:selected={kampfleiter}></TypeAheadSearch>
|
||||
</div>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button class="ml-auto" on:click={updateKampfleiter}>Change</Button>
|
||||
<Button on:click={() => kampfleiterOpen = false} color="alternative">Cancel</Button>
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
|
||||
<Modal bind:open={groupChangeOpen} title="Change Group" size="sm">
|
||||
<div class="m-2">
|
||||
<Label for="fight-kampf">Group</Label>
|
||||
<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>
|
||||
</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 type="datetime-local" {...props} bind:value={changedTime}/>
|
||||
</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>
|
||||
</Modal>
|
||||
|
||||
<SpeedDial>
|
||||
<SpeedDialButton name="Add" on:click={() => createOpen = true}>
|
||||
<PlusSolid/>
|
||||
</SpeedDialButton>
|
||||
<SpeedDialButton name="Generate" href="#/event/{data.event.id}/generate">
|
||||
<ArrowsRepeatSolid/>
|
||||
</SpeedDialButton>
|
||||
</SpeedDial>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import {Avatar, Button, Modal} from "flowbite-svelte";
|
||||
import type {ExtendedEvent} from "../../types/event.js";
|
||||
|
||||
export let data: ExtendedEvent;
|
||||
</script>
|
||||
<div class="m-4">
|
||||
{#each data.teams as team}
|
||||
<div class="flex flex-row my-2">
|
||||
<Avatar size="lg">{team.kuerzel}</Avatar>
|
||||
<div class="m-2">
|
||||
<h1 class="text-2xl">{team.name}</h1>
|
||||
<h2 class="text-lg text-gray-400">Fights: {data.fights.filter(value => value.blueTeam.id === team.id || value.redTeam.id === team.id).length}</h2>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<svelte:head>
|
||||
<title>{data.event.name} - Teams</title>
|
||||
</svelte:head>
|
||||
@@ -0,0 +1,87 @@
|
||||
<script lang="ts">
|
||||
import {Button, Modal} from "flowbite-svelte";
|
||||
import type {ExtendedEvent} from "../../../types/event.js";
|
||||
import FightEditPart from "../../../components/FightEditPart.svelte";
|
||||
import {fightRepo} from "../../../repo/repo.js";
|
||||
import type {CreateFight} from "../../../repo/fight.ts";
|
||||
import ErrorModal from "../../../components/ErrorModal.svelte";
|
||||
import {createEventDispatcher} from "svelte";
|
||||
import moment from "moment";
|
||||
|
||||
let dispatch = createEventDispatcher();
|
||||
|
||||
export let open: boolean = false;
|
||||
export let data: ExtendedEvent;
|
||||
|
||||
let blueTeam: string = "";
|
||||
let redTeam: string = "";
|
||||
|
||||
let start: string = "";
|
||||
|
||||
let gamemode: string = "";
|
||||
let map: string = "";
|
||||
|
||||
let kampfleiter: string | null = null;
|
||||
let group: string | null = null;
|
||||
let groupSearch = "";
|
||||
|
||||
let errorOpen = false;
|
||||
let error: Error | null = null;
|
||||
|
||||
$: canCreate = blueTeam !== "" && redTeam !== "" && start !== "" && gamemode !== "" && map !== "";
|
||||
|
||||
async function create() {
|
||||
try {
|
||||
open = false;
|
||||
let res = await $fightRepo.createFight(data.event.id, {
|
||||
spielmodus: gamemode,
|
||||
blueTeam: parseInt(blueTeam),
|
||||
redTeam: parseInt(redTeam),
|
||||
start: moment(start),
|
||||
map,
|
||||
kampfleiter: parseInt(kampfleiter),
|
||||
group,
|
||||
});
|
||||
reset()
|
||||
|
||||
dispatch("create")
|
||||
} catch (e) {
|
||||
error = e;
|
||||
errorOpen = true;
|
||||
reset()
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
blueTeam = "";
|
||||
redTeam = "";
|
||||
start = "";
|
||||
gamemode = "";
|
||||
map = "";
|
||||
kampfleiter = "";
|
||||
group = null;
|
||||
groupSearch = "";
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal bind:open outsideclose title="Create Fight" on:hide={reset}>
|
||||
<div class="text-center">
|
||||
<FightEditPart
|
||||
bind:blueTeam
|
||||
bind:redTeam
|
||||
bind:start
|
||||
bind:kampfleiter
|
||||
bind:gamemode
|
||||
bind:map
|
||||
bind:group
|
||||
bind:groupSearch
|
||||
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>
|
||||
</Modal>
|
||||
|
||||
<ErrorModal bind:open={errorOpen} bind:error={error} on:close={() => errorOpen = false}/>
|
||||
@@ -0,0 +1,68 @@
|
||||
<script lang="ts">
|
||||
import {Button, Input, Label, Modal, Select} from "flowbite-svelte";
|
||||
import moment from "moment";
|
||||
import {gamemodes, groups, maps, players} from "../../../stores/stores.js";
|
||||
import type {EventFight, ExtendedEvent} from "../../../types/event.js";
|
||||
import TypeAheadSearch from "../../../components/TypeAheadSearch.svelte";
|
||||
import FightEditPart from "../../../components/FightEditPart.svelte";
|
||||
import type {UpdateFight} from "../../../repo/fight.js";
|
||||
import {fightRepo} from "../../../repo/repo.js";
|
||||
import ErrorModal from "../../../components/ErrorModal.svelte";
|
||||
import {createEventDispatcher} from "svelte";
|
||||
|
||||
export let fight: EventFight;
|
||||
export let data: ExtendedEvent;
|
||||
export let open = false;
|
||||
|
||||
let redTeam = fight.redTeam.id.toString();
|
||||
let blueTeam = fight.blueTeam.id.toString();
|
||||
let start = moment(fight.start).utc(true).toISOString().slice(0, -1);
|
||||
let kampfleiter = fight.kampfleiter.id.toString();
|
||||
let gamemode = fight.spielmodus
|
||||
let map = fight.map;
|
||||
let group = fight.group;
|
||||
let groupSearch = fight.group ?? "";
|
||||
|
||||
let errorOpen = false;
|
||||
let error = undefined;
|
||||
|
||||
let dispatch = createEventDispatcher();
|
||||
function save() {
|
||||
const update: UpdateFight = {
|
||||
blueTeam: parseInt(blueTeam), group: group === "" ? null : group, kampfleiter: parseInt(kampfleiter), map: map, redTeam: parseInt(redTeam), spielmodus: gamemode, start: moment(start)
|
||||
}
|
||||
|
||||
$fightRepo.updateFight(fight.id, update)
|
||||
.then(value => {
|
||||
open = false;
|
||||
fight = value;
|
||||
dispatch("update", value);
|
||||
})
|
||||
.catch((e) => {
|
||||
error = e.message;
|
||||
errorOpen = true;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal title="Edit {fight.blueTeam.name} vs. {fight.redTeam.name}" bind:open outsideclose size="xs">
|
||||
<div class="text-center">
|
||||
<FightEditPart
|
||||
bind:blueTeam
|
||||
bind:redTeam
|
||||
bind:start
|
||||
bind:kampfleiter
|
||||
bind:gamemode
|
||||
bind:map
|
||||
bind:group
|
||||
bind:groupSearch
|
||||
teams={data.teams}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<Button on:click={save}>Save</Button>
|
||||
<Button color="light" class="ml-auto" on:click={() => open = false}>Cancel</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<ErrorModal bind:open={errorOpen} bind:error={error} on:close={() => errorOpen = false}/>
|
||||
Reference in New Issue
Block a user