chore: add new features cabine & admin
This commit is contained in:
@@ -119,7 +119,7 @@ export const getCommandByID = async (commandId: number) => {
|
||||
|
||||
export const getCommandItems = async (commandId: number) => {
|
||||
const { data } = await apiClient.get(
|
||||
`${CABINE_URL}/commands/${commandId}/items`,
|
||||
`${V2}/admin/protected/orders/${commandId}/items`,
|
||||
);
|
||||
return {
|
||||
success: true,
|
||||
@@ -130,6 +130,13 @@ export const getCommandItems = async (commandId: number) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteCommandItem = async (commandId: number, itemId: number) => {
|
||||
const { data } = await apiClient.delete(
|
||||
`${V2}/admin/protected/orders/${commandId}/items/${itemId}`,
|
||||
);
|
||||
return { success: true, message: data.message };
|
||||
};
|
||||
|
||||
export const updateCommandStatus = async (
|
||||
commandId: number,
|
||||
newStatus: string,
|
||||
@@ -159,6 +166,13 @@ export const validateCommand = async (commandId: number) => {
|
||||
return { success: true, message: data.message };
|
||||
};
|
||||
|
||||
export const notifyClientToDescend = async (commandId: number) => {
|
||||
const { data } = await apiClient.post(
|
||||
`${V2}/admin/protected/orders/${commandId}/notify-client`,
|
||||
);
|
||||
return { success: true, message: data.message, client_username: data.client_username };
|
||||
};
|
||||
|
||||
export const confirmReceptionAdmin = async (commandId: number) => {
|
||||
const { data } = await apiClient.post(
|
||||
`${V2}/admin/protected/orders/${commandId}/confirm-reception`,
|
||||
|
||||
@@ -117,6 +117,13 @@ export const deleteCommand = async (commandId: number) => {
|
||||
return { success: true, message: data.message };
|
||||
};
|
||||
|
||||
export const notifyClientToDescendCabine = async (commandId: number) => {
|
||||
const { data } = await apiClient.post(
|
||||
`${API}/commands/${commandId}/notify-client`,
|
||||
);
|
||||
return { success: true, message: data.message, client_username: data.client_username };
|
||||
};
|
||||
|
||||
export const getCabineLivreursList = async (): Promise<
|
||||
{ id: number; username: string }[]
|
||||
> => {
|
||||
|
||||
@@ -18,6 +18,7 @@ interface ButtonProps {
|
||||
| "secondary"
|
||||
| "danger"
|
||||
| "success"
|
||||
| "warning"
|
||||
| "outline"
|
||||
| "ghost";
|
||||
size?: "sm" | "md" | "lg";
|
||||
@@ -46,6 +47,7 @@ export default function Button({
|
||||
secondary: colors.bgCard,
|
||||
danger: colors.danger,
|
||||
success: colors.success,
|
||||
warning: colors.warning,
|
||||
outline: "transparent",
|
||||
ghost: "transparent",
|
||||
}[variant];
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
TouchableOpacity,
|
||||
Modal,
|
||||
StatusBar,
|
||||
Alert,
|
||||
} from "react-native";
|
||||
import { useRoute, type RouteProp } from "@react-navigation/native";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
@@ -19,7 +20,9 @@ import {
|
||||
updateCommandStatus,
|
||||
validateCommand,
|
||||
confirmReceptionAdmin,
|
||||
notifyClientToDescend,
|
||||
getDeliveryPersonDetails,
|
||||
deleteCommandItem,
|
||||
} from "../../api/api_admin";
|
||||
import { geocodeAddress, calculateRoute } from "../../api/tomtom";
|
||||
import type { RouteInfo, LatLng } from "../../api/tomtom";
|
||||
@@ -167,6 +170,40 @@ export default function OrderDetailScreen() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleNotifyClient = async () => {
|
||||
try {
|
||||
await notifyClientToDescend(orderId);
|
||||
showSuccess("Notification envoyée", "Le client a été prévenu de descendre");
|
||||
} catch (e: any) {
|
||||
showError("Erreur", e.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteItem = (itemId: number, itemName: string) => {
|
||||
Alert.alert(
|
||||
"Supprimer l'article",
|
||||
`Supprimer "${itemName}" de la commande ?`,
|
||||
[
|
||||
{ text: "Annuler", style: "cancel" },
|
||||
{
|
||||
text: "Supprimer",
|
||||
style: "destructive",
|
||||
onPress: async () => {
|
||||
try {
|
||||
await deleteCommandItem(orderId, itemId);
|
||||
const itemsRes = await getCommandItems(orderId);
|
||||
setItems(itemsRes.items);
|
||||
const cmdRes = await getCommandByID(orderId);
|
||||
setCommand(cmdRes.command);
|
||||
} catch (e: any) {
|
||||
showError("Erreur", e.message);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
);
|
||||
};
|
||||
|
||||
const handleConfirmReception = async () => {
|
||||
try {
|
||||
const res = await confirmReceptionAdmin(orderId);
|
||||
@@ -222,6 +259,11 @@ export default function OrderDetailScreen() {
|
||||
itemDetails: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
},
|
||||
itemDeleteBtn: {
|
||||
padding: spacing.xs,
|
||||
marginLeft: spacing.s,
|
||||
},
|
||||
actions: { marginTop: spacing.m, marginBottom: spacing.xxl },
|
||||
empty: {
|
||||
@@ -605,7 +647,26 @@ export default function OrderDetailScreen() {
|
||||
<Text style={styles.sectionTitle}>Articles ({items.length})</Text>
|
||||
{items.map((item: any) => (
|
||||
<Card key={item.id} style={{ marginBottom: spacing.s }}>
|
||||
<Text style={styles.itemName}>{item.product_name}</Text>
|
||||
<View style={styles.row}>
|
||||
<Text style={[styles.itemName, { flex: 1 }]}>
|
||||
{item.produit ?? item.product_name}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={styles.itemDeleteBtn}
|
||||
onPress={() =>
|
||||
handleDeleteItem(
|
||||
item.id,
|
||||
item.produit ?? item.product_name,
|
||||
)
|
||||
}
|
||||
>
|
||||
<Ionicons
|
||||
name="trash-outline"
|
||||
size={18}
|
||||
color={colors.danger}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.itemDetails}>
|
||||
<Text style={styles.info}>
|
||||
Quantité: {item.quantite}
|
||||
@@ -647,6 +708,15 @@ export default function OrderDetailScreen() {
|
||||
style={{ marginTop: spacing.s }}
|
||||
/>
|
||||
)}
|
||||
{!["approved", "cancelled"].includes(command.status) && (
|
||||
<Button
|
||||
title="Le client est là"
|
||||
onPress={handleNotifyClient}
|
||||
variant="warning"
|
||||
fullWidth
|
||||
style={{ marginTop: spacing.s }}
|
||||
/>
|
||||
)}
|
||||
{command.status === "livre" && (
|
||||
<Button
|
||||
title="Confirmer la réception"
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
getCommandItems,
|
||||
deleteCommand,
|
||||
confirmReceptionCabine,
|
||||
notifyClientToDescendCabine,
|
||||
getCabineLivreursList,
|
||||
assignDeliveryPersonByCabine,
|
||||
} from "../../api/api_cabine";
|
||||
@@ -51,7 +52,7 @@ export default function OrdersScreen() {
|
||||
const [commands, setCommands] = useState<CommandResponse[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const { alert, showError, showConfirm, hideAlert } = useAlert();
|
||||
const { alert, showError, showSuccess, showConfirm, hideAlert } = useAlert();
|
||||
const [itemsModal, setItemsModal] = useState<{
|
||||
visible: boolean;
|
||||
commandId: number | null;
|
||||
@@ -135,6 +136,15 @@ export default function OrdersScreen() {
|
||||
);
|
||||
};
|
||||
|
||||
const handleNotifyClient = async (commandId: number) => {
|
||||
try {
|
||||
await notifyClientToDescendCabine(commandId);
|
||||
showSuccess("Notification envoyée", "Le client a été prévenu de descendre");
|
||||
} catch (e: any) {
|
||||
showError("Erreur", e.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = (commandId: number) => {
|
||||
showConfirm(
|
||||
"Supprimer",
|
||||
@@ -356,6 +366,12 @@ export default function OrdersScreen() {
|
||||
size="sm"
|
||||
variant="primary"
|
||||
/>
|
||||
<Button
|
||||
title="Le client est là"
|
||||
onPress={() => handleNotifyClient(item.id)}
|
||||
size="sm"
|
||||
variant="warning"
|
||||
/>
|
||||
<Button
|
||||
title="Assigner"
|
||||
onPress={() => openAssignModal(item.id)}
|
||||
|
||||
Reference in New Issue
Block a user