BillTracker/client/components/ui/save-status.jsx

39 lines
1.4 KiB
React
Raw Normal View History

import { AnimatePresence, motion } from 'framer-motion';
import { Check, CloudUpload, AlertCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
const STATES = {
saving: { icon: CloudUpload, text: 'Saving…', cls: 'text-muted-foreground border-border/70 bg-muted/40' },
saved: { icon: Check, text: 'Saved', cls: 'text-emerald-600 dark:text-emerald-300 border-emerald-500/30 bg-emerald-500/10' },
error: { icon: AlertCircle, text: 'Save failed', cls: 'text-rose-500 dark:text-rose-300 border-rose-500/35 bg-rose-500/10' },
};
/**
* Tiny animated pill that reflects auto-save state. Renders nothing while idle
* the page communicates "changes save automatically" once, statically.
*/
export function SaveStatus({ status, className }) {
const state = STATES[status];
return (
<AnimatePresence mode="wait">
{state && (
<motion.span
key={status}
initial={{ opacity: 0, y: -2 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 2 }}
transition={{ duration: 0.15 }}
className={cn(
'inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] font-medium',
state.cls,
className,
)}
>
<state.icon className={cn('h-3 w-3', status === 'saving' && 'animate-pulse')} />
{state.text}
</motion.span>
)}
</AnimatePresence>
);
}