Files
buzz-sheet/components/commission/push-entry-prompt.tsx
T
gunshiz 96c27f8fc3
CI / Verify (push) Successful in 1m36s
CI / Build immutable images and deploy (push) Successful in 2m17s
fix(commission) : replace repeated notification buttons with entry prompt
2026-10-02 12:07:41 +07:00

67 lines
3.3 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { subscribeCommissionPush, syncCommissionPush } from "./push-client";
type PushRequest = { scope: "customer" | "admin"; publicKey: string };
const askedKey = "commission-push-asked";
export function CommissionPushEntryPrompt({ scope }: { scope: "customer" | "admin" }) {
const [request, setRequest] = useState<PushRequest | null>(null);
const [busy, setBusy] = useState(false);
const [error, setError] = useState("");
useEffect(() => {
if (!window.isSecureContext ||
!("Notification" in window) || !("PushManager" in window) || !("serviceWorker" in navigator) ||
Notification.permission === "denied" ||
(Notification.permission === "default" && sessionStorage.getItem(askedKey)) ||
(Notification.permission === "granted" && (sessionStorage.getItem(`commission-push-synced-${scope}`) ||
(scope === "customer" && sessionStorage.getItem("commission-push-synced-admin"))))) return;
let active = true;
void fetch("/api/commission/push-subscription", { cache: "no-store" }).then(async (response) => {
if (!response.ok) return;
const config = await response.json() as { publicKey: string; canAdmin: boolean };
if (!active || (scope === "admin" && !config.canAdmin)) return;
const subscriptionScope = config.canAdmin ? "admin" : scope;
if (Notification.permission === "granted") {
await syncCommissionPush(subscriptionScope, config.publicKey);
return;
}
if (Notification.permission !== "default") return;
sessionStorage.setItem(askedKey, "1");
setRequest({ scope: subscriptionScope, publicKey: config.publicKey });
}).catch(() => undefined);
return () => { active = false; };
}, [scope]);
async function enable() {
if (!request) return;
setBusy(true);
setError("");
try {
await subscribeCommissionPush(request.scope, request.publicKey);
setRequest(null);
} catch {
setError("เปิดการแจ้งเตือนไม่สำเร็จ กรุณาลองอีกครั้ง");
} finally { setBusy(false); }
}
return <Dialog open={request !== null} onOpenChange={(open) => { if (!open) setRequest(null); }}>
<DialogContent>
<DialogHeader>
<DialogTitle>รับการแจ้งเตือนข้อความใหม่?</DialogTitle>
<DialogDescription>เมื่อมีข้อความใหม่ใน Ticket เราจะแจ้งเตือนพร้อมชื่อผู้ส่งและข้อความ แม้ปิดแท็บแล้ว</DialogDescription>
</DialogHeader>
{error && <p role="alert" className="text-sm text-destructive">{error}</p>}
<DialogFooter>
<Button type="button" variant="outline" disabled={busy} onClick={() => setRequest(null)}>ไว้ก่อน</Button>
<Button type="button" disabled={busy} onClick={() => void enable()}>เปิดการแจ้งเตือน</Button>
</DialogFooter>
</DialogContent>
</Dialog>;
}