chore: add history connection deliveryman
Frontend Admin - EAS Build / build (push) Failing after 2h5m32s

This commit is contained in:
Nuxgrid
2026-07-18 18:02:04 +02:00
parent dfa432862a
commit 48340317d8
@@ -25,7 +25,9 @@ import {
getAllDeliveryPersonsWithDetails, getAllDeliveryPersonsWithDetails,
getCommandByID, getCommandByID,
getLivreurRatings, getLivreurRatings,
getLivreurLoginHistory,
} from "../../api/api_admin"; } from "../../api/api_admin";
import type { LoginHistoryWeek } from "../../api/api_admin";
import { geocodeAddress, calculateRoute } from "../../api/tomtom"; import { geocodeAddress, calculateRoute } from "../../api/tomtom";
import type { RouteInfo } from "../../api/tomtom"; import type { RouteInfo } from "../../api/tomtom";
import type { DeliveryPerson } from "../../api/types"; import type { DeliveryPerson } from "../../api/types";
@@ -80,6 +82,50 @@ export default function DeliveryScreen() {
setRatingsLoading(false); 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 () => { const loadData = useCallback(async () => {
try { try {
const result = await getAllDeliveryPersonsWithDetails(); const result = await getAllDeliveryPersonsWithDetails();
@@ -375,6 +421,48 @@ export default function DeliveryScreen() {
fontWeight: "600", 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: { trackBtn: {
flexDirection: "row", flexDirection: "row",
alignItems: "center", alignItems: "center",
@@ -643,6 +731,21 @@ export default function DeliveryScreen() {
<Text style={styles.ratingsBtnText}>Voir les avis</Text> <Text style={styles.ratingsBtnText}>Voir les avis</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity
style={styles.historyBtn}
onPress={() => openLoginHistory(item.username)}
activeOpacity={0.7}
>
<Ionicons
name="time-outline"
size={14}
color={colors.accent}
/>
<Text style={styles.historyBtnText}>
Historique de connexion
</Text>
</TouchableOpacity>
{hasGPS && ( {hasGPS && (
<TouchableOpacity <TouchableOpacity
style={[ style={[
@@ -1027,6 +1130,146 @@ export default function DeliveryScreen() {
</Pressable> </Pressable>
</Pressable> </Pressable>
</Modal> </Modal>
{/* ── Modal historique de connexion livreur ── */}
<Modal
visible={loginHistoryModal !== null}
transparent
animationType="slide"
onRequestClose={() => setLoginHistoryModal(null)}
>
<Pressable
style={styles.ratingsOverlay}
onPress={() => setLoginHistoryModal(null)}
>
<Pressable onPress={() => {}}>
<View style={styles.ratingsSheet}>
<View style={styles.ratingsHeader}>
<Text style={styles.ratingsTitle}>
Connexions — {loginHistoryModal?.username}
</Text>
<TouchableOpacity
onPress={() => setLoginHistoryModal(null)}
>
<Ionicons
name="close"
size={22}
color={colors.textMuted}
/>
</TouchableOpacity>
</View>
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginBottom: spacing.m,
}}
>
<TouchableOpacity
onPress={() => changeLoginHistoryMonth(-1)}
>
<Ionicons
name="chevron-back"
size={20}
color={colors.textPrimary}
/>
</TouchableOpacity>
<Text
style={{
color: colors.textWhite,
fontWeight: "700",
fontSize: fontSize.md,
}}
>
{loginHistoryModal &&
new Date(
loginHistoryModal.year,
loginHistoryModal.month - 1,
1,
)
.toLocaleDateString("fr-FR", {
month: "long",
year: "numeric",
})
.replace(/^./, (c) =>
c.toUpperCase(),
)}
</Text>
<TouchableOpacity
onPress={() => changeLoginHistoryMonth(1)}
>
<Ionicons
name="chevron-forward"
size={20}
color={colors.textPrimary}
/>
</TouchableOpacity>
</View>
{loginHistoryLoading ? (
<Text style={styles.ratingsEmpty}>
Chargement...
</Text>
) : loginHistoryModal &&
loginHistoryModal.weeks.length > 0 ? (
<ScrollView showsVerticalScrollIndicator={false}>
{loginHistoryModal.weeks.map((week) => (
<View key={week.week}>
<Text style={styles.historyWeekLabel}>
Semaine {week.week}
</Text>
{week.entries.map((entry) => (
<View
key={entry.id}
style={styles.historyEntryRow}
>
<Text
style={
styles.historyEntryDate
}
>
{new Date(
entry.created_at,
).toLocaleDateString(
"fr-FR",
{
weekday: "short",
day: "2-digit",
month: "2-digit",
},
)}
</Text>
<Text
style={
styles.historyEntryTime
}
>
{new Date(
entry.created_at,
).toLocaleTimeString(
"fr-FR",
{
hour: "2-digit",
minute: "2-digit",
},
)}
</Text>
</View>
))}
</View>
))}
</ScrollView>
) : (
<Text style={styles.ratingsEmpty}>
Aucune connexion ce mois-ci
</Text>
)}
</View>
</Pressable>
</Pressable>
</Modal>
</View> </View>
); );
} }