chore: fix comming soon

This commit is contained in:
2026-03-07 18:42:18 +01:00
parent ab7d8929a8
commit 91ad46c0f8
4 changed files with 315 additions and 131 deletions
@@ -9,7 +9,11 @@ import {
StatusBar, StatusBar,
Alert, Alert,
} from "react-native"; } from "react-native";
import { useRoute, useNavigation, type RouteProp } from "@react-navigation/native"; import {
useRoute,
useNavigation,
type RouteProp,
} from "@react-navigation/native";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import MapView, { Marker, Polyline, PROVIDER_DEFAULT } from "react-native-maps"; import MapView, { Marker, Polyline, PROVIDER_DEFAULT } from "react-native-maps";
import { spacing, fontSize, borderRadius } from "../../theme"; import { spacing, fontSize, borderRadius } from "../../theme";
@@ -87,7 +91,9 @@ export default function OrderDetailScreen() {
try { try {
const res = await getCommandByID(orderId); const res = await getCommandByID(orderId);
setCommand(res.command); setCommand(res.command);
} catch { /* ignore */ } } catch {
/* ignore */
}
}, 20000); }, 20000);
return () => clearInterval(interval); return () => clearInterval(interval);
}, [orderId]); }, [orderId]);
@@ -176,7 +182,10 @@ export default function OrderDetailScreen() {
const handleNotifyClient = async () => { const handleNotifyClient = async () => {
try { try {
await notifyClientToDescend(orderId); await notifyClientToDescend(orderId);
showSuccess("Notification envoyée", "Le client a été prévenu de descendre"); showSuccess(
"Notification envoyée",
"Le client a été prévenu de descendre",
);
} catch (e: any) { } catch (e: any) {
showError("Erreur", e.message); showError("Erreur", e.message);
} }
@@ -773,7 +782,7 @@ export default function OrderDetailScreen() {
)} )}
{!["approved", "cancelled"].includes(command.status) && ( {!["approved", "cancelled"].includes(command.status) && (
<Button <Button
title="Le client est là" title="Le livreur est là"
onPress={handleNotifyClient} onPress={handleNotifyClient}
variant="warning" variant="warning"
fullWidth fullWidth
@@ -823,9 +832,17 @@ export default function OrderDetailScreen() {
</View> </View>
<ScrollView showsVerticalScrollIndicator={false}> <ScrollView showsVerticalScrollIndicator={false}>
{items.map((item: any) => ( {items.map((item: any) => (
<View key={item.id} style={styles.itemsModalCard}> <View
key={item.id}
style={styles.itemsModalCard}
>
<View style={styles.row}> <View style={styles.row}>
<Text style={[styles.itemName, { flex: 1 }]}> <Text
style={[
styles.itemName,
{ flex: 1 },
]}
>
{item.produit ?? item.product_name} {item.produit ?? item.product_name}
</Text> </Text>
<TouchableOpacity <TouchableOpacity
@@ -834,7 +851,8 @@ export default function OrderDetailScreen() {
setShowItemsModal(false); setShowItemsModal(false);
handleDeleteItem( handleDeleteItem(
item.id, item.id,
item.produit ?? item.product_name, item.produit ??
item.product_name,
); );
}} }}
> >
+101 -27
View File
@@ -55,7 +55,8 @@ export default function OrdersScreen() {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false); const [refreshing, setRefreshing] = useState(false);
const [filter, setFilter] = useState("all"); const [filter, setFilter] = useState("all");
const { alert, showError, showSuccess, showConfirm, hideAlert } = useAlert(); const { alert, showError, showSuccess, showConfirm, hideAlert } =
useAlert();
const [openMenuId, setOpenMenuId] = useState<number | null>(null); const [openMenuId, setOpenMenuId] = useState<number | null>(null);
const [assignModal, setAssignModal] = useState<{ const [assignModal, setAssignModal] = useState<{
@@ -162,7 +163,10 @@ export default function OrdersScreen() {
const handleNotifyClient = async (commandId: number) => { const handleNotifyClient = async (commandId: number) => {
try { try {
await notifyClientToDescend(commandId); await notifyClientToDescend(commandId);
showSuccess("Notification envoyée", "Le client a été prévenu de descendre"); showSuccess(
"Notification envoyée",
"Le client a été prévenu de descendre",
);
} catch (e: any) { } catch (e: any) {
showError("Erreur", e.message); showError("Erreur", e.message);
} }
@@ -191,15 +195,25 @@ export default function OrdersScreen() {
const handleProposeAddress = async () => { const handleProposeAddress = async () => {
if (!addressModal.commandId || !addressModal.input.trim()) return; if (!addressModal.commandId || !addressModal.input.trim()) return;
try { try {
await proposeAddressChangeAdmin(addressModal.commandId, addressModal.input.trim()); await proposeAddressChangeAdmin(
addressModal.commandId,
addressModal.input.trim(),
);
setAddressModal({ visible: false, commandId: null, input: "" }); setAddressModal({ visible: false, commandId: null, input: "" });
showSuccess("Proposition envoyée", "Le client a été notifié de la nouvelle adresse proposée"); showSuccess(
"Proposition envoyée",
"Le client a été notifié de la nouvelle adresse proposée",
);
} catch (e: any) { } catch (e: any) {
showError("Erreur", e.message); showError("Erreur", e.message);
} }
}; };
const handleDeleteItem = (commandId: number, itemId: number, itemName: string) => { const handleDeleteItem = (
commandId: number,
itemId: number,
itemName: string,
) => {
showConfirm( showConfirm(
"Supprimer l'article", "Supprimer l'article",
`Supprimer "${itemName}" de la commande #${commandId} ?`, `Supprimer "${itemName}" de la commande #${commandId} ?`,
@@ -429,54 +443,83 @@ export default function OrdersScreen() {
condition?: boolean; condition?: boolean;
}; };
const actions: Action[] = ([ const actions: Action[] = (
[
{ {
label: "Voir items", label: "Voir items",
icon: "receipt-outline" as keyof typeof Ionicons.glyphMap, icon: "receipt-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); openItems(item.id); }, onPress: () => {
setOpenMenuId(null);
openItems(item.id);
},
}, },
{ {
label: "Proposer adresse", label: "Proposer adresse",
icon: "location-outline" as keyof typeof Ionicons.glyphMap, icon: "location-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); setAddressModal({ visible: true, commandId: item.id, input: "" }); }, onPress: () => {
setOpenMenuId(null);
setAddressModal({
visible: true,
commandId: item.id,
input: "",
});
},
condition: !isDone, condition: !isDone,
}, },
{ {
label: "Le client est là", label: "Le livreur est là",
icon: "notifications-outline" as keyof typeof Ionicons.glyphMap, icon: "notifications-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleNotifyClient(item.id); }, onPress: () => {
setOpenMenuId(null);
handleNotifyClient(item.id);
},
condition: !isDone, condition: !isDone,
}, },
{ {
label: "Assigner livreur", label: "Assigner livreur",
icon: "bicycle-outline" as keyof typeof Ionicons.glyphMap, icon: "bicycle-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); openAssignModal(item.id); }, onPress: () => {
setOpenMenuId(null);
openAssignModal(item.id);
},
condition: !isDone, condition: !isDone,
}, },
{ {
label: "Passer en route", label: "Passer en route",
icon: "car-outline" as keyof typeof Ionicons.glyphMap, icon: "car-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleStatusUpdate(item.id, "en_route"); }, onPress: () => {
setOpenMenuId(null);
handleStatusUpdate(item.id, "en_route");
},
condition: item.status === "assigned", condition: item.status === "assigned",
}, },
{ {
label: "Confirmer réception", label: "Confirmer réception",
icon: "checkmark-circle-outline" as keyof typeof Ionicons.glyphMap, icon: "checkmark-circle-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleConfirmReception(item.id); }, onPress: () => {
setOpenMenuId(null);
handleConfirmReception(item.id);
},
condition: item.status === "livre", condition: item.status === "livre",
}, },
{ {
label: "Supprimer", label: "Supprimer",
icon: "trash-outline" as keyof typeof Ionicons.glyphMap, icon: "trash-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleDelete(item.id); }, onPress: () => {
setOpenMenuId(null);
handleDelete(item.id);
},
danger: true, danger: true,
}, },
] as Action[]).filter((a) => a.condition !== false); ] as Action[]
).filter((a) => a.condition !== false);
return ( return (
<Card style={{ marginBottom: spacing.m }}> <Card style={{ marginBottom: spacing.m }}>
<TouchableOpacity <TouchableOpacity
onPress={() => navigation.navigate("OrderDetail", { orderId: item.id })} onPress={() =>
navigation.navigate("OrderDetail", { orderId: item.id })
}
activeOpacity={0.7} activeOpacity={0.7}
> >
<View style={styles.row}> <View style={styles.row}>
@@ -489,7 +532,9 @@ export default function OrdersScreen() {
Total: {item.total_prix.toFixed(2)} Total: {item.total_prix.toFixed(2)}
</Text> </Text>
{item.livreur_assign && ( {item.livreur_assign && (
<Text style={styles.cardText}>Livreur: {item.livreur_assign}</Text> <Text style={styles.cardText}>
Livreur: {item.livreur_assign}
</Text>
)} )}
<Text style={styles.cardDate}> <Text style={styles.cardDate}>
{new Date(item.created_at).toLocaleString("fr-FR")} {new Date(item.created_at).toLocaleString("fr-FR")}
@@ -515,16 +560,27 @@ export default function OrdersScreen() {
key={action.label} key={action.label}
style={[ style={[
styles.dropdownItem, styles.dropdownItem,
index === actions.length - 1 && styles.dropdownItemLast, index === actions.length - 1 &&
styles.dropdownItemLast,
]} ]}
onPress={action.onPress} onPress={action.onPress}
> >
<Ionicons <Ionicons
name={action.icon} name={action.icon}
size={16} size={16}
color={action.danger ? colors.danger : colors.accent} color={
action.danger
? colors.danger
: colors.accent
}
/> />
<Text style={action.danger ? styles.dropdownTextDanger : styles.dropdownText}> <Text
style={
action.danger
? styles.dropdownTextDanger
: styles.dropdownText
}
>
{action.label} {action.label}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
@@ -588,7 +644,10 @@ export default function OrdersScreen() {
title={`Commande #${itemsModal.commandId}`} title={`Commande #${itemsModal.commandId}`}
icon="receipt-outline" icon="receipt-outline"
> >
<ScrollView showsVerticalScrollIndicator={false} bounces={false}> <ScrollView
showsVerticalScrollIndicator={false}
bounces={false}
>
{(itemsModal.commandInfo || itemsModal.clientInfo) && ( {(itemsModal.commandInfo || itemsModal.clientInfo) && (
<View style={styles.modalSummary}> <View style={styles.modalSummary}>
{itemsModal.clientInfo?.username && ( {itemsModal.clientInfo?.username && (
@@ -638,8 +697,12 @@ export default function OrdersScreen() {
{item.produit ?? item.product_name} {item.produit ?? item.product_name}
</Text> </Text>
<Text style={styles.itemMeta}> <Text style={styles.itemMeta}>
Qté: {item.quantite ?? item.quantity} ·{" "} Qté:{" "}
{(item.prix ?? item.price)?.toFixed(2)} {item.quantite ?? item.quantity} ·{" "}
{(item.prix ?? item.price)?.toFixed(
2,
)}{" "}
</Text> </Text>
</View> </View>
<TouchableOpacity <TouchableOpacity
@@ -648,7 +711,8 @@ export default function OrdersScreen() {
handleDeleteItem( handleDeleteItem(
itemsModal.commandId!, itemsModal.commandId!,
item.id, item.id,
item.produit ?? item.product_name, item.produit ??
item.product_name,
) )
} }
> >
@@ -699,7 +763,13 @@ export default function OrdersScreen() {
{/* Modal proposition adresse */} {/* Modal proposition adresse */}
<Modal <Modal
visible={addressModal.visible} visible={addressModal.visible}
onClose={() => setAddressModal({ visible: false, commandId: null, input: "" })} onClose={() =>
setAddressModal({
visible: false,
commandId: null,
input: "",
})
}
title={`Proposer adresse — commande #${addressModal.commandId}`} title={`Proposer adresse — commande #${addressModal.commandId}`}
icon="location-outline" icon="location-outline"
> >
@@ -708,14 +778,18 @@ export default function OrdersScreen() {
placeholder="Nouvelle adresse..." placeholder="Nouvelle adresse..."
placeholderTextColor={colors.textMuted} placeholderTextColor={colors.textMuted}
value={addressModal.input} value={addressModal.input}
onChangeText={(t) => setAddressModal((prev) => ({ ...prev, input: t }))} onChangeText={(t) =>
setAddressModal((prev) => ({ ...prev, input: t }))
}
multiline multiline
/> />
<TouchableOpacity <TouchableOpacity
style={styles.addressConfirmBtn} style={styles.addressConfirmBtn}
onPress={handleProposeAddress} onPress={handleProposeAddress}
> >
<Text style={styles.addressConfirmText}>Envoyer la proposition</Text> <Text style={styles.addressConfirmText}>
Envoyer la proposition
</Text>
</TouchableOpacity> </TouchableOpacity>
</Modal> </Modal>
@@ -54,7 +54,8 @@ export default function OrdersScreen() {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false); const [refreshing, setRefreshing] = useState(false);
const [openMenuId, setOpenMenuId] = useState<number | null>(null); const [openMenuId, setOpenMenuId] = useState<number | null>(null);
const { alert, showError, showSuccess, showConfirm, hideAlert } = useAlert(); const { alert, showError, showSuccess, showConfirm, hideAlert } =
useAlert();
const [itemsModal, setItemsModal] = useState<{ const [itemsModal, setItemsModal] = useState<{
visible: boolean; visible: boolean;
commandId: number | null; commandId: number | null;
@@ -77,7 +78,9 @@ export default function OrdersScreen() {
commandId: number | null; commandId: number | null;
input: string; input: string;
}>({ visible: false, commandId: null, input: "" }); }>({ visible: false, commandId: null, input: "" });
const [livreurs, setLivreurs] = useState<{ id: number; username: string }[]>([]); const [livreurs, setLivreurs] = useState<
{ id: number; username: string }[]
>([]);
const loadData = useCallback(async () => { const loadData = useCallback(async () => {
try { try {
@@ -148,7 +151,10 @@ export default function OrdersScreen() {
setOpenMenuId(null); setOpenMenuId(null);
try { try {
await notifyClientToDescendCabine(commandId); await notifyClientToDescendCabine(commandId);
showSuccess("Notification envoyée", "Le client a été prévenu de descendre"); showSuccess(
"Notification envoyée",
"Le client a été prévenu de descendre",
);
} catch (e: any) { } catch (e: any) {
showError("Erreur", e.message); showError("Erreur", e.message);
} }
@@ -157,9 +163,15 @@ export default function OrdersScreen() {
const handleProposeAddress = async () => { const handleProposeAddress = async () => {
if (!addressModal.commandId || !addressModal.input.trim()) return; if (!addressModal.commandId || !addressModal.input.trim()) return;
try { try {
await proposeAddressChangeCabine(addressModal.commandId, addressModal.input.trim()); await proposeAddressChangeCabine(
addressModal.commandId,
addressModal.input.trim(),
);
setAddressModal({ visible: false, commandId: null, input: "" }); setAddressModal({ visible: false, commandId: null, input: "" });
showSuccess("Proposition envoyée", "Le client a été notifié de la nouvelle adresse proposée"); showSuccess(
"Proposition envoyée",
"Le client a été notifié de la nouvelle adresse proposée",
);
} catch (e: any) { } catch (e: any) {
showError("Erreur", e.message); showError("Erreur", e.message);
} }
@@ -205,7 +217,10 @@ export default function OrdersScreen() {
const handleAssign = async (livreurUsername: string) => { const handleAssign = async (livreurUsername: string) => {
if (!assignModal.commandId) return; if (!assignModal.commandId) return;
try { try {
await assignDeliveryPersonByCabine(assignModal.commandId, livreurUsername); await assignDeliveryPersonByCabine(
assignModal.commandId,
livreurUsername,
);
setAssignModal({ visible: false, commandId: null }); setAssignModal({ visible: false, commandId: null });
await loadData(); await loadData();
} catch (e: any) { } catch (e: any) {
@@ -412,7 +427,8 @@ export default function OrdersScreen() {
condition?: boolean; condition?: boolean;
}; };
const actions: Action[] = ([ const actions: Action[] = (
[
{ {
label: "Voir items", label: "Voir items",
icon: "receipt-outline" as keyof typeof Ionicons.glyphMap, icon: "receipt-outline" as keyof typeof Ionicons.glyphMap,
@@ -421,10 +437,17 @@ export default function OrdersScreen() {
{ {
label: "Proposer adresse", label: "Proposer adresse",
icon: "location-outline" as keyof typeof Ionicons.glyphMap, icon: "location-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); setAddressModal({ visible: true, commandId: item.id, input: "" }); }, onPress: () => {
setOpenMenuId(null);
setAddressModal({
visible: true,
commandId: item.id,
input: "",
});
},
}, },
{ {
label: "Le client est là", label: "Le livreur est là",
icon: "notifications-outline" as keyof typeof Ionicons.glyphMap, icon: "notifications-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => handleNotifyClient(item.id), onPress: () => handleNotifyClient(item.id),
}, },
@@ -445,7 +468,8 @@ export default function OrdersScreen() {
onPress: () => handleDelete(item.id), onPress: () => handleDelete(item.id),
danger: true, danger: true,
}, },
] as Action[]).filter((a) => a.condition !== false); ] as Action[]
).filter((a) => a.condition !== false);
return ( return (
<Card style={{ marginBottom: spacing.m }}> <Card style={{ marginBottom: spacing.m }}>
@@ -478,14 +502,19 @@ export default function OrdersScreen() {
key={action.label} key={action.label}
style={[ style={[
styles.dropdownItem, styles.dropdownItem,
index === actions.length - 1 && styles.dropdownItemLast, index === actions.length - 1 &&
styles.dropdownItemLast,
]} ]}
onPress={action.onPress} onPress={action.onPress}
> >
<Ionicons <Ionicons
name={action.icon} name={action.icon}
size={16} size={16}
color={action.danger ? colors.danger : colors.accent} color={
action.danger
? colors.danger
: colors.accent
}
/> />
<Text <Text
style={ style={
@@ -504,7 +533,9 @@ export default function OrdersScreen() {
); );
}; };
const readyCount = itemsModal.items.filter((i) => i.status === "ready").length; const readyCount = itemsModal.items.filter(
(i) => i.status === "ready",
).length;
const totalCount = itemsModal.items.length; const totalCount = itemsModal.items.length;
const progress = totalCount > 0 ? readyCount / totalCount : 0; const progress = totalCount > 0 ? readyCount / totalCount : 0;
@@ -535,12 +566,19 @@ export default function OrdersScreen() {
title={`Commande #${itemsModal.commandId}`} title={`Commande #${itemsModal.commandId}`}
icon="receipt-outline" icon="receipt-outline"
> >
<ScrollView showsVerticalScrollIndicator={false} bounces={false}> <ScrollView
showsVerticalScrollIndicator={false}
bounces={false}
>
{(itemsModal.commandInfo || itemsModal.clientInfo) && ( {(itemsModal.commandInfo || itemsModal.clientInfo) && (
<View style={styles.modalSummary}> <View style={styles.modalSummary}>
{itemsModal.clientInfo?.username && ( {itemsModal.clientInfo?.username && (
<View style={styles.modalSummaryRow}> <View style={styles.modalSummaryRow}>
<Ionicons name="person-outline" size={14} color={colors.textMuted} /> <Ionicons
name="person-outline"
size={14}
color={colors.textMuted}
/>
<Text style={styles.modalSummaryText}> <Text style={styles.modalSummaryText}>
{itemsModal.clientInfo.prenom}{" "} {itemsModal.clientInfo.prenom}{" "}
{itemsModal.clientInfo.nom} ·{" "} {itemsModal.clientInfo.nom} ·{" "}
@@ -548,17 +586,26 @@ export default function OrdersScreen() {
</Text> </Text>
</View> </View>
)} )}
{(itemsModal.commandInfo?.address || itemsModal.commandInfo?.adresse) && ( {(itemsModal.commandInfo?.address ||
itemsModal.commandInfo?.adresse) && (
<View style={styles.modalSummaryRow}> <View style={styles.modalSummaryRow}>
<Ionicons name="location-outline" size={14} color={colors.textMuted} /> <Ionicons
name="location-outline"
size={14}
color={colors.textMuted}
/>
<Text style={styles.modalSummaryText}> <Text style={styles.modalSummaryText}>
{itemsModal.commandInfo.address || itemsModal.commandInfo.adresse} {itemsModal.commandInfo.address ||
itemsModal.commandInfo.adresse}
</Text> </Text>
</View> </View>
)} )}
{itemsModal.commandInfo?.total_prix != null && ( {itemsModal.commandInfo?.total_prix != null && (
<Text style={styles.modalTotal}> <Text style={styles.modalTotal}>
{Number(itemsModal.commandInfo.total_prix).toFixed(2)} {Number(
itemsModal.commandInfo.total_prix,
).toFixed(2)}{" "}
</Text> </Text>
)} )}
</View> </View>
@@ -576,7 +623,9 @@ export default function OrdersScreen() {
{ {
width: `${progress * 100}%`, width: `${progress * 100}%`,
backgroundColor: backgroundColor:
progress === 1 ? STATUS_COLORS.ready : colors.info, progress === 1
? STATUS_COLORS.ready
: colors.info,
}, },
]} ]}
/> />
@@ -585,30 +634,51 @@ export default function OrdersScreen() {
)} )}
{itemsModal.items.map((item: any, index: number) => { {itemsModal.items.map((item: any, index: number) => {
const statusColor = STATUS_COLORS[item.status] || colors.textMuted; const statusColor =
STATUS_COLORS[item.status] || colors.textMuted;
return ( return (
<View key={item.id} style={styles.itemCard}> <View key={item.id} style={styles.itemCard}>
<View style={[styles.itemCardAccent, { backgroundColor: statusColor }]} /> <View
style={[
styles.itemCardAccent,
{ backgroundColor: statusColor },
]}
/>
<View style={styles.itemCardBody}> <View style={styles.itemCardBody}>
<View style={styles.itemIndex}> <View style={styles.itemIndex}>
<Text style={styles.itemIndexText}>{index + 1}</Text> <Text style={styles.itemIndexText}>
{index + 1}
</Text>
</View> </View>
<View style={styles.itemInfo}> <View style={styles.itemInfo}>
<Text style={styles.itemName}> <Text style={styles.itemName}>
{item.produit ?? item.product_name} {item.produit ?? item.product_name}
</Text> </Text>
<Text style={styles.itemMeta}> <Text style={styles.itemMeta}>
Qté: {item.quantite ?? item.quantity} ·{" "} Qté:{" "}
{(item.prix ?? item.price)?.toFixed(2)} {item.quantite ?? item.quantity} ·{" "}
{(item.prix ?? item.price)?.toFixed(
2,
)}{" "}
</Text> </Text>
<View style={styles.itemStatusRow}> <View style={styles.itemStatusRow}>
<Ionicons <Ionicons
name={STATUS_ICONS[item.status] || "ellipse-outline"} name={
STATUS_ICONS[item.status] ||
"ellipse-outline"
}
size={13} size={13}
color={statusColor} color={statusColor}
/> />
<Text style={[styles.itemStatusText, { color: statusColor }]}> <Text
{STATUS_LABELS[item.status] || item.status} style={[
styles.itemStatusText,
{ color: statusColor },
]}
>
{STATUS_LABELS[item.status] ||
item.status}
</Text> </Text>
</View> </View>
</View> </View>
@@ -625,7 +695,9 @@ export default function OrdersScreen() {
<Modal <Modal
visible={assignModal.visible} visible={assignModal.visible}
onClose={() => setAssignModal({ visible: false, commandId: null })} onClose={() =>
setAssignModal({ visible: false, commandId: null })
}
title={`Assigner commande #${assignModal.commandId}`} title={`Assigner commande #${assignModal.commandId}`}
icon="bicycle-outline" icon="bicycle-outline"
> >
@@ -635,7 +707,11 @@ export default function OrdersScreen() {
style={styles.livreurItem} style={styles.livreurItem}
onPress={() => handleAssign(l.username)} onPress={() => handleAssign(l.username)}
> >
<Ionicons name="person-outline" size={20} color={colors.accent} /> <Ionicons
name="person-outline"
size={20}
color={colors.accent}
/>
<Text style={styles.livreurName}>{l.username}</Text> <Text style={styles.livreurName}>{l.username}</Text>
</TouchableOpacity> </TouchableOpacity>
))} ))}
@@ -647,7 +723,13 @@ export default function OrdersScreen() {
{/* Modal proposition adresse */} {/* Modal proposition adresse */}
<Modal <Modal
visible={addressModal.visible} visible={addressModal.visible}
onClose={() => setAddressModal({ visible: false, commandId: null, input: "" })} onClose={() =>
setAddressModal({
visible: false,
commandId: null,
input: "",
})
}
title={`Proposer adresse — commande #${addressModal.commandId}`} title={`Proposer adresse — commande #${addressModal.commandId}`}
icon="location-outline" icon="location-outline"
> >
@@ -656,14 +738,18 @@ export default function OrdersScreen() {
placeholder="Nouvelle adresse..." placeholder="Nouvelle adresse..."
placeholderTextColor={colors.textMuted} placeholderTextColor={colors.textMuted}
value={addressModal.input} value={addressModal.input}
onChangeText={(t) => setAddressModal((prev) => ({ ...prev, input: t }))} onChangeText={(t) =>
setAddressModal((prev) => ({ ...prev, input: t }))
}
multiline multiline
/> />
<TouchableOpacity <TouchableOpacity
style={styles.addressConfirmBtn} style={styles.addressConfirmBtn}
onPress={handleProposeAddress} onPress={handleProposeAddress}
> >
<Text style={styles.addressConfirmText}>Envoyer la proposition</Text> <Text style={styles.addressConfirmText}>
Envoyer la proposition
</Text>
</TouchableOpacity> </TouchableOpacity>
</Modal> </Modal>
+7 -1
View File
@@ -94,9 +94,15 @@ export default function ProductsScreen() {
}, [selectedCategory]); }, [selectedCategory]);
useEffect(() => { useEffect(() => {
const catObj = categories.find((c) => c.name === selectedCategory);
if (catObj?.is_coming_soon) {
setLoading(false);
setProducts([]);
return;
}
setLoading(true); setLoading(true);
fetchProducts(); fetchProducts();
}, [fetchProducts]); }, [selectedCategory, categories, fetchProducts]);
useEffect(() => { useEffect(() => {
if (carouselRef.current && products.length > 0) { if (carouselRef.current && products.length > 0) {