import { useEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { usePageTitle } from '../../hooks/usePageTitle'; import { Upload, Pencil, Trash2, KeyRound } from 'lucide-react'; import { CodeBlock } from '../../ui'; import { stringify as yamlStringify } from 'yaml'; import { credentials } from '../../api'; import type { Credential } from '../../api'; import { Breadcrumbs, Button, Card, DescriptionList, Timestamp, UuidBadge } from '../../ui'; import { DeleteConfirmationModal } from '../../components/modals'; import styles from '../Page.module.css'; export function CredentialDetailPage() { const { t } = useTranslation(); const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const [credential, setCredential] = useState(null); const [loading, setLoading] = useState(true); usePageTitle(credential?.name ?? null); const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false); const [deleting, setDeleting] = useState(false); useEffect(() => { if (!id) return; credentials .get(id) .then(setCredential) .finally(() => setLoading(false)); }, [id]); const handleDelete = async () => { if (!credential) return; setDeleting(true); try { await credentials.remove(credential.id); navigate('/credentials'); } finally { setDeleting(false); setConfirmDeleteOpen(false); } }; const handleExport = async () => { if (!credential) return; const data = await credentials.exportCredential(credential.id); const blob = new Blob([yamlStringify(data)], { type: 'application/yaml' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `credential-${credential.name}.yaml`; a.click(); URL.revokeObjectURL(url); }; return (
, onClick: () => navigate('/credentials'), }, { label: credential?.name ?? `#${id}` }, ]} /> {credential && (
)}
{loading &&

{t('credentials.loading')}

} {credential && ( <> }, { term: t('credentials.field_last_used'), detail: credential.lastUsedAt ? : '—', }, { term: t('credentials.field_created'), detail: , }, { term: t('credentials.field_updated'), detail: , }, ]} /> {credential.data && (

{t('credentials.section_data')}

{ try { return JSON.stringify(JSON.parse(credential.data), null, 2); } catch { return credential.data; } })()} />
)} )} setConfirmDeleteOpen(false)} onConfirm={handleDelete} isDeleting={deleting} />
); }