56 lines
1.2 KiB
TypeScript
56 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import { AlertCircle, Check, Loader2 } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import type { AutoSaveStatus } from "@/hooks/use-debounced-autosave";
|
|
|
|
export function SaveStatusIndicator({
|
|
status,
|
|
error,
|
|
onRetry,
|
|
fallbackError = "Could not save.",
|
|
}: {
|
|
status: AutoSaveStatus;
|
|
error: string | null;
|
|
onRetry: () => Promise<void>;
|
|
fallbackError?: string;
|
|
}) {
|
|
if (status === "clean") return null;
|
|
|
|
return (
|
|
<span
|
|
className="flex items-center gap-1.5 text-xs text-muted-foreground"
|
|
aria-live="polite"
|
|
>
|
|
{status === "dirty" && "Unsaved"}
|
|
{status === "saving" && (
|
|
<>
|
|
<Loader2 className="animate-spin" />
|
|
Saving
|
|
</>
|
|
)}
|
|
{status === "saved" && (
|
|
<>
|
|
<Check />
|
|
Saved
|
|
</>
|
|
)}
|
|
{status === "error" && (
|
|
<>
|
|
<AlertCircle />
|
|
<span>{error || fallbackError}</span>
|
|
<Button
|
|
type="button"
|
|
variant="link"
|
|
size="sm"
|
|
className="h-auto px-1"
|
|
onClick={() => void onRetry().catch(() => undefined)}
|
|
>
|
|
Retry
|
|
</Button>
|
|
</>
|
|
)}
|
|
</span>
|
|
);
|
|
}
|