import { useSignal } from '@preact/signals'; import { Contact } from '/lib/models/contacts.ts'; import { convertObjectToFormData } from '/lib/utils/misc.ts'; import { FormField, generateFieldHtml } from '/lib/form-utils.tsx'; import { RequestBody as DeleteRequestBody, ResponseBody as DeleteResponseBody } from '/routes/api/contacts/delete.tsx'; interface ViewContactProps { addressBookId: string; initialContact: Contact; formData: Record; error?: string; notice?: string; } export function formFields(contact: Contact, updateType: 'raw' | 'ui') { const fields: FormField[] = [ { name: 'update-type', label: 'Update type', type: 'hidden', value: updateType, readOnly: true, }, ]; if (updateType === 'ui') { fields.push({ name: 'first_name', label: 'First name', type: 'text', placeholder: 'John', value: contact.firstName, required: true, }, { name: 'last_name', label: 'Last name', type: 'text', placeholder: 'Doe', value: contact.lastName, required: false, }, { name: 'main_phone', label: 'Main phone', type: 'tel', placeholder: '+44 0000 111 2222', value: contact.phone, required: false, }, { name: 'main_email', label: 'Main email', type: 'email', placeholder: 'john.doe@example.com', value: contact.email, required: false, }, { name: 'notes', label: 'Notes', type: 'textarea', placeholder: 'Some notes...', value: contact.notes, required: false, }); } else if (updateType === 'raw') { fields.push({ name: 'vcard', label: 'Raw vCard', type: 'textarea', placeholder: 'Raw vCard...', value: contact.data, description: 'This is the raw vCard for this contact. Use this to manually update the contact _if_ you know what you are doing.', rows: '10', }); } return fields; } export default function ViewContact( { initialContact, formData: formDataObject, error, notice, addressBookId }: ViewContactProps, ) { const isDeleting = useSignal(false); const contact = useSignal(initialContact); const formData = convertObjectToFormData(formDataObject); async function onClickDeleteContact() { if (confirm('Are you sure you want to delete this contact?')) { if (isDeleting.value) { return; } isDeleting.value = true; try { const requestBody: DeleteRequestBody = { contactId: contact.value.uid!, addressBookId }; const response = await fetch(`/api/contacts/delete`, { method: 'POST', body: JSON.stringify(requestBody), }); if (!response.ok) { throw new Error(`Failed to delete contact. ${response.statusText} ${await response.text()}`); } const result = await response.json() as DeleteResponseBody; if (!result.success) { throw new Error('Failed to delete contact!'); } window.location.href = '/contacts'; } catch (error) { console.error(error); } isDeleting.value = false; } } return ( <>
View contacts
{error ? (

Failed to update!

{error}

) : null} {notice ? (

Success!

{notice}

) : null}
{formFields(contact.peek(), 'ui').map((field) => generateFieldHtml(field, formData))}

Edit Raw vCard{' '} Expand
{formFields(contact.peek(), 'raw').map((field) => generateFieldHtml(field, formData))}
{isDeleting.value ? ( <> Deleting... ) : null} {!isDeleting.value ? <>  : null}
); }