frontend/app/components/sync-status.tsx
2025-08-19 19:32:03 +02:00

105 lines
3.3 KiB
TypeScript

import { useState } from "react";
import { Button } from "~/components/ui/button";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { Cloud, CloudOff, Wifi, WifiOff } from "lucide-react";
import { cn } from "~/lib/utils";
export function SyncButton({
healthyUntil,
lastSync,
}: {
healthyUntil: Date;
lastSync: Date;
}) {
const healthyUntilDate = new Date(healthyUntil) || new Date(0);
const lastSyncDate = new Date(lastSync) || new Date(0);
// Determine if the sync is healthy based on the healthyUntil date
const isSync = healthyUntilDate > new Date();
const [isOpen, setIsOpen] = useState(false);
const getIcon = () => {
if (isSync) return <Cloud className="w-6! h-6!" />;
return <CloudOff className="w-6! h-6!" />;
};
const getStatusColor = () => {
if (isSync) return "text-primary";
return "text-muted-foreground";
};
const formatLastSync = (date: Date | null) => {
if (!date) return "N/A";
const now = new Date();
const diff = now.getTime() - date.getTime();
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(diff / 60000);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (minutes < 1) return `il y a ${seconds}s`;
if (minutes < 60) return `il y a ${minutes}m`;
if (hours < 24) return `il y a ${hours}h`;
return `il y a ${days}j`;
};
return (
<Popover open={isOpen} onOpenChange={setIsOpen}>
<PopoverTrigger asChild>
<Button
variant="ghost"
size="sm"
className={cn("h-9 w-9 p-0 transition-colors", getStatusColor())}
// TODO: Implement sync functionality
onClick={() => {}}
>
{getIcon()}
<span className="sr-only">{isSync ? "Sync" : "Offline"}</span>
</Button>
</PopoverTrigger>
<PopoverContent className="w-64" align="end">
<div className="space-y-3">
<div className="flex items-center gap-2">
<div className={cn("flex items-center gap-2", getStatusColor())}>
{isSync ? (
<Wifi className="h-4 w-4" />
) : (
<WifiOff className="h-4 w-4" />
)}
<span className="font-medium">Status</span>
</div>
<div
className={cn(
"ml-auto px-2 py-1 rounded-full text-xs font-medium",
isSync
? "bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-400"
: "bg-gray-100 text-gray-800 dark:bg-gray-900/20 dark:text-gray-400",
)}
>
{isSync ? "Connecté" : "Hors ligne"}
</div>
</div>
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-muted-foreground">
Dernière mis à jour :
</span>
<span>{formatLastSync(lastSyncDate)}</span>
</div>
</div>
{/* TODO:
{syncStatus.isOnline && syncStatus.status !== "syncing" && (
<Button size="sm" className="w-full" onClick={handleSync}>
Sync Now
</Button>
)} */}
</div>
</PopoverContent>
</Popover>
);
}