penisularhr-ui / src / routes / app / monthly / +page.svelte
+page.svelte
Raw
<script lang="ts">
	import {
		Button,
		Input,
		Label,
		P,
		Spinner,
		Table,
		TableBody,
		TableBodyCell,
		TableBodyRow,
		TableHead,
		TableHeadCell
	} from 'flowbite-svelte';
	import { ArrowRightSolid, ArrowLeftSolid } from 'flowbite-svelte-icons';
	import Form from './Form.svelte';
	import { enhance } from '$app/forms';
	import { onMount } from 'svelte';

	// Input value
	let formValues: {
		id: null | string;
		restDayWages: null | number;
		advance: null | number;
		cleaningFee: null | number;
		epf: null | number;
		eis: null | number;
		socso: null | number;
		levy: null | number;
		deduct: null | number;
		addition: null | number;
		remark: null | string;
	} = {
		id: null,
		restDayWages: null,
		advance: null,
		cleaningFee: null,
		epf: null,
		eis: null,
		socso: null,
		levy: null,
		deduct: null,
		addition: null,
		remark: null
	};

	let inputLoading = false;

	async function editFormValue(el: any) {
		formValues = {
			...el
		};
	}

	function resetFormInput() {
		formValues = {
			id: null,
			restDayWages: null,
			advance: null,
			cleaningFee: null,
			epf: null,
			eis: null,
			socso: null,
			levy: null,
			deduct: null,
			addition: null,
			remark: null
		};
	}

	function updateInputLoading(state: boolean) {
		inputLoading = state;
	}

	// Page meta value
	let page = 1;
	let pageCount: number | string = '...';
	let hasPreviousPage = false;
	let hasNextPage = false;

	// Filter page value
	let filterDate: Date | null = null;
	let filterEmployee: string | null = null;
	let tableError: string | null = null;

	let tableLoading = false;
	let tableData: any;

	function handleSubmit({ formData }: { formData: any }) {
		tableLoading = true;

		formData.set('page', page);

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

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

			if (result.type !== 'success') {
				tableError = result.data.message;
				tableData = null;
				pageCount = 1;
				hasPreviousPage = false;
				hasNextPage = false;
				return;
			}

			tableError = null;
			tableData = result.data.returnData;
			pageCount = result.data.pageCount;
			hasPreviousPage = result.data.hasPreviousPage;
			hasNextPage = result.data.hasNextPage;
			return;
		};
	}

	function reloadTable() {
		const form: any = document.getElementById('getTableData'); // Replace with your form ID
		const submitEvent = new Event('submit', { bubbles: true, cancelable: true });

		// Dispatch the submit event on the form element
		form.dispatchEvent(submitEvent);
	}

	onMount(() => {
		reloadTable();
	});
</script>

<div>
	<Form {reloadTable} {formValues} {resetFormInput} {updateInputLoading} {inputLoading} />

	<div class="mt-10 flex flex-col">
		<form method="post" id="getTableData" action="?/getTableData" use:enhance={handleSubmit}>
			<div class="mb-5 flex gap-3">
				<div>
					<Label for="filterDate" class="mb-2">Date</Label>
					<Input id="filterDate" type="date" name="filterDate" bind:value={filterDate} />
				</div>
				<div>
					<Label for="filterEmployee" class="mb-2">Employee</Label>
					<Input
						id="filterEmployee"
						type="text"
						name="filterEmployee"
						bind:value={filterEmployee}
					/>
				</div>
				<Button
					color="alternative"
					class="h-fit place-self-end"
					on:click={() => {
						filterDate = null;
						filterEmployee = null;
					}}>Reset</Button
				>
				<Button type="submit" class="h-fit place-self-end">Filter</Button>
			</div>
		</form>

		{#if tableLoading}
			<Spinner />
			<p>loading...</p>
		{/if}

		{#if tableError}
			<p>{tableError}</p>
		{/if}

		{#if tableData}
			<Table hoverable={true}>
				<TableHead>
					{#each Object.keys(tableData[0]) as header}
						<TableHeadCell class="normal-case text-sm text-center">{header}</TableHeadCell>
					{/each}
				</TableHead>

				<TableBody>
					{#each tableData as el}
						<TableBodyRow>
							{#each Object.keys(el) as keys}
								<TableBodyCell class="font-normal text-center"
									>{el[keys] === null || el[keys] === 0 ? '-' : el[keys]}</TableBodyCell
								>
							{/each}
							<TableBodyCell class="font-normal text-center">
								<button
									class="font-medium text-primary-600 hover:underline dark:text-primary-500 cursor-pointer"
									on:click={editFormValue.bind(null, el)}
								>
									Edit
								</button></TableBodyCell
							>
						</TableBodyRow>
					{/each}
				</TableBody>
			</Table>
		{/if}
	</div>

	<div class="flex gap-3 mt-5">
		<Button
			size="xs"
			disabled={!hasPreviousPage}
			on:click={async () => {
				page--;
				tableError = null;
				reloadTable();
			}}
		>
			<ArrowLeftSolid size="sm" />
		</Button>
		<P size="base" class="self-center">{page}/{pageCount}</P>
		<Button
			size="xs"
			disabled={!hasNextPage}
			on:click={async () => {
				page++;
				tableError = null;
				reloadTable();
			}}
		>
			<ArrowRightSolid size="sm" />
		</Button>
	</div>
</div>