penamabahan menu approval untill received
This commit is contained in:
@@ -122,17 +122,37 @@
|
||||
{ key: "actions", title: "Actions" },
|
||||
];
|
||||
|
||||
async function fetchTimeSheets() {
|
||||
const { data: timesheet, error: timesheetError } = await supabase
|
||||
async function fetchTimeSheets(
|
||||
filter: string | null = null,
|
||||
searchTerm: string | null = null,
|
||||
sortColumn: string | null = "created_at",
|
||||
sortOrder: "asc" | "desc" = "desc",
|
||||
offset: number = 0,
|
||||
limit: number = 10,
|
||||
) {
|
||||
let query = supabase
|
||||
.from("timesheets")
|
||||
.select("*")
|
||||
.order("created_at", { ascending: false });
|
||||
|
||||
if (timesheetError) {
|
||||
console.error("Error fetching issues:", timesheetError);
|
||||
.select("*", { count: "exact" })
|
||||
.order(sortColumn || "created_at", {
|
||||
ascending: sortOrder === "asc",
|
||||
});
|
||||
if (filter) {
|
||||
query = query.eq("category_of_work", filter);
|
||||
}
|
||||
if (searchTerm) {
|
||||
query = query.ilike("name", `%${searchTerm}%`);
|
||||
}
|
||||
if (offset) {
|
||||
query = query.range(offset, offset + limit - 1);
|
||||
}
|
||||
if (limit) {
|
||||
query = query.limit(limit);
|
||||
}
|
||||
const { data: timesheet, error } = await query;
|
||||
if (error) {
|
||||
console.error("Error fetching timesheets:", error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ambil semua villa_id unik dari issues
|
||||
const villaIds = [
|
||||
...new Set(timesheet.map((i: Timesheets) => i.villa_id)),
|
||||
@@ -328,19 +348,54 @@
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="p-4 border-b border-gray-200 flex justify-between items-center">
|
||||
<div
|
||||
class="p-6 bg-white shadow-md rounded-2xl mb-4 flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4"
|
||||
>
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold text-gray-800">Timesheet List</h2>
|
||||
<h2 class="text-lg font-semibold text-gray-800">
|
||||
🕒 Timesheet List
|
||||
</h2>
|
||||
<p class="text-sm text-gray-600">
|
||||
Manage and track timesheets for staff members.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 text-sm"
|
||||
on:click={() => openModal()}
|
||||
>
|
||||
➕ Add Timesheet
|
||||
</button>
|
||||
<div class="flex flex-col sm:flex-row sm:items-center gap-2">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="🔍 Search by 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) => {
|
||||
const searchTerm = (
|
||||
e.target as HTMLInputElement
|
||||
).value.toLowerCase();
|
||||
fetchTimeSheets(null, searchTerm, "created_at", "desc");
|
||||
}}
|
||||
/>
|
||||
<select
|
||||
class="border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:outline-none px-4 py-2 rounded-xl text-sm w-48 transition"
|
||||
on:change={(e) => {
|
||||
const filter = (e.target as HTMLSelectElement).value;
|
||||
fetchTimeSheets(filter, null, null, "desc");
|
||||
}}
|
||||
>
|
||||
<option value="">All Issues</option>
|
||||
<option value="PROJECT">Project Issues</option>
|
||||
<option value="PURCHASE_ORDER">Purchase Order Issues</option>
|
||||
</select>
|
||||
<button
|
||||
class="bg-gray-200 text-gray-700 px-4 py-2 rounded-xl hover:bg-gray-300 text-sm transition"
|
||||
on:click={() =>
|
||||
fetchTimeSheets(null, null, "created_at", "desc", 0, 10)}
|
||||
>
|
||||
🔄 Reset
|
||||
</button>
|
||||
<button
|
||||
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 text-sm"
|
||||
on:click={() => openModal()}
|
||||
>
|
||||
➕ Add Timesheet
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto rounded-lg shadow mb-4">
|
||||
<table class="min-w-[1000px] divide-y divide-gray-200 text-sm w-max">
|
||||
|
||||
Reference in New Issue
Block a user