2026-07-19 00:29:30 +08:00
|
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
|
|
import { useState } from "react";
|
|
|
|
|
|
|
2026-07-19 05:36:52 +08:00
|
|
|
|
export function WebhookControl({ sourceId, configured, automatic = false }: { sourceId: number; configured: boolean; automatic?: boolean }) {
|
2026-07-19 00:29:30 +08:00
|
|
|
|
const [url, setUrl] = useState(""); const [error, setError] = useState(""); const [busy, setBusy] = useState(false);
|
|
|
|
|
|
async function generate() {
|
|
|
|
|
|
setBusy(true); setError("");
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await fetch(`/api/sources/${sourceId}/webhook`, { method: "POST", headers: { Accept: "application/json" } });
|
|
|
|
|
|
const body = await response.json(); if (!response.ok) throw new Error(body.error || "無法產生 webhook URL"); setUrl(body.url);
|
|
|
|
|
|
} catch (reason) { setError(reason instanceof Error ? reason.message : "無法產生 webhook URL"); }
|
|
|
|
|
|
finally { setBusy(false); }
|
|
|
|
|
|
}
|
|
|
|
|
|
async function copy() { if (url) await navigator.clipboard.writeText(url); }
|
2026-07-19 05:36:52 +08:00
|
|
|
|
if (automatic) return <div className="webhook-control"><p className="meta">Webhook:已由 Memos 自動設定並驗證簽章。為避免讓遠端設定失效,此處不提供手動重產網址。</p></div>;
|
2026-07-19 00:29:30 +08:00
|
|
|
|
return <div className="webhook-control"><p className="meta">Webhook:{configured ? "已設定" : "尚未設定"}</p>
|
|
|
|
|
|
{url ? <><label className="sr-only" htmlFor={`webhook-${sourceId}`}>Webhook URL</label><input id={`webhook-${sourceId}`} readOnly value={url} onFocus={(event) => event.currentTarget.select()} /><div className="row"><button type="button" onClick={copy}>複製 URL</button><button type="button" className="danger" onClick={generate} disabled={busy}>重新產生</button></div><p className="meta">請立即複製到 Memos;重新整理後完整密鑰不會再顯示。</p></> : <button type="button" onClick={generate} disabled={busy}>{busy ? "產生中…" : configured ? "重新產生 webhook URL" : "產生 webhook URL"}</button>}
|
|
|
|
|
|
{error && <p className="error">{error}</p>}
|
|
|
|
|
|
</div>;
|
|
|
|
|
|
}
|