chore: update

This commit is contained in:
2026-03-08 18:14:03 +01:00
parent dc9e812391
commit 8d63ecd496
3 changed files with 141 additions and 84 deletions
@@ -25,6 +25,7 @@ import OrdersScreen from "../screens/cabine/OrdersScreen";
import DeliveryScreen from "../screens/cabine/DeliveryScreen"; import DeliveryScreen from "../screens/cabine/DeliveryScreen";
import UsersScreen from "../screens/cabine/UsersScreen"; import UsersScreen from "../screens/cabine/UsersScreen";
import AlertsScreen from "../screens/cabine/AlertsScreen"; import AlertsScreen from "../screens/cabine/AlertsScreen";
import AddressScreen from "../screens/cabine/AddressScreen";
const Tab = createBottomTabNavigator<CabineTabParamList>(); const Tab = createBottomTabNavigator<CabineTabParamList>();
@@ -42,7 +43,9 @@ export default function CabineNavigator() {
const res = await getCabineNotifications(); const res = await getCabineNotifications();
setNotifications(res.notifications ?? []); setNotifications(res.notifications ?? []);
setUnreadCount(res.unread_count ?? 0); setUnreadCount(res.unread_count ?? 0);
} catch { /* ignore */ } } catch {
/* ignore */
}
}, []); }, []);
useEffect(() => { useEffect(() => {
@@ -59,8 +62,12 @@ export default function CabineNavigator() {
try { try {
await markCabineNotificationsRead(); await markCabineNotificationsRead();
setUnreadCount(0); setUnreadCount(0);
setNotifications((prev) => prev.map((n) => ({ ...n, read: true }))); setNotifications((prev) =>
} catch { /* ignore */ } prev.map((n) => ({ ...n, read: true })),
);
} catch {
/* ignore */
}
} }
}; };
@@ -106,11 +113,16 @@ export default function CabineNavigator() {
<View <View
style={[ style={[
styles.badge, styles.badge,
{ backgroundColor: colors.danger }, {
backgroundColor:
colors.danger,
},
]} ]}
> >
<Text style={styles.badgeText}> <Text style={styles.badgeText}>
{unreadCount > 9 ? "9+" : unreadCount} {unreadCount > 9
? "9+"
: unreadCount}
</Text> </Text>
</View> </View>
)} )}
@@ -121,7 +133,11 @@ export default function CabineNavigator() {
style={{ marginRight: spacing.m }} style={{ marginRight: spacing.m }}
> >
<Ionicons <Ionicons
name={isDark ? "sunny-outline" : "moon-outline"} name={
isDark
? "sunny-outline"
: "moon-outline"
}
size={22} size={22}
color={colors.textSecondary} color={colors.textSecondary}
/> />
@@ -151,7 +167,11 @@ export default function CabineNavigator() {
options={{ options={{
title: "Dashboard", title: "Dashboard",
tabBarIcon: ({ color, size }) => ( tabBarIcon: ({ color, size }) => (
<Ionicons name="grid-outline" size={size} color={color} /> <Ionicons
name="grid-outline"
size={size}
color={color}
/>
), ),
}} }}
/> />
@@ -161,7 +181,11 @@ export default function CabineNavigator() {
options={{ options={{
title: "Commandes", title: "Commandes",
tabBarIcon: ({ color, size }) => ( tabBarIcon: ({ color, size }) => (
<Ionicons name="receipt-outline" size={size} color={color} /> <Ionicons
name="receipt-outline"
size={size}
color={color}
/>
), ),
}} }}
/> />
@@ -171,7 +195,11 @@ export default function CabineNavigator() {
options={{ options={{
title: "Livreurs", title: "Livreurs",
tabBarIcon: ({ color, size }) => ( tabBarIcon: ({ color, size }) => (
<Ionicons name="bicycle-outline" size={size} color={color} /> <Ionicons
name="bicycle-outline"
size={size}
color={color}
/>
), ),
}} }}
/> />
@@ -181,7 +209,11 @@ export default function CabineNavigator() {
options={{ options={{
title: "Clients", title: "Clients",
tabBarIcon: ({ color, size }) => ( tabBarIcon: ({ color, size }) => (
<Ionicons name="people-outline" size={size} color={color} /> <Ionicons
name="people-outline"
size={size}
color={color}
/>
), ),
}} }}
/> />
@@ -191,7 +223,25 @@ export default function CabineNavigator() {
options={{ options={{
title: "Alertes", title: "Alertes",
tabBarIcon: ({ color, size }) => ( tabBarIcon: ({ color, size }) => (
<Ionicons name="alert-circle-outline" size={size} color={color} /> <Ionicons
name="alert-circle-outline"
size={size}
color={color}
/>
),
}}
/>
<Tab.Screen
name="Adresses"
component={AddressScreen}
options={{
title: "Adresses",
tabBarIcon: ({ color, size }) => (
<Ionicons
name="map-outline"
size={size}
color={color}
/>
), ),
}} }}
/> />
@@ -211,16 +261,32 @@ export default function CabineNavigator() {
]} ]}
> >
<View style={styles.modalHeader}> <View style={styles.modalHeader}>
<Text style={[styles.modalTitle, { color: colors.textWhite }]}> <Text
style={[
styles.modalTitle,
{ color: colors.textWhite },
]}
>
Notifications Notifications
</Text> </Text>
<TouchableOpacity onPress={() => setModalVisible(false)}> <TouchableOpacity
<Ionicons name="close" size={24} color={colors.textSecondary} /> onPress={() => setModalVisible(false)}
>
<Ionicons
name="close"
size={24}
color={colors.textSecondary}
/>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<ScrollView style={styles.notifList}> <ScrollView style={styles.notifList}>
{notifications.length === 0 ? ( {notifications.length === 0 ? (
<Text style={[styles.emptyText, { color: colors.textMuted }]}> <Text
style={[
styles.emptyText,
{ color: colors.textMuted },
]}
>
Aucune notification Aucune notification
</Text> </Text>
) : ( ) : (
@@ -235,7 +301,8 @@ export default function CabineNavigator() {
: colors.info, : colors.info,
backgroundColor: n.read backgroundColor: n.read
? "transparent" ? "transparent"
: colors.bgPrimary ?? colors.bgSecondary, : (colors.bgPrimary ??
colors.bgSecondary),
}, },
]} ]}
> >
@@ -248,7 +315,10 @@ export default function CabineNavigator() {
{n.message} {n.message}
</Text> </Text>
<Text <Text
style={[styles.notifTime, { color: colors.textMuted }]} style={[
styles.notifTime,
{ color: colors.textMuted },
]}
> >
{formatTime(n.created_at)} {formatTime(n.created_at)}
</Text> </Text>
+24 -23
View File
@@ -1,37 +1,38 @@
export type AuthStackParamList = { export type AuthStackParamList = {
RoleSelect: undefined; RoleSelect: undefined;
AdminLogin: undefined; AdminLogin: undefined;
CabineLogin: undefined; CabineLogin: undefined;
DeliveryLogin: undefined; DeliveryLogin: undefined;
}; };
export type AdminTabParamList = { export type AdminTabParamList = {
Dashboard: undefined; Dashboard: undefined;
Orders: undefined; Orders: undefined;
Users: undefined; Users: undefined;
Products: undefined; Products: undefined;
Categories: undefined; Categories: undefined;
Delivery: undefined; Delivery: undefined;
Alerts: undefined; Alerts: undefined;
Addresses: undefined; Addresses: undefined;
}; };
export type AdminStackParamList = { export type AdminStackParamList = {
AdminTabs: undefined; AdminTabs: undefined;
OrderDetail: { orderId: number }; OrderDetail: { orderId: number };
Settings: undefined; Settings: undefined;
}; };
export type CabineTabParamList = { export type CabineTabParamList = {
Dashboard: undefined; Dashboard: undefined;
Orders: undefined; Orders: undefined;
Delivery: undefined; Delivery: undefined;
Users: undefined; Users: undefined;
Alerts: undefined; Alerts: undefined;
Adresses: undefined;
}; };
export type DeliveryTabParamList = { export type DeliveryTabParamList = {
Dashboard: undefined; Dashboard: undefined;
Stats: undefined; Stats: undefined;
Alerts: undefined; Alerts: undefined;
}; };
@@ -319,15 +319,10 @@ export default function SettingsScreen() {
const ZIP_COLOR = "#9333ea"; const ZIP_COLOR = "#9333ea";
const TOTAL_COLOR = "#f97316"; const TOTAL_COLOR = "#f97316";
// Le mode séparé nécessite que W ET Z aient au moins une catégorie
const hasBothPools =
(settings.points_categories_weed ?? []).length > 0 &&
(settings.points_categories_zipette ?? []).length > 0;
// Chips disponibles selon le mode // Chips disponibles selon le mode
const availableChips: PoolAssignment[] = settings.points_separated const availableChips: PoolAssignment[] = settings.points_separated
? ["weed", "zipette", "none"] // mode séparé : T désactivé ? ["weed", "zipette", "none"] // mode séparé : T désactivé
: ["total", "none"]; // mode non-séparé : W/Z désactivés : ["total", "none"]; // mode non-séparé : W/Z désactivés
return ( return (
<View style={s.container}> <View style={s.container}>
@@ -411,20 +406,16 @@ export default function SettingsScreen() {
thumbColor="#fff" thumbColor="#fff"
/> />
</View> </View>
<View style={[s.row, { opacity: hasBothPools ? 1 : 0.4 }]}> <View style={s.row}>
<View style={s.rowLeft}> <View style={s.rowLeft}>
<Text style={s.rowLabel}>Points séparés par pool</Text> <Text style={s.rowLabel}>Points séparés par pool</Text>
<Text style={s.rowDesc}> <Text style={s.rowDesc}>
Activé : Weed point / Zipette point_zipette{"\n"} Activé : barèmes Weed + Zipette utilisés séparément{"\n"}
Désactivé : Barème Total sur la somme W+Z{"\n"} Désactivé : barème Total utilisé (catégorie T)
{!hasBothPools && (
"⚠️ Nécessite des catégories W ET Z configurées"
)}
</Text> </Text>
</View> </View>
<Switch <Switch
value={settings.points_separated} value={settings.points_separated}
disabled={!hasBothPools}
onValueChange={(v) => onValueChange={(v) =>
setSettings((prev) => ({ ...prev, points_separated: v })) setSettings((prev) => ({ ...prev, points_separated: v }))
} }
@@ -542,36 +533,31 @@ export default function SettingsScreen() {
)} )}
</View> </View>
{/* Barème de points — conditionnel selon le mode */} {/* Barèmes de points — toujours présents */}
{settings.points_separated ? ( <TiersSection
<> title="Barème Weed / Hash"
<TiersSection tiers={settings.points_weed_tiers ?? []}
title="Barème Weed / Hash" onChange={(tiers) => setSettings((p) => ({ ...p, points_weed_tiers: tiers }))}
tiers={settings.points_weed_tiers ?? []} colors={colors}
onChange={(tiers) => setSettings((p) => ({ ...p, points_weed_tiers: tiers }))} s={s}
colors={colors} accentColor={WEED_COLOR}
s={s} />
accentColor={WEED_COLOR} <TiersSection
/> title="Barème Zipette"
<TiersSection tiers={settings.points_zipette_tiers ?? []}
title="Barème Zipette" onChange={(tiers) => setSettings((p) => ({ ...p, points_zipette_tiers: tiers }))}
tiers={settings.points_zipette_tiers ?? []} colors={colors}
onChange={(tiers) => setSettings((p) => ({ ...p, points_zipette_tiers: tiers }))} s={s}
colors={colors} accentColor={ZIP_COLOR}
s={s} />
accentColor={ZIP_COLOR} <TiersSection
/> title="Barème Total"
</> tiers={settings.points_total_tiers ?? []}
) : ( onChange={(tiers) => setSettings((p) => ({ ...p, points_total_tiers: tiers }))}
<TiersSection colors={colors}
title="Barème Total (W + Z)" s={s}
tiers={settings.points_total_tiers ?? []} accentColor={TOTAL_COLOR}
onChange={(tiers) => setSettings((p) => ({ ...p, points_total_tiers: tiers }))} />
colors={colors}
s={s}
accentColor={TOTAL_COLOR}
/>
)}
<TouchableOpacity <TouchableOpacity
style={s.saveButton} style={s.saveButton}