feat: create offline indicator UI components

This commit is contained in:
Ashis Kumar Naik 2025-07-02 08:25:21 +05:30
parent 8ee9a5b6e0
commit 52a28deb96
2 changed files with 76 additions and 0 deletions

View File

@ -0,0 +1,53 @@
import { AlertCircle, Wifi, WifiOff, RefreshCw } from "lucide-react";
import { cn } from "@/lib/utils";
interface OfflineIndicatorProps {
isNetworkConnected: boolean;
isSyncing: boolean;
outboxCount: number;
className?: string;
}
export function OfflineIndicator({
isNetworkConnected,
isSyncing,
outboxCount,
className
}: OfflineIndicatorProps) {
if (isNetworkConnected && !isSyncing && outboxCount === 0) {
return null;
}
return (
<div className={cn(
"fixed top-4 right-4 z-50 max-w-sm",
className
)}>
{!isNetworkConnected && (
<div className="bg-destructive/90 backdrop-blur-sm text-destructive-foreground px-3 py-2 rounded-md shadow-lg flex items-center gap-2 text-sm">
<WifiOff className="h-4 w-4" />
<span>Offline</span>
{outboxCount > 0 && (
<span className="bg-destructive-foreground text-destructive px-2 py-0.5 rounded-full text-xs font-medium">
{outboxCount} pending
</span>
)}
</div>
)}
{isNetworkConnected && isSyncing && outboxCount > 0 && (
<div className="bg-blue-500/90 backdrop-blur-sm text-white px-3 py-2 rounded-md shadow-lg flex items-center gap-2 text-sm">
<RefreshCw className="h-4 w-4 animate-spin" />
<span>Syncing {outboxCount} items...</span>
</div>
)}
{isNetworkConnected && !isSyncing && outboxCount > 0 && (
<div className="bg-yellow-500/90 backdrop-blur-sm text-white px-3 py-2 rounded-md shadow-lg flex items-center gap-2 text-sm">
<AlertCircle className="h-4 w-4" />
<span>{outboxCount} items pending sync</span>
</div>
)}
</div>
);
}

View File

@ -0,0 +1,23 @@
import { Clock, Upload } from "lucide-react";
import { cn } from "@/lib/utils";
interface PendingIndicatorProps {
size?: "sm" | "md";
className?: string;
}
export function PendingIndicator({ size = "sm", className }: PendingIndicatorProps) {
return (
<div className={cn(
"flex items-center gap-1 text-orange-500 bg-orange-50 dark:bg-orange-950/20 px-2 py-1 rounded-sm",
size === "sm" ? "text-xs" : "text-sm",
className
)}>
<Upload className={cn(
"animate-pulse",
size === "sm" ? "h-3 w-3" : "h-4 w-4"
)} />
<span>Pending</span>
</div>
);
}