From 20facfc48e1c68b70f76a96c06f0b9da4021eaa2 Mon Sep 17 00:00:00 2001 From: Aji Setiaji Date: Fri, 12 Sep 2025 04:31:56 +0700 Subject: [PATCH] perbaikan data HR dengan BENEFITS --- .../humanresource/employee/+page.svelte | 317 +++++++++++++++++- 1 file changed, 302 insertions(+), 15 deletions(-) diff --git a/src/routes/backoffice/humanresource/employee/+page.svelte b/src/routes/backoffice/humanresource/employee/+page.svelte index 88520f3..68a636b 100644 --- a/src/routes/backoffice/humanresource/employee/+page.svelte +++ b/src/routes/backoffice/humanresource/employee/+page.svelte @@ -54,6 +54,17 @@ created_at?: Date; }; + type EmployeeBenefits = { + id: string; + employee_id: string; + basic_salary: number; + position_allowance: number; + meal_allowance: number; + transportation_allowance: number; + created_at: Date; + updated_at: Date; + }; + const EmployeeStatus = { Active: "Active", Inactive: "Inactive", @@ -110,7 +121,10 @@ { key: "temporary_address", title: "Temporary Address" }, { key: "job_title", title: "Job Title" }, { key: "emergency_contact_name", title: "Emergency Contact Name" }, - { key: "emergency_contact_relation", title: "Emergency Contact Relation" }, + { + key: "emergency_contact_relation", + title: "Emergency Contact Relation", + }, { key: "emergency_contact_phone", title: "Emergency Contact Phone" }, { key: "bank_account", title: "Bank Account" }, { key: "bank_account_name", title: "Employee Bank Account Name" }, @@ -130,10 +144,20 @@ { key: "child_2", title: "Child 2" }, { key: "child_3", title: "Child 3" }, { key: "document", title: "Document" }, + { key: "benefits", title: "Benefits" }, { key: "created_at", title: "Created At" }, { key: "actions", title: "Actions" }, ]; + const columnBenefits: columns[] = [ + { key: "basic_salary", title: "Basic Salary" }, + { key: "position_allowance", title: "Position Allowance" }, + { key: "meal_allowance", title: "Meal Allowance" }, + { key: "transportation_allowance", title: "Transportation Allowance" }, + { key: "created_at", title: "Created At" }, + { key: "updated_at", title: "Updated At" }, + ]; + let currentPage = offset + 1; let rowsPerPage = 10; let totalItems = 0; @@ -177,6 +201,21 @@ console.log("Total Items:", totalItems); } + async function fetchEmployeeBenefits(employeeId: string) { + const { data, error } = await supabase + .from("vb_benefits") + .select("*") + .eq("employee_id", employeeId) + .single(); + + if (error) { + console.error("Error fetching Employee Benefits:", error); + return null; + } + + return data as EmployeeBenefits; + } + $: totalPages = Math.ceil(totalItems / rowsPerPage); function goToPage(page: number) { @@ -185,7 +224,13 @@ currentPage = page; offset = (currentPage - 1) * rowsPerPage; - fetchEmployee(search, "created_at", "desc", currentPage - 1, rowsPerPage); + fetchEmployee( + search, + "created_at", + "desc", + currentPage - 1, + rowsPerPage, + ); } function pageRange( @@ -220,7 +265,13 @@ currentPage = page; offset = (currentPage - 1) * rowsPerPage; - fetchEmployee(search, "created_at", "desc", currentPage - 1, rowsPerPage); + fetchEmployee( + search, + "created_at", + "desc", + currentPage - 1, + rowsPerPage, + ); } onMount(() => { @@ -231,6 +282,7 @@ $: currentPage = 1; let showModal = false; + let showModalBenefits = false; let isEditing = false; let currentEditingId: string | null = null; let newEmployeeInsert: EmployeeItem = { @@ -282,21 +334,68 @@ created_at: new Date(), }; + let newEmployeeBenefits: EmployeeBenefits = { + id: "", + employee_id: "", + basic_salary: 0, + position_allowance: 0, + meal_allowance: 0, + transportation_allowance: 0, + created_at: new Date(), + updated_at: new Date(), + }; + + let employeeBenefits: EmployeeBenefits = { + id: "", + employee_id: "", + basic_salary: 0, + position_allowance: 0, + meal_allowance: 0, + transportation_allowance: 0, + created_at: new Date(), + updated_at: new Date(), + } + const excludedKeys = ["id", "actions", "created_at", "no"]; const formColumns = columns.filter( (col) => !excludedKeys.includes(col.key), ); - function openModal(newEmployeeItem?: EmployeeItem) { - if (newEmployeeItem) { - console.log("Editing Employee:", newEmployeeItem); + const excludedKeysBenefits = [ + "id", + "employee_id", + "created_at", + "updated_at", + ]; + const formColumnsBenefits = columnBenefits.filter( + (col) => !excludedKeysBenefits.includes(col.key), + ); + function openModal(newEmployeeItem?: EmployeeItem, emp?: number) { + if (newEmployeeItem) { isEditing = true; currentEditingId = newEmployeeItem.id; - console.log("Current Editing ID:", currentEditingId); // Copy data to avoid direct mutation newEmployeeInsert = { ...newEmployeeItem }; + + // Fetch and populate benefits data + fetchEmployeeBenefits(newEmployeeItem.id).then((benefits) => { + if (benefits) { + newEmployeeBenefits = benefits; + } else { + newEmployeeBenefits = { + id: "", + employee_id: newEmployeeItem.id, + basic_salary: newEmployeeItem.salary || 0, + position_allowance: 0, + meal_allowance: 0, + transportation_allowance: 0, + created_at: new Date(), + updated_at: new Date(), + }; + } + }); } else { isEditing = false; currentEditingId = null; @@ -349,10 +448,42 @@ place_of_birth: "", created_at: new Date(), }; + + newEmployeeBenefits = { + id: "", + employee_id: "", + basic_salary: 0, + position_allowance: 0, + meal_allowance: 0, + transportation_allowance: 0, + created_at: new Date(), + updated_at: new Date(), + }; } showModal = true; } + async function openModalBenefits(employee: EmployeeItem) { + const benefits = await fetchEmployeeBenefits(employee.id); + + if (benefits) { + employeeBenefits = benefits; + } else { + employeeBenefits = { + id: "", + employee_id: employee.id, + basic_salary: employee.salary || 0, + position_allowance: 0, + meal_allowance: 0, + transportation_allowance: 0, + created_at: new Date(), + updated_at: new Date(), + }; + } + + showModalBenefits = true; + } + async function saveEmployee(event: Event) { event.preventDefault(); @@ -372,9 +503,50 @@ alert("Error updating Employee: " + error.message); console.error("Error updating Employee:", error); return; - } else { - alert("Employee updated successfully!"); } + // cek apakah data vb_benefits sudah ada + const { data: existingBenefits, error: checkError } = await supabase + .from("vb_benefits") + .select("id") + .eq("employee_id", currentEditingId) + .maybeSingle(); + + if (checkError) { + console.error("Error checking vb_benefits:", checkError); + } + + if (existingBenefits) { + // update jika ada + const { error: benefitsError } = await supabase + .from("vb_benefits") + .update(newEmployeeBenefits) + .eq("employee_id", currentEditingId); + + if (benefitsError) { + console.error("Error updating vb_benefits:", benefitsError); + } + } else { + + const idBenefit = uuidv4(); + newEmployeeBenefits.id = idBenefit; + newEmployeeBenefits.employee_id = currentEditingId; + + // insert jika belum ada + const { error: benefitsInsertError } = await supabase + .from("vb_benefits") + .insert({ + ...newEmployeeBenefits, + }); + + if (benefitsInsertError) { + console.error( + "Error inserting vb_benefits:", + benefitsInsertError, + ); + } + } + + alert("Employee Updated successfully!"); } else { newEmployeeInsert.id = uuidv4(); // Generate a new UUID for the ID @@ -386,6 +558,21 @@ alert("Error creating New Employee: " + error.message); console.error("Error creating New Employee:", error); return; + } + + newEmployeeBenefits.id = uuidv4(); + newEmployeeBenefits.employee_id = newEmployeeInsert.id; + + const { error: benefitsError } = await supabase + .from("vb_employee_benefits") + .insert(newEmployeeBenefits); + + if (benefitsError) { + console.error( + "Error creating Employee Benefits:", + benefitsError, + ); + return; } else { alert("New Employee created successfully!"); } @@ -467,9 +654,7 @@ placeholder="🔍 Search by item name..." class="border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:outline-none px-4 py-2 rounded-xl text-sm w-64 transition" on:input={(e) => { - search = ( - e.target as HTMLInputElement - ).value.toLowerCase(); + search = (e.target as HTMLInputElement).value.toLowerCase(); if (search !== "" && search.length > 3) { fetchEmployee(search, "created_at", "desc", 0, 10); @@ -575,7 +760,9 @@ {#if row[col.key as keyof EmployeeItem]} View - {:else if col.key === "contract_start" || col.key === "end_of_contract" || col.key === "date_of_birth"} + {:else if col.key === "contract_start" || col.key === "end_of_contract" || col.key === "date_of_birth" || col.key === "hire_date" || col.key === "leaving_date"} {row[col.key as keyof EmployeeItem] ? new Date( @@ -607,6 +794,15 @@ ).toLocaleDateString() : "N/A"} + {:else if col.key === "benefits"} + + + {:else if col.key === "created_at"} {row[col.key as keyof EmployeeItem] @@ -681,6 +877,7 @@ + {#if showModal} @@ -756,7 +953,9 @@ col.key, )}" > - + {#each Object.entries(MaritalStatus) as [key, value]} {/each} @@ -784,6 +983,38 @@ {/each} +

Benefits

+ + {#each formColumnsBenefits as col} +
+ + {#if col.key === "basic_salary"} + + {:else} + + {/if} +
+ {/each} +
{/if} + +{#if showModalBenefits} +
+
+

Employee Benefits

+ +
+ {#each formColumnsBenefits as col} +
+ + {#if col.key === "basic_salary"} + + {:else} + + {/if} +
+ {/each} + +
+ +
+
+
+
+{/if}