feat: add skeleton loaders for match details page
This commit is contained in:
@@ -0,0 +1,79 @@
|
|||||||
|
import { For } from "solid-js";
|
||||||
|
|
||||||
|
export function MatchDetailsFutureSkeleton() {
|
||||||
|
return (
|
||||||
|
<div class="animate-pulse">
|
||||||
|
<div class="bg-gradient-to-b from-gray-800 to-gray-850 p-6 border-b border-gray-800 text-center">
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-24 mx-auto mb-4 animate-skeleton-loop" />
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between gap-4 my-2">
|
||||||
|
<div class="flex-1 flex flex-col items-center gap-2 min-w-0">
|
||||||
|
<div
|
||||||
|
class="size-14 bg-gray-700 rounded-full animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "0ms" }}
|
||||||
|
/>
|
||||||
|
<div class="h-3 bg-gray-700 rounded w-20" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col items-center justify-center px-4 py-2 bg-gray-950/50 rounded-2xl border border-gray-800 min-w-[100px] gap-1.5">
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-14" />
|
||||||
|
<div class="h-5 bg-gray-700 rounded w-12" />
|
||||||
|
<div class="h-2 bg-gray-700 rounded w-6" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-1 flex flex-col items-center gap-2 min-w-0">
|
||||||
|
<div
|
||||||
|
class="size-14 bg-gray-700 rounded-full animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "80ms" }}
|
||||||
|
/>
|
||||||
|
<div class="h-3 bg-gray-700 rounded w-20" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-32 mx-auto mt-4" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 space-y-6">
|
||||||
|
<div class="bg-gray-800/50 rounded-2xl p-4 border border-gray-800 animate-skeleton-loop">
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-40 mx-auto mb-3" />
|
||||||
|
<div class="h-3.5 w-full rounded-full bg-gray-900 border border-gray-750" />
|
||||||
|
<div class="flex justify-between items-center mt-2.5">
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-14" />
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-14" />
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-14" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bg-gray-800/50 rounded-2xl p-4 border border-gray-800 h-32 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "120ms" }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bg-gray-800/50 rounded-2xl p-4 border border-gray-800 space-y-4 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "240ms" }}
|
||||||
|
>
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-32 mx-auto" />
|
||||||
|
<div class="flex items-center justify-between gap-2 px-2">
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<For each={[0, 1, 2, 3, 4]}>
|
||||||
|
{() => <div class="size-6 bg-gray-700 rounded-full" />}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-8" />
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<For each={[0, 1, 2, 3, 4]}>
|
||||||
|
{() => <div class="size-6 bg-gray-700 rounded-full" />}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bg-gray-800/50 rounded-2xl p-4 border border-gray-800 h-40 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "360ms" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { For } from "solid-js";
|
||||||
|
|
||||||
|
export function MatchDetailsGenericSkeleton() {
|
||||||
|
return (
|
||||||
|
<div class="animate-pulse">
|
||||||
|
<div class="bg-gradient-to-b from-gray-800 to-gray-850 p-6 border-b border-gray-800 flex items-center justify-center gap-4">
|
||||||
|
<div
|
||||||
|
class="size-10 bg-gray-700 rounded-full animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "0ms" }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="w-14 h-7 bg-gray-950/60 rounded-lg border border-gray-700/50 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "100ms" }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="size-10 bg-gray-700 rounded-full animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "50ms" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 space-y-3">
|
||||||
|
<For each={[0, 1, 2]}>
|
||||||
|
{(i) => (
|
||||||
|
<div
|
||||||
|
class="bg-gray-800/40 rounded-2xl h-16 border border-gray-800 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": `${i * 150}ms` }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { For } from "solid-js";
|
||||||
|
|
||||||
|
export function MatchDetailsSkeleton() {
|
||||||
|
return (
|
||||||
|
<div class="animate-pulse">
|
||||||
|
<div class="bg-gradient-to-b from-gray-800 to-gray-850 w-full py-5.5 px-10 border-b border-gray-800">
|
||||||
|
<div class="flex items-center justify-between gap-2">
|
||||||
|
<div class="flex-1 flex items-center gap-2 justify-end">
|
||||||
|
<div
|
||||||
|
class="h-3 bg-gray-700 rounded w-16 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "0ms" }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="size-8 bg-gray-700 rounded-full animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "50ms" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="w-16 min-w-16 h-7 bg-gray-950/60 rounded-lg border border-gray-700/50 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "100ms" }}
|
||||||
|
/>
|
||||||
|
<div class="flex-1 flex items-center gap-2 justify-start">
|
||||||
|
<div
|
||||||
|
class="size-8 bg-gray-700 rounded-full animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "50ms" }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="h-3 bg-gray-700 rounded w-16 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": "0ms" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 space-y-3">
|
||||||
|
<For each={[0, 1, 2, 3]}>
|
||||||
|
{(i) => (
|
||||||
|
<div
|
||||||
|
class="bg-gray-800/40 rounded-2xl p-3 border border-gray-800 animate-skeleton-loop"
|
||||||
|
style={{ "--delay": `${i * 120}ms` }}
|
||||||
|
>
|
||||||
|
<div class="flex justify-center mb-2">
|
||||||
|
<div class="h-2.5 bg-gray-700 rounded w-14" />
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="flex-1 flex flex-col gap-2">
|
||||||
|
<div class="flex items-center gap-2 justify-end">
|
||||||
|
<div class="h-3 bg-gray-700 rounded w-16" />
|
||||||
|
<div class="size-8 bg-gray-700 rounded-full" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-8 h-6 bg-gray-950/60 rounded border border-gray-700/50 flex-shrink-0" />
|
||||||
|
<div class="flex-1 flex flex-col gap-2">
|
||||||
|
<div class="flex items-center gap-2 justify-start">
|
||||||
|
<div class="size-8 bg-gray-700 rounded-full" />
|
||||||
|
<div class="h-3 bg-gray-700 rounded w-16" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
import { onMount } from "solid-js";
|
import { createSignal, onMount } from "solid-js";
|
||||||
import { Header } from "../components/Header";
|
import { Header } from "../components/Header";
|
||||||
import { useParams } from "@solidjs/router";
|
import { useParams } from "@solidjs/router";
|
||||||
import { matchStore, loadMatch } from "../stores/matchStore";
|
import { matchStore, loadMatch } from "../stores/matchStore";
|
||||||
import { MatchItem } from "../components/MatchItem";
|
import { MatchItem } from "../components/MatchItem";
|
||||||
import { MatchInsights } from "../components/MatchInsights";
|
import { MatchInsights } from "../components/MatchInsights";
|
||||||
import { ResultTile } from "../components/ResultTile";
|
import { ResultTile } from "../components/ResultTile";
|
||||||
|
import { MatchDetailsSkeleton } from "../components/MatchDetailsSkeleton";
|
||||||
|
import { MatchDetailsFutureSkeleton } from "../components/MatchDetailsFutureSkeleton";
|
||||||
|
import { MatchDetailsGenericSkeleton } from "../components/MatchDetailsGenericSkeleton";
|
||||||
export function MatchPage() {
|
export function MatchPage() {
|
||||||
// const { id } = useParams();
|
// const { id } = useParams();
|
||||||
const id = window.location.pathname.split("/").pop();
|
const id = window.location.pathname.split("/").pop();
|
||||||
const match = () => matchStore.matches.find((m) => m.id === id);
|
const match = () => matchStore.matches.find((m) => m.id === id);
|
||||||
|
const [isLoading, setIsLoading] = createSignal(true);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(async () => {
|
||||||
loadMatch(id);
|
await loadMatch(id);
|
||||||
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -41,12 +46,24 @@ export function MatchPage() {
|
|||||||
</button>
|
</button>
|
||||||
<div class="bg-gray-900">
|
<div class="bg-gray-900">
|
||||||
{/* <Header title={""} showBackButton /> */}
|
{/* <Header title={""} showBackButton /> */}
|
||||||
{match() && match().status !== "SCHEDULED" && (
|
<Show when={match()} fallback={<MatchDetailsGenericSkeleton />}>
|
||||||
|
<Show when={match().status !== "SCHEDULED"}>
|
||||||
|
<Show
|
||||||
|
when={!isLoading()}
|
||||||
|
fallback={<MatchDetailsSkeleton />}
|
||||||
|
>
|
||||||
<MatchDetails match={match()} />
|
<MatchDetails match={match()} />
|
||||||
)}
|
</Show>
|
||||||
{match() && match().status === "SCHEDULED" && (
|
</Show>
|
||||||
|
<Show when={match().status === "SCHEDULED"}>
|
||||||
|
<Show
|
||||||
|
when={!isLoading()}
|
||||||
|
fallback={<MatchDetailsFutureSkeleton />}
|
||||||
|
>
|
||||||
<MatchDetailsFuture match={match()} />
|
<MatchDetailsFuture match={match()} />
|
||||||
)}
|
</Show>
|
||||||
|
</Show>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user