penisularhr-ui / src / routes / app / employee / Form.svelte
Form.svelte
Raw
<script lang="ts">
	import { enhance } from '$app/forms';
	import { Input, Label, Button, Select, Spinner, Toast, Toggle } from 'flowbite-svelte';
	import { CheckCircleSolid, CloseCircleSolid } from 'flowbite-svelte-icons';

	export let formValues: any;
	export let resetFormInput: any;
	export let inputLoading: any;
	export let updateInputLoading: any;
	export let reloadDropdown: any;

	export let reloadTable: any;

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

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

		if (formValues.isActive !== null) {
			formData.set('isActive', formValues.isActive);
		}

		if (formValues.shouldDeductSocso !== null) {
			formData.set('shouldDeductSocso', formValues.shouldDeductSocso);
		}

		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();
			await reloadDropdown();
			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"
				required
				on:keydown={resetActionForm}
				bind:value={formValues.name}
			/>
		</div>
		<div>
			<Label for="origin" class="mb-2">Origin (Optional)</Label>
			<Input
				type="text"
				id="origin"
				name="origin"
				on:keydown={resetActionForm}
				bind:value={formValues.origin}
			/>
		</div>
		<div>
			<Label for="dateJoin" class="mb-2">Date Join</Label>
			<Input
				type="date"
				id="dateJoin"
				name="dateJoin"
				required
				on:change={resetActionForm}
				bind:value={formValues.dateJoin}
			/>
		</div>
		<div>
			<Label for="dateResign" class="mb-2">Date Resign (Optional)</Label>
			<Input
				type="date"
				id="dateResign"
				name="dateResign"
				on:change={resetActionForm}
				bind:value={formValues.dateResign}
			/>
		</div>
		<div>
			<Label class={`${!formValues.selection ? '' : 'text-black'}`}>
				Referral By
				<Select
					class="mt-2"
					items={formValues.selection ? formValues.selection.fullSelectionEmployee : []}
					bind:value={formValues.referralBy}
					on:change={resetActionForm}
					name="referralBy"
					disabled={!formValues.selection}
				/>
			</Label>
		</div>
		<div>
			<Label for="referralFeePaidAt" class="mb-2">Referral Fee Paid At (Optional)</Label>
			<Input
				type="date"
				id="referralFeePaidAt"
				name="referralFeePaidAt"
				on:change={resetActionForm}
				bind:value={formValues.referralFeePaidAt}
			/>
		</div>
		<div>
			<Label for="basicSalary" class="mb-2">Basic Salary</Label>
			<Input
				type="number"
				id="basicSalary"
				name="basicSalary"
				min="0"
				step=".01"
				required
				on:keydown={resetActionForm}
				bind:value={formValues.basicSalary}
			/>
		</div>
		<div>
			<Label for="monthlyAllowanceAmount" class="mb-2">Monthly Fixed Allowance Amount</Label>
			<Input
				type="number"
				id="monthlyAllowanceAmount"
				name="monthlyAllowanceAmount"
				step=".01"
				min="0"
				required
				on:keydown={resetActionForm}
				bind:value={formValues.monthlyAllowanceAmount}
			/>
		</div>
		<div>
			<Label for="annualLeave" class="mb-2">Annual Leave By Year</Label>
			<Input
				type="number"
				id="annualLeave"
				name="annualLeave"
				step=".01"
				min="0"
				required
				on:keydown={resetActionForm}
				bind:value={formValues.annualLeave}
			/>
		</div>
		<div>
			<Label for="sickLeave" class="mb-2">Sick Leave By Year</Label>
			<Input
				type="number"
				id="sickLeave"
				name="sickLeave"
				step=".01"
				min="0"
				required
				on:keydown={resetActionForm}
				bind:value={formValues.sickLeave}
			/>
		</div>
		<div>
			<Label for="epfRatePer" class="mb-2">EPF Rate Percentage</Label>
			<Input
				type="number"
				id="epfRatePer"
				name="epfRatePer"
				step=".01"
				min="0"
				required
				on:keydown={resetActionForm}
				bind:value={formValues.epfRatePer}
			/>
		</div>
		<div>
			<Label for="isActive">Is Active</Label>
			<Toggle
				id="isActive"
				name="isActive"
				bind:checked={formValues.isActive}
				on:change={resetActionForm}
			/>
		</div>
		<div>
			<Label for="shouldDeductSocso">Should Deduct Socso</Label>
			<Toggle
				id="shouldDeductSocso"
				name="shouldDeductSocso"
				bind:checked={formValues.shouldDeductSocso}
				on:change={resetActionForm}
			/>
		</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
		>
	</div>
</form>