Compare commits
3 Commits
9a6e44b2d5
...
6e4a7f0ac9
Author | SHA1 | Date | |
---|---|---|---|
6e4a7f0ac9 | |||
55f5f25e5a | |||
03ee87d7cf |
@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Skeleton from '@assets/img/steve.png';
|
|
||||||
import type { GetDeathsRes } from '@db/schema/death.ts';
|
import type { GetDeathsRes } from '@db/schema/death.ts';
|
||||||
import { type ActionReturnType, actions } from 'astro:actions';
|
import { type ActionReturnType, actions } from 'astro:actions';
|
||||||
|
|
||||||
@ -13,20 +12,24 @@
|
|||||||
const entries = teams.map((team) => ({
|
const entries = teams.map((team) => ({
|
||||||
...team,
|
...team,
|
||||||
memberOne: Object.assign(team.memberOne, {
|
memberOne: Object.assign(team.memberOne, {
|
||||||
dead: team.memberOne.id != null ? deaths.findIndex((d) => d.deadUserId === team.memberOne.id) !== -1 : null
|
deathMessage: deaths.find((d) => d.deadUserId === team.memberOne.id)?.message ?? null
|
||||||
}),
|
}),
|
||||||
memberTwo: Object.assign(team.memberTwo, {
|
memberTwo: Object.assign(team.memberTwo, {
|
||||||
dead: team.memberTwo.id != null ? deaths.findIndex((d) => d.deadUserId === team.memberTwo.id) !== -1 : null
|
deathMessage: deaths.find((d) => d.deadUserId === team.memberTwo.id)?.message ?? null
|
||||||
}),
|
}),
|
||||||
kills: deaths.filter((d) => d.killerUserId === team.memberOne.id || d.killerUserId === team.memberTwo.id).length
|
kills: deaths.filter((d) => d.killerUserId === team.memberOne.id || d.killerUserId === team.memberTwo.id).length
|
||||||
}));
|
}));
|
||||||
entries.sort((a, b) => {
|
entries.sort((a, b) => {
|
||||||
const aAllowed = !!a.memberOne.id && !!a.memberTwo.id && !(a.memberOne.dead && a.memberTwo.dead);
|
const aBothSignedUp = a.memberOne.id != null && a.memberTwo.id != null;
|
||||||
const bAllowed = !!b.memberOne.id && !!b.memberTwo.id && !(b.memberOne.dead && b.memberTwo.dead);
|
const aBothDeathMessage = a.memberOne.deathMessage != null && a.memberTwo.deathMessage != null;
|
||||||
if (!aAllowed && !bAllowed) {
|
|
||||||
return 0;
|
const bBothSignedUp = b.memberOne.id != null && b.memberTwo.id != null;
|
||||||
} else if (!aAllowed || !bAllowed) {
|
const bBothDeathMessage = b.memberOne.deathMessage != null && b.memberTwo.deathMessage != null;
|
||||||
return (bAllowed as unknown as number) - (aAllowed as unknown as number);
|
|
||||||
|
if (!aBothSignedUp || !bBothSignedUp) {
|
||||||
|
return Number(bBothSignedUp) - Number(aBothSignedUp);
|
||||||
|
} else if (aBothDeathMessage && !bBothDeathMessage || !aBothDeathMessage && bBothDeathMessage) {
|
||||||
|
return Number(aBothDeathMessage) - Number(bBothDeathMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.kills - a.kills;
|
return b.kills - a.kills;
|
||||||
@ -51,7 +54,7 @@
|
|||||||
<div class="rounded-sm min-w-3 w-3 min-h-3 h-3" style="background-color: {team.color}"></div>
|
<div class="rounded-sm min-w-3 w-3 min-h-3 h-3" style="background-color: {team.color}"></div>
|
||||||
<h3
|
<h3
|
||||||
class="text-xs sm:text-xl break-all"
|
class="text-xs sm:text-xl break-all"
|
||||||
class:line-through={team.memberOne.dead && team.memberTwo.dead}
|
class:line-through={team.memberOne.deathMessage !== null && team.memberTwo.deathMessage !== null}
|
||||||
class:text-red-200={!team.memberOne}
|
class:text-red-200={!team.memberOne}
|
||||||
>
|
>
|
||||||
{team.name}
|
{team.name}
|
||||||
@ -62,33 +65,25 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
<td class="max-w-9 overflow-ellipsis">
|
<td class="max-w-9 overflow-ellipsis">
|
||||||
<div class="flex items-center gap-x-2">
|
<div class="flex items-center gap-x-2 w-max tooltip" data-tip={team.memberOne.deathMessage}>
|
||||||
{#if team.memberOne.id != null}
|
{#if team.memberOne.id != null}
|
||||||
<img
|
<img class="h-4 pixelated" src="https://mc-heads.net/head/{team.memberOne.username}/8" alt="head" />
|
||||||
class="h-4 pixelated"
|
|
||||||
src={team.memberOne.dead ? Skeleton.src : `https://mc-heads.net/head/${team.memberOne.username}/8`}
|
|
||||||
alt="head"
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
<span
|
<span
|
||||||
class="text-xs sm:text-md break-all"
|
class="text-xs sm:text-md break-all"
|
||||||
class:line-through={team.memberOne.dead}
|
class:line-through={team.memberOne.deathMessage !== null}
|
||||||
class:text-gray-500={team.memberOne.id == null}>{team.memberOne.username}</span
|
class:text-gray-500={team.memberOne.id == null}>{team.memberOne.username}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="flex items-center gap-x-2">
|
<div class="flex items-center gap-x-2 w-max tooltip" data-tip={team.memberTwo.deathMessage}>
|
||||||
{#if team.memberTwo.id != null}
|
{#if team.memberTwo.id != null}
|
||||||
<img
|
<img class="h-4 pixelated" src="https://mc-heads.net/head/{team.memberTwo.username}/8" alt="head" />
|
||||||
class="h-4 pixelated"
|
|
||||||
src={team.memberTwo.dead ? Skeleton.src : `https://mc-heads.net/head/${team.memberTwo.username}/8`}
|
|
||||||
alt="head"
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
<span
|
<span
|
||||||
class="text-xs sm:text-md break-all"
|
class="text-xs sm:text-md break-all"
|
||||||
class:line-through={team.memberTwo.dead}
|
class:line-through={team.memberTwo.deathMessage !== null}
|
||||||
class:text-gray-500={team.memberTwo.id == null}>{team.memberTwo.username}</span
|
class:text-gray-500={team.memberTwo.id == null}>{team.memberTwo.username}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,20 +9,17 @@
|
|||||||
// inputs
|
// inputs
|
||||||
let { available, value = $bindable(), readonly }: Props = $props();
|
let { available, value = $bindable(), readonly }: Props = $props();
|
||||||
|
|
||||||
// idk why, but this is needed to trigger loop reactivity
|
|
||||||
let reactiveValue = $derived(value);
|
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
function onOptionSelect(e: Event) {
|
function onOptionSelect(e: Event) {
|
||||||
const selected = Number((e.target as HTMLSelectElement).value);
|
const selected = Number((e.target as HTMLSelectElement).value);
|
||||||
|
|
||||||
reactiveValue |= selected;
|
value |= selected;
|
||||||
|
|
||||||
(e.target as HTMLSelectElement).value = '-';
|
(e.target as HTMLSelectElement).value = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBadgeRemove(flag: number) {
|
function onBadgeRemove(flag: number) {
|
||||||
reactiveValue &= ~flag;
|
value &= ~flag;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -31,20 +28,22 @@
|
|||||||
<select class="select select-xs w-min" onchange={onOptionSelect}>
|
<select class="select select-xs w-min" onchange={onOptionSelect}>
|
||||||
<option selected hidden>-</option>
|
<option selected hidden>-</option>
|
||||||
{#each Object.entries(available) as [flag, badge] (flag)}
|
{#each Object.entries(available) as [flag, badge] (flag)}
|
||||||
<option value={flag} hidden={(reactiveValue & Number(flag)) !== 0}>{badge}</option>
|
<option value={flag} hidden={(value & Number(flag)) !== 0}>{badge}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex flow flex-wrap gap-2">
|
<div class="flex flow flex-wrap gap-2">
|
||||||
{#each Object.entries(available) as [flag, badge] (flag)}
|
{#key value}
|
||||||
{#if (reactiveValue & Number(flag)) !== 0}
|
{#each Object.entries(available) as [flag, badge] (flag)}
|
||||||
<div class="badge badge-outline gap-1">
|
{#if (value & Number(flag)) !== 0}
|
||||||
{#if !readonly}
|
<div class="badge badge-outline gap-1">
|
||||||
<button class="cursor-pointer" type="button" onclick={() => onBadgeRemove(Number(flag))}>✕</button>
|
{#if !readonly}
|
||||||
{/if}
|
<button class="cursor-pointer" type="button" onclick={() => onBadgeRemove(Number(flag))}>✕</button>
|
||||||
<span>{badge}</span>
|
{/if}
|
||||||
</div>
|
<span>{badge}</span>
|
||||||
{/if}
|
</div>
|
||||||
{/each}
|
{/if}
|
||||||
|
{/each}
|
||||||
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,7 +6,7 @@ import { Session } from '@util/session.ts';
|
|||||||
import { Permissions } from '@util/permissions.ts';
|
import { Permissions } from '@util/permissions.ts';
|
||||||
import { BASE_PATH } from 'astro:env/server';
|
import { BASE_PATH } from 'astro:env/server';
|
||||||
|
|
||||||
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Admin);
|
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Users);
|
||||||
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { Session } from '@util/session.ts';
|
|||||||
import { Permissions } from '@util/permissions.ts';
|
import { Permissions } from '@util/permissions.ts';
|
||||||
import { BASE_PATH } from 'astro:env/server';
|
import { BASE_PATH } from 'astro:env/server';
|
||||||
|
|
||||||
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Admin);
|
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Users);
|
||||||
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { Session } from '@util/session.ts';
|
|||||||
import { Permissions } from '@util/permissions.ts';
|
import { Permissions } from '@util/permissions.ts';
|
||||||
import { BASE_PATH } from 'astro:env/server';
|
import { BASE_PATH } from 'astro:env/server';
|
||||||
|
|
||||||
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Admin);
|
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Users);
|
||||||
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user