Compare commits
17 Commits
c939fb80d3
...
6a49c361a0
Author | SHA1 | Date | |
---|---|---|---|
6a49c361a0 | |||
0a947d8bdd | |||
403d82adba | |||
008fc75f7b | |||
2a20947f59 | |||
5b3f9f4d88 | |||
4fab4dbfb8 | |||
162638eb0b | |||
95e42a9df2 | |||
090b541056 | |||
ba15468eba | |||
86c620cafc | |||
26103814ac | |||
827b7ef98a | |||
745b860b0e | |||
533d7c52a4 | |||
9cd64e43b2 |
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "chuni-national-matchmaking-webui",
|
"name": "yukiotoko",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<title>yukiotoko</title>
|
<title>yukiotoko</title>
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover" class="bg-dark text-light">
|
<body data-sveltekit-preload-data="hover" class="bg-dark text-text">
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
<div style="display: contents">%sveltekit.body%</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
let { rank, ...rest }: { rank: number } & HTMLAttributes<HTMLDivElement> = $props();
|
let { rank, ...rest }: { rank: number } & HTMLAttributes<HTMLDivElement> = $props();
|
||||||
|
|
||||||
const [xOffset, yOffset] = imageOffset(rank);
|
const [xOffset, yOffset] = $derived(imageOffset(rank));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div {...rest}>
|
<div {...rest}>
|
||||||
|
@ -1,16 +1,31 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
const { date }: { date: Date } = $props();
|
let { date }: { date: Date } = $props();
|
||||||
const difference = new Date().getTime() / 1000 - date.getTime() / 1000;
|
|
||||||
const seconds = ~~(difference % 60);
|
let currentDate = $state(Date.now());
|
||||||
const minutes = ~~(difference / 60) % 60;
|
let difference = $derived(currentDate / 1000 - date.getTime() / 1000);
|
||||||
const hours = ~~(difference / 3600) % 24;
|
let seconds = $derived(~~(difference % 60));
|
||||||
const days = ~~(difference / 86400);
|
let minutes = $derived(~~(difference / 60) % 60);
|
||||||
|
let hours = $derived(~~(difference / 3600) % 24);
|
||||||
|
let days = $derived(~~(difference / 86400));
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
currentDate = Date.now();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<p class="group underline">
|
<span class="group text-light underline">
|
||||||
<span class="group-hover:hidden">
|
<span class="group-hover:hidden">
|
||||||
about
|
about
|
||||||
{#if minutes == 0}
|
{#if days > 0}
|
||||||
|
<span>{days}d</span>
|
||||||
|
{:else if hours > 0}
|
||||||
|
<span>{hours}h</span>
|
||||||
|
{:else if minutes > 0}
|
||||||
|
<span>{minutes}m</span>
|
||||||
|
{:else}
|
||||||
|
<span>{seconds}s</span>
|
||||||
|
{/if}
|
||||||
|
<!-- {#if minutes == 0}
|
||||||
<span>{seconds}s</span>
|
<span>{seconds}s</span>
|
||||||
{:else if hours == 0}
|
{:else if hours == 0}
|
||||||
<span>{minutes}m</span>
|
<span>{minutes}m</span>
|
||||||
@ -18,10 +33,10 @@
|
|||||||
<span>{hours}h</span>
|
<span>{hours}h</span>
|
||||||
{:else}
|
{:else}
|
||||||
<span>{days}d</span>
|
<span>{days}d</span>
|
||||||
{/if}
|
{/if} -->
|
||||||
ago
|
ago
|
||||||
</span>
|
</span>
|
||||||
<span class="hidden group-hover:block">
|
<span class="hidden group-hover:block">
|
||||||
{date.toLocaleString()}
|
{date.toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</span>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<footer class="bg-medium">
|
<footer class="bg-medium text-light">
|
||||||
<div class="mx-auto flex w-full max-w-screen-xl flex-col p-4 md:flex-row md:justify-between">
|
<div class="mx-auto flex w-full max-w-screen-xl flex-col p-4 md:flex-row md:justify-between">
|
||||||
<p>
|
<p>
|
||||||
made with <a href="https://svelte.dev/">sveltekit</a>, powered by
|
made with <a href="https://svelte.dev/">sveltekit</a>, powered by
|
||||||
@ -6,8 +6,8 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
you can find the repo of the website <a href="https://tea.metatable.sh/meta/yukiotoko-webui"
|
wana help out, or issue a bug? you can find the repo <a
|
||||||
>here</a
|
href="https://tea.metatable.sh/meta/yukiotoko-webui">here</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
let { version, ...rest }: { version: string } & HTMLAttributes<HTMLImageElement> = $props();
|
let { version, ...rest }: { version: string } & HTMLAttributes<HTMLImageElement> = $props();
|
||||||
|
|
||||||
const { minor } = fromVersionString(version);
|
const { minor } = $derived(fromVersionString(version));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<img src="/versions/{gameVersions[minor.toString()]}" alt={version} {...rest} />
|
<img src="/versions/{gameVersions[minor.toString()]}" alt={version} {...rest} />
|
||||||
|
40
src/lib/Pagination.svelte
Normal file
40
src/lib/Pagination.svelte
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<script lang="ts" generics="T">
|
||||||
|
let {
|
||||||
|
items,
|
||||||
|
itemsPerPage,
|
||||||
|
pageItems = $bindable()
|
||||||
|
}: { items: Array<T>; itemsPerPage: number; pageItems: Array<T> } = $props();
|
||||||
|
|
||||||
|
let currentPage = $state(0);
|
||||||
|
let pageIndexStart = $derived(currentPage * itemsPerPage);
|
||||||
|
let pageIndexEnd = $derived(Math.min(itemsPerPage * (currentPage + 1), items.length));
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
currentPage = Math.min(Math.max(currentPage, 0), ~~(items.length / itemsPerPage));
|
||||||
|
pageItems = items.slice(pageIndexStart, pageIndexEnd);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p>
|
||||||
|
showing <span class="font-bold text-light">{pageIndexStart + 1}</span> to
|
||||||
|
<span class="font-bold text-light">{pageIndexEnd}</span>
|
||||||
|
of <span class="font-bold text-light">{items.length}</span>
|
||||||
|
entires
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="flex divide-x divide-border">
|
||||||
|
<button class="rounded-bl-lg rounded-tl-lg text-light" onclick={() => currentPage--}
|
||||||
|
>prev</button
|
||||||
|
>
|
||||||
|
<button class="rounded-br-lg rounded-tr-lg text-light" onclick={() => currentPage++}
|
||||||
|
>next</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
button {
|
||||||
|
@apply bg-medium px-4 py-2 transition hover:brightness-150;
|
||||||
|
}
|
||||||
|
</style>
|
@ -9,13 +9,11 @@
|
|||||||
|
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<p>{player.name}</p>
|
<p class="font-bold text-light">{player.name}</p>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<Rating rating={player.rating} />
|
<Rating rating={player.rating} />
|
||||||
<BattleRank rank={player.battleRank} class="w-16" />
|
<BattleRank rank={player.battleRank} class="w-16" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if player.team}
|
<Team team={player?.team ?? { name: 'No Team', rank: 0 }} />
|
||||||
<Team team={player.team} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
let { rating }: { rating: number } = $props();
|
let { rating }: { rating: number } = $props();
|
||||||
|
|
||||||
const characters = rating.toString().padStart(4, '0');
|
const characters = $derived(rating.toString().padStart(4, '0'));
|
||||||
const type = ratingType(rating);
|
const type = $derived(ratingType(rating));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
...rest
|
...rest
|
||||||
}: { character: number | '.'; type: number } & HTMLAttributes<HTMLDivElement> = $props();
|
}: { character: number | '.'; type: number } & HTMLAttributes<HTMLDivElement> = $props();
|
||||||
|
|
||||||
const [xOffset, yOffset] = imageOffset(character, type);
|
const [xOffset, yOffset] = $derived(imageOffset(character, type));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div {...rest}>
|
<div {...rest}>
|
||||||
|
@ -1,20 +1,44 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { User, Calendar } from 'lucide-svelte';
|
import { User, Calendar } from 'lucide-svelte';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
import Player from './Player.svelte';
|
import Player from './Player.svelte';
|
||||||
import BattleRank from './BattleRank.svelte';
|
import BattleRank from './BattleRank.svelte';
|
||||||
import GameVersion from './GameVersion.svelte';
|
import GameVersion from './GameVersion.svelte';
|
||||||
import Separator from './Separator.svelte';
|
import Separator from './Separator.svelte';
|
||||||
import type { Room } from './types';
|
|
||||||
import Date from './Date.svelte';
|
import Date from './Date.svelte';
|
||||||
|
import axios from 'axios';
|
||||||
|
import type { Room } from './types';
|
||||||
|
|
||||||
let { room }: { room: Room } = $props();
|
let { room }: { room: Room } = $props();
|
||||||
|
|
||||||
let secondsRemaining = $state(room.secondsRemaining);
|
let roomTimer = $state(room.secondsRemaining);
|
||||||
|
let players = $state(room.players);
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
onMount(() => {
|
||||||
if (secondsRemaining <= 0 || room.finished) clearInterval(interval);
|
if (!room.finished) {
|
||||||
secondsRemaining--;
|
const roomTimerUpdateInterval = setInterval(() => {
|
||||||
|
if (roomTimer <= 0) {
|
||||||
|
roomTimer = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
roomTimer--;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
const roomTimerSyncInterval = setInterval(async () => {
|
||||||
|
console.log('updating');
|
||||||
|
const updatedRoom = await axios
|
||||||
|
.get<Room>(`/api/room/${room.roomId}`)
|
||||||
|
.then((result) => result.data);
|
||||||
|
roomTimer = updatedRoom.secondsRemaining;
|
||||||
|
players = updatedRoom.players;
|
||||||
|
if (updatedRoom.finished) {
|
||||||
|
console.log('killing invervals');
|
||||||
|
clearInterval(roomTimerUpdateInterval);
|
||||||
|
clearInterval(roomTimerSyncInterval);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col gap-8 rounded-lg bg-medium p-6">
|
<div class="flex flex-col gap-8 rounded-lg bg-medium p-6">
|
||||||
@ -27,19 +51,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<p class="flex items-center gap-2 text-sub">game version <Separator /> {room.gameVersion}</p>
|
<p class="flex items-center gap-2">game version <Separator /> {room.gameVersion}</p>
|
||||||
<p class="flex items-center gap-2 text-sub">
|
<p class="flex items-center gap-2">
|
||||||
room battle rank <Separator />
|
room battle rank <Separator />
|
||||||
{room.roomBattleRank}
|
{room.roomBattleRank}
|
||||||
</p>
|
</p>
|
||||||
{#if !room.finished}
|
{#if !room.finished}
|
||||||
<p class="flex items-center gap-2">seconds remaining <Separator /> {secondsRemaining}s</p>
|
<p class="flex items-center gap-2">seconds remaining <Separator /> {roomTimer}s</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<p class="flex items-center gap-2">
|
<p class="flex items-center gap-2 text-light">
|
||||||
<User class="inline-block w-6" />
|
<User class="inline-block w-6" />
|
||||||
{room.players.length} / 4
|
{room.players.length} / 4
|
||||||
<Separator />
|
<Separator />
|
||||||
@ -48,7 +72,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:grid-rows-2">
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:grid-rows-2">
|
||||||
{#each room.players as player}
|
{#each players as player}
|
||||||
<Player {player} />
|
<Player {player} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,3 +1 @@
|
|||||||
<span class="inline-block"
|
<span class="inline-block h-[2px] w-4 rounded-full bg-current brightness-50"></span>
|
||||||
><div class="h-[2px] w-4 rounded-full bg-current brightness-50"></div></span
|
|
||||||
>
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
? 'team-second'
|
? 'team-second'
|
||||||
: team.rank == 3
|
: team.rank == 3
|
||||||
? 'team-third'
|
? 'team-third'
|
||||||
: ''}"
|
: 'text-light'}"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
{team.name}
|
{team.name}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
export function arrayPadEnd<T>(array: T[], amount: number, data: T) {
|
export function arrayPadEnd<T>(array: T[], amount: number, data: T) {
|
||||||
for (let i = 0; i < amount - array.length; i++) array.push(data);
|
if (amount > array.length) {
|
||||||
|
array.push(...Array(amount - array.length).fill(data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ function toPlayer(apiPlayer: APIPlayer): Player {
|
|||||||
|
|
||||||
function toRoom(apiRoom: APIRoom): Room {
|
function toRoom(apiRoom: APIRoom): Room {
|
||||||
return {
|
return {
|
||||||
id: apiRoom.id,
|
|
||||||
roomId: apiRoom.roomId,
|
roomId: apiRoom.roomId,
|
||||||
createdAt: new Date(apiRoom.updatedAt),
|
createdAt: new Date(apiRoom.updatedAt),
|
||||||
gameVersion: apiRoom.dataVersion,
|
gameVersion: apiRoom.dataVersion,
|
||||||
@ -31,10 +30,12 @@ function toRoom(apiRoom: APIRoom): Room {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validRoom(room: Room): boolean {
|
||||||
|
return !greaterThan(fromVersionString(room.gameVersion), fromVersionString(env.MAX_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
function filterRooms(rooms: Room[]): Room[] {
|
function filterRooms(rooms: Room[]): Room[] {
|
||||||
return rooms.filter(
|
return rooms.filter((room) => validRoom(room));
|
||||||
(room) => !greaterThan(fromVersionString(room.gameVersion), fromVersionString(env.MAX_VERSION))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRooms() {
|
export async function fetchRooms() {
|
||||||
@ -56,7 +57,20 @@ export async function fetchRooms() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO!
|
export async function fetchRoom(roomId: number | string): Promise<Room | undefined> {
|
||||||
// export async function fetchRoom(roomId: string): Promise<Room> {
|
const result = await axios.get<APIRoom[]>(`http://yukiotoko.chara.lol:9000/api/get/${roomId}`, {
|
||||||
// return new Promise()
|
headers: {
|
||||||
// }
|
Authorization: env.YUKIOTOKO_API_TOKEN
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const apiRoom = result.data[0];
|
||||||
|
|
||||||
|
if (!apiRoom) return;
|
||||||
|
|
||||||
|
const room = toRoom(apiRoom);
|
||||||
|
|
||||||
|
if (!validRoom(room)) return;
|
||||||
|
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
@ -56,7 +56,6 @@ export interface APIPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Room {
|
export interface Room {
|
||||||
id: string;
|
|
||||||
roomId: number;
|
roomId: number;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
gameVersion: string;
|
gameVersion: string;
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
import type { PageServerLoad } from './$types';
|
|
||||||
import { fetchRooms } from '$lib/server/yukiotoko';
|
import { fetchRooms } from '$lib/server/yukiotoko';
|
||||||
|
import { arrayPadEnd } from '$lib/array';
|
||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ fetch }) => {
|
export const load: PageServerLoad = async ({ fetch }) => {
|
||||||
return await fetchRooms();
|
const { activeRooms, archivedRooms } = await fetchRooms();
|
||||||
|
|
||||||
|
archivedRooms.forEach((archivedRoom) =>
|
||||||
|
arrayPadEnd(archivedRoom.players, 4, {
|
||||||
|
name: 'CPU',
|
||||||
|
battleRank: 0,
|
||||||
|
rating: 0
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
activeRooms,
|
||||||
|
archivedRooms
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,25 +1,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { arrayPadEnd } from '$lib/array';
|
import Pagination from '$lib/Pagination.svelte';
|
||||||
import Room from '$lib/Room.svelte';
|
import Room from '$lib/Room.svelte';
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
|
||||||
let props: { data: PageData } = $props();
|
let { data }: { data: PageData } = $props();
|
||||||
|
let { activeRooms, archivedRooms } = data;
|
||||||
|
|
||||||
let data = $state(props.data);
|
let paginationArchivedRooms = $state([]);
|
||||||
|
|
||||||
data.archivedRooms.forEach((archivedRoom) =>
|
|
||||||
arrayPadEnd(archivedRoom.players, 4, {
|
|
||||||
name: 'CPU',
|
|
||||||
battleRank: 0,
|
|
||||||
rating: 0
|
|
||||||
})
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mb-16 space-y-8">
|
<div class="mb-8 space-y-8">
|
||||||
<section>
|
<section>
|
||||||
<h1 class="text-4xl font-bold">yukiotoko webui</h1>
|
<h1 class="text-4xl font-bold text-light">yukiotoko webui</h1>
|
||||||
<p>a frontend redesign for <a href="http://yukiotoko.chara.lol/">yukiotoko</a></p>
|
<p>
|
||||||
|
a frontend redesign for <a href="http://yukiotoko.chara.lol/">yukiotoko</a> made by metamethods
|
||||||
|
</p>
|
||||||
<p class="text-sub">refresh the page to fetch newer yukiotoko data</p>
|
<p class="text-sub">refresh the page to fetch newer yukiotoko data</p>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
@ -27,14 +22,14 @@
|
|||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-8">
|
||||||
<section class="flex flex-col gap-4">
|
<section class="flex flex-col gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-2xl font-bold">
|
<h1 class="text-2xl font-bold text-light">
|
||||||
active rooms <span class="text-sub">({data.activeRooms.length})</span>
|
active rooms <span class="text-sub">({activeRooms.length})</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-sub">all of the currently matchmaking rooms</p>
|
<p class="text-sub">all of the currently matchmaking rooms</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
||||||
{#each data.activeRooms as activeRoom}
|
{#each activeRooms as activeRoom}
|
||||||
<Room room={activeRoom} />
|
<Room room={activeRoom} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@ -42,14 +37,16 @@
|
|||||||
|
|
||||||
<section class="flex flex-col gap-4">
|
<section class="flex flex-col gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-2xl font-bold">
|
<h1 class="text-2xl font-bold text-light">
|
||||||
archived rooms <span class="text-sub">({data.archivedRooms.length})</span>
|
archived rooms <span class="text-sub">({data.archivedRooms.length})</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-sub">rooms that were created from the last 24 hours</p>
|
<p class="text-sub">rooms that were created from the last 24 hours</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Pagination items={archivedRooms} itemsPerPage={20} bind:pageItems={paginationArchivedRooms} />
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
||||||
{#each data.archivedRooms as archivedRoom}
|
{#each paginationArchivedRooms as archivedRoom}
|
||||||
<Room room={archivedRoom} />
|
<Room room={archivedRoom} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
10
src/routes/api/room/[roomId]/+server.ts
Normal file
10
src/routes/api/room/[roomId]/+server.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { fetchRoom } from '$lib/server/yukiotoko';
|
||||||
|
import { error, json } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export async function GET({ params }) {
|
||||||
|
const room = await fetchRoom(params.roomId);
|
||||||
|
|
||||||
|
if (!room) return error(404);
|
||||||
|
|
||||||
|
return json(room);
|
||||||
|
}
|
@ -7,11 +7,12 @@ export default {
|
|||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
dark: '#060710',
|
dark: '#111117',
|
||||||
medium: '#0A0B17',
|
medium: '#1F2128',
|
||||||
light: '#CFD3FA',
|
light: '#CFD3FA',
|
||||||
sub: '#4D4D80',
|
text: '#9B9FC0',
|
||||||
accent: '#7E61FF'
|
accent: '#8D74FF',
|
||||||
|
border: '#353741'
|
||||||
},
|
},
|
||||||
|
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
|
Loading…
Reference in New Issue
Block a user