81 lines
2.2 KiB
Svelte
81 lines
2.2 KiB
Svelte
<script lang="ts">
|
|
import type { ComponentProps } from 'svelte';
|
|
import type { DB } from '$lib/integrations/db';
|
|
import Modal from '../atoms/Modal.svelte';
|
|
import Button from '../atoms/Button.svelte';
|
|
import { page } from '$app/state';
|
|
|
|
type CreatePerson = Parameters<typeof DB.createPerson>[0];
|
|
|
|
type Props = {
|
|
onSave: (data: CreatePerson) => Promise<void>;
|
|
editPerson?: Person;
|
|
} & Omit<ComponentProps<typeof Modal>, 'children'>;
|
|
|
|
let { onSave, isOpen, onClose, editPerson }: Props = $props();
|
|
|
|
let person = $state<Person>(editPerson ?? ({} as Person));
|
|
let isLoading = $state(false);
|
|
|
|
if (!person?.name) {
|
|
person.name = '';
|
|
person.notes = '';
|
|
person.years = [page.params.year || new Date().getFullYear().toString()];
|
|
}
|
|
|
|
const handleSubmit = async (e: Event) => {
|
|
e.preventDefault();
|
|
if (!person) return;
|
|
|
|
isLoading = true;
|
|
try {
|
|
await onSave(person);
|
|
} catch (error) {
|
|
console.error(error);
|
|
} finally {
|
|
isLoading = false;
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<Modal {isOpen} {onClose} title={person ? 'Edytuj osobę' : 'Dodaj nową osobę'}>
|
|
<form onsubmit={handleSubmit} class="space-y-4">
|
|
<div>
|
|
<label for="name" class="mb-2 block text-sm font-medium text-gray-700">
|
|
Imię i nazwisko *
|
|
</label>
|
|
<input
|
|
id="name"
|
|
type="text"
|
|
class="w-full rounded-xl border border-gray-300 px-4 py-2 transition-all outline-none focus:border-transparent focus:ring-2 focus:ring-blue-500"
|
|
required
|
|
disabled={isLoading}
|
|
bind:value={person.name}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label for="notes" class="mb-2 block text-sm font-medium text-gray-700"> Notatki </label>
|
|
<textarea
|
|
id="notes"
|
|
rows={4}
|
|
class="w-full resize-none rounded-xl border border-gray-300 px-4 py-2 transition-all outline-none focus:border-transparent focus:ring-2 focus:ring-blue-500"
|
|
disabled={isLoading}
|
|
bind:value={person.notes}
|
|
></textarea>
|
|
</div>
|
|
</form>
|
|
|
|
{#snippet footer()}
|
|
<div class="flex justify-end gap-3">
|
|
<Button variant="secondary" onClick={onClose} disabled={isLoading}>Anuluj</Button>
|
|
<Button
|
|
variant="primary"
|
|
onClick={handleSubmit}
|
|
disabled={isLoading || !person?.name?.trim()}
|
|
>
|
|
{isLoading ? 'Zapisywanie...' : 'Zapisz'}
|
|
</Button>
|
|
</div>
|
|
{/snippet}
|
|
</Modal>
|