'use client' import { useState } from 'react' import { createSecret } from '@/lib/actions' import { toast } from 'sonner' import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' import type { Secret } from '../types' // ─── Add Secret Modal ────────────────────────────────────────────────────────── export function AddSecretModal({ onClose, onSaved, }: { onClose: () => void onSaved: (s: Secret) => void }) { const [title, setTitle] = useState('') const [area, setArea] = useState('') const [value, setValue] = useState('') const [saving, setSaving] = useState(false) async function handleSave(e: React.FormEvent) { e.preventDefault() if (!title.trim() || !value.trim()) return setSaving(true) // Use the createSecret server action, which AES-encrypts the value at rest // (and applies the admin/board authz gate + Zod validation + activity log). // The previous direct browser insert wrote the value in PLAINTEXT — despite // the "Stored encrypted at rest" promise — since the encryption key is // server-only and never reaches the browser. const result = await createSecret({ title: title.trim(), value: value.trim(), area: area.trim() || undefined, }) setSaving(false) if (result.error) { toast.error(result.error); return } toast.success('Secret saved') onSaved(result.data as Secret) onClose() } return ( { if (!o) onClose() }}> Add Secret / Credential
setTitle(e.target.value)} className="w-full bg-background border border-border rounded px-3 py-2 font-sans text-sm text-foreground focus:outline-none focus:border-primary transition" placeholder="e.g. WiFi Password" required />
setArea(e.target.value)} className="w-full bg-background border border-border rounded px-3 py-2 font-sans text-sm text-foreground focus:outline-none focus:border-primary transition" placeholder="e.g. Network" />