Refactor player handling: replace player arrays with IDs, implement PlayerSelector component
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
<script lang="ts">
|
||||
import {Input, Label, Select} from "flowbite-svelte";
|
||||
import TypeAheadSearch from "./TypeAheadSearch.svelte";
|
||||
import {gamemodes, groups, maps, players} from "@stores/stores.ts";
|
||||
import {gamemodes, groups, maps} from "@stores/stores.ts";
|
||||
import type {Team} from "@type/team.ts";
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -22,17 +22,33 @@
|
||||
|
||||
import {Button, Card, Checkbox, Input, Label, Navbar, NavBrand, Radio, Spinner} from "flowbite-svelte";
|
||||
import {ArrowLeftOutline} from "flowbite-svelte-icons";
|
||||
import {players} from "@stores/stores.ts";
|
||||
import {capitalize} from "../util.ts";
|
||||
import {permsRepo} from "@repo/perms.ts";
|
||||
import {me} from "@stores/me.ts";
|
||||
import SWButton from "@components/styled/SWButton.svelte";
|
||||
import SWModal from "@components/styled/SWModal.svelte";
|
||||
import {userRepo} from "@repo/user.ts";
|
||||
import {dataRepo} from "@repo/data.ts";
|
||||
import type {Player} from "@type/data";
|
||||
|
||||
let search = $state("");
|
||||
let playersList: Player[] = $state([]);
|
||||
let debounceTimer: NodeJS.Timeout;
|
||||
|
||||
function fetchPlayers(searchTerm: string) {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(async () => {
|
||||
const res = await $dataRepo.queryPlayers(searchTerm || undefined, undefined, undefined, 100, 0, undefined, undefined);
|
||||
playersList = res.players;
|
||||
}, 300);
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
fetchPlayers(search);
|
||||
});
|
||||
|
||||
let selectedPlayer: string | null = $state(null);
|
||||
let selectedPlayerName: string = $state("");
|
||||
let playerPerms = $state(loadPlayer(selectedPlayer));
|
||||
|
||||
let prefixEdit = $state("PREFIX_NONE");
|
||||
@@ -99,9 +115,7 @@
|
||||
resetPasswordRepeat = "";
|
||||
resetPasswordModal = false;
|
||||
}
|
||||
let lowerCaseSearch = $derived(search.toLowerCase());
|
||||
let filteredPlayers = $derived($players.filter(value => value.name.toLowerCase().includes(lowerCaseSearch)));
|
||||
let player = $derived($players.find(value => value.uuid === selectedPlayer));
|
||||
|
||||
run(() => {
|
||||
playerPerms = loadPlayer(selectedPlayer);
|
||||
});
|
||||
@@ -126,12 +140,15 @@
|
||||
<Label for="user_search" class="mb-2">Search Users...</Label>
|
||||
<Input type="text" id="user_search" placeholder="Name..." bind:value={search}/>
|
||||
</div>
|
||||
{#if filteredPlayers.length < 100}
|
||||
{#if playersList.length < 100}
|
||||
<ul class="flex-1 overflow-scroll">
|
||||
{#each filteredPlayers as player (player.uuid)}
|
||||
{#each playersList as player (player.uuid)}
|
||||
<li class="p-4 transition-colors hover:bg-gray-700 cursor-pointer"
|
||||
class:text-orange-500={player.uuid === selectedPlayer}
|
||||
onclick={preventDefault(() => selectedPlayer = player.uuid)}>
|
||||
onclick={preventDefault(() => {
|
||||
selectedPlayer = player.uuid;
|
||||
selectedPlayerName = player.name;
|
||||
})}>
|
||||
{player.name}
|
||||
</li>
|
||||
{/each}
|
||||
@@ -140,7 +157,7 @@
|
||||
</Card>
|
||||
<Card class="!max-w-full" style="grid-column: 2/4">
|
||||
{#if selectedPlayer}
|
||||
<h1 class="text-3xl">{player.name}</h1>
|
||||
<h1 class="text-3xl">{selectedPlayerName}</h1>
|
||||
{#await permsFuture}
|
||||
<Spinner></Spinner>
|
||||
{:then perms}
|
||||
|
||||
@@ -36,8 +36,9 @@
|
||||
} from "flowbite-svelte-icons";
|
||||
import FightCard from "./FightCard.svelte";
|
||||
import CreateFightModal from "./modals/CreateFightModal.svelte";
|
||||
import {groups, players} from "@stores/stores.ts";
|
||||
import {groups} from "@stores/stores.ts";
|
||||
import TypeAheadSearch from "../../components/TypeAheadSearch.svelte";
|
||||
import PlayerSelector from "@components/ui/PlayerSelector.svelte";
|
||||
import {fightRepo, type UpdateFight} from "@repo/fight.ts";
|
||||
import dayjs from "dayjs";
|
||||
import duration from "dayjs/plugin/duration";
|
||||
@@ -97,12 +98,6 @@
|
||||
}
|
||||
|
||||
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 = $state("");
|
||||
|
||||
async function updateSpectatePort() {
|
||||
@@ -262,12 +257,12 @@
|
||||
<TypeAheadSearch items={selectPlayers} bind:selected={spectatePort}></TypeAheadSearch>
|
||||
</div>
|
||||
{#snippet footer()}
|
||||
|
||||
<Button class="ml-auto" onclick={updateSpectatePort}>Change</Button>
|
||||
<Button onclick={() => spectatePortOpen = false} color="alternative">Cancel</Button>
|
||||
|
||||
{/snippet}
|
||||
</Modal>
|
||||
<Modal bind:open={spectatePortOpen} title="Change Kampfleiter" size="sm">
|
||||
<div class="m-2">
|
||||
<Label for="fight-kampf">Kampfleiter</Label>
|
||||
<PlayerSelector bind:value={spectatePort} placeholder="Search player..." />
|
||||
</div>
|
||||
{#snippet footer()}
|
||||
|
||||
<Modal bind:open={groupChangeOpen} title="Change Group" size="sm">
|
||||
<div class="m-2">
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
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 PlayerSelector from "@components/ui/PlayerSelector.svelte";
|
||||
import {eventRepo} from "@repo/event.ts";
|
||||
|
||||
interface Props {
|
||||
@@ -102,8 +101,7 @@
|
||||
<SWModal title="Schiedsrichter hinzufügen" bind:open={showAdd}>
|
||||
<div class="flex flex-grow justify-center h-80">
|
||||
<div>
|
||||
<TypeAheadSearch bind:searchValue bind:selected={selectedPlayer}
|
||||
items={$players.map(v => ({ name: v.name, value: v.uuid }))}/>
|
||||
<PlayerSelector bind:value={selectedPlayer} placeholder="Search player..." />
|
||||
</div>
|
||||
</div>
|
||||
{#snippet footer()}
|
||||
|
||||
Reference in New Issue
Block a user