diff --git a/frontend-admin/src/screens/admin/DeliveryScreen.tsx b/frontend-admin/src/screens/admin/DeliveryScreen.tsx
index c8048f6e..77ccbcc3 100644
--- a/frontend-admin/src/screens/admin/DeliveryScreen.tsx
+++ b/frontend-admin/src/screens/admin/DeliveryScreen.tsx
@@ -25,7 +25,9 @@ import {
getAllDeliveryPersonsWithDetails,
getCommandByID,
getLivreurRatings,
+ getLivreurLoginHistory,
} from "../../api/api_admin";
+import type { LoginHistoryWeek } from "../../api/api_admin";
import { geocodeAddress, calculateRoute } from "../../api/tomtom";
import type { RouteInfo } from "../../api/tomtom";
import type { DeliveryPerson } from "../../api/types";
@@ -80,6 +82,50 @@ export default function DeliveryScreen() {
setRatingsLoading(false);
};
+ // Historique de connexion livreur
+ const [loginHistoryModal, setLoginHistoryModal] = useState<{
+ username: string;
+ year: number;
+ month: number;
+ weeks: LoginHistoryWeek[];
+ } | null>(null);
+ const [loginHistoryLoading, setLoginHistoryLoading] = useState(false);
+
+ const fetchLoginHistory = async (
+ username: string,
+ year: number,
+ month: number,
+ ) => {
+ setLoginHistoryLoading(true);
+ const res = await getLivreurLoginHistory(username, year, month);
+ setLoginHistoryModal({
+ username,
+ year: res.year,
+ month: res.month,
+ weeks: res.weeks,
+ });
+ setLoginHistoryLoading(false);
+ };
+
+ const openLoginHistory = (username: string) => {
+ const now = new Date();
+ fetchLoginHistory(username, now.getFullYear(), now.getMonth() + 1);
+ };
+
+ const changeLoginHistoryMonth = (delta: number) => {
+ if (!loginHistoryModal) return;
+ let year = loginHistoryModal.year;
+ let month = loginHistoryModal.month + delta;
+ if (month < 1) {
+ month = 12;
+ year -= 1;
+ } else if (month > 12) {
+ month = 1;
+ year += 1;
+ }
+ fetchLoginHistory(loginHistoryModal.username, year, month);
+ };
+
const loadData = useCallback(async () => {
try {
const result = await getAllDeliveryPersonsWithDetails();
@@ -375,6 +421,48 @@ export default function DeliveryScreen() {
fontWeight: "600",
},
+ historyBtn: {
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "center",
+ gap: spacing.s,
+ marginTop: spacing.m,
+ paddingVertical: spacing.s,
+ paddingHorizontal: spacing.m,
+ borderRadius: borderRadius.sm,
+ borderWidth: 1,
+ borderColor: colors.accent,
+ },
+ historyBtnText: {
+ color: colors.accent,
+ fontSize: fontSize.sm,
+ fontWeight: "600",
+ },
+
+ historyWeekLabel: {
+ color: colors.textMuted,
+ fontSize: fontSize.xs,
+ fontWeight: "700",
+ textTransform: "uppercase",
+ marginBottom: spacing.xs,
+ marginTop: spacing.m,
+ },
+ historyEntryRow: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ paddingVertical: spacing.xs,
+ borderTopWidth: 1,
+ borderTopColor: colors.borderLight,
+ },
+ historyEntryDate: {
+ color: colors.textPrimary,
+ fontSize: fontSize.sm,
+ },
+ historyEntryTime: {
+ color: colors.textMuted,
+ fontSize: fontSize.sm,
+ },
+
trackBtn: {
flexDirection: "row",
alignItems: "center",
@@ -643,6 +731,21 @@ export default function DeliveryScreen() {
Voir les avis
+ openLoginHistory(item.username)}
+ activeOpacity={0.7}
+ >
+
+
+ Historique de connexion
+
+
+
{hasGPS && (
+
+ {/* ── Modal historique de connexion livreur ── */}
+ setLoginHistoryModal(null)}
+ >
+ setLoginHistoryModal(null)}
+ >
+ {}}>
+
+
+
+ Connexions — {loginHistoryModal?.username}
+
+ setLoginHistoryModal(null)}
+ >
+
+
+
+
+
+ changeLoginHistoryMonth(-1)}
+ >
+
+
+
+ {loginHistoryModal &&
+ new Date(
+ loginHistoryModal.year,
+ loginHistoryModal.month - 1,
+ 1,
+ )
+ .toLocaleDateString("fr-FR", {
+ month: "long",
+ year: "numeric",
+ })
+ .replace(/^./, (c) =>
+ c.toUpperCase(),
+ )}
+
+ changeLoginHistoryMonth(1)}
+ >
+
+
+
+
+ {loginHistoryLoading ? (
+
+ Chargement...
+
+ ) : loginHistoryModal &&
+ loginHistoryModal.weeks.length > 0 ? (
+
+ {loginHistoryModal.weeks.map((week) => (
+
+
+ Semaine {week.week}
+
+ {week.entries.map((entry) => (
+
+
+ {new Date(
+ entry.created_at,
+ ).toLocaleDateString(
+ "fr-FR",
+ {
+ weekday: "short",
+ day: "2-digit",
+ month: "2-digit",
+ },
+ )}
+
+
+ {new Date(
+ entry.created_at,
+ ).toLocaleTimeString(
+ "fr-FR",
+ {
+ hour: "2-digit",
+ minute: "2-digit",
+ },
+ )}
+
+
+ ))}
+
+ ))}
+
+ ) : (
+
+ Aucune connexion ce mois-ci
+
+ )}
+
+
+
+
);
}