Files
buzz-sheet/components/admin/guide-visibility-control.tsx
T
2026-10-03 14:51:40 +07:00

112 lines
4.0 KiB
TypeScript

"use client";
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 { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { cn } from "@/lib/utils";
export function GuideVisibilityControl({
guideId,
guideName,
isPublic,
version,
className,
}: {
guideId: string;
guideName: string;
isPublic: boolean;
version: number;
className?: string;
}) {
const router = useRouter();
const [pending, startTransition] = useTransition();
const [open, setOpen] = useState(false);
const [error, setError] = useState<string | null>(null);
const updateVisibility = (nextPublic: boolean) => {
startTransition(async () => {
setError(null);
const result = await setStructuredGuideVisibility(guideId, {
isPublic: nextPublic,
expectedVersion: version,
});
if (result.status !== "saved") {
const message = result.message ?? "เปลี่ยนสถานะ Guide ไม่สำเร็จ";
setError(message);
toast.error(message);
return;
}
toast.success(nextPublic ? "เผยแพร่ Guide แล้ว" : "เปลี่ยน Guide เป็น Private แล้ว");
setOpen(false);
router.refresh();
});
};
return (
<div className={cn("flex flex-wrap items-center gap-2", className)}>
<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" />}
{isPublic ? "Make private" : "Make Publish"}
</Button>
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
{isPublic ? `เปลี่ยน ${guideName} เป็น Private?` : `เผยแพร่ ${guideName} เป็น Public?`}
</AlertDialogTitle>
<AlertDialogDescription>
{isPublic
? "Guide จะหายจากหน้าเว็บไซต์และลิงก์สาธารณะจะเปิดไม่ได้ แต่ยังแก้ไขได้ใน Admin"
: "Guide จะแสดงบนหน้าเว็บไซต์และทุกคนจะเปิดดูผ่านลิงก์สาธารณะได้"}
</AlertDialogDescription>
</AlertDialogHeader>
{error ? (
<Alert variant="destructive">
<AlertTitle>ยังเผยแพร่ไม่ได้</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
) : null}
<AlertDialogFooter>
<AlertDialogCancel disabled={pending}>ยกเลิก</AlertDialogCancel>
<AlertDialogAction
variant={isPublic ? "destructive" : "default"}
disabled={pending}
onClick={(event) => {
event.preventDefault();
updateVisibility(!isPublic);
}}
>
{pending && <Spinner data-icon="inline-start" />}
{isPublic ? "ยืนยัน Private" : "ยืนยัน Public"}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
);
}