chore: build
Frontend Admin - EAS Build / build (push) Failing after 59m42s

This commit is contained in:
2026-06-28 12:44:17 +02:00
parent 75161a1ae0
commit 3be323fcfe
2 changed files with 246 additions and 41 deletions
+9
View File
@@ -156,6 +156,15 @@ export const getAdminStats = async (): Promise<AdminStats> => {
return data;
};
export const getAdminDailyDetail = async (
date: string,
): Promise<DailyDetail> => {
const { data } = await apiClient.get(`${V2}/admin/protected/stats/daily`, {
params: { date },
});
return data;
};
export const resetAdminStats = async (
section: StatSection,
): Promise<{ success: boolean; reset_at: string }> => {
+237 -41
View File
@@ -6,6 +6,7 @@ import {
StyleSheet,
RefreshControl,
TouchableOpacity,
Modal,
} from "react-native";
import AlertModal from "../../components/ui/AlertModal";
import { Ionicons } from "@expo/vector-icons";
@@ -18,6 +19,7 @@ import {
getAdminStats,
resetAdminStats,
getAdminStatsByMonth,
getAdminDailyDetail,
} from "../../api/api_admin";
import type {
AdminStats,
@@ -380,46 +382,15 @@ function SectionResetBtn({
);
}
// ── Section détail du jour ────────────────────────────────────────────────────
function DailyDetailSection({ daily }: { daily: DailyDetail }) {
// ── Contenu détaillé d'un jour (catégories → produits) ───────────────────────
// Réutilisé à la fois par la section "Activité du jour" (aujourd'hui) et par
// la modal de détail d'un jour cliqué dans l'historique mensuel.
function DailyDetailContent({ daily }: { daily: DailyDetail }) {
const { colors } = useTheme();
const hasData = daily.categories.length > 0;
return (
<View
style={[
ddStyles.card,
{
backgroundColor: colors.bgCard,
borderColor: colors.borderLight,
},
]}
>
{/* En-tête */}
<View style={ddStyles.header}>
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: spacing.s,
}}
>
<Ionicons
name="today-outline"
size={16}
color={CHART_ACCENT}
/>
<Text
style={[ddStyles.title, { color: colors.textPrimary }]}
>
Activité du jour
</Text>
</View>
<Text style={[ddStyles.date, { color: colors.textMuted }]}>
{daily.date}
</Text>
</View>
<>
{/* Mini-résumé */}
<View style={ddStyles.chipRow}>
<View
@@ -510,7 +481,7 @@ function DailyDetailSection({ daily }: { daily: DailyDetail }) {
{!hasData ? (
<Text style={[ddStyles.empty, { color: colors.textMuted }]}>
Aucune commande aujourd'hui
Aucune commande ce jour-
</Text>
) : (
daily.categories.map((cat: DailyCategoryDetail, ci: number) => {
@@ -676,6 +647,50 @@ function DailyDetailSection({ daily }: { daily: DailyDetail }) {
);
})
)}
</>
);
}
// ── Section détail du jour (aujourd'hui, dans le flux principal) ────────────
function DailyDetailSection({ daily }: { daily: DailyDetail }) {
const { colors } = useTheme();
return (
<View
style={[
ddStyles.card,
{
backgroundColor: colors.bgCard,
borderColor: colors.borderLight,
},
]}
>
{/* En-tête */}
<View style={ddStyles.header}>
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: spacing.s,
}}
>
<Ionicons
name="today-outline"
size={16}
color={CHART_ACCENT}
/>
<Text
style={[ddStyles.title, { color: colors.textPrimary }]}
>
Activité du jour
</Text>
</View>
<Text style={[ddStyles.date, { color: colors.textMuted }]}>
{daily.date}
</Text>
</View>
<DailyDetailContent daily={daily} />
</View>
);
}
@@ -747,6 +762,159 @@ const ddStyles = StyleSheet.create({
barFill: { height: "100%", borderRadius: 3 },
});
// ── Modal — détail d'un jour cliqué dans l'historique mensuel ───────────────
function DayDetailModal({
visible,
dateLabel,
onClose,
}: {
visible: boolean;
dateLabel: string | null; // "2026-06-05"
onClose: () => void;
}) {
const { colors } = useTheme();
const [detail, setDetail] = useState<DailyDetail | null>(null);
const [loading, setLoading] = useState(false);
const [errored, setErrored] = useState(false);
useEffect(() => {
if (!visible || !dateLabel) return;
setLoading(true);
setErrored(false);
getAdminDailyDetail(dateLabel)
.then((data) => setDetail(data))
.catch(() => setErrored(true))
.finally(() => setLoading(false));
}, [visible, dateLabel]);
const prettyDate = useMemo(() => {
if (!dateLabel) return "";
const [y, m, d] = dateLabel.split("-").map(Number);
return new Date(y, m - 1, d).toLocaleDateString("fr-FR", {
weekday: "long",
day: "2-digit",
month: "long",
year: "numeric",
});
}, [dateLabel]);
return (
<Modal
visible={visible}
transparent
animationType="fade"
onRequestClose={onClose}
>
<View style={dayModalStyles.overlay}>
<View
style={[
dayModalStyles.sheet,
{
backgroundColor: colors.bgCard,
borderColor: colors.borderLight,
},
]}
>
<View style={dayModalStyles.header}>
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: spacing.s,
flex: 1,
}}
>
<Ionicons
name="calendar-outline"
size={16}
color={CHART_ACCENT}
/>
<Text
style={[
dayModalStyles.title,
{ color: colors.textPrimary },
]}
numberOfLines={1}
>
{prettyDate}
</Text>
</View>
<TouchableOpacity
onPress={onClose}
style={dayModalStyles.closeBtn}
>
<Ionicons
name="close"
size={18}
color={colors.textMuted}
/>
</TouchableOpacity>
</View>
<ScrollView
style={{ maxHeight: 480 }}
showsVerticalScrollIndicator={false}
>
{loading ? (
<Text
style={{
color: colors.textMuted,
fontSize: fontSize.sm,
textAlign: "center",
paddingVertical: spacing.l,
}}
>
Chargement...
</Text>
) : errored ? (
<Text
style={{
color: CHART_RED,
fontSize: fontSize.sm,
textAlign: "center",
paddingVertical: spacing.l,
}}
>
Impossible de charger le détail de ce jour
</Text>
) : detail ? (
<DailyDetailContent daily={detail} />
) : null}
</ScrollView>
</View>
</View>
</Modal>
);
}
const dayModalStyles = StyleSheet.create({
overlay: {
flex: 1,
backgroundColor: "rgba(0,0,0,0.55)",
justifyContent: "center",
padding: spacing.l,
},
sheet: {
borderRadius: borderRadius.md,
borderWidth: 1,
padding: spacing.l,
maxHeight: "85%",
},
header: {
flexDirection: "row",
alignItems: "center",
marginBottom: spacing.m,
},
title: {
fontSize: fontSize.md,
fontWeight: "700",
textTransform: "capitalize",
},
closeBtn: {
padding: spacing.xs,
},
});
// ── Helpers de mois (clé "YYYY-MM") ───────────────────────────────────────────
function monthKey(date: Date): string {
const y = date.getFullYear();
@@ -773,6 +941,7 @@ function MonthlyHistorySection() {
const [monthly, setMonthly] = useState<MonthlyStats | null>(null);
const [loadingMonth, setLoadingMonth] = useState(false);
const [expanded, setExpanded] = useState(false);
const [selectedDay, setSelectedDay] = useState<string | null>(null);
const currentMonthKey = monthKey(new Date());
const isCurrentMonth = monthKeyState === currentMonthKey;
@@ -1087,7 +1256,7 @@ function MonthlyHistorySection() {
</Text>
</View>
{/* Liste détaillée jour par jour */}
{/* Liste détaillée jour par jour — cliquable */}
{[...days].reverse().map((d) => {
const isBest = best && d.day === best.day;
const pct =
@@ -1097,9 +1266,15 @@ function MonthlyHistorySection() {
d.count > 0 ? 3 : 0,
)
: 0;
const hasData = d.count > 0;
return (
<View
<TouchableOpacity
key={d.day}
onPress={() =>
hasData && setSelectedDay(d.day)
}
disabled={!hasData}
activeOpacity={0.6}
style={{
flexDirection: "row",
alignItems: "center",
@@ -1111,7 +1286,15 @@ function MonthlyHistorySection() {
style={{
width: 42,
fontSize: fontSize.xs,
color: colors.textMuted,
color: hasData
? colors.textPrimary
: colors.textMuted,
fontWeight: hasData
? "600"
: "400",
textDecorationLine: hasData
? "underline"
: "none",
}}
>
{d.label}
@@ -1179,7 +1362,14 @@ function MonthlyHistorySection() {
color={CHART_AMBER}
/>
)}
</View>
{hasData && (
<Ionicons
name="chevron-forward"
size={12}
color={colors.textMuted}
/>
)}
</TouchableOpacity>
);
})}
@@ -1220,6 +1410,12 @@ function MonthlyHistorySection() {
)}
</>
)}
<DayDetailModal
visible={selectedDay !== null}
dateLabel={selectedDay}
onClose={() => setSelectedDay(null)}
/>
</View>
);
}