From 97712f240e9accbce0f22dcbb9bc771273e0a8c0 Mon Sep 17 00:00:00 2001 From: Xor290 Date: Sat, 9 May 2026 15:30:48 +0200 Subject: [PATCH] fix: ts --- backend/gestion/services/geo_services.go | 4 - .../src/pages/User/ConsultationHistorique.tsx | 636 +++++++++++------- 2 files changed, 383 insertions(+), 257 deletions(-) diff --git a/backend/gestion/services/geo_services.go b/backend/gestion/services/geo_services.go index e9131819..820b2746 100644 --- a/backend/gestion/services/geo_services.go +++ b/backend/gestion/services/geo_services.go @@ -52,10 +52,6 @@ type GeoService struct { httpClient *http.Client } -// ============================================ -// CONSTRUCTEUR -// ============================================ - func NewGeoService(redisClient *redis.Client, ctx context.Context) *GeoService { return &GeoService{ redis: redisClient, diff --git a/frontend-prep/src/pages/User/ConsultationHistorique.tsx b/frontend-prep/src/pages/User/ConsultationHistorique.tsx index 2127dd8f..4f453899 100644 --- a/frontend-prep/src/pages/User/ConsultationHistorique.tsx +++ b/frontend-prep/src/pages/User/ConsultationHistorique.tsx @@ -1,278 +1,408 @@ -import { useState, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; -import Navbar from '../../components/Navbar'; -import './ConsultationHistorique.css'; +import { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import Navbar from "../../components/Navbar"; +import "./ConsultationHistorique.css"; import { - getMyCompletedOrders, - formatPrice, - getOrderAge, - getMyPenalties, - isUserAuthenticated, - getPublicSettings, - getReferralBalance, -} from '../../api/api'; -import type { PublicSettings } from '../../api/api'; -import type { CompletedOrder, ClientStats, PenaltyInfo } from "../../api/api_types"; + getMyCompletedOrders, + formatPrice, + getOrderAge, + getMyPenalties, + isUserAuthenticated, + getPublicSettings, + getReferralBalance, +} from "../../api/api"; +import type { PublicSettings } from "../../api/api"; +import type { + CompletedOrder, + ClientStats, + PenaltyInfo, +} from "../../api/api_types"; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { - faCannabis, - faPills, - faFlask, - faMortarPestle, - faStar, - faTrophy, - faExclamationTriangle, - faShieldAlt, - faGift, - faReceipt, - faMapMarkerAlt, - faClock, - faBicycle, - faChevronRight, - faCheckCircle, - faHistory, -} from '@fortawesome/free-solid-svg-icons'; + faCannabis, + faPills, + faFlask, + faMortarPestle, + faStar, + faTrophy, + faExclamationTriangle, + faShieldAlt, + faGift, + faReceipt, + faMapMarkerAlt, + faClock, + faBicycle, + faChevronRight, + faCheckCircle, + faHistory, +} from "@fortawesome/free-solid-svg-icons"; function ConsultationHistorique() { - const navigate = useNavigate(); + const navigate = useNavigate(); - const [orders, setOrders] = useState([]); - const [clientStats, setClientStats] = useState(null); - const [penalties, setPenalties] = useState(null); - const [appSettings, setAppSettings] = useState({ penalties_enabled: true, show_amende_score: true, points_enabled: true, points_separated: true, referral_enabled: true, referral_amount: 0, pool_names: ['Pool 1', 'Pool 2'], crypto_payment_enabled: false, crypto_only: false, nowpayments_currencies: [], shop_name: 'Milieu-Nantais', two_fa_enabled: false }); - const [referralBalance, setReferralBalance] = useState(0); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(''); - - useEffect(() => { - if (!isUserAuthenticated()) navigate('/login/client', { replace: true }); - }, [navigate]); - - useEffect(() => { - const interval = setInterval(() => { - if (!isUserAuthenticated()) navigate('/login/client', { replace: true }); - }, 5000); - return () => clearInterval(interval); - }, [navigate]); - - useEffect(() => { - fetchHistory(); - fetchPenalties(); - getPublicSettings().then((s) => { - setAppSettings(s); - if (s.referral_enabled) { - getReferralBalance().then((r) => { if (r.success) setReferralBalance(r.balance); }); - } + const [orders, setOrders] = useState([]); + const [clientStats, setClientStats] = useState(null); + const [penalties, setPenalties] = useState(null); + const [appSettings, setAppSettings] = useState({ + penalties_enabled: true, + show_amende_score: true, + points_enabled: true, + points_separated: true, + referral_enabled: true, + referral_amount: 0, + pool_names: ["Pool 1", "Pool 2"], + crypto_payment_enabled: false, + crypto_only: false, + nowpayments_currencies: [], + shop_name: "Milieu-Nantais", + two_fa_enabled: false, }); - }, []); // eslint-disable-line react-hooks/exhaustive-deps + const [referralBalance, setReferralBalance] = useState(0); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(""); - const fetchHistory = async () => { - if (!isUserAuthenticated()) { navigate('/login/client', { replace: true }); return; } - setIsLoading(true); - setError(''); - try { - const result = await getMyCompletedOrders(); - if (result.success) { - setOrders(result.commands); - setClientStats(result.client_stats || null); - } else { - setError(result.message || 'Erreur lors du chargement'); - } - } catch { - setError('Erreur de connexion'); - } finally { - setIsLoading(false); + useEffect(() => { + if (!isUserAuthenticated()) + navigate("/login/client", { replace: true }); + }, [navigate]); + + useEffect(() => { + const interval = setInterval(() => { + if (!isUserAuthenticated()) + navigate("/login/client", { replace: true }); + }, 5000); + return () => clearInterval(interval); + }, [navigate]); + + useEffect(() => { + fetchHistory(); + fetchPenalties(); + getPublicSettings().then((s) => { + setAppSettings(s); + if (s.referral_enabled) { + getReferralBalance().then((r) => { + if (r.success) setReferralBalance(r.balance); + }); + } + }); + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + const fetchHistory = async () => { + if (!isUserAuthenticated()) { + navigate("/login/client", { replace: true }); + return; + } + setIsLoading(true); + setError(""); + try { + const result = await getMyCompletedOrders(); + if (result.success) { + setOrders(result.commands); + setClientStats(result.client_stats || null); + } else { + setError(result.message || "Erreur lors du chargement"); + } + } catch { + setError("Erreur de connexion"); + } finally { + setIsLoading(false); + } + }; + + const fetchPenalties = async () => { + if (!isUserAuthenticated()) return; + try { + const result = await getMyPenalties(); + if (result.success && result.data) setPenalties(result.data); + } catch { + /* ignore */ + } + }; + + const viewOrderDetails = (order: CompletedOrder) => { + if (!isUserAuthenticated()) { + navigate("/login/client", { replace: true }); + return; + } + navigate(`/user/commande/${order.client_order_number ?? order.id}`, { + state: { commandId: order.id }, + }); + }; + + const formatDate = (dateStr: string) => { + const d = new Date(dateStr); + return d.toLocaleDateString("fr-FR", { + day: "2-digit", + month: "short", + year: "numeric", + }); + }; + + if (isLoading) { + return ( + <> + +
+
+
+
+
+

