practical5 wip
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"pluginSearchDirs": ["."], // should be removed in v3
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }],
|
||||
"printWidth": 120,
|
||||
"singleAttributePerLine": true
|
||||
}
|
||||
|
||||
@@ -26,7 +26,18 @@
|
||||
description: "",
|
||||
weight_kg: 0,
|
||||
dimensions: { length_cm: 0, width_cm: 0, height_cm: 0 },
|
||||
status: "PENDING",
|
||||
status: "",
|
||||
});
|
||||
|
||||
let errors = $derived.by(() => {
|
||||
const e = {};
|
||||
if (!formData.name.trim()) e.name = "Name is required";
|
||||
if (formData.weight_kg <= 0) e.weight_kg = "Weight must be positive";
|
||||
if (formData.dimensions.length_cm <= 0) e.length_cm = "Length must be positive";
|
||||
if (formData.dimensions.width_cm <= 0) e.width_cm = "Width must be positive";
|
||||
if (formData.dimensions.height_cm <= 0) e.height_cm = "Height must be positive";
|
||||
if (!formData.status.trim()) e.status = "Status is required";
|
||||
return e;
|
||||
});
|
||||
|
||||
const BASE_URL = "http://localhost:8079/freight-service/freights";
|
||||
@@ -75,7 +86,7 @@
|
||||
description: "",
|
||||
weight_kg: 0,
|
||||
dimensions: { length_cm: 0, width_cm: 0, height_cm: 0 },
|
||||
status: "PENDING",
|
||||
status: "",
|
||||
};
|
||||
}
|
||||
isModalOpen = true;
|
||||
@@ -94,11 +105,24 @@
|
||||
|
||||
<div class="p-8 space-y-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<Heading tag="h2" class="text-2xl font-bold">Freights</Heading>
|
||||
<Button color="blue" onclick={() => openModal()}>+ Add Freight</Button>
|
||||
<Heading
|
||||
tag="h2"
|
||||
class="text-2xl font-bold"
|
||||
>
|
||||
Freights
|
||||
</Heading>
|
||||
<Button
|
||||
color="blue"
|
||||
onclick={() => openModal()}
|
||||
>
|
||||
+ Add Freight
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Table shadow hoverable={true}>
|
||||
<Table
|
||||
shadow
|
||||
hoverable={true}
|
||||
>
|
||||
<TableHead>
|
||||
<TableHeadCell>ID</TableHeadCell>
|
||||
<TableHeadCell>Cargo Name</TableHeadCell>
|
||||
@@ -117,13 +141,10 @@
|
||||
</TableBodyCell>
|
||||
<TableBodyCell>{item.weight_kg} kg</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
{item.dimensions.length_cm}×{item.dimensions.width_cm}×{item
|
||||
.dimensions.height_cm} cm
|
||||
{item.dimensions.length_cm}×{item.dimensions.width_cm}×{item.dimensions.height_cm} cm
|
||||
</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
<Badge color={statusMap[item.status].color}
|
||||
>{statusMap[item.status].label}</Badge
|
||||
>
|
||||
<Badge color={statusMap[item.status].color}>{statusMap[item.status].label}</Badge>
|
||||
</TableBodyCell>
|
||||
<TableBodyCell class="space-x-2">
|
||||
<Button
|
||||
@@ -131,8 +152,10 @@
|
||||
color="alternative"
|
||||
onclick={() => openModal(item)}>Edit</Button
|
||||
>
|
||||
<Button size="xs" color="red" onclick={() => deleteFreight(item.id)}
|
||||
>Delete</Button
|
||||
<Button
|
||||
size="xs"
|
||||
color="red"
|
||||
onclick={() => deleteFreight(item.id)}>Delete</Button
|
||||
>
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
@@ -148,49 +171,158 @@
|
||||
>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="col-span-2">
|
||||
<Label class="mb-2">Item Name</Label>
|
||||
<Input bind:value={formData.name} placeholder="e.g. Electronics" />
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.name ? "red" : "default"}
|
||||
>
|
||||
Item Name
|
||||
</Label>
|
||||
<Input
|
||||
bind:value={formData.name}
|
||||
placeholder="e.g. Electronics"
|
||||
color={errors.name ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.name}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.name}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="col-span-2">
|
||||
<Label class="mb-2">Description</Label>
|
||||
<Input bind:value={formData.description} placeholder="Cargo details..." />
|
||||
<Input
|
||||
bind:value={formData.description}
|
||||
placeholder="Cargo details (optional)"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label class="mb-2">Weight (kg)</Label>
|
||||
<Input type="number" bind:value={formData.weight_kg} />
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.weight_kg ? "red" : "default"}
|
||||
>
|
||||
Weight (kg)
|
||||
</Label>
|
||||
<Input
|
||||
type="number"
|
||||
bind:value={formData.weight_kg}
|
||||
color={errors.weight_kg ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.weight_kg}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.weight_kg}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Label class="mb-2">Status</Label>
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.status ? "red" : "default"}
|
||||
>
|
||||
Status
|
||||
</Label>
|
||||
<Select
|
||||
items={Object.keys(statusMap).map((k) => ({
|
||||
value: k,
|
||||
name: statusMap[k].label,
|
||||
}))}
|
||||
bind:value={formData.status}
|
||||
color={errors.status ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.status}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.status}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="col-span-2 border-t pt-4 mt-2">
|
||||
<Label class="mb-2 font-bold">Dimensions (cm)</Label>
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<div>
|
||||
<Helper>Length (cm.)</Helper>
|
||||
<Input type="number" bind:value={formData.dimensions.length_cm} />
|
||||
<Helper
|
||||
class="mb-2"
|
||||
color={errors.length_cm ? "red" : "default"}
|
||||
>
|
||||
Length (cm.)
|
||||
</Helper>
|
||||
<Input
|
||||
type="number"
|
||||
bind:value={formData.dimensions.length_cm}
|
||||
color={errors.width_cm ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.length_cm}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.length_cm}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Helper>Width (cm.)</Helper>
|
||||
<Input type="number" bind:value={formData.dimensions.width_cm} />
|
||||
<Helper
|
||||
class="mb-2"
|
||||
color={errors.width_cm ? "red" : "default"}
|
||||
>
|
||||
Width (cm.)
|
||||
</Helper>
|
||||
<Input
|
||||
type="number"
|
||||
bind:value={formData.dimensions.width_cm}
|
||||
color={errors.width_cm ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.width_cm}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.width_cm}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Helper>Height (cm.)</Helper>
|
||||
<Input type="number" bind:value={formData.dimensions.height_cm} />
|
||||
<Helper
|
||||
class="mb-2"
|
||||
color={errors.height_cm ? "red" : "default"}
|
||||
>
|
||||
Height (cm.)
|
||||
</Helper>
|
||||
<Input
|
||||
type="number"
|
||||
bind:value={formData.dimensions.height_cm}
|
||||
color={errors.height_cm ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.height_cm}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.height_cm}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-3 mt-6">
|
||||
<Button color="alternative" onclick={closeModal}>Cancel</Button>
|
||||
<Button color="blue" onclick={saveFreight}>Confirm</Button>
|
||||
<Button
|
||||
color="alternative"
|
||||
onclick={closeModal}>Cancel</Button
|
||||
>
|
||||
<Button
|
||||
color="blue"
|
||||
disabled={!(Object.keys(errors).length === 0)}
|
||||
onclick={saveFreight}>Confirm</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
Heading,
|
||||
MultiSelect,
|
||||
Helper,
|
||||
Toast,
|
||||
} from "flowbite-svelte";
|
||||
|
||||
let routes = $state([]);
|
||||
@@ -31,7 +32,7 @@
|
||||
end_location: "",
|
||||
distance_km: 0,
|
||||
estimated_duration_hours: 0,
|
||||
status: "PLANNED",
|
||||
status: "",
|
||||
});
|
||||
|
||||
const BASE_URL = "http://localhost:8079/route-service/routes";
|
||||
@@ -62,13 +63,12 @@
|
||||
let errors = $derived.by(() => {
|
||||
const e = {};
|
||||
if (!formData.vehicle_id) e.vehicle_id = "Vehicle is required";
|
||||
if (formData.freight_id.length === 0)
|
||||
e.freight_id = "Select at least one freight";
|
||||
if (!formData.status.trim()) e.status = "Status is required";
|
||||
if (formData.freight_id.length === 0) e.freight_id = "Select at least one freight";
|
||||
if (!formData.start_location.trim()) e.start_location = "Origin required";
|
||||
if (!formData.end_location.trim()) e.end_location = "Destination required";
|
||||
if (formData.distance_km <= 0) e.distance_km = "Distance must be > 0";
|
||||
if (formData.estimated_duration_hours <= 0)
|
||||
e.duration = "Duration must be > 0";
|
||||
if (formData.estimated_duration_hours <= 0) e.duration = "Duration must be > 0";
|
||||
return e;
|
||||
});
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
end_location: "",
|
||||
distance_km: 0,
|
||||
estimated_duration_hours: 0,
|
||||
status: "PLANNED",
|
||||
status: "",
|
||||
};
|
||||
}
|
||||
isModalOpen = true;
|
||||
@@ -125,11 +125,20 @@
|
||||
|
||||
<div class="p-8 space-y-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<Heading tag="h2" class="text-2xl font-bold text-gray-800">Routes</Heading>
|
||||
<Button color="blue" onclick={() => openModal()}>+ Add Route</Button>
|
||||
<Heading
|
||||
tag="h2"
|
||||
class="text-2xl font-bold text-gray-800">Routes</Heading
|
||||
>
|
||||
<Button
|
||||
color="blue"
|
||||
onclick={() => openModal()}>+ Add Route</Button
|
||||
>
|
||||
</div>
|
||||
|
||||
<Table shadow hoverable>
|
||||
<Table
|
||||
shadow
|
||||
hoverable
|
||||
>
|
||||
<TableHead>
|
||||
<TableHeadCell>ID</TableHeadCell>
|
||||
<TableHeadCell>Path</TableHeadCell>
|
||||
@@ -155,9 +164,7 @@
|
||||
</div>
|
||||
</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
<Badge color={statusMap[route.status].color}
|
||||
>{statusMap[route.status].label}</Badge
|
||||
>
|
||||
<Badge color={statusMap[route.status].color}>{statusMap[route.status].label}</Badge>
|
||||
</TableBodyCell>
|
||||
<TableBodyCell class="space-x-2">
|
||||
<Button
|
||||
@@ -165,8 +172,10 @@
|
||||
color="alternative"
|
||||
onclick={() => openModal(route)}>Edit</Button
|
||||
>
|
||||
<Button size="xs" color="red" onclick={() => deleteRoute(route.id)}
|
||||
>Delete</Button
|
||||
<Button
|
||||
size="xs"
|
||||
color="red"
|
||||
onclick={() => deleteRoute(route.id)}>Delete</Button
|
||||
>
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
@@ -182,111 +191,172 @@
|
||||
>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label class="mb-2">Assign Vehicle</Label>
|
||||
<Label
|
||||
color={errors.vehicle_id ? "red" : "default"}
|
||||
class="mb-2">Assign Vehicle</Label
|
||||
>
|
||||
<Select
|
||||
items={vehicles}
|
||||
bind:value={formData.vehicleId}
|
||||
bind:value={formData.vehicle_id}
|
||||
color={errors.vehicle_id ? "red" : "default"}
|
||||
placeholder="Select vehicle..."
|
||||
/>
|
||||
{#if errors.vehicle_id}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.vehicle_id}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Label class="mb-2">Status</Label>
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.status ? "red" : "default"}
|
||||
>
|
||||
Status
|
||||
</Label>
|
||||
<Select
|
||||
items={Object.keys(statusMap).map((k) => ({
|
||||
value: k,
|
||||
name: statusMap[k].label,
|
||||
}))}
|
||||
bind:value={formData.status}
|
||||
color={errors.status ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.status}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.status}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="col-span-2">
|
||||
<Label class="mb-2">Freights (Multi-select)</Label>
|
||||
<MultiSelect items={freights} bind:value={formData.freight_id} />
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.freight_id ? "red" : "default"}
|
||||
>
|
||||
Freights
|
||||
</Label>
|
||||
<MultiSelect
|
||||
items={freights}
|
||||
bind:value={formData.freight_id}
|
||||
color={errors.freight_id ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.freight_id}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.freight_id}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label class="mb-2">Start Location</Label>
|
||||
<Input bind:value={formData.start_location} placeholder="City A" />
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.start_location ? "red" : "default"}
|
||||
>
|
||||
Start Location
|
||||
</Label>
|
||||
<Input
|
||||
bind:value={formData.start_location}
|
||||
color={errors.start_location ? "red" : "default"}
|
||||
placeholder="City A"
|
||||
/>
|
||||
{#if errors.start_location}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.start_location}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Label class="mb-2">End Location</Label>
|
||||
<Input bind:value={formData.end_location} placeholder="City B" />
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.end_location ? "red" : "default"}
|
||||
>
|
||||
End Location
|
||||
</Label>
|
||||
<Input
|
||||
bind:value={formData.end_location}
|
||||
placeholder="City B"
|
||||
color={errors.end_location ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.end_location}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.end_location}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label class="mb-2">Distance (km)</Label>
|
||||
<Input type="number" bind:value={formData.distance_km} />
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.distance_km ? "red" : "default"}
|
||||
>
|
||||
Distance (km)
|
||||
</Label>
|
||||
<Input
|
||||
type="number"
|
||||
bind:value={formData.distance_km}
|
||||
color={errors.distance_km ? "red" : "default"}
|
||||
/>
|
||||
{#if errors.distance_km}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.distance_km}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label class="mb-2">Est. Time (hours)</Label>
|
||||
<Label
|
||||
class="mb-2"
|
||||
color={errors.estimated_duration_hours ? "red" : "default"}>Est. Time (hours)</Label
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
step="0.5"
|
||||
bind:value={formData.estimated_duration_hours}
|
||||
color={errors.estimated_duration_hours ? "red" : "default"}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label color={errors.vehicle_id ? "red" : "base"} class="mb-2"
|
||||
>Assign Vehicle</Label
|
||||
>
|
||||
<Select
|
||||
items={vehicles}
|
||||
bind:value={formData.vehicle_id}
|
||||
color={errors.vehicle_id ? "red" : "base"}
|
||||
/>
|
||||
{#if errors.vehicle_id}<Helper class="mt-2" color="red"
|
||||
>{errors.vehicle_id}</Helper
|
||||
>{/if}
|
||||
</div>
|
||||
|
||||
<div class="col-span-2">
|
||||
<Label color={errors.freight_id ? "red" : "base"} class="mb-2"
|
||||
>Freights</Label
|
||||
>
|
||||
<MultiSelect items={freights} bind:value={formData.freight_id} />
|
||||
{#if errors.freight_id}<Helper class="mt-2" color="red"
|
||||
>{errors.freight_id}</Helper
|
||||
>{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label color={errors.start_location ? "red" : "base"} class="mb-2"
|
||||
>Start Location</Label
|
||||
>
|
||||
<Input
|
||||
bind:value={formData.start_location}
|
||||
color={errors.start_location ? "red" : "base"}
|
||||
/>
|
||||
{#if errors.start_location}<Helper class="mt-2" color="red"
|
||||
>{errors.start_location}</Helper
|
||||
>{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label color={errors.distance_km ? "red" : "base"} class="mb-2"
|
||||
>Distance (km)</Label
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
bind:value={formData.distance_km}
|
||||
color={errors.distance_km ? "red" : "base"}
|
||||
/>
|
||||
{#if errors.distance_km}<Helper class="mt-2" color="red"
|
||||
>{errors.distance_km}</Helper
|
||||
>{/if}
|
||||
{#if errors.estimated_duration_hours}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errors.estimated_duration_hours}
|
||||
</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-3 mt-6">
|
||||
<Button color="alternative" onclick={closeModal}>Cancel</Button>
|
||||
<Button
|
||||
color="alternative"
|
||||
onclick={closeModal}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
color="blue"
|
||||
disabled={!(Object.keys(errors).length === 0)}
|
||||
onclick={saveRoute}>Save Route</Button
|
||||
onclick={saveRoute}
|
||||
>
|
||||
Confirm
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
Select,
|
||||
Badge,
|
||||
Heading,
|
||||
Helper,
|
||||
} from "flowbite-svelte";
|
||||
|
||||
let vehicles = $state([]);
|
||||
@@ -24,9 +25,9 @@
|
||||
brand: "",
|
||||
model: "",
|
||||
license_plate: "",
|
||||
year: 2024,
|
||||
year: 0,
|
||||
capacity_kg: 0,
|
||||
status: "AVAILABLE",
|
||||
status: "",
|
||||
});
|
||||
|
||||
const BASE_URL = "http://localhost:8079/vehicle-service/vehicles";
|
||||
@@ -46,6 +47,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
let errors = $derived.by(() => {
|
||||
const e = {};
|
||||
if (!formData.brand.trim()) e.brand = "Manufacturer is required";
|
||||
if (!formData.model.trim()) e.model = "Model is required";
|
||||
if (!formData.status.trim()) e.status = "Status is required";
|
||||
if (!formData.license_plate.trim()) e.license_plate = "License plate required";
|
||||
if (formData.capacity_kg <= 0) e.capacity_kg = "Capacity must be > 0";
|
||||
if (formData.year <= 1980) e.year = "Year must be > 1980";
|
||||
return e;
|
||||
});
|
||||
|
||||
async function saveVehicle() {
|
||||
const method = editingId ? "PUT" : "POST";
|
||||
const url = editingId ? `${BASE_URL}/${editingId}` : BASE_URL;
|
||||
@@ -85,9 +97,9 @@
|
||||
brand: "",
|
||||
model: "",
|
||||
license_plate: "",
|
||||
year: 2024,
|
||||
year: 0,
|
||||
capacity_kg: 0,
|
||||
status: "AVAILABLE",
|
||||
status: "",
|
||||
};
|
||||
}
|
||||
isModalOpen = true;
|
||||
@@ -116,11 +128,20 @@
|
||||
|
||||
<div class="p-8 space-y-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<Heading tag="h2" class="text-2xl font-bold">Vehicles</Heading>
|
||||
<Button color="blue" onclick={() => openModal()}>+ Add Vehicle</Button>
|
||||
<Heading
|
||||
tag="h2"
|
||||
class="text-2xl font-bold">Vehicles</Heading
|
||||
>
|
||||
<Button
|
||||
color="blue"
|
||||
onclick={() => openModal()}>+ Add Vehicle</Button
|
||||
>
|
||||
</div>
|
||||
|
||||
<Table shadow hoverable={true}>
|
||||
<Table
|
||||
shadow
|
||||
hoverable={true}
|
||||
>
|
||||
<TableHead>
|
||||
<TableHeadCell>ID</TableHeadCell>
|
||||
<TableHeadCell>Manufacturer/Model</TableHeadCell>
|
||||
@@ -134,16 +155,13 @@
|
||||
{#each vehicles as vehicle (vehicle.id)}
|
||||
<TableBodyRow>
|
||||
<TableBodyCell>{vehicle.id}</TableBodyCell>
|
||||
<TableBodyCell class="font-medium"
|
||||
>{vehicle.brand} {vehicle.model}</TableBodyCell
|
||||
>
|
||||
<TableBodyCell class="font-medium">{vehicle.brand} {vehicle.model}</TableBodyCell>
|
||||
<TableBodyCell>{vehicle.license_plate}</TableBodyCell>
|
||||
<TableBodyCell>{vehicle.year}</TableBodyCell>
|
||||
<TableBodyCell>{vehicle.capacity_kg}</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
<Badge color={getStatusColor(vehicle.status)}
|
||||
>{statusOptions.filter((s) => s.value === vehicle.status).at(0)
|
||||
.name}</Badge
|
||||
>{statusOptions.filter((s) => s.value === vehicle.status).at(0).name}</Badge
|
||||
>
|
||||
</TableBodyCell>
|
||||
<TableBodyCell class="space-x-2">
|
||||
@@ -164,6 +182,17 @@
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{#snippet err(errs)}
|
||||
{#if errs}
|
||||
<Helper
|
||||
class="mt-2"
|
||||
color="red"
|
||||
>
|
||||
{errs}
|
||||
</Helper>
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
<Modal
|
||||
title={editingId ? "Update Vehicle" : "Add Vehicle"}
|
||||
bind:open={isModalOpen}
|
||||
@@ -172,53 +201,117 @@
|
||||
>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<Label for="brand" class="mb-2">Make</Label>
|
||||
<Label
|
||||
for="brand"
|
||||
color={errors.brand ? "red" : "default"}
|
||||
class="mb-2"
|
||||
>
|
||||
Manufacturer
|
||||
</Label>
|
||||
<Input
|
||||
type="text"
|
||||
id="brand"
|
||||
color={errors.brand ? "red" : "default"}
|
||||
bind:value={formData.brand}
|
||||
placeholder="e.g. Mercedes"
|
||||
required
|
||||
/>
|
||||
{@render err(errors.brand)}
|
||||
</div>
|
||||
<div>
|
||||
<Label for="model" class="mb-2">Model</Label>
|
||||
<Label
|
||||
for="model"
|
||||
color={errors.model ? "red" : "default"}
|
||||
class="mb-2"
|
||||
>
|
||||
Model
|
||||
</Label>
|
||||
<Input
|
||||
type="text"
|
||||
id="model"
|
||||
bind:value={formData.model}
|
||||
color={errors.brand ? "red" : "default"}
|
||||
placeholder="e.g. Actros"
|
||||
required
|
||||
/>
|
||||
{@render err(errors.model)}
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div>
|
||||
<Label for="plate" class="mb-2">License Plate</Label>
|
||||
<Label
|
||||
for="plate"
|
||||
color={errors.license_plate ? "red" : "default"}
|
||||
class="mb-2"
|
||||
>
|
||||
License Plate
|
||||
</Label>
|
||||
<Input
|
||||
type="text"
|
||||
id="plate"
|
||||
color={errors.license_plate ? "red" : "default"}
|
||||
bind:value={formData.license_plate}
|
||||
placeholder="AA1234BB"
|
||||
/>
|
||||
{@render err(errors.license_plate)}
|
||||
</div>
|
||||
<div>
|
||||
<Label for="year" class="mb-2">Year</Label>
|
||||
<Input type="number" id="year" bind:value={formData.year} />
|
||||
<Label
|
||||
for="year"
|
||||
color={errors.year ? "red" : "default"}
|
||||
class="mb-2"
|
||||
>
|
||||
Year
|
||||
</Label>
|
||||
<Input
|
||||
type="number"
|
||||
id="year"
|
||||
color={errors.year ? "red" : "default"}
|
||||
bind:value={formData.year}
|
||||
/>
|
||||
{@render err(errors.year)}
|
||||
</div>
|
||||
<div>
|
||||
<Label for="capacity" class="mb-2">Capacity (kg.)</Label>
|
||||
<Input type="number" id="capacity" bind:value={formData.capacity_kg} />
|
||||
<Label
|
||||
for="capacity"
|
||||
color={errors.capacity_kg ? "red" : "default"}
|
||||
class="mb-2">Capacity (kg.)</Label
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
color={errors.capacity_kg ? "red" : "default"}
|
||||
id="capacity"
|
||||
bind:value={formData.capacity_kg}
|
||||
/>
|
||||
{@render err(errors.capacity_kg)}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label for="status" class="mb-2">Status</Label>
|
||||
<Select items={statusOptions} bind:value={formData.status} />
|
||||
<Label
|
||||
for="status"
|
||||
color={errors.status ? "red" : "default"}
|
||||
class="mb-2"
|
||||
>
|
||||
Status
|
||||
</Label>
|
||||
<Select
|
||||
items={statusOptions}
|
||||
bind:value={formData.status}
|
||||
color={errors.status ? "red" : "default"}
|
||||
/>
|
||||
{@render err(errors.status)}
|
||||
</div>
|
||||
<div class="flex justify-end space-x-3 pt-4">
|
||||
<Button color="alternative" onclick={closeModal}>Cancel</Button>
|
||||
<Button color="blue" onclick={saveVehicle}
|
||||
>{editingId ? "Update" : "Create"}</Button
|
||||
<Button
|
||||
color="alternative"
|
||||
onclick={closeModal}>Cancel</Button
|
||||
>
|
||||
<Button
|
||||
color="blue"
|
||||
disabled={!(Object.keys(errors).length === 0)}
|
||||
onclick={saveVehicle}
|
||||
>
|
||||
Confirm
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
Reference in New Issue
Block a user