This commit is contained in:
2025-06-06 11:46:55 +08:00
5 changed files with 1640 additions and 2 deletions

BIN
src/lib/images/logo.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -303,8 +303,18 @@
class="max-w-6xl mx-auto bg-white p-8 rounded-2xl shadow-xl space-y-8 text-gray-800" class="max-w-6xl mx-auto bg-white p-8 rounded-2xl shadow-xl space-y-8 text-gray-800"
on:submit|preventDefault={handleSubmit} on:submit|preventDefault={handleSubmit}
> >
<!-- logo -->
<div class="text-center mb-6">
<img
src="/src/lib/images/logo.webp"
alt="Logo"
class="mx-auto"
loading="lazy"
width="250"
/>
</div>
<!-- Title --> <!-- Title -->
<h2 class="text-2xl font-semibold">Submit New Issue</h2> <h2 class="text-2xl font-semibold text-center">Submit New Issue</h2>
<!-- 2 Column Grid --> <!-- 2 Column Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> <div class="grid grid-cols-1 md:grid-cols-2 gap-8">

File diff suppressed because it is too large Load Diff

View File

@@ -158,8 +158,18 @@
class="max-w-6xl mx-auto bg-white p-8 rounded-2xl shadow-xl space-y-8 text-gray-800" class="max-w-6xl mx-auto bg-white p-8 rounded-2xl shadow-xl space-y-8 text-gray-800"
on:submit|preventDefault={handleSubmit} on:submit|preventDefault={handleSubmit}
> >
<!-- logo -->
<div class="text-center mb-6">
<img
src="/src/lib/images/logo.webp"
alt="Logo"
class="mx-auto"
loading="lazy"
width="250"
/>
</div>
<!-- Title --> <!-- Title -->
<h2 class="text-2xl font-semibold">Timesheet Form</h2> <h2 class="text-2xl font-semibold text-center">Timesheet Form</h2>
<!-- 2 Column Grid --> <!-- 2 Column Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> <div class="grid grid-cols-1 md:grid-cols-2 gap-8">

View File

@@ -0,0 +1,244 @@
<script lang="ts">
// This is a placeholder for any script you might want to add
// For example, you could handle form submission here
import { onMount } from "svelte";
import { supabase } from "$lib/supabaseClient";
import { writable } from "svelte/store";
const area = [
{ label: "Laksamana", value: "Laksamana" },
{ label: "Drupadi", value: "Drupadi" },
{ label: "Abimanyu", value: "Abimanyu" },
{ label: "Seminyak", value: "Seminyak" },
];
const requestThings = [
{ label: "Airport pickup", value: "Airport pickup" },
{ label: "Airport transfer", value: "Airport transfer" },
{ label: "Day car charter", value: "Day car charter" },
{ label: "One way drop off", value: "One way drop off" },
{ label: "One way pickup", value: "One way pickup" },
{ label: "Other", value: "Other" },
];
type transport = {
guest_name: string;
requested_date: string;
area: string;
pickup_date: string;
request_things: string;
additional_notes: string;
requested_by: string;
vendor_email_address: string;
};
type transportInsert = {
guest_name: string;
requested_date: string;
area: string;
pickup_date: string;
request_things: string;
additional_notes: string;
requested_by: string;
vendor_email_address: string;
};
async function handleSubmit(event: Event): Promise<void> {
event.preventDefault();
const formData = new FormData(event.target as HTMLFormElement);
// Validate form data
if (!validateForm(formData)) {
console.error("Form validation failed");
return;
}
const transport: transportInsert = {
guest_name: formData.get("guest_name") as string,
requested_date: formData.get("requested_date") as string,
area: formData.get("area") as string,
pickup_date: formData.get("pickup_date") as string,
request_things: formData.get("request_things") as string,
additional_notes: formData.get("additional_notes") as string,
requested_by: formData.get("requested_by") as string,
vendor_email_address: formData.get(
"vendor_email_address",
) as string,
};
const { data, error } = await supabase
.from("vb_transport")
.insert([transport]);
if (error) {
console.error("Error submitting transport:", error);
} else {
console.log("Transport submitted successfully:", data);
alert("Transport submitted successfully!");
}
}
export let formErrors = writable<{ [key: string]: string }>({});
function validateForm(formData: FormData): boolean {
const errors: { [key: string]: string } = {};
const requiredFields = [
"guest_name",
"requested_date",
"area",
"pickup_date",
"request_things",
"requested_by",
"vendor_email_address",
];
requiredFields.forEach((field) => {
if (!formData.get(field) || formData.get(field) === "") {
errors[field] = `${field.replace(/_/g, " ")} is required.`;
}
});
formErrors.set(errors);
return Object.keys(errors).length === 0;
}
function errorClass(field: string): string {
return $formErrors[field] ? "border-red-500" : "border";
}
</script>
<div>
<form
class="max-w-6xl mx-auto bg-white p-8 rounded-2xl shadow-xl space-y-8 text-gray-800"
on:submit|preventDefault={handleSubmit}
>
<!-- logo -->
<div class="text-center mb-6">
<img
src="/src/lib/images/logo.webp"
alt="Logo"
class="mx-auto"
loading="lazy"
width="250"
/>
</div>
<!-- Title -->
<h2 class="text-2xl font-semibold text-center">Transport Request</h2>
<!-- 2 Column Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div>
<label class="block text-sm font-medium mb-1">Guest Name</label>
<input
type="text"
name="guest_name"
placeholder="Guest Name"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'guest_name',
)}"
/>
</div>
<div>
<label class="block text-sm font-medium mb-1"
>Requested Date</label
>
<input
type="date"
name="requested_date"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'requested_date',
)}"
/>
</div>
<div>
<label class="block text-sm font-medium mb-1">Area</label>
<select
name="area"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'area',
)}"
>
<option value="" disabled selected>Select Area</option>
{#each area as item}
<option value={item.value}>{item.label}</option>
{/each}
</select>
</div>
<div>
<label class="block text-sm font-medium mb-1">Pickup Date</label
>
<input
type="date"
name="pickup_date"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'pickup_date',
)}"
/>
</div>
<div>
<label class="block text-sm font-medium mb-1"
>Request Things</label
>
<select
name="request_things"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'request_things',
)}"
>
<option value="" disabled selected>Select Request</option>
{#each requestThings as item}
<option value={item.value}>{item.label}</option>
{/each}
</select>
</div>
<div>
<label class="block text-sm font-medium mb-1"
>Additional Notes</label
>
<textarea
name="additional_notes"
placeholder="Additional Notes"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'additional_notes',
)}"
></textarea>
</div>
<div>
<label class="block text-sm font-medium mb-1"
>Requested By</label
>
<input
type="text"
name="requested_by"
placeholder="Requested By"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'requested_by',
)}"
/>
</div>
<div>
<label class="block text-sm font-medium mb-1"
>Vendor Email Address</label
>
<input
type="email"
name="vendor_email_address"
placeholder="Vendor Email Address"
class="w-full border rounded-xl px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-400 {errorClass(
'vendor_email_address',
)}"
/>
</div>
</div>
<!-- Submit Button -->
<div class="text-center pt-4">
<button
type="submit"
class="bg-purple-600 text-white px-8 py-3 rounded-xl hover:bg-purple-700 transition-all font-medium shadow-md"
>
Submit
</button>
</div>
</form>
</div>