"use client"; import React, { useState } from "react"; import useSWR from "swr"; import axios from "@/lib/axios"; import PageBreadcrumb from "@/components/common/PageBreadCrumb"; import ComponentCard from "@/components/common/ComponentCard"; import RootCaTable from "@/components/admin/RootCaTable"; import { useAuth } from "@/hooks/useAuth"; import { useRouter } from "next/navigation"; import { useToast } from "@/context/ToastContext"; import ConfirmationModal from "@/components/common/ConfirmationModal"; import PageLoader from "@/components/ui/PageLoader"; import { useTranslations } from "next-intl"; import CdnManagementCard from "@/components/admin/CdnManagementCard"; import ArchiveManagementTable from "@/components/admin/ArchiveManagementTable"; import Button from "@/components/ui/button/Button"; const fetcher = (url: string) => axios.get(url).then((res) => res.data); export default function RootCaManagementClient() { const t = useTranslations("RootCA"); const { user } = useAuth(); const router = useRouter(); const { addToast } = useToast(); const { data, error, mutate, isLoading } = useSWR("/api/admin/ca-certificates", fetcher); const [isRenewing, setIsRenewing] = useState(false); const [isSettingUp, setIsSettingUp] = useState(false); const [isBulkRenewing, setIsBulkRenewing] = useState(false); const [activeSync, setActiveSync] = useState(null); const [isPromoting, setIsPromoting] = useState(false); const [confirmRenewUuid, setConfirmRenewUuid] = useState(null); const [showBulkRenewConfirm, setShowBulkRenewConfirm] = useState(false); const [showPurgeConfirm, setShowPurgeConfirm] = useState(false); const [isPurging, setIsPurging] = useState(false); // Redirect if not admin or owner (double security, backend also checks) const { isAdminOrOwner } = useAuth(); React.useEffect(() => { if (user && !isAdminOrOwner) { router.push("/dashboard"); } }, [user, isAdminOrOwner, router]); const handleRenew = async (uuid: string) => { setIsRenewing(true); try { await axios.post(`/api/admin/ca-certificates/${uuid}/renew`, { days: 3650 }); mutate(); addToast(t("toast_renew_success"), "success"); setConfirmRenewUuid(null); } catch (err: any) { console.error(err); addToast(err.response?.data?.message || t("toast_renew_failed"), "error"); } finally { setIsRenewing(false); } }; const handleSyncCdn = async (type: 'all' | 'crt' | 'installers' | 'bundles', mode: 'latest' | 'archive' | 'both' = 'both') => { const syncKey = `${type}-${mode}`; setActiveSync(syncKey); try { let endpoint = "/api/admin/ca-certificates/sync-cdn"; if (type === 'crt') { endpoint = "/api/admin/ca-certificates/sync-crt"; } else if (type === 'installers') { endpoint = "/api/admin/ca-certificates/sync-installers"; } else if (type === 'bundles') { endpoint = "/api/admin/ca-certificates/sync-bundles"; } const response = await axios.post(endpoint, { mode }); addToast(response.data.message || t("toast_sync_success"), "success"); mutate(); } catch (err: any) { console.error(err); addToast(err.response?.data?.message || t("toast_sync_failed"), "error"); } finally { setActiveSync(null); } }; const handlePurgeCdn = async () => { setIsPurging(true); try { const response = await axios.post("/api/admin/ca-certificates/purge-cdn"); addToast(response.data.message || t("toast_purge_success"), "success"); setShowPurgeConfirm(false); mutate(); // Refresh local list to see 'Local Only' status } catch (err: any) { console.error(err); addToast(err.response?.data?.message || t("toast_purge_failed"), "error"); } finally { setIsPurging(false); } }; const handlePromote = async (uuid: string) => { setIsPromoting(true); try { const response = await axios.post(`/api/admin/ca-certificates/${uuid}/promote`); addToast(response.data.message || t("toast_promote_success"), "success"); mutate(); } catch (err: any) { console.error(err); addToast(err.response?.data?.message || t("toast_promote_failed"), "error"); } finally { setIsPromoting(false); } }; const handleRenewAll = async () => { setIsBulkRenewing(true); try { const response = await axios.post("/api/admin/ca-certificates/renew-all", { days: 3650 }); if (response.data.status === "success") { addToast(t("toast_bulk_renew_success"), "success"); mutate(); setShowBulkRenewConfirm(false); } } catch (err: any) { console.error(err); addToast(err.response?.data?.message || t("toast_bulk_renew_failed"), "error"); } finally { setIsBulkRenewing(false); } }; const handleSetupCa = async () => { setIsSettingUp(true); try { await axios.post("/api/ca/setup"); mutate(); addToast(t("toast_ca_setup_success"), "success"); } catch (err: any) { console.error(err); addToast(err.response?.data?.message || t("toast_ca_setup_failed"), "error"); } finally { setIsSettingUp(false); } }; if (error) return
{t("load_failed")}
; const certificates = data?.data || []; return (
{certificates.length === 0 && !isLoading && ( )}
{/* Main CA Management Table */} c.is_latest || certificates.length === 1)} onRenew={setConfirmRenewUuid} isRenewing={isRenewing} /> {(isLoading || isRenewing) && (
)}
{/* CDN Synchronization Controls */} setShowPurgeConfirm(true)} activeSync={activeSync} disabled={isLoading || isPromoting || isPurging} /> {/* Full-width Archive History */}

{t("info_title")}

  • {t("info_point_1")}
  • {t("info_point_2")}
  • {t("info_point_3")}
  • {t("info_point_4")}
setConfirmRenewUuid(null)} onConfirm={() => confirmRenewUuid && handleRenew(confirmRenewUuid)} title={t("renew_modal_title")} message={t("renew_modal_msg")} isLoading={isRenewing} confirmLabel={t("renew_modal_confirm")} variant="warning" requiredInput="RENEW" /> setShowBulkRenewConfirm(false)} onConfirm={handleRenewAll} title={t("bulk_renew_modal_title")} message={t("bulk_renew_modal_msg")} isLoading={isBulkRenewing} confirmLabel={t("bulk_renew_confirm_label")} variant="warning" requiredInput="RENEW-ALL" /> setShowPurgeConfirm(false)} onConfirm={handlePurgeCdn} title={t("purge_modal_title")} message={t("purge_modal_msg")} isLoading={isPurging} confirmLabel={t("purge_confirm_label")} variant="error" requiredInput="PURGE" />
); }