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
+134 -60
View File
@@ -55,7 +55,8 @@ export default function OrdersScreen() {
const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false);
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 [assignModal, setAssignModal] = useState<{
@@ -162,7 +163,10 @@ export default function OrdersScreen() {
const handleNotifyClient = async (commandId: number) => {
try {
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) {
showError("Erreur", e.message);
}
@@ -191,15 +195,25 @@ export default function OrdersScreen() {
const handleProposeAddress = async () => {
if (!addressModal.commandId || !addressModal.input.trim()) return;
try {
await proposeAddressChangeAdmin(addressModal.commandId, addressModal.input.trim());
await proposeAddressChangeAdmin(
addressModal.commandId,
addressModal.input.trim(),
);
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) {
showError("Erreur", e.message);
}
};
const handleDeleteItem = (commandId: number, itemId: number, itemName: string) => {
const handleDeleteItem = (
commandId: number,
itemId: number,
itemName: string,
) => {
showConfirm(
"Supprimer l'article",
`Supprimer "${itemName}" de la commande #${commandId} ?`,
@@ -429,54 +443,83 @@ export default function OrdersScreen() {
condition?: boolean;
};
const actions: Action[] = ([
{
label: "Voir items",
icon: "receipt-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); openItems(item.id); },
},
{
label: "Proposer adresse",
icon: "location-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); setAddressModal({ visible: true, commandId: item.id, input: "" }); },
condition: !isDone,
},
{
label: "Le client est là",
icon: "notifications-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleNotifyClient(item.id); },
condition: !isDone,
},
{
label: "Assigner livreur",
icon: "bicycle-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); openAssignModal(item.id); },
condition: !isDone,
},
{
label: "Passer en route",
icon: "car-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleStatusUpdate(item.id, "en_route"); },
condition: item.status === "assigned",
},
{
label: "Confirmer réception",
icon: "checkmark-circle-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleConfirmReception(item.id); },
condition: item.status === "livre",
},
{
label: "Supprimer",
icon: "trash-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => { setOpenMenuId(null); handleDelete(item.id); },
danger: true,
},
] as Action[]).filter((a) => a.condition !== false);
const actions: Action[] = (
[
{
label: "Voir items",
icon: "receipt-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => {
setOpenMenuId(null);
openItems(item.id);
},
},
{
label: "Proposer adresse",
icon: "location-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => {
setOpenMenuId(null);
setAddressModal({
visible: true,
commandId: item.id,
input: "",
});
},
condition: !isDone,
},
{
label: "Le livreur est là",
icon: "notifications-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => {
setOpenMenuId(null);
handleNotifyClient(item.id);
},
condition: !isDone,
},
{
label: "Assigner livreur",
icon: "bicycle-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => {
setOpenMenuId(null);
openAssignModal(item.id);
},
condition: !isDone,
},
{
label: "Passer en route",
icon: "car-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => {
setOpenMenuId(null);
handleStatusUpdate(item.id, "en_route");
},
condition: item.status === "assigned",
},
{
label: "Confirmer réception",
icon: "checkmark-circle-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => {
setOpenMenuId(null);
handleConfirmReception(item.id);
},
condition: item.status === "livre",
},
{
label: "Supprimer",
icon: "trash-outline" as keyof typeof Ionicons.glyphMap,
onPress: () => {
setOpenMenuId(null);
handleDelete(item.id);
},
danger: true,
},
] as Action[]
).filter((a) => a.condition !== false);
return (
<Card style={{ marginBottom: spacing.m }}>
<TouchableOpacity
onPress={() => navigation.navigate("OrderDetail", { orderId: item.id })}
onPress={() =>
navigation.navigate("OrderDetail", { orderId: item.id })
}
activeOpacity={0.7}
>
<View style={styles.row}>
@@ -489,7 +532,9 @@ export default function OrdersScreen() {
Total: {item.total_prix.toFixed(2)}
</Text>
{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}>
{new Date(item.created_at).toLocaleString("fr-FR")}
@@ -515,16 +560,27 @@ export default function OrdersScreen() {
key={action.label}
style={[
styles.dropdownItem,
index === actions.length - 1 && styles.dropdownItemLast,
index === actions.length - 1 &&
styles.dropdownItemLast,
]}
onPress={action.onPress}
>
<Ionicons
name={action.icon}
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}
</Text>
</TouchableOpacity>
@@ -588,7 +644,10 @@ export default function OrdersScreen() {
title={`Commande #${itemsModal.commandId}`}
icon="receipt-outline"
>
<ScrollView showsVerticalScrollIndicator={false} bounces={false}>
<ScrollView
showsVerticalScrollIndicator={false}
bounces={false}
>
{(itemsModal.commandInfo || itemsModal.clientInfo) && (
<View style={styles.modalSummary}>
{itemsModal.clientInfo?.username && (
@@ -638,8 +697,12 @@ export default function OrdersScreen() {
{item.produit ?? item.product_name}
</Text>
<Text style={styles.itemMeta}>
Qté: {item.quantite ?? item.quantity} ·{" "}
{(item.prix ?? item.price)?.toFixed(2)}
Qté:{" "}
{item.quantite ?? item.quantity} ·{" "}
{(item.prix ?? item.price)?.toFixed(
2,
)}{" "}
</Text>
</View>
<TouchableOpacity
@@ -648,7 +711,8 @@ export default function OrdersScreen() {
handleDeleteItem(
itemsModal.commandId!,
item.id,
item.produit ?? item.product_name,
item.produit ??
item.product_name,
)
}
>
@@ -699,7 +763,13 @@ export default function OrdersScreen() {
{/* Modal proposition adresse */}
<Modal
visible={addressModal.visible}
onClose={() => setAddressModal({ visible: false, commandId: null, input: "" })}
onClose={() =>
setAddressModal({
visible: false,
commandId: null,
input: "",
})
}
title={`Proposer adresse — commande #${addressModal.commandId}`}
icon="location-outline"
>
@@ -708,14 +778,18 @@ export default function OrdersScreen() {
placeholder="Nouvelle adresse..."
placeholderTextColor={colors.textMuted}
value={addressModal.input}
onChangeText={(t) => setAddressModal((prev) => ({ ...prev, input: t }))}
onChangeText={(t) =>
setAddressModal((prev) => ({ ...prev, input: t }))
}
multiline
/>
<TouchableOpacity
style={styles.addressConfirmBtn}
onPress={handleProposeAddress}
>
<Text style={styles.addressConfirmText}>Envoyer la proposition</Text>
<Text style={styles.addressConfirmText}>
Envoyer la proposition
</Text>
</TouchableOpacity>
</Modal>