Files
ember-market-frontend/app/dashboard/shipping/page.tsx
2025-04-07 19:25:24 +01:00

217 lines
6.1 KiB
TypeScript

"use client";
import { useState, useEffect, ChangeEvent } from "react";
import { useRouter } from "next/navigation";
import Layout from "@/components/layout/layout";
import { Edit, Plus, Trash } from "lucide-react";
import { Button } from "@/components/ui/button";
import { ShippingModal } from "@/components/modals/shipping-modal";
import { Skeleton } from "@/components/ui/skeleton";
import {
fetchShippingMethods,
addShippingMethod,
deleteShippingMethod,
updateShippingMethod,
ShippingMethod,
ShippingData
} from "@/lib/services/shipping-service";
import { ShippingTable } from "@/components/tables/shipping-table";
export default function ShippingPage() {
const [shippingMethods, setShippingMethods] = useState<ShippingMethod[]>([]);
const [newShipping, setNewShipping] = useState<ShippingData>({
name: "",
price: 0,
});
const [loading, setLoading] = useState<boolean>(true);
const [modalOpen, setModalOpen] = useState<boolean>(false);
const [editing, setEditing] = useState<boolean>(false);
const [refreshTrigger, setRefreshTrigger] = useState<number>(0);
const router = useRouter();
const refreshShippingMethods = () => {
setRefreshTrigger(prev => prev + 1);
};
useEffect(() => {
const fetchShippingMethodsData = async () => {
try {
setLoading(true);
const authToken = document.cookie
.split("; ")
.find((row) => row.startsWith("Authorization="))
?.split("=")[1];
if (!authToken) {
router.push("/login");
return;
}
const fetchedMethods: ShippingMethod[] = await fetchShippingMethods(
authToken
);
const sanitizedMethods: ShippingMethod[] = fetchedMethods.map(
(method) => ({
...method,
_id: method._id ?? "",
})
);
console.log("Fetched Shipping Methods:", sanitizedMethods);
setShippingMethods(sanitizedMethods);
} catch (error) {
console.error("Error loading shipping options:", error);
} finally {
setLoading(false);
}
};
fetchShippingMethodsData();
}, [refreshTrigger]); // Add refreshTrigger as a dependency
const handleAddShipping = async () => {
if (!newShipping.name || !newShipping.price) return;
try {
setLoading(true);
const authToken = document.cookie
.split("; ")
.find((row) => row.startsWith("Authorization="))
?.split("=")[1];
if (!authToken) {
console.error("No auth token found");
return;
}
await addShippingMethod(
newShipping,
authToken
);
// Close modal and reset form before refreshing to avoid UI delays
setModalOpen(false);
setNewShipping({ name: "", price: 0 });
// Refresh the list after adding
refreshShippingMethods();
console.log("Shipping method added successfully");
} catch (error) {
console.error("Error adding shipping method:", error);
alert("Failed to add shipping method. Please try again.");
} finally {
setLoading(false);
}
};
const handleUpdateShipping = async () => {
if (!newShipping.name || !newShipping.price || !newShipping._id) return; // Ensure `_id` exists
try {
setLoading(true);
const authToken = document.cookie
.split("; ")
.find((row) => row.startsWith("Authorization="))
?.split("=")[1];
if (!authToken) {
console.error("No auth token found");
return;
}
await updateShippingMethod(
newShipping._id,
newShipping,
authToken
);
// Close modal and reset form before refreshing to avoid UI delays
setModalOpen(false);
setNewShipping({ name: "", price: 0 });
setEditing(false);
// Refresh the list after updating
refreshShippingMethods();
console.log("Shipping method updated successfully");
} catch (error) {
console.error("Error updating shipping method:", error);
alert("Failed to update shipping method. Please try again.");
} finally {
setLoading(false);
}
};
const handleDeleteShipping = async (_id: string) => {
try {
const authToken = document.cookie.split("Authorization=")[1];
const response = await deleteShippingMethod(_id, authToken);
if (response.success) {
refreshShippingMethods(); // Refresh the list after deleting
} else {
console.error("Deletion was not successful.");
}
} catch (error) {
console.error("Error deleting shipping method:", error);
}
};
const handleEditShipping = (shipping: ShippingMethod) => {
setNewShipping({
...shipping,
_id: shipping._id ?? "", // ✅ Ensure _id is always a string
});
setEditing(true);
setModalOpen(true);
};
return (
<Layout>
<div className="space-y-6">
<div className="flex items-center justify-between">
<h1 className="text-2xl font-semibold text-gray-900 dark:text-white">
Manage Shipping Options
</h1>
<Button onClick={() => {
setNewShipping({ name: "", price: 0 });
setEditing(false);
setModalOpen(true);
}}>
<Plus className="mr-2 h-5 w-5" />
Add Shipping Method
</Button>
</div>
{/* Shipping Methods Table */}
<ShippingTable
shippingMethods={shippingMethods}
loading={loading}
onEditShipping={handleEditShipping}
onDeleteShipping={handleDeleteShipping}
/>
</div>
{/* Shipping Modal */}
<ShippingModal
open={modalOpen}
onClose={() => {
setNewShipping({ name: "", price: 0 });
setEditing(false);
setModalOpen(false);
}}
onSave={editing ? handleUpdateShipping : handleAddShipping}
shippingData={newShipping}
editing={editing}
handleChange={(e) =>
setNewShipping({ ...newShipping, [e.target.name]: e.target.value })
}
setShippingData={setNewShipping}
/>
</Layout>
);
}