+ Chargement de l'historique... +

+
+
+ + ); } - }; - const fetchPenalties = async () => { - if (!isUserAuthenticated()) return; - try { - const result = await getMyPenalties(); - if (result.success && result.data) setPenalties(result.data); - } catch { /* ignore */ } - }; + const poolNames = clientStats?.pool_names?.length + ? clientStats.pool_names + : appSettings.pool_names; + const poolPoints = clientStats?.pool_points ?? [clientStats?.points ?? 0]; + const totalPoints = poolPoints.reduce((s, v) => s + (v || 0), 0); + const penaltyCount = + penalties?.total_penalty || clientStats?.penalties || 0; + const poolIcons = [faCannabis, faPills, faFlask, faMortarPestle, faStar]; + const poolIconColors = [ + "#10b981", + "#e879f9", + "#fb923c", + "#38bdf8", + "#7c3aed", + ]; - const viewOrderDetails = (order: CompletedOrder) => { - if (!isUserAuthenticated()) { navigate('/login/client', { replace: true }); return; } - navigate(`/user/commande/${order.client_order_number ?? order.id}`, { - state: { commandId: order.id }, - }); - }; - - const formatDate = (dateStr: string) => { - const d = new Date(dateStr); - return d.toLocaleDateString('fr-FR', { day: '2-digit', month: 'short', year: 'numeric' }); - }; - - if (isLoading) { return ( - <> - -
-
-
-

Chargement de l'historique...

-
-
- - ); - } + <> + +
+

Historique des commandes

- const poolNames = clientStats?.pool_names?.length ? clientStats.pool_names : appSettings.pool_names; - const poolPoints = clientStats?.pool_points ?? [clientStats?.points ?? 0]; - const totalPoints = poolPoints.reduce((s, v) => s + (v || 0), 0); - const penaltyCount = penalties?.total_penalty || clientStats?.penalties || 0; - const poolIcons = [faCannabis, faPills, faFlask, faMortarPestle, faStar]; - const poolIconColors = ['#10b981', '#e879f9', '#fb923c', '#38bdf8', '#7c3aed']; + {/* Stats grid */} +
+ {/* Total commandes */} +
+
+ +
+

+ {clientStats?.total_commands ?? orders.length} +

+

Commandes

