chore: build
Frontend Admin - EAS Build / build (push) Failing after 56m59s

This commit is contained in:
2026-06-21 15:07:04 +02:00
parent 531602512b
commit a1a8e6c3f3
4 changed files with 104 additions and 21 deletions
+2
View File
@@ -1101,6 +1101,8 @@ export interface AppSettings {
client_color_success: string; client_color_success: string;
client_color_danger: string; client_color_danger: string;
client_color_warning: string; client_color_warning: string;
client_title_gradient_from: string;
client_title_gradient_to: string;
} }
export const getSettings = async (): Promise<{ export const getSettings = async (): Promise<{
@@ -782,7 +782,7 @@ export default function OrdersScreen() {
setOpenMenuId(null); setOpenMenuId(null);
handleForceValidate(item.id); handleForceValidate(item.id);
}, },
condition: !isDone && item.status !== "livre", condition: !isDone,
}, },
{ {
label: "Supprimer", label: "Supprimer",
@@ -1205,6 +1205,8 @@ export default function SettingsScreen() {
client_color_success: "#4ade80", client_color_success: "#4ade80",
client_color_danger: "#ef4444", client_color_danger: "#ef4444",
client_color_warning: "#f59e0b", client_color_warning: "#f59e0b",
client_title_gradient_from: "#a78bfa",
client_title_gradient_to: "#22d3ee",
}); });
const [showApiKey, setShowApiKey] = useState(false); const [showApiKey, setShowApiKey] = useState(false);
const [showIpnSecret, setShowIpnSecret] = useState(false); const [showIpnSecret, setShowIpnSecret] = useState(false);
@@ -1501,6 +1503,7 @@ export default function SettingsScreen() {
<ScrollView contentContainerStyle={s.content}> <ScrollView contentContainerStyle={s.content}>
{/* Personnalisation */} {/* Personnalisation */}
<AccordionSection title="Personnalisation" colors={colors} s={s}> <AccordionSection title="Personnalisation" colors={colors} s={s}>
{/* Nom du shop */}
<View style={[s.row, s.rowFirst]}> <View style={[s.row, s.rowFirst]}>
<View style={s.rowLeft}> <View style={s.rowLeft}>
<Text style={s.rowLabel}>Nom du shop</Text> <Text style={s.rowLabel}>Nom du shop</Text>
@@ -1517,6 +1520,67 @@ export default function SettingsScreen() {
autoCorrect={false} autoCorrect={false}
/> />
</View> </View>
{/* Dégradé titre boutique */}
<View style={{ borderTopWidth: 1, borderTopColor: colors.border, paddingHorizontal: spacing.l, paddingVertical: spacing.m, gap: spacing.m }}>
<Text style={s.rowLabel}>Dégradé du titre boutique</Text>
<Text style={s.rowDesc}>Couleurs du nom de la boutique dans le header du site client.</Text>
{/* Aperçu du dégradé */}
<View style={{ height: 36, borderRadius: borderRadius.sm, overflow: "hidden" }}>
<View style={{
flex: 1,
backgroundColor: settings.client_title_gradient_from,
// gradient simulé : deux moitiés de couleur
}}>
<View style={{
position: "absolute", right: 0, top: 0, bottom: 0,
width: "50%",
backgroundColor: settings.client_title_gradient_to,
}} />
<View style={{
position: "absolute", left: "25%", right: "25%", top: 0, bottom: 0,
backgroundColor: `${settings.client_title_gradient_from}00`,
}} />
</View>
</View>
{/* Couleur de départ */}
<View style={{ flexDirection: "row", alignItems: "center", gap: spacing.m }}>
<View style={{ width: 32, height: 32, borderRadius: borderRadius.sm, backgroundColor: settings.client_title_gradient_from, borderWidth: 1, borderColor: colors.border }} />
<View style={{ flex: 1 }}>
<Text style={[s.rowDesc, { marginBottom: 4 }]}>Couleur de départ</Text>
<TextInput
style={[s.input, { fontFamily: "monospace" }]}
value={settings.client_title_gradient_from}
onChangeText={(v) => setSettings((p) => ({ ...p, client_title_gradient_from: v }))}
placeholder="#a78bfa"
placeholderTextColor={colors.textMuted}
autoCorrect={false}
autoCapitalize="none"
maxLength={7}
/>
</View>
</View>
{/* Couleur de fin */}
<View style={{ flexDirection: "row", alignItems: "center", gap: spacing.m }}>
<View style={{ width: 32, height: 32, borderRadius: borderRadius.sm, backgroundColor: settings.client_title_gradient_to, borderWidth: 1, borderColor: colors.border }} />
<View style={{ flex: 1 }}>
<Text style={[s.rowDesc, { marginBottom: 4 }]}>Couleur de fin</Text>
<TextInput
style={[s.input, { fontFamily: "monospace" }]}
value={settings.client_title_gradient_to}
onChangeText={(v) => setSettings((p) => ({ ...p, client_title_gradient_to: v }))}
placeholder="#22d3ee"
placeholderTextColor={colors.textMuted}
autoCorrect={false}
autoCapitalize="none"
maxLength={7}
/>
</View>
</View>
</View>
</AccordionSection> </AccordionSection>
{/* Amendes */} {/* Amendes */}
@@ -6,8 +6,8 @@ import {
StyleSheet, StyleSheet,
RefreshControl, RefreshControl,
TouchableOpacity, TouchableOpacity,
Alert,
} from "react-native"; } from "react-native";
import AlertModal from "../../components/ui/AlertModal";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import { useFocusEffect } from "@react-navigation/native"; import { useFocusEffect } from "@react-navigation/native";
import { useTheme } from "../../context/ThemeContext"; import { useTheme } from "../../context/ThemeContext";
@@ -197,6 +197,8 @@ export default function StatsScreen() {
const [refreshing, setRefreshing] = useState(false); const [refreshing, setRefreshing] = useState(false);
const [resetting, setResetting] = useState<StatSection | null>(null); const [resetting, setResetting] = useState<StatSection | null>(null);
const [prodSort, setProdSort] = useState<ProdSort>("quantity"); const [prodSort, setProdSort] = useState<ProdSort>("quantity");
const [confirmModal, setConfirmModal] = useState<{ section: StatSection; label: string } | null>(null);
const [errorModal, setErrorModal] = useState<string | null>(null);
const loadStats = useCallback(async () => { const loadStats = useCallback(async () => {
try { try {
@@ -215,25 +217,21 @@ export default function StatsScreen() {
}; };
const handleReset = (section: StatSection, label: string) => { const handleReset = (section: StatSection, label: string) => {
Alert.alert( setConfirmModal({ section, label });
`Réinitialiser — ${label}`, };
"Les données de cette section repartiront de zéro. Les commandes restent en base.\n\nConfirmer ?",
[ const doReset = async () => {
{ text: "Annuler", style: "cancel" }, if (!confirmModal) return;
{ const { section } = confirmModal;
text: "Réinitialiser", setConfirmModal(null);
style: "destructive",
onPress: async () => {
setResetting(section); setResetting(section);
try { try {
await resetAdminStats(section); await resetAdminStats(section);
await loadStats(); await loadStats();
} catch { /* ignore */ } } catch (e: any) {
setErrorModal(e?.response?.data?.error || e?.message || "Impossible de réinitialiser");
}
setResetting(null); setResetting(null);
},
},
],
);
}; };
// Produits triés selon le sélecteur // Produits triés selon le sélecteur
@@ -271,6 +269,24 @@ export default function StatsScreen() {
)); ));
return ( return (
<>
<AlertModal
visible={confirmModal !== null}
type="confirm"
title={`Réinitialiser — ${confirmModal?.label ?? ""}`}
message={`Les données "${confirmModal?.label ?? ""}" repartiront de zéro.\nLes commandes restent en base.`}
confirmText="Réinitialiser"
cancelText="Annuler"
onClose={() => setConfirmModal(null)}
onConfirm={doReset}
/>
<AlertModal
visible={errorModal !== null}
type="error"
title="Erreur"
message={errorModal ?? ""}
onClose={() => setErrorModal(null)}
/>
<ScrollView <ScrollView
style={styles.container} style={styles.container}
contentContainerStyle={styles.content} contentContainerStyle={styles.content}
@@ -561,5 +577,6 @@ export default function StatsScreen() {
)} )}
</Section> </Section>
</ScrollView> </ScrollView>
</>
); );
} }