penisularhr-ui / src / routes / app / sector / Form.svelte
Form.svelte
Raw
<script lang="ts">
	import { enhance } from '$app/forms';
	import { Input, Label, Button, Spinner, Toast, Modal } from 'flowbite-svelte';
	import { CheckCircleSolid, CloseCircleSolid } from 'flowbite-svelte-icons';
	import type { PageData } from './$types';
	import { PUBLIC_BASE_API_URL } from '$env/static/public';

	export let formValues: any;
	export let resetFormInput: any;
	export let inputLoading: any;
	export let updateInputLoading: any;
	export let reloadTable: any;
	export let data: PageData;

	let inputError: string | null = null;
	let inputResponse: string | null = null;
	let popupModal = false;

	function handleSubmit({ formData }: { formData: FormData }) {
		if (formValues.id) {
			formData.set('id', formValues.id);
		}

		updateInputLoading(true);

		return async ({ result, update }: { result: any; update: any }) => {
			await update({ reset: false });

			if (result.data.id !== 'inputData') {
				return;
			}

			if (result.type !== 'success') {
				inputError = result.data.message;
				updateInputLoading(false);
				return;
			}

			inputResponse = result.data.message;

			reloadTable();
			updateInputLoading(false);
		};
	}

	const deleteData = async (uuid: string) => {
		updateInputLoading(true);
		const response = await fetch(`${PUBLIC_BASE_API_URL}/sector/${uuid}`, {
			headers: {
				'Content-Type': 'application/json',
				Authorization: `Bearer ${data.accessToken}`
			},
			method: 'DELETE'
		});

		const parsedResponse = await response.json();

		if (
			parsedResponse.statusCode?.toString().startsWith('4') ||
			parsedResponse.statusCode?.toString().startsWith('5')
		) {
			inputError = parsedResponse.message;
		} else {
			reloadTable();
			resetFormInput();
			inputResponse = 'Deleted';
		}

		updateInputLoading(false);
	};

	const resetActionForm = () => {
		inputError = null;
		inputResponse = null;
	};
</script>

<form method="post" action="?/create" use:enhance={handleSubmit}>
	<div class="grid gap-6 mb-6 grid-cols-2 lg:grid-cols-5 w-fit">
		<div>
			<Label for="id" class="mb-2">Id</Label>
			<Input disabled type="text" id="id" name="id" bind:value={formValues.id} />
		</div>
		<div>
			<Label for="name" class="mb-2">Name</Label>
			<Input
				type="text"
				id="name"
				name="name"
				on:keydown={resetActionForm}
				bind:value={formValues.name}
			/>
		</div>
	</div>

	{#if inputError !== null}
		<Toast color="red" position="top-right" dismissable={true}>
			<svelte:fragment slot="icon">
				<CloseCircleSolid class="w-5 h-5" />
				<span class="sr-only">Error icon</span>
			</svelte:fragment>
			{inputError}
		</Toast>
	{/if}

	{#if inputResponse !== null}
		<Toast color="green" position="top-right" dismissable={true}>
			<svelte:fragment slot="icon">
				<CheckCircleSolid class="w-5 h-5" />
				<span class="sr-only">Check icon</span>
			</svelte:fragment>
			{inputResponse} successfully.
		</Toast>
	{/if}

	<div class="flex gap-4">
		<Button color="alternative" on:click={resetFormInput}>Reset</Button>
		<Button type="submit" disabled={!!formValues.id}
			>{#if inputLoading}
				<Spinner />
			{:else}
				<p>Create</p>
			{/if}
		</Button>
		<Button type="submit" formaction="?/update" color="purple" disabled={!formValues.id}>
			{#if inputLoading}
				<Spinner />
			{:else}
				<p>Update</p>
			{/if}</Button
		>
		<Button color="red" disabled={!formValues.id} on:click={() => (popupModal = true)}
			>Delete</Button
		>
	</div>

	<Modal bind:open={popupModal} size="xs" autoclose>
		<div class="text-center">
			<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">
				Are you sure you want to delete this data?
			</h3>
			<Button
				color="red"
				class="mr-2"
				type="submit"
				on:click={async () => await deleteData(formValues.id)}>Yes, I'm sure</Button
			>
			<Button color="alternative">No, cancel</Button>
		</div>
	</Modal>
</form>