This commit is contained in:
2025-11-14 14:44:46 +07:00
parent 0ca7536b70
commit f150a84cf0
10 changed files with 1581 additions and 184 deletions

View File

@@ -1,18 +1,19 @@
import React from 'react';
import { Ionicons } from '@expo/vector-icons';
import { useLocalSearchParams, useRouter } from 'expo-router';
import React, { useState } from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
Image,
ActivityIndicator,
TouchableOpacity,
Dimensions,
Image,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useLocalSearchParams, useRouter } from 'expo-router';
import { useCart } from '../../../hooks/useCart';
import { useProduct } from '../../../hooks/useProducts';
import { Ionicons } from '@expo/vector-icons';
const { width } = Dimensions.get('window');
@@ -22,6 +23,8 @@ export default function ProductDetailScreen() {
const productId = typeof id === 'string' ? parseInt(id) : null;
const { product, loading, error } = useProduct(productId);
const { addToCart } = useCart();
const [isAddingToCart, setIsAddingToCart] = useState(false);
const formatPrice = (price: number) => {
return new Intl.NumberFormat('vi-VN', {
@@ -38,6 +41,19 @@ export default function ProductDetailScreen() {
});
};
const handleAddToCart = async () => {
if (!product || product.stockQuantity <= 0) {
return;
}
setIsAddingToCart(true);
try {
await addToCart(product.productId, 1);
} finally {
setIsAddingToCart(false);
}
};
if (loading) {
return (
<SafeAreaView style={styles.container}>
@@ -167,16 +183,36 @@ export default function ProductDetailScreen() {
{/* Bottom Action Buttons */}
<View style={styles.bottomActions}>
<TouchableOpacity
style={[styles.actionButton, styles.addToCartButton]}
disabled={product.stockQuantity === 0}
style={[
styles.actionButton,
styles.addToCartButton,
(product.stockQuantity === 0 || isAddingToCart) && styles.actionButtonDisabled
]}
onPress={handleAddToCart}
disabled={product.stockQuantity === 0 || isAddingToCart}
>
<Ionicons name="cart-outline" size={24} color="#fff" />
{isAddingToCart ? (
<ActivityIndicator size="small" color="#fff" />
) : (
<Ionicons name="cart-outline" size={24} color="#fff" />
)}
<Text style={styles.actionButtonText}>
{product.stockQuantity > 0 ? 'Thêm vào giỏ' : 'Hết hàng'}
{isAddingToCart
? 'Đang thêm...'
: product.stockQuantity > 0
? 'Thêm vào giỏ'
: 'Hết hàng'}
</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.actionButton, styles.buyNowButton]}>
<TouchableOpacity
style={[
styles.actionButton,
styles.buyNowButton,
product.stockQuantity === 0 && styles.actionButtonDisabled
]}
disabled={product.stockQuantity === 0}
>
<Ionicons name="flash-outline" size={24} color="#fff" />
<Text style={styles.actionButtonText}>Mua ngay</Text>
</TouchableOpacity>
@@ -344,6 +380,9 @@ const styles = StyleSheet.create({
fontWeight: '600',
color: '#fff',
},
actionButtonDisabled: {
opacity: 0.5,
},
loadingContainer: {
flex: 1,
justifyContent: 'center',