import { Form, Head } from '@inertiajs/react'; import { useEffect, useRef, useState } from 'react'; import InputError from '@/components/input-error'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; type Props = { setting: { base_username: string; use_tls: boolean; verify_tls: boolean; connection_timeout: number; } | null; hasPassword: boolean; encryptionKey: { version: number; source: string; created_at: string; } | null; devices: { id: number; name: string; base_sync_status: string; base_sync_error_code?: string; base_sync_message?: string; base_synced_at?: string; vendor: { name: string }; }[]; }; export default function DeviceSettings({ setting, hasPassword, encryptionKey, devices, }: Props) { const [keyMode, setKeyMode] = useState('generated'); const [loginPassword, setLoginPassword] = useState(''); const [revealedPassword, setRevealedPassword] = useState(''); const [revealError, setRevealError] = useState(''); const [revealing, setRevealing] = useState(false); const hideTimer = useRef | null>(null); useEffect(() => () => { if (hideTimer.current) { clearTimeout(hideTimer.current); } }, []); const revealBasePassword = async () => { setRevealing(true); setRevealError(''); setRevealedPassword(''); try { const csrf = document.querySelector('meta[name="csrf-token"]')?.content ?? ''; const response = await fetch('/device-settings/reveal-password', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', Accept: 'application/json', 'X-CSRF-TOKEN': csrf }, body: JSON.stringify({ current_password: loginPassword }), }); const result = await response.json(); if (!response.ok) { throw new Error(result.errors?.current_password?.[0] ?? result.message ?? 'Password tidak dapat ditampilkan.'); } setRevealedPassword(result.password); setLoginPassword(''); if (hideTimer.current) { clearTimeout(hideTimer.current); } hideTimer.current = setTimeout(() => setRevealedPassword(''), 30000); } catch (error) { setRevealError(error instanceof Error ? error.message : 'Password tidak dapat ditampilkan.'); } finally { setRevealing(false); } }; return ( <>

Base User Perangkat

Akun management terpusat untuk seluruh perangkat tenant. Perubahan username atau password akan disinkronkan ke semua perangkat yang aktif.

{({ processing, errors }) => ( Template Base User Tenant Password disimpan terenkripsi dan tidak pernah ditampilkan kembali.
Group yang dibuat:{' '} RADIQ-READ, RADIQ-WRITE, dan RADIQ-NOC tanpa permission policy, serta group bawaan full untuk akun provisioning terpusat.
{hasPassword && (
Lihat Base Password

Masukkan password login Tenant Admin. Password perangkat akan disembunyikan otomatis setelah 30 detik.

setLoginPassword(event.target.value)} placeholder="Password login Tenant Admin" autoComplete="current-password" />
{revealError &&

{revealError}

} {revealedPassword && ( )}
)}
)}
Status Rotasi Base User Perangkat offline akan dicoba kembali oleh scheduler. Vendor tanpa driver ditandai unsupported. {devices.map((device) => (
{device.name}
{device.vendor.name} ยท {device.base_sync_message ?? 'Belum pernah disinkronkan'}
{device.base_sync_status}
))} {devices.length === 0 &&

Belum ada perangkat.

}
{({ processing, errors }) => ( Encryption Key Tenant Key aktif versi{' '} {encryptionKey?.version ?? 1} ( {encryptionKey?.source ?? 'generated'}). Rotasi mengenkripsi ulang seluruh password perangkat dan Base Password pada database.
{keyMode === 'manual' && ( <>
)}
Rotasi key tidak mengubah password yang berada di router/OLT. Perubahan password perangkat dilakukan melalui operasi rotasi credential terpisah dan harus diverifikasi login ulang.
)}
); }