"use client"; import { useState } from "react"; import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation"; import { GitFork, Copy, Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { toast } from "sonner"; // Forking someone else's recipe and duplicating your own hit the exact same // endpoint (apps/web/app/api/v1/recipes/[id]/fork/route.ts has no // "isn't yours" check) — only the label/icon/toast copy differs, since // "fork" implies attribution that doesn't apply to your own recipe. export function ForkRecipeButton({ recipeId, variant = "fork" }: { recipeId: string; variant?: "fork" | "duplicate" }) { const t = useTranslations("recipe"); const router = useRouter(); const [forking, setForking] = useState(false); const isDuplicate = variant === "duplicate"; async function handleFork() { setForking(true); try { const res = await fetch(`/api/v1/recipes/${recipeId}/fork`, { method: "POST" }); if (!res.ok) { const data = await res.json() as { error?: string }; throw new Error( res.status === 403 ? t("forkLimitReached") : (data.error ?? t("forkFailed")) ); } const data = await res.json() as { id: string }; toast.success(isDuplicate ? t("duplicated") : t("forked")); router.push(`/recipes/${data.id}`); } catch (err) { toast.error(err instanceof Error ? err.message : t("forkFailed")); setForking(false); } } const label = isDuplicate ? t("duplicateTooltip") : t("forkTooltip"); return ( { void handleFork(); }} disabled={forking} aria-label={label}> {forking ? : isDuplicate ? : } } /> {label} ); }