From eaea8dbd2ad29efae7964264db421b2bb7adf276 Mon Sep 17 00:00:00 2001 From: dyzulk <66510723+dyzulk@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:56:25 +0700 Subject: [PATCH] feat: implement global bundle UI, granular sync buttons, and integration with new API endpoints --- src/app/(public)/HomeClient.tsx | 45 +++++++++ .../admin/root-ca/RootCaManagementClient.tsx | 98 +++++++++++++++---- src/messages/en.json | 4 + src/messages/id.json | 6 +- 4 files changed, 131 insertions(+), 22 deletions(-) diff --git a/src/app/(public)/HomeClient.tsx b/src/app/(public)/HomeClient.tsx index 7c54c07..e24b67b 100644 --- a/src/app/(public)/HomeClient.tsx +++ b/src/app/(public)/HomeClient.tsx @@ -149,6 +149,51 @@ function OsGuideContent({ title, steps, selectedOs, certificates, t }: { title: + {/* Global Bundle Section (Recommendations) */} +
+
+
+
+ + + +
+
+
+ {t('bundle_guide_title')} + Recommended +
+

+ {t('bundle_guide_desc')} +

+ + {(selectedOs === 'linux' || selectedOs === 'windows' || selectedOs === 'macos') && ( +
+ {(selectedOs === 'linux') && ( + + )} + {(selectedOs === 'windows' || selectedOs === 'macos') && ( +
+ : } + onClick={() => {}} + variant="blue" + /> +
+ )} +
+ )} +
+
+
+
+ {selectedOs === 'linux' && (
diff --git a/src/app/dashboard/admin/root-ca/RootCaManagementClient.tsx b/src/app/dashboard/admin/root-ca/RootCaManagementClient.tsx index 81c0e8f..46832d4 100644 --- a/src/app/dashboard/admin/root-ca/RootCaManagementClient.tsx +++ b/src/app/dashboard/admin/root-ca/RootCaManagementClient.tsx @@ -15,6 +15,35 @@ import { useTranslations } from "next-intl"; const fetcher = (url: string) => axios.get(url).then((res) => res.data); +function SyncButton({ onClick, disabled, isLoading, label, variant = 'blue' }: { onClick: () => void, disabled: boolean, isLoading: boolean, label: string, variant?: 'blue' | 'gray' | 'purple' | 'indigo' }) { + const variantClasses = { + blue: 'bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400', + gray: 'bg-gray-600 hover:bg-gray-700 disabled:bg-gray-400', + purple: 'bg-purple-600 hover:bg-purple-700 disabled:bg-purple-400', + indigo: 'bg-indigo-600 hover:bg-indigo-700 disabled:bg-indigo-400', + }; + + return ( + + ); +} + export default function RootCaManagementClient() { const t = useTranslations("RootCA"); const { user } = useAuth(); @@ -50,15 +79,29 @@ export default function RootCaManagementClient() { } }; - const handleSyncCdn = async () => { + const handleSyncCdn = async (type: 'all' | 'crt' | 'installers' | 'bundles') => { setIsSyncing(true); try { - const response = await axios.post("/api/admin/ca-certificates/sync-cdn"); - addToast(response.data.message || "Sync to CDN successful", "success"); + let endpoint = "/api/admin/ca-certificates/sync-cdn"; + let msg = "Full Sync successful"; + + if (type === 'crt') { + endpoint = "/api/admin/ca-certificates/sync-crt"; + msg = "CRT Files Sync successful"; + } else if (type === 'installers') { + endpoint = "/api/admin/ca-certificates/sync-installers"; + msg = "Individual Installers Sync successful"; + } else if (type === 'bundles') { + endpoint = "/api/admin/ca-certificates/sync-bundles"; + msg = "Global Bundles Sync successful"; + } + + const response = await axios.post(endpoint); + addToast(response.data.message || msg, "success"); mutate(); } catch (err: any) { console.error(err); - addToast(err.response?.data?.message || "Sync to CDN failed", "error"); + addToast(err.response?.data?.message || "Sync failed", "error"); } finally { setIsSyncing(false); } @@ -73,23 +116,36 @@ export default function RootCaManagementClient() {
- +
+ handleSyncCdn('crt')} + disabled={isSyncing || isLoading} + isLoading={isSyncing} + label="Sync CRT Only" + variant="gray" + /> + handleSyncCdn('installers')} + disabled={isSyncing || isLoading} + isLoading={isSyncing} + label="Sync Installers Only" + variant="blue" + /> + handleSyncCdn('bundles')} + disabled={isSyncing || isLoading} + isLoading={isSyncing} + label="Sync Full Bundles" + variant="purple" + /> + handleSyncCdn('all')} + disabled={isSyncing || isLoading} + isLoading={isSyncing} + label="Sync All to CDN" + variant="indigo" + /> +
diff --git a/src/messages/en.json b/src/messages/en.json index 447b772..5be5ee6 100644 --- a/src/messages/en.json +++ b/src/messages/en.json @@ -218,6 +218,10 @@ ], "guide_linux_shortcut_title": "Instant Installation (CLI)", "guide_linux_shortcut_desc": "Run the corresponding command for the certificate you wish to trust:", + "bundle_guide_title": "Trust All Certificates (Quick Start)", + "bundle_guide_desc": "If you are setting up a new device, we recommend using the Bundle Installer. This will instantly untrust all TrustLab Root and Intermediate CAs in one go.", + "bundle_cli_label": "Global Bundle Installer (All-in-One)", + "download_all_bundle": "Download Full Bundle", "guide_steps_mobile": [ "Android: Settings > Security > Install from storage > CA Certificate.", "iOS: Install the profile, then Settings > General > About > Certificate Trust Settings." diff --git a/src/messages/id.json b/src/messages/id.json index 9ca140c..1494f81 100644 --- a/src/messages/id.json +++ b/src/messages/id.json @@ -217,7 +217,11 @@ "Skrip akan secara otomatis mendeteksi distro dan memperbarui penyimpanan CA Anda." ], "guide_linux_shortcut_title": "Instalasi Instan (CLI)", - "guide_linux_shortcut_desc": "Jalankan perintah yang sesuai untuk sertifikat yang ingin Anda percayai:", + "guide_linux_shortcut_desc": "Jalankan perintah sesuai dengan sertifikat yang ingin Anda percayai:", + "bundle_guide_title": "Percayai Semua Sertifikat (Mulai Cepat)", + "bundle_guide_desc": "Jika Anda baru menyiapkan perangkat baru, kami menyarankan Anda menggunakan Bundle Installer. Ini akan langsung memercayai semua Root dan Intermediate CA TrustLab sekaligus.", + "bundle_cli_label": "Global Bundle Installer (Sapujagat)", + "download_all_bundle": "Unduh Bundle Lengkap", "guide_steps_mobile": [ "Android: Pengaturan > Keamanan > Instal dari penyimpanan > Sertifikat CA.", "iOS: Instal profil, lalu Pengaturan > Umum > Mengenai > Pengaturan Kepercayaan Sertifikat."