99 lines
3.7 KiB
TypeScript
99 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { useTranslation } from "@/components/i18n/locale-provider";
|
|
import { EyeIcon, EyeOffIcon } from "lucide-react";
|
|
import { useRouter } from "next/navigation";
|
|
import { useState, useTransition } from "react";
|
|
import { toast } from "sonner";
|
|
|
|
import { setStructuredGuideVisibility } from "@/app/admin/actions";
|
|
import {
|
|
AlertDialog,
|
|
AlertDialogAction,
|
|
AlertDialogCancel,
|
|
AlertDialogContent,
|
|
AlertDialogDescription,
|
|
AlertDialogFooter,
|
|
AlertDialogHeader,
|
|
AlertDialogTitle,
|
|
} from "@/components/ui/alert-dialog";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Spinner } from "@/components/ui/spinner";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export function GuideVisibilityControl({
|
|
guideId,
|
|
guideName,
|
|
isPublic,
|
|
className,
|
|
}: {
|
|
guideId: string;
|
|
guideName: string;
|
|
isPublic: boolean;
|
|
className?: string;
|
|
}) {
|
|
const { t } = useTranslation();
|
|
const router = useRouter();
|
|
const [pending, startTransition] = useTransition();
|
|
const [open, setOpen] = useState(false);
|
|
|
|
const updateVisibility = (nextPublic: boolean) => {
|
|
startTransition(async () => {
|
|
const result = await setStructuredGuideVisibility(guideId, nextPublic);
|
|
if (result.status !== "saved") {
|
|
toast.error(t(result.message ?? "เปลี่ยนสถานะ Guide ไม่สำเร็จ"));
|
|
return;
|
|
}
|
|
toast.success(nextPublic ? "เผยแพร่ Guide แล้ว" : "เปลี่ยน Guide เป็น Private แล้ว");
|
|
setOpen(false);
|
|
router.refresh();
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className={cn("flex flex-wrap items-center gap-2", className)}>
|
|
<Badge variant={isPublic ? "default" : "secondary"}>
|
|
{t(isPublic ? "Public" : "Private")}
|
|
</Badge>
|
|
<Button
|
|
type="button"
|
|
variant={isPublic ? "outline" : "default"}
|
|
size="sm"
|
|
disabled={pending}
|
|
aria-haspopup="dialog"
|
|
aria-expanded={open}
|
|
onClick={() => setOpen(true)}
|
|
>
|
|
{pending ? <Spinner data-icon="inline-start" /> : isPublic ? <EyeOffIcon data-icon="inline-start" /> : <EyeIcon data-icon="inline-start" />}
|
|
{t(isPublic ? "Make private" : "Publish")}
|
|
</Button>
|
|
<AlertDialog open={open} onOpenChange={setOpen}>
|
|
<AlertDialogContent>
|
|
<AlertDialogHeader>
|
|
<AlertDialogTitle>
|
|
{isPublic ? t("เปลี่ยน {guideName} เป็น Private?", { guideName: guideName }) : t("เผยแพร่ {guideName} เป็น Public?", { guideName: guideName })}
|
|
</AlertDialogTitle>
|
|
<AlertDialogDescription>
|
|
{isPublic
|
|
? t("Guide จะหายจากหน้าเว็บไซต์และลิงก์สาธารณะจะเปิดไม่ได้ แต่ยังแก้ไขได้ใน Admin")
|
|
: t("Guide จะแสดงบนหน้าเว็บไซต์และทุกคนจะเปิดดูผ่านลิงก์สาธารณะได้")}
|
|
</AlertDialogDescription>
|
|
</AlertDialogHeader>
|
|
<AlertDialogFooter>
|
|
<AlertDialogCancel disabled={pending}>{t("ยกเลิก")}</AlertDialogCancel>
|
|
<AlertDialogAction
|
|
variant={isPublic ? "destructive" : "default"}
|
|
disabled={pending}
|
|
onClick={() => updateVisibility(!isPublic)}
|
|
>
|
|
{pending && <Spinner data-icon="inline-start" />}
|
|
{isPublic ? t("ยืนยัน Private") : t("ยืนยัน Public")}
|
|
</AlertDialogAction>
|
|
</AlertDialogFooter>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
</div>
|
|
);
|
|
}
|