Files
Epicure/apps/web/components/recipe/save-offline-button.tsx
T
Arnaud e78e24e40d fix: save-offline button icon+tooltip only, matches other recipe actions
Was a labeled outline button, inconsistent with PrintButton/
ShareRecipeButton's icon-only ghost + tooltip convention on the same
row.
2026-07-21 00:33:21 +02:00

59 lines
2.1 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import { toast } from "sonner";
import { Download, Check } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { isRecipeSavedOffline, saveRecipeOffline, unsaveRecipeOffline } from "@/lib/offline-db";
export function SaveOfflineButton({ recipeId, recipeTitle }: { recipeId: string; recipeTitle: string }) {
const pathname = usePathname();
const [saved, setSaved] = useState(false);
const [busy, setBusy] = useState(false);
useEffect(() => {
isRecipeSavedOffline(recipeId).then(setSaved).catch(() => {});
}, [recipeId]);
async function toggle() {
setBusy(true);
try {
if (saved) {
await unsaveRecipeOffline(recipeId);
setSaved(false);
toast.success("Removed from offline recipes");
return;
}
// Re-fetching the current page (rather than relying on the visit that
// already happened) forces the service worker's fetch handler to pin
// a fresh copy in its cache right now, regardless of how the normal
// cache eviction/versioning plays out later.
await fetch(pathname, { cache: "reload" });
await saveRecipeOffline(recipeId, recipeTitle);
setSaved(true);
toast.success("Saved for offline — photos and linked pages aren't included");
} catch {
toast.error("Couldn't save this recipe for offline use");
} finally {
setBusy(false);
}
}
const label = saved ? "Saved offline" : "Save offline";
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={
<Button type="button" variant="ghost" size="icon" disabled={busy} aria-label={label} onClick={() => { void toggle(); }}>
{saved ? <Check className="h-4 w-4" /> : <Download className="h-4 w-4" />}
</Button>
} />
<TooltipContent>{label}</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}