finish 5th practical
This commit is contained in:
@@ -6,8 +6,11 @@
|
|||||||
import Routes from "./Routes.svelte";
|
import Routes from "./Routes.svelte";
|
||||||
import { Route, Router } from "svelte5-router";
|
import { Route, Router } from "svelte5-router";
|
||||||
import { fly } from "svelte/transition";
|
import { fly } from "svelte/transition";
|
||||||
|
import Toaster from "./Toaster.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<Toaster />
|
||||||
|
|
||||||
<Router>
|
<Router>
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Table,
|
Table,
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
Heading,
|
Heading,
|
||||||
Helper,
|
Helper,
|
||||||
} from "flowbite-svelte";
|
} from "flowbite-svelte";
|
||||||
|
import toastManager from "./toastManager.svelte";
|
||||||
|
|
||||||
let freights = $state([]);
|
let freights = $state([]);
|
||||||
let isModalOpen = $state(false);
|
let isModalOpen = $state(false);
|
||||||
@@ -47,7 +48,7 @@
|
|||||||
const res = await fetch(BASE_URL);
|
const res = await fetch(BASE_URL);
|
||||||
freights = await res.json();
|
freights = await res.json();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Fetch error:", err);
|
toastManager.addToast(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,13 +67,21 @@
|
|||||||
closeModal();
|
closeModal();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Save error:", err);
|
toastManager.addToast(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteFreight(id) {
|
async function deleteFreight(id) {
|
||||||
await fetch(`${BASE_URL}/${id}`, { method: "DELETE" });
|
try {
|
||||||
fetchFreights();
|
const res = await fetch(`${BASE_URL}/${id}`, { method: "DELETE" });
|
||||||
|
if (!res.ok) {
|
||||||
|
const err = await res.json();
|
||||||
|
throw new Error(err.detail ?? res.statusText);
|
||||||
|
}
|
||||||
|
fetchFreights();
|
||||||
|
} catch (err) {
|
||||||
|
toastManager.addToast(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openModal(freight = null) {
|
function openModal(freight = null) {
|
||||||
@@ -100,6 +109,8 @@
|
|||||||
DELIVERED: { color: "green", label: "Delivered" },
|
DELIVERED: { color: "green", label: "Delivered" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onDestroy(() => toastManager.onDestroy());
|
||||||
|
|
||||||
onMount(fetchFreights);
|
onMount(fetchFreights);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
+30
-13
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Table,
|
Table,
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
Heading,
|
Heading,
|
||||||
MultiSelect,
|
MultiSelect,
|
||||||
Helper,
|
Helper,
|
||||||
Toast,
|
|
||||||
} from "flowbite-svelte";
|
} from "flowbite-svelte";
|
||||||
|
import toastManager from "./toastManager.svelte";
|
||||||
|
|
||||||
let routes = $state([]);
|
let routes = $state([]);
|
||||||
let vehicles = $state([]); // For dropdown
|
let vehicles = $state([]); // For dropdown
|
||||||
@@ -25,6 +25,8 @@
|
|||||||
let isModalOpen = $state(false);
|
let isModalOpen = $state(false);
|
||||||
let editingId = $state(null);
|
let editingId = $state(null);
|
||||||
|
|
||||||
|
onDestroy(() => toastManager.onDestroy());
|
||||||
|
|
||||||
let formData = $state({
|
let formData = $state({
|
||||||
vehicle_id: "",
|
vehicle_id: "",
|
||||||
freight_id: [],
|
freight_id: [],
|
||||||
@@ -56,7 +58,7 @@
|
|||||||
name: f.name,
|
name: f.name,
|
||||||
}));
|
}));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Load error:", err);
|
toastManager.addToast(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,21 +78,36 @@
|
|||||||
const method = editingId ? "PUT" : "POST";
|
const method = editingId ? "PUT" : "POST";
|
||||||
const url = editingId ? `${BASE_URL}/${editingId}` : BASE_URL;
|
const url = editingId ? `${BASE_URL}/${editingId}` : BASE_URL;
|
||||||
|
|
||||||
const res = await fetch(url, {
|
try {
|
||||||
method,
|
const res = await fetch(url, {
|
||||||
headers: { "Content-Type": "application/json" },
|
method,
|
||||||
body: JSON.stringify(formData),
|
headers: { "Content-Type": "application/json" },
|
||||||
});
|
body: JSON.stringify(formData),
|
||||||
|
});
|
||||||
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
await fetchData();
|
await fetchData();
|
||||||
closeModal();
|
closeModal();
|
||||||
|
} else {
|
||||||
|
const err = await res.json();
|
||||||
|
throw new Error(err.detail ?? res.statusText);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
toastManager.addToast(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteRoute(id) {
|
async function deleteRoute(id) {
|
||||||
await fetch(`${BASE_URL}/${id}`, { method: "DELETE" });
|
try {
|
||||||
fetchData();
|
const res = await fetch(`${BASE_URL}/${id}`, { method: "DELETE" });
|
||||||
|
if (!res.ok) {
|
||||||
|
const err = await res.json();
|
||||||
|
throw new Error(err.detail ?? res.statusText);
|
||||||
|
}
|
||||||
|
fetchData();
|
||||||
|
} catch (err) {
|
||||||
|
toastManager.addToast(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openModal(route = null) {
|
function openModal(route = null) {
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<script>
|
||||||
|
import { Toast, ToastContainer } from "flowbite-svelte";
|
||||||
|
import { fly } from "svelte/transition";
|
||||||
|
import toastManager from "./toastManager.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ToastContainer position="top-right">
|
||||||
|
{#each toastManager.toasts as toast (toast.id)}
|
||||||
|
<Toast
|
||||||
|
color={toast.color}
|
||||||
|
dismissable={true}
|
||||||
|
transition={fly}
|
||||||
|
params={{ x: 200, duration: 800 }}
|
||||||
|
class="w-64"
|
||||||
|
onclose={toastManager.handleClose(toast.id)}
|
||||||
|
bind:toastStatus={toast.visible}
|
||||||
|
>
|
||||||
|
{toast.message}
|
||||||
|
</Toast>
|
||||||
|
{/each}
|
||||||
|
</ToastContainer>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Table,
|
Table,
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
Heading,
|
Heading,
|
||||||
Helper,
|
Helper,
|
||||||
} from "flowbite-svelte";
|
} from "flowbite-svelte";
|
||||||
|
import toastManager from "./toastManager.svelte";
|
||||||
|
|
||||||
let vehicles = $state([]);
|
let vehicles = $state([]);
|
||||||
let isModalOpen = $state(false);
|
let isModalOpen = $state(false);
|
||||||
@@ -41,9 +42,12 @@
|
|||||||
async function fetchVehicles() {
|
async function fetchVehicles() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(BASE_URL);
|
const res = await fetch(BASE_URL);
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error(res.statusText);
|
||||||
|
}
|
||||||
vehicles = await res.json();
|
vehicles = await res.json();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error fetching vehicles:", err);
|
toastManager.addToast(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,18 +76,26 @@
|
|||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
await fetchVehicles();
|
await fetchVehicles();
|
||||||
closeModal();
|
closeModal();
|
||||||
|
} else {
|
||||||
|
const err = await res.json();
|
||||||
|
throw new Error(err.detail ?? res.statusText);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error saving vehicle:", err);
|
toastManager.addToast(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteVehicle(id) {
|
async function deleteVehicle(id) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${BASE_URL}/${id}`, { method: "DELETE" });
|
const res = await fetch(`${BASE_URL}/${id}`, { method: "DELETE" });
|
||||||
if (res.ok) fetchVehicles();
|
if (res.ok) {
|
||||||
|
fetchVehicles();
|
||||||
|
} else {
|
||||||
|
const err = await res.json();
|
||||||
|
throw new Error(err.detail ?? res.statusText);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error deleting vehicle:", err);
|
toastManager.addToast(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +135,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDestroy(() => toastManager.onDestroy());
|
||||||
|
|
||||||
onMount(fetchVehicles);
|
onMount(fetchVehicles);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
class ToastManager {
|
||||||
|
toasts = $state([]);
|
||||||
|
#nextId = $state(1);
|
||||||
|
|
||||||
|
addToast(msg) {
|
||||||
|
const selectedColor = "red";
|
||||||
|
const newToast = {
|
||||||
|
id: this.#nextId,
|
||||||
|
message: msg,
|
||||||
|
color: selectedColor,
|
||||||
|
visible: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Auto-dismiss after 5 seconds
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
this.dismissToast(newToast.id);
|
||||||
|
}, 5000);
|
||||||
|
newToast.timeoutId = timeoutId;
|
||||||
|
|
||||||
|
this.toasts = [...this.toasts, newToast];
|
||||||
|
this.#nextId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dismissToast(id) {
|
||||||
|
const toast = this.toasts.find((t) => t.id === id);
|
||||||
|
if (toast?.timeoutId) {
|
||||||
|
clearTimeout(toast.timeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toasts = this.toasts.map((t) => (t.id === id ? { ...t, visible: false } : t));
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.toasts = this.toasts.filter((t) => t.id !== id);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClose(id) {
|
||||||
|
return () => {
|
||||||
|
this.dismissToast(id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy() {
|
||||||
|
this.toasts.forEach((toast) => {
|
||||||
|
if (toast.timeoutId) {
|
||||||
|
clearTimeout(toast.timeoutId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new ToastManager();
|
||||||
Reference in New Issue
Block a user