improve web ui

This commit is contained in:
2026-06-26 05:43:34 +00:00
parent 00cf51d610
commit 803573b4ec
73 changed files with 3373 additions and 2847 deletions
+47 -37
View File
@@ -1,43 +1,53 @@
import type { ReactNode } from 'react'
import { ApiError } from '@/api/fetcher'
import { Spinner } from '@/components/ui/spinner'
import { Button } from '@/components/ui/button'
import { m } from '@/paraglide/messages'
import type { ReactNode } from "react";
import { ApiError } from "@/api/fetcher";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { m } from "@/paraglide/messages";
interface QueryStateProps {
isLoading: boolean
error: unknown
refetch?: () => void
children: ReactNode
isLoading: boolean;
error: unknown;
refetch?: () => void;
children: ReactNode;
}
/** Uniform loading/error wrapper for a query-backed view. */
export function QueryState({ isLoading, error, refetch, children }: QueryStateProps) {
if (isLoading) {
return (
<div
role="status"
className="flex min-h-40 flex-col items-center justify-center gap-3 text-sm text-muted-foreground"
>
<Spinner className="size-8" />
{m.common_loading()}
</div>
)
}
if (error) {
const unauthorized = error instanceof ApiError && error.status === 401
return (
<div className="rounded-lg border border-destructive/40 bg-destructive/5 p-4 text-sm">
<p className="font-medium text-destructive">
{unauthorized ? m.common_unauthorized() : m.common_error()}
</p>
{refetch && !unauthorized && (
<Button variant="outline" size="sm" className="mt-3" onClick={() => refetch()}>
{m.common_retry()}
</Button>
)}
</div>
)
}
return <>{children}</>
export function QueryState({
isLoading,
error,
refetch,
children,
}: QueryStateProps) {
if (isLoading) {
return (
<div
role="status"
className="flex min-h-40 flex-col items-center justify-center gap-3 text-sm text-muted-foreground"
>
<Spinner className="size-8" />
{m.common_loading()}
</div>
);
}
if (error) {
const unauthorized = error instanceof ApiError && error.status === 401;
return (
<div className="rounded-lg border border-destructive/40 bg-destructive/5 p-4 text-sm">
<p className="font-medium text-destructive">
{unauthorized ? m.common_unauthorized() : m.common_error()}
</p>
{refetch && !unauthorized && (
<Button
variant="outline"
size="sm"
className="mt-3"
onClick={() => refetch()}
>
{m.common_retry()}
</Button>
)}
</div>
);
}
return <>{children}</>;
}