This commit is contained in:
NotII
2025-03-23 21:25:37 +00:00
parent dc51901c5c
commit 8d7d9b9e1c
5 changed files with 74 additions and 80 deletions

View File

@@ -8,11 +8,11 @@ import { Input } from "@/components/ui/input";
import { Product } from "@/models/products";
import { Plus, Upload, Search, RefreshCw } from "lucide-react";
import {
fetchProductData,
saveProductData,
saveProductImage,
deleteProductData,
} from "@/lib/productData";
import { clientFetch } from "@/lib/client-utils";
import { ProductModal } from "@/components/modals/product-modal";
import ProductTable from "@/components/tables/product-table";
import { Category } from "@/models/categories";
@@ -55,12 +55,9 @@ export default function ProductsPage() {
try {
setLoading(true);
const productsUrl = `${process.env.NEXT_PUBLIC_API_URL}/products`;
const categoriesUrl = `${process.env.NEXT_PUBLIC_API_URL}/categories`;
const [fetchedProducts, fetchedCategories] = await Promise.all([
fetchProductData(productsUrl, authToken),
fetchProductData(categoriesUrl, authToken),
clientFetch('/products'),
clientFetch('/categories'),
]);
console.log("Fetched Products:", fetchedProducts);
@@ -76,6 +73,7 @@ export default function ProductsPage() {
setLoading(false);
} catch (error) {
console.error("Error fetching data:", error);
toast.error("Failed to load products");
setLoading(false);
}
};
@@ -115,67 +113,41 @@ export default function ProductsPage() {
const handleSaveProduct = async (data: Product, file?: File | null) => {
const authToken = document.cookie
.split("; ")
.find((row) => row.startsWith("Authorization="))
?.split("=")[1];
if (!authToken) {
router.push("/login");
return;
}
setLoading(true);
try {
const url = editing
? `${process.env.NEXT_PUBLIC_API_URL}/products/${data._id}`
: `${process.env.NEXT_PUBLIC_API_URL}/products`;
setLoading(true);
// Save product data
const savedProduct = await saveProductData(
url,
{
name: data.name,
description: data.description,
unitType: data.unitType,
category: data.category,
pricing: data.pricing,
stockTracking: data.stockTracking,
currentStock: data.currentStock,
lowStockThreshold: data.lowStockThreshold
},
authToken,
editing ? "PUT" : "POST"
);
if (file) {
const imageUrl = `${process.env.NEXT_PUBLIC_API_URL}/products/${savedProduct._id}/image`;
await saveProductImage(
imageUrl,
file,
authToken
);
if (editing && !data._id) {
throw new Error("Cannot update product without an ID");
}
// If editing and stock values were updated, update stock in the dedicated endpoint
if (editing && data.stockTracking !== undefined) {
const stockUrl = `${process.env.NEXT_PUBLIC_API_URL}/stock/${data._id}`;
await saveProductData(
stockUrl,
{
stockTracking: data.stockTracking,
currentStock: data.currentStock || 0,
lowStockThreshold: data.lowStockThreshold || 10
},
authToken,
"PUT"
);
// Save the product data
const endpoint = editing ? `/products/${data._id}` : "/products";
const method = editing ? "PUT" : "POST";
const productResponse = await clientFetch(endpoint, {
method,
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
// If there's a new image to upload
if (file) {
const imageEndpoint = `/products/${productResponse._id || data._id}/image`;
const formData = new FormData();
formData.append("file", file);
await clientFetch(imageEndpoint, {
method: "PUT",
body: formData,
headers: {}, // Let the browser set the content-type for FormData
});
}
// Refresh products list
const productsUrl = `${process.env.NEXT_PUBLIC_API_URL}/products`;
const fetchedProducts = await fetchProductData(productsUrl, authToken);
const fetchedProducts = await clientFetch('/products');
setProducts(fetchedProducts);
setModalOpen(false);
@@ -195,25 +167,23 @@ export default function ProductsPage() {
const handleDeleteProduct = async (productId: string) => {
if (!confirm("Are you sure you want to delete this product?")) return;
const authToken = document.cookie
.split("; ")
.find((row) => row.startsWith("Authorization="))
?.split("=")[1];
if (!authToken) {
router.push("/login");
return;
}
try {
const url = `${process.env.NEXT_PUBLIC_API_URL}/products/${productId}`;
await deleteProductData(url, authToken);
setLoading(true);
await clientFetch(`/products/${productId}`, {
method: "DELETE",
});
// Refresh products list
const fetchedProducts = await clientFetch('/products');
setProducts(fetchedProducts);
setProducts(products.filter((p) => p._id !== productId));
toast.success("Product deleted successfully");
setLoading(false);
} catch (error) {
console.error("Error deleting product:", error);
console.error(error);
toast.error("Failed to delete product");
setLoading(false);
}
};