163 lines
3.9 KiB
Svelte
163 lines
3.9 KiB
Svelte
<script lang="ts">
|
|
import { client } from '$lib/graphql/client';
|
|
import {
|
|
CREATE_ACCOUNT_CONTACT,
|
|
UPDATE_ACCOUNT_CONTACT,
|
|
type CreateAccountContactInput,
|
|
type UpdateAccountContactInput
|
|
} from '$lib/graphql/mutations/account';
|
|
import type { AccountContact } from '$lib/graphql/queries/account';
|
|
|
|
interface Props {
|
|
contact?: AccountContact;
|
|
accountId: string;
|
|
onSuccess: () => void;
|
|
onCancel: () => void;
|
|
}
|
|
|
|
let { contact, accountId, onSuccess, onCancel }: Props = $props();
|
|
|
|
let isEdit = $derived(!!contact);
|
|
|
|
// Form state - use $effect to sync from props
|
|
let firstName = $state('');
|
|
let lastName = $state('');
|
|
let email = $state('');
|
|
let phone = $state('');
|
|
let notes = $state('');
|
|
let isPrimary = $state(false);
|
|
|
|
$effect(() => {
|
|
firstName = contact?.firstName ?? '';
|
|
lastName = contact?.lastName ?? '';
|
|
email = contact?.email ?? '';
|
|
phone = contact?.phone ?? '';
|
|
notes = contact?.notes ?? '';
|
|
isPrimary = contact?.isPrimary ?? false;
|
|
});
|
|
|
|
let loading = $state(false);
|
|
let error = $state<string | null>(null);
|
|
|
|
async function handleSubmit(event: SubmitEvent) {
|
|
event.preventDefault();
|
|
loading = true;
|
|
error = null;
|
|
|
|
try {
|
|
if (isEdit && contact) {
|
|
const input: UpdateAccountContactInput = {
|
|
firstName: firstName || undefined,
|
|
lastName: lastName || undefined,
|
|
email: email || undefined,
|
|
phone: phone || undefined,
|
|
notes: notes || undefined,
|
|
isPrimary
|
|
};
|
|
|
|
await client.mutate({
|
|
mutation: UPDATE_ACCOUNT_CONTACT,
|
|
variables: { id: contact.id, input }
|
|
});
|
|
} else {
|
|
const input: CreateAccountContactInput = {
|
|
firstName,
|
|
lastName,
|
|
email: email || undefined,
|
|
phone: phone || undefined,
|
|
notes: notes || undefined,
|
|
isPrimary
|
|
};
|
|
|
|
await client.mutate({
|
|
mutation: CREATE_ACCOUNT_CONTACT,
|
|
variables: { accountId, input }
|
|
});
|
|
}
|
|
|
|
onSuccess();
|
|
} catch (err) {
|
|
error = err instanceof Error ? err.message : 'An error occurred';
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<form onsubmit={handleSubmit} class="space-y-5">
|
|
{#if error}
|
|
<div class="rounded-lg border border-error-500/30 bg-error-50/50 p-3 dark:bg-error-950/30">
|
|
<p class="text-sm text-error-700 dark:text-error-400">{error}</p>
|
|
</div>
|
|
{/if}
|
|
|
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
|
<div>
|
|
<label for="firstName" class="form-label">
|
|
First Name <span class="required-indicator">*</span>
|
|
</label>
|
|
<input
|
|
id="firstName"
|
|
type="text"
|
|
bind:value={firstName}
|
|
class="input-base"
|
|
required
|
|
disabled={loading}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label for="lastName" class="form-label">
|
|
Last Name <span class="required-indicator">*</span>
|
|
</label>
|
|
<input
|
|
id="lastName"
|
|
type="text"
|
|
bind:value={lastName}
|
|
class="input-base"
|
|
required
|
|
disabled={loading}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="email" class="form-label">Email</label>
|
|
<input id="email" type="email" bind:value={email} class="input-base" disabled={loading} />
|
|
</div>
|
|
|
|
<div>
|
|
<label for="phone" class="form-label">Phone</label>
|
|
<input id="phone" type="tel" bind:value={phone} class="input-base" disabled={loading} />
|
|
</div>
|
|
|
|
<div>
|
|
<label for="notes" class="form-label">Notes</label>
|
|
<textarea id="notes" bind:value={notes} class="textarea-base" rows="3" disabled={loading}
|
|
></textarea>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2">
|
|
<input
|
|
id="isPrimary"
|
|
type="checkbox"
|
|
bind:checked={isPrimary}
|
|
class="h-4 w-4 rounded border-theme text-primary-600 focus:ring-primary-500"
|
|
disabled={loading}
|
|
/>
|
|
<label for="isPrimary" class="text-sm text-theme">Primary Contact</label>
|
|
</div>
|
|
|
|
<div class="form-actions border-t border-theme pt-5">
|
|
<button type="button" class="btn-cancel" onclick={onCancel} disabled={loading}>Cancel</button>
|
|
<button type="submit" class="btn-submit" disabled={loading}>
|
|
{#if loading}
|
|
Saving...
|
|
{:else if isEdit}
|
|
Update Contact
|
|
{:else}
|
|
Add Contact
|
|
{/if}
|
|
</button>
|
|
</div>
|
|
</form>
|