This commit is contained in:
@@ -67,6 +67,11 @@ export default function OrderHistoryScreen() {
|
|||||||
telegram_notifications_enabled: false,
|
telegram_notifications_enabled: false,
|
||||||
two_fa_enabled: false,
|
two_fa_enabled: false,
|
||||||
contact_telegram: "",
|
contact_telegram: "",
|
||||||
|
client_color_primary: "",
|
||||||
|
client_color_secondary: "",
|
||||||
|
client_color_success: "",
|
||||||
|
client_color_danger: "",
|
||||||
|
client_color_warning: "",
|
||||||
});
|
});
|
||||||
const [referralBalance, setReferralBalance] = useState(0);
|
const [referralBalance, setReferralBalance] = useState(0);
|
||||||
const [pointsRewards, setPointsRewards] = useState<{
|
const [pointsRewards, setPointsRewards] = useState<{
|
||||||
|
|||||||
@@ -274,6 +274,21 @@ export default function OrderTrackingScreen() {
|
|||||||
gap: spacing.s,
|
gap: spacing.s,
|
||||||
marginTop: spacing.l,
|
marginTop: spacing.l,
|
||||||
},
|
},
|
||||||
|
confirmBanner: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
gap: spacing.s,
|
||||||
|
backgroundColor: colors.success,
|
||||||
|
borderRadius: borderRadius.md,
|
||||||
|
paddingVertical: spacing.m,
|
||||||
|
marginTop: spacing.m,
|
||||||
|
},
|
||||||
|
confirmBannerText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "700",
|
||||||
|
fontSize: fontSize.sm,
|
||||||
|
},
|
||||||
proposalBox: {
|
proposalBox: {
|
||||||
backgroundColor: colors.warning + "18",
|
backgroundColor: colors.warning + "18",
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
@@ -466,6 +481,16 @@ export default function OrderTrackingScreen() {
|
|||||||
color={colors.textMuted}
|
color={colors.textMuted}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
{canConfirm && (
|
||||||
|
<TouchableOpacity
|
||||||
|
activeOpacity={0.85}
|
||||||
|
onPress={() => setConfirmingId(order.id)}
|
||||||
|
style={styles.confirmBanner}
|
||||||
|
>
|
||||||
|
<Ionicons name="checkmark-circle-outline" size={18} color="#fff" />
|
||||||
|
<Text style={styles.confirmBannerText}>Valider la réception</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
{order.address_proposal_status === "pending" &&
|
{order.address_proposal_status === "pending" &&
|
||||||
order.proposed_address && (
|
order.proposed_address && (
|
||||||
<View style={styles.proposalBox}>
|
<View style={styles.proposalBox}>
|
||||||
@@ -602,18 +627,6 @@ export default function OrderTrackingScreen() {
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
/>
|
/>
|
||||||
{canConfirm && (
|
|
||||||
<Button
|
|
||||||
title="Confirmer reception"
|
|
||||||
onPress={() =>
|
|
||||||
setConfirmingId(
|
|
||||||
order.id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
variant="success"
|
|
||||||
size="sm"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{canCancel && (
|
{canCancel && (
|
||||||
<Button
|
<Button
|
||||||
title="Annuler"
|
title="Annuler"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default function ProductDetailScreen() {
|
|||||||
const [adding, setAdding] = useState(false);
|
const [adding, setAdding] = useState(false);
|
||||||
const [showSuccess, setShowSuccess] = useState(false);
|
const [showSuccess, setShowSuccess] = useState(false);
|
||||||
const [showQuantityPicker, setShowQuantityPicker] = useState(false);
|
const [showQuantityPicker, setShowQuantityPicker] = useState(false);
|
||||||
|
const [stockWarning, setStockWarning] = useState<{ wanted: number; available: number } | null>(null);
|
||||||
const [showVideo, setShowVideo] = useState(false);
|
const [showVideo, setShowVideo] = useState(false);
|
||||||
const [catColor, setCatColor] = useState<string>("#7c3aed");
|
const [catColor, setCatColor] = useState<string>("#7c3aed");
|
||||||
|
|
||||||
@@ -95,6 +96,10 @@ export default function ProductDetailScreen() {
|
|||||||
|
|
||||||
const handleAddToCart = async () => {
|
const handleAddToCart = async () => {
|
||||||
if (!product || isOutOfStock || selectedGrams === null) return;
|
if (!product || isOutOfStock || selectedGrams === null) return;
|
||||||
|
if (product.stock > 0 && selectedGrams > product.stock) {
|
||||||
|
setStockWarning({ wanted: selectedGrams, available: product.stock });
|
||||||
|
return;
|
||||||
|
}
|
||||||
setAdding(true);
|
setAdding(true);
|
||||||
try {
|
try {
|
||||||
await addToCart({
|
await addToCart({
|
||||||
@@ -794,6 +799,42 @@ export default function ProductDetailScreen() {
|
|||||||
</View>
|
</View>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
{/* Modal stock insuffisant */}
|
||||||
|
<Modal
|
||||||
|
visible={stockWarning !== null}
|
||||||
|
transparent
|
||||||
|
animationType="fade"
|
||||||
|
onRequestClose={() => setStockWarning(null)}
|
||||||
|
>
|
||||||
|
<Pressable
|
||||||
|
style={{ flex: 1, backgroundColor: "rgba(0,0,0,0.6)", justifyContent: "center", alignItems: "center", padding: 24 }}
|
||||||
|
onPress={() => setStockWarning(null)}
|
||||||
|
>
|
||||||
|
<Pressable
|
||||||
|
style={{ backgroundColor: colors.bgCard, borderRadius: 16, padding: 28, width: "100%", maxWidth: 340, alignItems: "center" }}
|
||||||
|
onPress={() => {}}
|
||||||
|
>
|
||||||
|
<Text style={{ fontSize: 36, marginBottom: 12 }}>⚠️</Text>
|
||||||
|
<Text style={{ fontSize: 17, fontWeight: "700", color: colors.textPrimary, marginBottom: 8, textAlign: "center" }}>
|
||||||
|
Stock insuffisant
|
||||||
|
</Text>
|
||||||
|
<Text style={{ fontSize: 14, color: colors.textMuted, textAlign: "center", marginBottom: 20, lineHeight: 20 }}>
|
||||||
|
Vous avez sélectionné{" "}
|
||||||
|
<Text style={{ fontWeight: "700", color: colors.textPrimary }}>{stockWarning?.wanted}g</Text>
|
||||||
|
{" "}mais il ne reste que{" "}
|
||||||
|
<Text style={{ fontWeight: "700", color: "#ef4444" }}>{stockWarning?.available}g</Text>
|
||||||
|
{" "}disponible pour ce produit.
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => setStockWarning(null)}
|
||||||
|
style={{ backgroundColor: "#ef4444", borderRadius: 10, paddingVertical: 12, paddingHorizontal: 32 }}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "#fff", fontWeight: "700", fontSize: 15 }}>OK</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</Pressable>
|
||||||
|
</Pressable>
|
||||||
|
</Modal>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,13 @@ export default function ProductsScreen() {
|
|||||||
const scaleAnim = useRef(new Animated.Value(1)).current;
|
const scaleAnim = useRef(new Animated.Value(1)).current;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCategories().then(setCategories);
|
getCategories().then((cats) => {
|
||||||
|
const sorted = [...cats].sort((a, b) => {
|
||||||
|
if (a.is_coming_soon === b.is_coming_soon) return 0;
|
||||||
|
return a.is_coming_soon ? 1 : -1;
|
||||||
|
});
|
||||||
|
setCategories(sorted);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user