+
- return ( - <> - -
+ {/* Points */} + {appSettings.points_enabled && + (poolNames.length <= 1 ? ( +
+
+ +
+

+ {poolPoints[0] || 0} +

+

+ Pts {poolNames[0] ?? "Points"} +

+
+ ) : ( + <> + {poolNames.map((name, i) => ( +
+
+ +
+

+ {poolPoints[i] || 0} +

+

Pts {name}

+
+ ))} + {totalPoints > 0 && ( +
+
+ +
+

+ {totalPoints} +

+

+ Total Points +

+
+ )} + + ))} -

Historique des commandes

- - {/* Stats grid */} -
- - {/* Total commandes */} -
-
- -
-

{clientStats?.total_commands ?? orders.length}

-

Commandes

-
- - {/* Points */} - {appSettings.points_enabled && ( - poolNames.length <= 1 ? ( -
-
- + {/* Score amendes */} + {appSettings.show_amende_score && ( +
= 3 ? " stat-card-danger" : penaltyCount > 0 ? " stat-card-warning" : ""}`} + > +
= 3 ? "icon-penalty-critical" : penaltyCount > 0 ? "icon-penalty-warning" : "icon-penalty-ok"}`} + > + 0 + ? faExclamationTriangle + : faShieldAlt + } + /> +
+

= 3 ? "value-danger" : penaltyCount > 0 ? "value-warning" : ""}`} + > + {penaltyCount} +

+

Score amendes

+
+ )}
-

{poolPoints[0] || 0}

-

Pts {poolNames[0] ?? 'Points'}

-
- ) : ( - <> - {poolNames.map((name, i) => ( -
-
- + + {/* Bouton parrainage */} + {appSettings.referral_enabled && ( +
navigate("/user/parrainage")} + > + + + Parrainage + {referralBalance > 0 + ? ` — ${referralBalance.toFixed(2)} €` + : ""} + +
-

{poolPoints[i] || 0}

-

Pts {name}

-
- ))} - {totalPoints > 0 && ( -
-
- -
-

{totalPoints}

-

Total Points

-
)} - - ) - )} - {/* Score amendes */} - {appSettings.show_amende_score && ( -
= 3 ? ' stat-card-danger' : penaltyCount > 0 ? ' stat-card-warning' : ''}`}> -
= 3 ? 'icon-penalty-critical' : penaltyCount > 0 ? 'icon-penalty-warning' : 'icon-penalty-ok'}`}> - 0 ? faExclamationTriangle : faShieldAlt} /> -
-

= 3 ? 'value-danger' : penaltyCount > 0 ? 'value-warning' : ''}`}>{penaltyCount}

-

Score amendes

-
- )} -
- - {/* Bouton parrainage */} - {appSettings.referral_enabled && ( -
navigate('/user/parrainage')}> - - - Parrainage{referralBalance > 0 ? ` — ${referralBalance.toFixed(2)} €` : ''} - - -
- )} - - {error && ( -
- -

{error}

-
- )} - - {orders.length === 0 ? ( -
- -

Aucun historique

-

Vos commandes terminées apparaîtront ici

- -
- ) : ( - <> -

Historique des commandes

-
- {orders.map((order) => ( -
viewOrderDetails(order)} - > -
- - Commande #{(order.client_order_number ?? 0).toString().padStart(4, '0')} - - - - Livrée - -
- -
- - - {order.adresse ? (order.adresse.length > 50 ? order.adresse.substring(0, 50) + '…' : order.adresse) : 'N/A'} - -
- -
- - - {formatDate(order.created_at)} · {getOrderAge(order.created_at)} - -
- - {order.livreur_assign && ( -
- - {order.livreur_assign} + {error && ( +
+ +

{error}

- )} + )} -
- {formatPrice(order.total_prix || 0)} - -
-
- ))} + {orders.length === 0 ? ( +
+ +

Aucun historique

+

Vos commandes terminées apparaîtront ici

+ +
+ ) : ( + <> +

+ Historique des commandes +

+
+ {orders.map((order) => ( +
viewOrderDetails(order)} + > +
+ + Commande # + {(order.client_order_number ?? 0) + .toString() + .padStart(4, "0")} + + + + Livrée + +
+ +
+ + + {order.adresse + ? order.adresse.length > 50 + ? order.adresse.substring( + 0, + 50, + ) + "…" + : order.adresse + : "N/A"} + +
+ +
+ + + {formatDate(order.created_at)} ·{" "} + {getOrderAge(order.created_at)} + +
+ + {order.livreur_assign && ( +
+ + + {order.livreur_assign} + +
+ )} + +
+ + {formatPrice(order.total_prix || 0)} + + +
+
+ ))} +
+ + )}
- - )} - -
- - ); + + ); } export default ConsultationHistorique;