chore: build
This commit is contained in:
@@ -235,8 +235,11 @@ export const updateCommandAddress = async (
|
|||||||
export const validateCommand = async (commandId: number) => {
|
export const validateCommand = async (commandId: number) => {
|
||||||
const { data } = await apiClient.post(
|
const { data } = await apiClient.post(
|
||||||
`${V2}/admin/protected/orders/${commandId}/force-validate`,
|
`${V2}/admin/protected/orders/${commandId}/force-validate`,
|
||||||
|
{ command_id: commandId },
|
||||||
);
|
);
|
||||||
return { success: true, message: data.message };
|
const validated = (data.validated ?? []) as { command_id: number; points_awarded: number }[];
|
||||||
|
const points = validated.find((v) => v.command_id === commandId)?.points_awarded ?? 0;
|
||||||
|
return { success: true, points_awarded: points, validated_count: data.validated_count ?? 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const proposeAddressChangeAdmin = async (
|
export const proposeAddressChangeAdmin = async (
|
||||||
@@ -937,6 +940,8 @@ export interface PointsReward {
|
|||||||
type: "free_product" | "half_price_product" | "custom";
|
type: "free_product" | "half_price_product" | "custom";
|
||||||
description: string;
|
description: string;
|
||||||
category_configs: RewardCategoryConfig[];
|
category_configs: RewardCategoryConfig[];
|
||||||
|
reward_product_id?: number;
|
||||||
|
reward_quantity?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PointsPool {
|
export interface PointsPool {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export default function OrderDetailScreen() {
|
|||||||
getCommandItems(orderId),
|
getCommandItems(orderId),
|
||||||
]);
|
]);
|
||||||
setCommand(cmdRes.command);
|
setCommand(cmdRes.command);
|
||||||
setItems(itemsRes.items);
|
setItems(itemsRes.items ?? []);
|
||||||
|
|
||||||
// If livreur assigned, fetch their location and calc route
|
// If livreur assigned, fetch their location and calc route
|
||||||
const cmd = cmdRes.command;
|
const cmd = cmdRes.command;
|
||||||
@@ -205,7 +205,7 @@ export default function OrderDetailScreen() {
|
|||||||
try {
|
try {
|
||||||
await deleteCommandItem(orderId, itemId);
|
await deleteCommandItem(orderId, itemId);
|
||||||
const itemsRes = await getCommandItems(orderId);
|
const itemsRes = await getCommandItems(orderId);
|
||||||
setItems(itemsRes.items);
|
setItems(itemsRes.items ?? []);
|
||||||
const cmdRes = await getCommandByID(orderId);
|
const cmdRes = await getCommandByID(orderId);
|
||||||
setCommand(cmdRes.command);
|
setCommand(cmdRes.command);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@@ -552,7 +552,7 @@ export default function OrderDetailScreen() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Groupement des items par product_id
|
// Groupement des items par product_id
|
||||||
const productGroups = items.reduce<Record<string, any[]>>((acc, item) => {
|
const productGroups = (items ?? []).reduce<Record<string, any[]>>((acc, item) => {
|
||||||
const key = String(item.product_id || item.produit);
|
const key = String(item.product_id || item.produit);
|
||||||
if (!acc[key]) acc[key] = [];
|
if (!acc[key]) acc[key] = [];
|
||||||
acc[key].push(item);
|
acc[key].push(item);
|
||||||
@@ -561,7 +561,7 @@ export default function OrderDetailScreen() {
|
|||||||
const groupedList = Object.values(productGroups);
|
const groupedList = Object.values(productGroups);
|
||||||
|
|
||||||
// Récapitulatif par catégorie
|
// Récapitulatif par catégorie
|
||||||
const categoryTotals = items.reduce<Record<string, { qty: number; total: number }>>((acc, item) => {
|
const categoryTotals = (items ?? []).reduce<Record<string, { qty: number; total: number }>>((acc, item) => {
|
||||||
const cat = item.category || "Autre";
|
const cat = item.category || "Autre";
|
||||||
if (!acc[cat]) acc[cat] = { qty: 0, total: 0 };
|
if (!acc[cat]) acc[cat] = { qty: 0, total: 0 };
|
||||||
acc[cat].qty += item.quantite ?? 0;
|
acc[cat].qty += item.quantite ?? 0;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
getCommandItems,
|
getCommandItems,
|
||||||
notifyClientToDescend,
|
notifyClientToDescend,
|
||||||
confirmReceptionAdmin,
|
confirmReceptionAdmin,
|
||||||
|
validateCommand,
|
||||||
deleteCommand,
|
deleteCommand,
|
||||||
deleteCommandItem,
|
deleteCommandItem,
|
||||||
proposeAddressChangeAdmin,
|
proposeAddressChangeAdmin,
|
||||||
@@ -240,6 +241,26 @@ export default function OrdersScreen() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleForceValidate = (commandId: number) => {
|
||||||
|
showConfirm(
|
||||||
|
"Finaliser la commande",
|
||||||
|
`Finaliser définitivement la commande #${commandId} et attribuer les points au client ?`,
|
||||||
|
async () => {
|
||||||
|
try {
|
||||||
|
const res = await validateCommand(commandId);
|
||||||
|
showSuccess(
|
||||||
|
"Commande finalisée",
|
||||||
|
`${res.points_awarded} point(s) attribués au client`,
|
||||||
|
);
|
||||||
|
await loadData();
|
||||||
|
} catch (e: any) {
|
||||||
|
showError("Erreur", e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Finaliser",
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleProposeAddress = async () => {
|
const handleProposeAddress = async () => {
|
||||||
if (!addressModal.commandId || !addressModal.input.trim()) return;
|
if (!addressModal.commandId || !addressModal.input.trim()) return;
|
||||||
try {
|
try {
|
||||||
@@ -647,14 +668,21 @@ export default function OrdersScreen() {
|
|||||||
|
|
||||||
{/* Total + parrainage */}
|
{/* Total + parrainage */}
|
||||||
<Text style={styles.cardText}>
|
<Text style={styles.cardText}>
|
||||||
<Text style={{ color: colors.textMuted }}>Total : </Text>
|
<Text style={{ color: colors.textMuted }}>
|
||||||
|
{(item.referral_used ?? 0) > 0 ? "Total brut : " : "Total : "}
|
||||||
|
</Text>
|
||||||
{item.total_prix.toFixed(2)} €
|
{item.total_prix.toFixed(2)} €
|
||||||
|
</Text>
|
||||||
{(item.referral_used ?? 0) > 0 && (
|
{(item.referral_used ?? 0) > 0 && (
|
||||||
<Text style={{ color: colors.accent }}>
|
<>
|
||||||
{" "}(parrainage -{item.referral_used!.toFixed(2)} €)
|
<Text style={[styles.cardText, { color: colors.success }]}>
|
||||||
|
Parrainage : -{item.referral_used!.toFixed(2)} €
|
||||||
</Text>
|
</Text>
|
||||||
|
<Text style={[styles.cardText, { fontWeight: "700" }]}>
|
||||||
|
Net : {(item.total_prix - item.referral_used!).toFixed(2)} €
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Text>
|
|
||||||
|
|
||||||
{/* Livreur */}
|
{/* Livreur */}
|
||||||
{!!item.livreur_assign && (
|
{!!item.livreur_assign && (
|
||||||
@@ -775,6 +803,15 @@ export default function OrdersScreen() {
|
|||||||
},
|
},
|
||||||
condition: item.status === "livre",
|
condition: item.status === "livre",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Finaliser commande",
|
||||||
|
icon: "trophy-outline" as keyof typeof Ionicons.glyphMap,
|
||||||
|
onPress: () => {
|
||||||
|
setOpenMenuId(null);
|
||||||
|
handleForceValidate(item.id);
|
||||||
|
},
|
||||||
|
condition: !isDone && item.status !== "livre",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Supprimer",
|
label: "Supprimer",
|
||||||
icon: "trash-outline" as keyof typeof Ionicons.glyphMap,
|
icon: "trash-outline" as keyof typeof Ionicons.glyphMap,
|
||||||
@@ -802,8 +839,18 @@ export default function OrdersScreen() {
|
|||||||
<Text style={styles.cardText}>Client: {item.username}</Text>
|
<Text style={styles.cardText}>Client: {item.username}</Text>
|
||||||
<Text style={styles.cardText}>Adresse: {item.adresse}</Text>
|
<Text style={styles.cardText}>Adresse: {item.adresse}</Text>
|
||||||
<Text style={styles.cardText}>
|
<Text style={styles.cardText}>
|
||||||
Total: {item.total_prix.toFixed(2)} €
|
{(item.referral_used ?? 0) > 0 ? "Total brut" : "Total"}: {item.total_prix.toFixed(2)} €
|
||||||
</Text>
|
</Text>
|
||||||
|
{(item.referral_used ?? 0) > 0 && (
|
||||||
|
<>
|
||||||
|
<Text style={[styles.cardText, { color: colors.success }]}>
|
||||||
|
Parrainage: -{(item.referral_used ?? 0).toFixed(2)} €
|
||||||
|
</Text>
|
||||||
|
<Text style={[styles.cardText, { fontWeight: "700" }]}>
|
||||||
|
Net: {(item.total_prix - (item.referral_used ?? 0)).toFixed(2)} €
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{item.livreur_assign && (
|
{item.livreur_assign && (
|
||||||
<Text style={styles.cardText}>
|
<Text style={styles.cardText}>
|
||||||
Livreur: {item.livreur_assign}
|
Livreur: {item.livreur_assign}
|
||||||
@@ -1111,12 +1158,22 @@ export default function OrdersScreen() {
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
{itemsModal.commandInfo?.total_prix != null && (
|
{itemsModal.commandInfo?.total_prix != null && (
|
||||||
|
<>
|
||||||
<Text style={styles.modalTotal}>
|
<Text style={styles.modalTotal}>
|
||||||
{Number(
|
{(itemsModal.commandInfo.referral_used ?? 0) > 0 ? "Brut : " : ""}
|
||||||
itemsModal.commandInfo.total_prix,
|
{Number(itemsModal.commandInfo.total_prix).toFixed(2)} €
|
||||||
).toFixed(2)}{" "}
|
|
||||||
€
|
|
||||||
</Text>
|
</Text>
|
||||||
|
{(itemsModal.commandInfo.referral_used ?? 0) > 0 && (
|
||||||
|
<>
|
||||||
|
<Text style={[styles.modalTotal, { color: colors.success, fontSize: 13 }]}>
|
||||||
|
Parrainage : -{Number(itemsModal.commandInfo.referral_used).toFixed(2)} €
|
||||||
|
</Text>
|
||||||
|
<Text style={[styles.modalTotal, { fontWeight: "700" }]}>
|
||||||
|
Net : {(Number(itemsModal.commandInfo.total_prix) - Number(itemsModal.commandInfo.referral_used)).toFixed(2)} €
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -657,6 +657,8 @@ const EMPTY_REWARD: PointsReward = {
|
|||||||
type: "free_product",
|
type: "free_product",
|
||||||
description: "",
|
description: "",
|
||||||
category_configs: [],
|
category_configs: [],
|
||||||
|
reward_product_id: 0,
|
||||||
|
reward_quantity: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ──────────────────────────────────────────────────────────────
|
// ──────────────────────────────────────────────────────────────
|
||||||
@@ -918,6 +920,76 @@ function CentralRewardSection({
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{/* Produit récompense */}
|
||||||
|
<View>
|
||||||
|
<Text style={[s.rowLabel, { marginBottom: spacing.xs }]}>Produit ajouté au panier</Text>
|
||||||
|
<Text style={[s.rowDesc, { marginBottom: spacing.m }]}>
|
||||||
|
Quand le client réclame sa récompense, ce produit est automatiquement ajouté à son panier (gratuit). Il doit commander au moins un produit normal.
|
||||||
|
</Text>
|
||||||
|
{/* Sélecteur produit */}
|
||||||
|
<View style={{ gap: spacing.s }}>
|
||||||
|
{Object.values(productsByCategory).flat().length === 0 ? (
|
||||||
|
<Text style={[s.hint, { paddingHorizontal: 0 }]}>Aucun produit disponible</Text>
|
||||||
|
) : (
|
||||||
|
<View style={{ gap: spacing.xs }}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => update({ reward_product_id: 0, reward_quantity: 0 })}
|
||||||
|
style={{
|
||||||
|
flexDirection: "row", alignItems: "center", gap: spacing.xs,
|
||||||
|
paddingHorizontal: spacing.m, paddingVertical: spacing.s,
|
||||||
|
borderRadius: borderRadius.sm, borderWidth: 1.5,
|
||||||
|
borderColor: !r.reward_product_id ? colors.border : "transparent",
|
||||||
|
backgroundColor: !r.reward_product_id ? colors.border + "30" : "transparent",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ fontSize: 13, color: !r.reward_product_id ? colors.textPrimary : colors.textMuted }}>
|
||||||
|
Aucun (désactivé)
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
{Object.values(productsByCategory).flat().map((prod) => {
|
||||||
|
const sel = r.reward_product_id === prod.id;
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={prod.id}
|
||||||
|
onPress={() => update({ reward_product_id: prod.id, reward_quantity: r.reward_quantity && r.reward_quantity > 0 ? r.reward_quantity : 1 })}
|
||||||
|
style={{
|
||||||
|
flexDirection: "row", alignItems: "center", gap: spacing.xs,
|
||||||
|
paddingHorizontal: spacing.m, paddingVertical: spacing.s,
|
||||||
|
borderRadius: borderRadius.sm, borderWidth: 1.5,
|
||||||
|
borderColor: sel ? REWARD_ACCENT : colors.border,
|
||||||
|
backgroundColor: sel ? REWARD_ACCENT + "18" : "transparent",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="gift-outline" size={14} color={sel ? REWARD_ACCENT : colors.textMuted} />
|
||||||
|
<Text style={{ flex: 1, fontSize: 13, fontWeight: sel ? "700" : "400", color: sel ? REWARD_ACCENT : colors.textMuted }}>
|
||||||
|
{prod.name} ({prod.category})
|
||||||
|
</Text>
|
||||||
|
{sel && <Ionicons name="checkmark-circle" size={16} color={REWARD_ACCENT} />}
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
{/* Quantité */}
|
||||||
|
{!!r.reward_product_id && (
|
||||||
|
<View style={{ flexDirection: "row", alignItems: "center", gap: spacing.m, marginTop: spacing.s }}>
|
||||||
|
<Text style={[s.rowLabel, { flex: 1 }]}>Quantité offerte</Text>
|
||||||
|
<TextInput
|
||||||
|
style={[s.thresholdInput, { width: 64 }]}
|
||||||
|
keyboardType="decimal-pad"
|
||||||
|
value={r.reward_quantity ? String(r.reward_quantity) : ""}
|
||||||
|
onChangeText={(v) => {
|
||||||
|
const n = parseFloat(v);
|
||||||
|
if (!isNaN(n) && n > 0) update({ reward_quantity: n });
|
||||||
|
}}
|
||||||
|
placeholder="1"
|
||||||
|
placeholderTextColor={colors.textMuted}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
{/* Catégories éligibles */}
|
{/* Catégories éligibles */}
|
||||||
<View>
|
<View>
|
||||||
<Text style={[s.rowLabel, { marginBottom: spacing.xs }]}>Catégories éligibles</Text>
|
<Text style={[s.rowLabel, { marginBottom: spacing.xs }]}>Catégories éligibles</Text>
|
||||||
|
|||||||
@@ -756,18 +756,28 @@ export default function DashboardScreen() {
|
|||||||
{(!item.items || item.items.length === 0) && (
|
{(!item.items || item.items.length === 0) && (
|
||||||
<>
|
<>
|
||||||
<Text style={styles.priceOnly}>
|
<Text style={styles.priceOnly}>
|
||||||
{item.total_prix ?? 0}€
|
{(item.referral_used ?? 0) > 0 ? "Brut : " : ""}
|
||||||
|
{(item.total_prix ?? 0)}€
|
||||||
</Text>
|
</Text>
|
||||||
{(item.referral_used ?? 0) > 0 && (
|
{(item.referral_used ?? 0) > 0 && (
|
||||||
|
<>
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
styles.priceOnly,
|
styles.priceOnly,
|
||||||
{ color: colors.success, marginTop: 2 },
|
{ color: colors.success, marginTop: 2 },
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
Parrainage: -
|
Parrainage: -{(item.referral_used ?? 0).toFixed(2)}€
|
||||||
{(item.referral_used ?? 0).toFixed(2)}€
|
|
||||||
</Text>
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.priceOnly,
|
||||||
|
{ fontWeight: "700", marginTop: 2 },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
Net à encaisser: {((item.total_prix ?? 0) - (item.referral_used ?? 0)).toFixed(2)}€
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ export default function StatsScreen() {
|
|||||||
const pending = deliveries.filter((d) => d.status === "assigned").length;
|
const pending = deliveries.filter((d) => d.status === "assigned").length;
|
||||||
const totalRevenue = deliveries
|
const totalRevenue = deliveries
|
||||||
.filter((d) => d.status === "livre" || d.status === "approved")
|
.filter((d) => d.status === "livre" || d.status === "approved")
|
||||||
.reduce((s, d) => s + d.total_prix, 0);
|
.reduce((s, d) => s + (d.total_prix - (d.referral_used ?? 0)), 0);
|
||||||
|
|
||||||
const chartData = period === "day" ? byDay : period === "week" ? byWeek : byMonth;
|
const chartData = period === "day" ? byDay : period === "week" ? byWeek : byMonth;
|
||||||
|
|
||||||
|
|||||||
@@ -965,6 +965,8 @@ export const claimMyReward = async (poolKey: string): Promise<{
|
|||||||
success: boolean;
|
success: boolean;
|
||||||
description?: string;
|
description?: string;
|
||||||
remaining_rewards?: number;
|
remaining_rewards?: number;
|
||||||
|
product_added?: boolean;
|
||||||
|
product_name?: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
}> => {
|
}> => {
|
||||||
try {
|
try {
|
||||||
@@ -973,6 +975,8 @@ export const claimMyReward = async (poolKey: string): Promise<{
|
|||||||
success: true,
|
success: true,
|
||||||
description: data.description,
|
description: data.description,
|
||||||
remaining_rewards: data.remaining_rewards,
|
remaining_rewards: data.remaining_rewards,
|
||||||
|
product_added: data.product_added,
|
||||||
|
product_name: data.product_name,
|
||||||
};
|
};
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return { success: false, error: e?.response?.data?.error || "Erreur" };
|
return { success: false, error: e?.response?.data?.error || "Erreur" };
|
||||||
@@ -980,14 +984,12 @@ export const claimMyReward = async (poolKey: string): Promise<{
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const calculateOrderTotal = (order: any): number => {
|
export const calculateOrderTotal = (order: any): number => {
|
||||||
let gross = 0;
|
if (typeof order.total_prix === "number" && order.total_prix > 0) return order.total_prix;
|
||||||
if (typeof order.total === "number" && order.total > 0) gross = order.total;
|
if (typeof order.total === "number" && order.total > 0) return order.total;
|
||||||
else if (typeof order.total_prix === "number" && order.total_prix > 0) gross = order.total_prix;
|
if (Array.isArray(order.items) && order.items.length > 0) {
|
||||||
else if (Array.isArray(order.items) && order.items.length > 0) {
|
return order.items.reduce((sum: number, item: any) => {
|
||||||
gross = order.items.reduce((sum: number, item: any) => {
|
|
||||||
return sum + (item.prix || item.price || 0) * (item.quantite || item.quantity || 1);
|
return sum + (item.prix || item.price || 0) * (item.quantite || item.quantity || 1);
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
const referralUsed = typeof order.referral_used === "number" ? order.referral_used : 0;
|
return 0;
|
||||||
return Math.max(0, gross - referralUsed);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -96,7 +96,10 @@ export default function OrderHistoryScreen() {
|
|||||||
const res = await claimMyReward(poolKey);
|
const res = await claimMyReward(poolKey);
|
||||||
setClaimingPool(null);
|
setClaimingPool(null);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
setClaimFeedback({ pool: poolKey, type: "success", text: res.description || "Récompense réclamée !" });
|
const text = res.product_added && res.product_name
|
||||||
|
? `🎁 ${res.product_name} ajouté à votre panier ! Commandez au moins un produit pour en profiter.`
|
||||||
|
: res.description || "Récompense réclamée !";
|
||||||
|
setClaimFeedback({ pool: poolKey, type: "success", text });
|
||||||
getMyPointsRewards().then((r) => { if (r.success) setPointsRewards(r); });
|
getMyPointsRewards().then((r) => { if (r.success) setPointsRewards(r); });
|
||||||
} else {
|
} else {
|
||||||
setClaimFeedback({ pool: poolKey, type: "error", text: res.error || "Erreur" });
|
setClaimFeedback({ pool: poolKey, type: "error", text: res.error || "Erreur" });
|
||||||
|
|||||||
@@ -385,7 +385,8 @@ export default function OrderTrackingScreen() {
|
|||||||
contentContainerStyle={styles.list}
|
contentContainerStyle={styles.list}
|
||||||
renderItem={({ item: order }) => {
|
renderItem={({ item: order }) => {
|
||||||
const expanded = expandedId === order.id;
|
const expanded = expandedId === order.id;
|
||||||
const total = calculateOrderTotal(order);
|
const gross = calculateOrderTotal(order);
|
||||||
|
const total = Math.max(0, gross - (order.referral_used ?? 0));
|
||||||
const progress = STATUS_PROGRESS[order.status] || 0;
|
const progress = STATUS_PROGRESS[order.status] || 0;
|
||||||
const track = tracking[order.id];
|
const track = tracking[order.id];
|
||||||
const eta = etas[order.id];
|
const eta = etas[order.id];
|
||||||
@@ -444,9 +445,16 @@ export default function OrderTrackingScreen() {
|
|||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.cardFooter}>
|
<View style={styles.cardFooter}>
|
||||||
|
<View>
|
||||||
<Text style={styles.cardTotal}>
|
<Text style={styles.cardTotal}>
|
||||||
{formatPrice(total)}
|
{formatPrice(total)}
|
||||||
</Text>
|
</Text>
|
||||||
|
{(order.referral_used ?? 0) > 0 && (
|
||||||
|
<Text style={{ fontSize: 11, color: colors.success, marginTop: 2 }}>
|
||||||
|
dont -{(order.referral_used as number).toFixed(2)} € parrainage
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
<Ionicons
|
<Ionicons
|
||||||
name={
|
name={
|
||||||
expanded
|
expanded
|
||||||
|
|||||||
Reference in New Issue
Block a user