import { useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Settings, Pencil, Trash2, Plus, Download } from 'lucide-react'; import { parse as yamlParse } from 'yaml'; import { credentials } from '../../api'; import type { Credential } from '../../api'; import { Breadcrumbs, Button, Card, ContextMenu, DescriptionList, Timestamp, UuidBadge } from '../../ui'; import styles from '../Page.module.css'; function CredentialCard({ credential, onDelete, }: { credential: Credential; onDelete: (id: string) => void; }) { const { t } = useTranslation(); const navigate = useNavigate(); const header = (
{credential.name}
e.stopPropagation()}> } items={[ { label: t('credentials.action_edit'), icon: , onClick: () => navigate(`/credentials/${credential.id}/edit`), }, { label: t('credentials.action_delete'), icon: , variant: 'danger', onClick: () => onDelete(credential.id), }, ]} />
); const footer = (
); return ( navigate(`/credentials/${credential.id}`)} > : '—', }, ]} /> ); } function AddCredentialCard() { const { t } = useTranslation(); const navigate = useNavigate(); return (
); } export function CredentialsPage() { const { t } = useTranslation(); const navigate = useNavigate(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fileInputRef = useRef(null); const load = () => { credentials .list() .then((res) => setItems(res.data)) .catch((err: Error) => setError(err.message)) .finally(() => setLoading(false)); }; useEffect(() => { load(); }, []); const handleDelete = async (id: string) => { await credentials.remove(id); setItems((prev) => prev.filter((c) => c.id !== id)); }; const handleImport = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; e.target.value = ''; try { const text = await file.text(); const payload = yamlParse(text) as unknown; const imported = await credentials.importCredential(payload); navigate(`/credentials/${imported.id}`); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } }; return (
{error &&

{error}

} {loading ? (

{t('credentials.loading')}

) : (
{items.map((credential) => ( ))}
)}
); }