46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
"use client";
|
|
|
|
import { type ReactNode, useEffect } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
import type { CharacterProfile } from "@/data/constants/character";
|
|
import { getCharacterRoutes } from "@/router/routes";
|
|
|
|
import { useCharacterCatalog } from "./character-catalog-provider";
|
|
import { CharacterProvider } from "./character-provider";
|
|
|
|
export function CharacterRouteBoundary({
|
|
character,
|
|
children,
|
|
}: {
|
|
character: CharacterProfile;
|
|
children: ReactNode;
|
|
}) {
|
|
const catalog = useCharacterCatalog();
|
|
const router = useRouter();
|
|
const activeCharacter = catalog.getById(character.id);
|
|
|
|
useEffect(() => {
|
|
if (catalog.status === "loading" || activeCharacter) return;
|
|
router.replace(getCharacterRoutes(catalog.defaultCharacter.slug).splash);
|
|
}, [activeCharacter, catalog.defaultCharacter.slug, catalog.status, router]);
|
|
|
|
if (catalog.status === "loading" || !activeCharacter) {
|
|
return (
|
|
<div
|
|
className="flex min-h-dvh flex-1 items-center justify-center bg-[#fbf1f2]"
|
|
aria-label="Loading character"
|
|
role="status"
|
|
>
|
|
<div className="size-9 animate-spin rounded-full border-4 border-[#f657a0] border-t-transparent" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<CharacterProvider character={activeCharacter}>
|
|
{children}
|
|
</CharacterProvider>
|
|
);
|
|
}
|