import { repertoireCache } from "@/cache"; import { client } from "@/client"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { useCache } from "@/hooks/useCache"; import { useLoading } from "@/hooks/useLoading"; import { created, DEBOUNCE, modified } from "@/snippets"; import { RepertoireId } from "common"; import { Cause, Effect, Match, Option, Scope } from "effect"; import { Loader2, Plus } from "lucide-react"; import { FormEventHandler, ReactNode, useId, useRef, useState } from "react"; import { Link, useNavigate } from "react-router-dom"; export function Repertoires() { const [name, setName] = useState(""); const debounce = useRef(Effect.void); const { isLoading, error, data: repertoireIds } = useLoading(Effect.gen(function* () { yield* debounce.current; const data = yield* client.queryRepertoires({ name: name !== "" ? Option.some(name) : Option.none(), offset: 0, limit: 100, }); return data; }), [name]); return (
{ setName(e.target.value); debounce.current = DEBOUNCE; }} />
Nazwa Utwory Dodano Zmodyfikowano {isLoading ? (
Ładowanie…
) : error !== null ? ( {Cause.isUnknownException(error) ? "Wystąpił nieznany błąd" : `Wystąpił błąd: ${JSON.stringify(error)}`} ) : ( repertoireIds.map((repertoireId) => ) )}
); } namespace RepertoireRow { export interface Props { readonly repertoireId: RepertoireId; } } function RepertoireRow(props: RepertoireRow.Props) { const { isLoading, error, data: repertoire } = useCache(repertoireCache, props.repertoireId); if (isLoading) { return ( Ładowanie… ); } if (error !== null) { return ( Wystąpił błąd: {Match.value(error).pipe( Match.tag("FetchError", () => "Nie można połączyć się z serwerem"), Match.tag("NotFound", () => "Repertuar nie istnieje"), Match.tag("Unauthenticated", () => "Zaloguj się, aby kontynuować"), Match.tag("Unauthorized", () => "Nie posiadasz uprawnień"), Match.exhaustive, )} ); } const piecesParts: ReactNode[] = []; if (repertoire.entries.length === 0) { piecesParts.push(Brak); } else { const CUTOFF = 10; let text = repertoire.entries.slice(0, CUTOFF).map(({ name }) => name).join(", "); if (repertoire.entries.length > CUTOFF) { text += ", …"; } piecesParts.push(text); } return ( {repertoire.name} {...piecesParts} {created(repertoire)} {modified(repertoire)} ); } function AddRepertoireDialogContent() { const navigate = useNavigate(); const [name, setName] = useState(""); const nameId = useId(); const [isLoading, setIsLoading] = useState(false); const onSubmit: FormEventHandler = (e) => Effect.gen(function* () { e.preventDefault(); yield* Effect.scopedWith((scope) => Effect.gen(function* () { yield* Scope.addFinalizer(scope, Effect.sync(() => setIsLoading(false))); setIsLoading(true); const { repertoireId } = yield* client.createRepertoire({ name, entries: [], }); navigate(repertoireId); })); }).pipe(Effect.runPromise); return (
Utwórz repertuar
setName(e.target.value)} />
); }