diff --git a/frontend-prep/package-lock.json b/frontend-prep/package-lock.json index 62db288a..ad85e5b9 100644 --- a/frontend-prep/package-lock.json +++ b/frontend-prep/package-lock.json @@ -62,6 +62,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -873,6 +874,7 @@ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.1.0.tgz", "integrity": "sha512-fNxRUk1KhjSbnbuBxlWSnBLKLBNun52ZBTcs22H/xEEzM6Ap81ZFTQ4bZBxVQGQgVY0xugKGoRcCbaKjLQ3XZA==", "license": "MIT", + "peer": true, "dependencies": { "@fortawesome/fontawesome-common-types": "7.1.0" }, @@ -1461,6 +1463,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1470,6 +1473,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "dev": true, + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -1526,6 +1530,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.0.tgz", "integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.48.0", "@typescript-eslint/types": "8.48.0", @@ -1764,6 +1769,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1863,6 +1869,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -2101,6 +2108,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -2669,6 +2677,7 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.2.tgz", "integrity": "sha512-CPjtWygL+f7naL+sGHoC2JQR0DG7u+9ik6WdkjjVmz2uy0kBC2l+aKfdi3ZzUR7VKSQJ6Mc/CeCN+6iVNah+ww==", + "peer": true, "dependencies": { "@mapbox/geojson-rewind": "^0.5.0", "@mapbox/geojson-types": "^1.0.2", @@ -2878,6 +2887,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "peer": true, "engines": { "node": ">=12" }, @@ -2950,6 +2960,7 @@ "version": "19.2.0", "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -2958,6 +2969,7 @@ "version": "19.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -3215,6 +3227,8 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3305,6 +3319,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz", "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", "dev": true, + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -3445,6 +3460,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", "dev": true, + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/frontend-prep/src/api/api.ts b/frontend-prep/src/api/api.ts index 6e92afb0..91b2692b 100644 --- a/frontend-prep/src/api/api.ts +++ b/frontend-prep/src/api/api.ts @@ -1220,8 +1220,8 @@ export const calculateOrderTotal = (order: Record): number => { // Fallback: calculer depuis les items si présents if (Array.isArray(order.items) && order.items.length > 0) { return (order.items as Record[]).reduce((sum: number, item) => { - const price = item.prix || item.price || 0; - const quantity = item.quantite || item.quantity || 1; + const price = Number(item.prix || item.price || 0); + const quantity = Number(item.quantite || item.quantity || 1); return sum + price * quantity; }, 0); } diff --git a/frontend-prep/src/context/CartContext.tsx b/frontend-prep/src/context/CartContext.tsx index 42dd4aac..c45fb7db 100644 --- a/frontend-prep/src/context/CartContext.tsx +++ b/frontend-prep/src/context/CartContext.tsx @@ -113,21 +113,22 @@ export function CartProvider({ children }: { children: ReactNode }) { } else { // ✅ Transformer les items - quantity = grammes const items: CartItem[] = panierData.map((item) => { - const category = (item.category || "autre") + const category = String(item.category || "autre") .toLowerCase() .trim(); return { - id: item.id, - product_id: item.product_id, - name_product: + id: item.id as number, + product_id: item.product_id as number, + name_product: String( item.product_name || item.name_product || "Produit", - price: item.price, - quantity: item.quantity, // ✨ En grammes (5, 10, 25, etc.) + ), + price: item.price as number, + quantity: item.quantity as number, category: category, - image: item.image, // Image sera gérée par Cart.tsx avec getProductById + image: item.image as string | undefined, }; }); diff --git a/frontend-prep/src/pages/User/Cart.tsx b/frontend-prep/src/pages/User/Cart.tsx index d749d087..57516a7a 100644 --- a/frontend-prep/src/pages/User/Cart.tsx +++ b/frontend-prep/src/pages/User/Cart.tsx @@ -71,7 +71,7 @@ function Cart() { const res = await getProductById(item.product_id); if (res.success && res.data) { const p = res.data; - const videoMedia = p.media?.find((m) => m && m.type === "video"); + const videoMedia = p.media?.find((m: { type: string; url?: string }) => m && m.type === "video"); return { ...item, image: getProductImage(p), diff --git a/frontend-prep/src/pages/User/SuiviLivraison.tsx b/frontend-prep/src/pages/User/SuiviLivraison.tsx index bb2ce401..e57357c3 100644 --- a/frontend-prep/src/pages/User/SuiviLivraison.tsx +++ b/frontend-prep/src/pages/User/SuiviLivraison.tsx @@ -21,6 +21,7 @@ import type { ETAResponse, TrackingResponse, OrderDetail, + OrderItem, CancelCommandResponse, } from "../../api/api_types"; import Navbar from "../../components/Navbar"; @@ -110,12 +111,11 @@ const getDeliveryAddress = (order: OrderWithTracking): string => { return order.delivery_address || order.adresse || "Non disponible"; }; -const formatOrderItem = (item: Record) => { +const formatOrderItem = (item: OrderItem) => { return { - name: - item.produit || item.product_name || item.name_product || "Produit", - quantity: item.quantite || item.quantity || 0, // Grammes - price: item.prix || item.price || 0, + name: String(item.produit || item.product_name || item.name_product || "Produit"), + quantity: Number(item.quantite || item.quantity || 0), + price: Number(item.prix || item.price || 0), }; }; @@ -187,9 +187,9 @@ const calculateOrderPoints = ( let excludedTotal = 0; if (order.items && order.items.length > 0) { - order.items.forEach((item: Record) => { - const cat = (item.category || "").toLowerCase(); - const itemPrice = item.prix || item.price || 0; + order.items.forEach((item: OrderItem) => { + const cat = String(item.category || "").toLowerCase(); + const itemPrice = Number(item.prix || item.price || 0); if (cat.includes("gros") || cat.includes("semi")) { excludedTotal += itemPrice; @@ -464,7 +464,7 @@ function SuiviLivraison() { const pointsEarned = response.points_earned || selectedOrderPoints; const apiCategory = - response.category || (response as Record & { data?: { category?: string } }).data?.category || ""; + response.category || response.data?.category || ""; const displayCategory = apiCategory && apiCategory !== "total" @@ -898,7 +898,7 @@ function SuiviLivraison() {
{order.items.map( ( - item: Record, + item: OrderItem, idx: number, ) => { const formatted =