add resident edit
This commit is contained in:
parent
15c52a30d7
commit
4f939c960e
5 changed files with 70 additions and 14 deletions
|
|
@ -24,7 +24,9 @@
|
||||||
"sms_button_submit": "Send Message",
|
"sms_button_submit": "Send Message",
|
||||||
"residents_title": "Residents",
|
"residents_title": "Residents",
|
||||||
"residents_button_new": "New Resident",
|
"residents_button_new": "New Resident",
|
||||||
"residents_modal_title": "Create a Resident",
|
"residents_table_edit": "Edit",
|
||||||
|
"residents_modal_title_new": "Create a Resident",
|
||||||
|
"residents_modal_title_edit": "Edit Resident",
|
||||||
"residents_modal_submit": "Submit",
|
"residents_modal_submit": "Submit",
|
||||||
"residents_modal_label_name": "Name",
|
"residents_modal_label_name": "Name",
|
||||||
"residents_modal_label_phone": "Phone Number",
|
"residents_modal_label_phone": "Phone Number",
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,34 @@
|
||||||
|
<script lang="ts" module>
|
||||||
|
export type ResidentItem = Pick<Resident, 'id' | 'name' | 'phoneNumber'>;
|
||||||
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Resident } from '@prisma/client';
|
import type { Resident } from '@prisma/client';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import { UserRoundPen } from 'lucide-svelte';
|
||||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
import Button from '../Actions/Button.svelte';
|
||||||
|
import { messages } from '$lib/i18n';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
items?: Pick<Resident, 'id' | 'name' | 'phoneNumber'>[];
|
items?: ResidentItem[];
|
||||||
|
onEdit?: (resident: ResidentItem) => void;
|
||||||
} & Omit<SvelteHTMLElements['table'], 'children'>;
|
} & Omit<SvelteHTMLElements['table'], 'children'>;
|
||||||
|
|
||||||
let { items, class: className, ...props }: Props = $props();
|
let { items, onEdit, class: className, ...props }: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<table {...props} class={twMerge('table', clsx(className))}>
|
<table {...props} class={twMerge('table', clsx(className))}>
|
||||||
<!-- head -->
|
<!-- head -->
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-base-100">
|
<tr class="bg-base-100">
|
||||||
<th></th>
|
<th>#</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Phone Number</th>
|
<th>Phone Number</th>
|
||||||
|
{#if onEdit}
|
||||||
|
<th class="flex justify-end"><UserRoundPen class="mx-3" /></th>
|
||||||
|
{/if}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
@ -28,6 +39,13 @@
|
||||||
<th>{index + 1}</th>
|
<th>{index + 1}</th>
|
||||||
<td>{resident.name}</td>
|
<td>{resident.name}</td>
|
||||||
<td>{resident.phoneNumber}</td>
|
<td>{resident.phoneNumber}</td>
|
||||||
|
{#if onEdit}
|
||||||
|
<td class="text-end">
|
||||||
|
<Button size="sm" color="accent" onclick={() => onEdit(resident)}>
|
||||||
|
{messages.residents_table_edit()}
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
{/if}
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
export { default as ResidentTable } from './ResidentTable.svelte';
|
export { default as ResidentTable } from './ResidentTable.svelte';
|
||||||
|
export * from './ResidentTable.svelte';
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,11 @@ export const actions = {
|
||||||
return fail(400, { error: 'message_missing' });
|
return fail(400, { error: 'message_missing' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const id = form.get('id');
|
||||||
|
if (id && typeof id !== 'string') {
|
||||||
|
return fail(400, { error: 'invalid_id' });
|
||||||
|
}
|
||||||
|
|
||||||
const name = form.get('name');
|
const name = form.get('name');
|
||||||
if (typeof name !== 'string') {
|
if (typeof name !== 'string') {
|
||||||
return fail(400, { error: 'invalid_name' });
|
return fail(400, { error: 'invalid_name' });
|
||||||
|
|
@ -47,12 +52,19 @@ export const actions = {
|
||||||
return fail(400, { error: 'invalid_phone' });
|
return fail(400, { error: 'invalid_phone' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.resident.create({
|
await prisma.resident.upsert({
|
||||||
data: {
|
where: {
|
||||||
|
id: id ?? '',
|
||||||
|
},
|
||||||
|
create: {
|
||||||
name: name,
|
name: name,
|
||||||
phoneNumber: phone,
|
phoneNumber: phone,
|
||||||
tenantId: event.locals.tenant.id,
|
tenantId: event.locals.tenant.id,
|
||||||
},
|
},
|
||||||
|
update: {
|
||||||
|
name: name,
|
||||||
|
phoneNumber: phone,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { enhance } from '$app/forms';
|
import { enhance } from '$app/forms';
|
||||||
import { Button, Modal, ModalActions, ModalBody } from '$lib/components/Actions';
|
import { Button, Modal, ModalActions, ModalBody } from '$lib/components/Actions';
|
||||||
import { TextInput } from '$lib/components/DataInput';
|
import { TextInput } from '$lib/components/DataInput';
|
||||||
import { ResidentTable } from '$lib/components/Residents';
|
import { ResidentTable, type ResidentItem } from '$lib/components/Residents';
|
||||||
import { messages } from '$lib/i18n';
|
import { messages } from '$lib/i18n';
|
||||||
import { Phone, UserRound, UserRoundPlus } from 'lucide-svelte';
|
import { Phone, UserRound, UserRoundPlus } from 'lucide-svelte';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
|
@ -17,25 +17,42 @@
|
||||||
|
|
||||||
let residents = $derived(data.residents);
|
let residents = $derived(data.residents);
|
||||||
|
|
||||||
let dialog = $state<HTMLDialogElement | undefined>(undefined);
|
let dialog: HTMLDialogElement | undefined = $state(undefined);
|
||||||
|
let form: HTMLFormElement | undefined = $state(undefined);
|
||||||
|
|
||||||
|
let resident: ResidentItem | undefined = $state(undefined);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Modal backdrop bind:dialog>
|
<Modal
|
||||||
|
backdrop
|
||||||
|
bind:dialog
|
||||||
|
onclose={() => {
|
||||||
|
resident = undefined;
|
||||||
|
form?.reset();
|
||||||
|
}}
|
||||||
|
>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h2 class="text-2xl">{messages.residents_modal_title()}</h2>
|
<h2 class="text-2xl">
|
||||||
|
{resident
|
||||||
|
? messages.residents_modal_title_edit()
|
||||||
|
: messages.residents_modal_title_new()}
|
||||||
|
</h2>
|
||||||
<form method="dialog">
|
<form method="dialog">
|
||||||
<button class="btn btn-square btn-ghost btn-sm">✕</button>
|
<button class="btn btn-square btn-ghost btn-sm">✕</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<form method="POST" use:enhance>
|
<form method="POST" bind:this={form} use:enhance>
|
||||||
<TextInput bordered name="name">
|
{#if resident}
|
||||||
|
<input type="hidden" name="id" value={resident.id} />
|
||||||
|
{/if}
|
||||||
|
<TextInput bordered name="name" value={resident?.name}>
|
||||||
{#snippet label()}
|
{#snippet label()}
|
||||||
<UserRound size="18" />
|
<UserRound size="18" />
|
||||||
{messages.residents_modal_label_name()}
|
{messages.residents_modal_label_name()}
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</TextInput>
|
</TextInput>
|
||||||
<TextInput bordered name="phoneNumber" type={'tel'}>
|
<TextInput bordered name="phoneNumber" type={'tel'} value={resident?.phoneNumber}>
|
||||||
{#snippet label()}
|
{#snippet label()}
|
||||||
<Phone size="18" />
|
<Phone size="18" />
|
||||||
{messages.residents_modal_label_phone()}
|
{messages.residents_modal_label_phone()}
|
||||||
|
|
@ -61,5 +78,11 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<ResidentTable items={residents} />
|
<ResidentTable
|
||||||
|
items={residents}
|
||||||
|
onEdit={(r) => {
|
||||||
|
resident = r;
|
||||||
|
dialog?.showModal();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue