diff --git a/frontend-admin/src/api/api_delivery.ts b/frontend-admin/src/api/api_delivery.ts index c4bf6a9e..30aac8c1 100644 --- a/frontend-admin/src/api/api_delivery.ts +++ b/frontend-admin/src/api/api_delivery.ts @@ -379,6 +379,8 @@ export const getMyStats = async (): Promise<{ by_day?: StatPoint[]; by_week?: StatPoint[]; by_month?: StatPoint[]; + today_count?: number; + today_revenue?: number; error?: string; }> => { try { @@ -388,6 +390,8 @@ export const getMyStats = async (): Promise<{ by_day: data.by_day || [], by_week: data.by_week || [], by_month: data.by_month || [], + today_count: data.today_count || 0, + today_revenue: data.today_revenue || 0, }; } catch (error: any) { return { success: false, error: error.response?.data?.error || "Erreur réseau" }; diff --git a/frontend-admin/src/screens/delivery/StatsScreen.tsx b/frontend-admin/src/screens/delivery/StatsScreen.tsx index 5033683e..06c03049 100644 --- a/frontend-admin/src/screens/delivery/StatsScreen.tsx +++ b/frontend-admin/src/screens/delivery/StatsScreen.tsx @@ -89,6 +89,7 @@ export default function StatsScreen() { const [byDay, setByDay] = useState([]); const [byWeek, setByWeek] = useState([]); const [byMonth, setByMonth] = useState([]); + const [todayCount, setTodayCount] = useState(0); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [period, setPeriod] = useState("week"); @@ -104,6 +105,7 @@ export default function StatsScreen() { setByDay(statsRes.by_day ?? []); setByWeek(statsRes.by_week ?? []); setByMonth(statsRes.by_month ?? []); + setTodayCount(statsRes.today_count ?? 0); } } catch { /* ignore */ @@ -205,6 +207,7 @@ export default function StatsScreen() { ); const summaryCards = [ + { label: "Livraisons du jour", value: todayCount.toString(), icon: "today-outline" as const, color: colors.accent }, { label: "Total livraisons", value: total.toString(), icon: "cube-outline" as const, color: colors.accent }, { label: "Complétées", value: completed.toString(), icon: "checkmark-circle-outline" as const, color: colors.success }, { label: "En cours", value: inProgress.toString(), icon: "time-outline" as const, color: colors.warning }, diff --git a/mobile/src/screens/client/ProductsScreen.tsx b/mobile/src/screens/client/ProductsScreen.tsx index 813f4450..7d8b78e2 100644 --- a/mobile/src/screens/client/ProductsScreen.tsx +++ b/mobile/src/screens/client/ProductsScreen.tsx @@ -50,16 +50,19 @@ export default function ProductsScreen() { const carouselRef = useRef(null); const scaleAnim = useRef(new Animated.Value(1)).current; - useEffect(() => { - getCategories().then((cats) => { - const sorted = [...cats].sort((a, b) => { - if (a.is_coming_soon === b.is_coming_soon) return 0; - return a.is_coming_soon ? 1 : -1; - }); - setCategories(sorted); + const loadCategories = useCallback(async () => { + const cats = await getCategories(); + const sorted = [...cats].sort((a, b) => { + if (a.is_coming_soon === b.is_coming_soon) return 0; + return a.is_coming_soon ? 1 : -1; }); + setCategories(sorted); }, []); + useEffect(() => { + loadCategories(); + }, [loadCategories]); + useEffect(() => { const pulse = Animated.loop( Animated.sequence([ @@ -118,7 +121,9 @@ export default function ProductsScreen() { const onRefresh = () => { setRefreshing(true); - fetchProducts(); + // Le rechargement des produits est déclenché par l'effet ci-dessus + // dès que `categories` change (nouvelle référence à chaque appel). + loadCategories(); }; const styles = useMemo(