penambahan fitur upload

This commit is contained in:
Aji Setiaji
2025-05-29 16:17:21 +07:00
parent 8d984635af
commit 5845704f1f
8 changed files with 1979 additions and 119 deletions

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import { supabase } from "$lib/supabaseClient";
import { onMount } from "svelte";
import { writable } from "svelte/store";
type Vendor = {
id: string;
@@ -18,6 +19,10 @@
let allRowsVendor: Vendor[] = [];
let allRowsContactVendor: ContactVendor[] = [];
let offset = 0;
let limit = 10;
let totalItems = 0;
export let formErrors = writable<{ [key: string]: string }>({});
type columns = {
key: string;
@@ -35,26 +40,48 @@
{ key: "created_at", title: "Created At" },
];
onMount(async () => {
const { data: vendorData, error: vendorError } = await supabase
async function fetchVendor(
searchTerm: string = "",
orderBy: string = "created_at",
orderDirection: "asc" | "desc" = "desc",
limit: number = 10,
offset: number = 0,
) {
let query = supabase
.from("vendor")
.select("*")
.order("created_at", { ascending: false });
.select("*", { count: "exact" })
.order(orderBy, { ascending: orderDirection === "asc" })
.range(offset, offset + limit - 1);
if (vendorError) {
console.error("Error fetching vendors:", vendorError);
} else {
allRowsVendor = vendorData as Vendor[];
if (searchTerm) {
query = query.ilike("name", `%${searchTerm}%`);
}
const { data, error, count } = await query;
if (error) {
console.error("Error fetching vendors:", error);
return [];
}
allRowsVendor = data as Vendor[];
const { count: total } = await supabase
.from("vendor")
.select("*", { count: "exact" })
.ilike("name", `%${searchTerm}%`);
totalItems = total || 0;
offset = Math.floor(totalItems / limit) * limit;
}
onMount(() => {
fetchVendor();
});
let currentPage = 1;
let itemsPerPage = 10;
$: totalPages = Math.ceil(allRowsVendor.length / itemsPerPage);
$: paginatedRows = allRowsVendor.slice(
(currentPage - 1) * itemsPerPage,
currentPage * itemsPerPage,
);
let currentPage = offset + 1;
let itemsPerPage = limit;
let totalPages = Math.ceil(totalItems / itemsPerPage);
function nextPage() {
if (currentPage < totalPages) {
@@ -276,22 +303,65 @@
</script>
<!-- Table untuk daftar Vendor -->
<div class="p-4 border-b border-gray-200 flex justify-between items-center">
<div>
<h2 class="text-lg font-semibold text-gray-800">Vendor List</h2>
<p class="text-sm text-gray-600">Manage your vendor and contact data</p>
</div>
<button
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 text-sm"
on:click={() => {
showModal = true;
isEditing = false;
newVendor = {};
currentEditingId = null;
}}
<div>
<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"
>
Add Vendor
</button>
<div>
<h2 class="text-xl font-semibold text-gray-800">🏡 Vendor List</h2>
<p class="text-sm text-gray-500">
Manage your vendors and their contact information here.
</p>
</div>
<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();
fetchVendor(searchTerm, "created_at", "desc", limit, 0);
}}
/>
<!-- filter -->
<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 value = (e.target as HTMLSelectElement).value;
fetchVendor("", value, "desc", limit, 0);
}}
>
<option value="created_at">Sort by Created At</option>
<option value="name">Sort by Name</option>
<option value="vendor_type">Sort by Vendor Type</option>
<option value="vendor_status">Sort by Vendor Status</option>
<option value="vendor_subtype">Sort by Vendor Subtype</option>
</select>
<!-- button reset -->
<button
class="bg-gray-200 text-gray-700 px-4 py-2 rounded hover:bg-gray-300 text-sm"
on:click={() => {
fetchVendor();
resetPagination();
}}
>
🔄 Reset
</button>
<button
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 text-sm"
on:click={() => {
showModal = true;
isEditing = false;
newVendor = {};
currentEditingId = null;
}}
>
Add Vendor
</button>
</div>
</div>
</div>
<!-- Vendor Table -->
@@ -310,7 +380,7 @@
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
{#each paginatedRows as vendor}
{#each allRowsVendor as vendor}
<tr
class="hover:bg-gray-50 transition"
on:click={() => handleVendorClick(vendor.id)}