update
This commit is contained in:
@@ -13,8 +13,11 @@ import PopupBuildpc from "@components/buildpc/PopupBuildpc"; // Bạn cần tự
|
||||
import Feather from "@expo/vector-icons/Feather";
|
||||
import AntDesign from "@expo/vector-icons/AntDesign";
|
||||
const { width } = Dimensions.get("window");
|
||||
import { useNavigation, NavigationProp } from "@react-navigation/native";
|
||||
|
||||
export function CreateBuildpc() {
|
||||
const navigation = useNavigation<NavigationProp<any>>();
|
||||
|
||||
const [showPopup, setShowPopup] = useState(false);
|
||||
|
||||
return (
|
||||
@@ -30,14 +33,17 @@ export function CreateBuildpc() {
|
||||
style={styles.productImage}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
<Text style={styles.productName}>
|
||||
<Text
|
||||
style={styles.productName}
|
||||
onPress={() => navigation?.navigate("buildpcdetail")}
|
||||
>
|
||||
AMD Ryzen 7 9800x3D 4.7 GHz 8-Core Processor
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.boxQlt}>
|
||||
<Text>Số lượng</Text>
|
||||
<TextInput
|
||||
value="111"
|
||||
value="1"
|
||||
style={styles.inputQl}
|
||||
keyboardType="numeric"
|
||||
placeholder="Nhập số"
|
||||
@@ -93,6 +99,91 @@ export function CreateBuildpc() {
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
{/* Thêm lựa chọn CPU */}
|
||||
<TouchableOpacity
|
||||
style={styles.addButton}
|
||||
onPress={() => setShowPopup(true)}
|
||||
>
|
||||
<Text style={styles.addButtonText}>+ Chọn thêm CPU</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Item CPU */}
|
||||
<View style={styles.itemRow}>
|
||||
<Text style={styles.componentTitle}>CPU</Text>
|
||||
<View style={styles.productInfo}>
|
||||
<View style={styles.productLeft}>
|
||||
<View style={styles.infolinhkien}>
|
||||
<Image
|
||||
source={require("../../../assets/images/lienkien-ram.png")}
|
||||
style={styles.productImage}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
<Text
|
||||
style={styles.productName}
|
||||
onPress={() => navigation?.navigate("buildpcdetail")}
|
||||
>
|
||||
AMD Ryzen 7 9800x3D 4.7 GHz 8-Core Processor
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.boxQlt}>
|
||||
<Text>Số lượng</Text>
|
||||
<TextInput
|
||||
value="1"
|
||||
style={styles.inputQl}
|
||||
keyboardType="numeric"
|
||||
placeholder="Nhập số"
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
<Text style={{ marginRight: 10, fontSize: 13 }}>Giá bán:</Text>
|
||||
<Text style={styles.oldPrice}>4.700.000 Vnđ</Text>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
<Text style={{ marginRight: 10, fontSize: 13 }}>Khuyến mãi:</Text>
|
||||
<Text style={styles.discount}>20%</Text>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
<Text style={{ marginRight: 10, fontSize: 13 }}>Thành tiền:</Text>
|
||||
<Text style={styles.totalPrice}>4.000.000đ</Text>
|
||||
</View>
|
||||
<View style={styles.supplierSection}>
|
||||
<Text style={{ marginRight: 10, fontSize: 13 }}>
|
||||
Nhà cung cấp
|
||||
</Text>
|
||||
<Image
|
||||
source={require("../../../assets/images/logo-hacom.png")}
|
||||
style={styles.supplierLogo}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.buttonGroup}>
|
||||
<TouchableOpacity style={styles.buyButton}>
|
||||
<Feather name="edit" size={24} color="#1877f2" />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.removeButton}>
|
||||
<AntDesign name="delete" size={24} color="#ff0000" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
{/* Thêm lựa chọn CPU */}
|
||||
<TouchableOpacity
|
||||
@@ -101,6 +192,21 @@ export function CreateBuildpc() {
|
||||
>
|
||||
<Text style={styles.addButtonText}>+ Chọn thêm CPU</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* item gcu */}
|
||||
|
||||
<View style={styles.itemRow}>
|
||||
<Text style={styles.componentTitle}>CPU</Text>
|
||||
{/* Thêm lựa chọn CPU */}
|
||||
<TouchableOpacity
|
||||
style={styles.addButton}
|
||||
onPress={() => setShowPopup(true)}
|
||||
>
|
||||
<Text style={styles.addButtonText}>+ Chọn sản phẩm</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Tổng tiền */}
|
||||
<View style={styles.totalSection}>
|
||||
<Text style={styles.totalText}>Tổng tiền 2 sản phẩm: 8.000.000đ</Text>
|
||||
@@ -140,6 +246,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
|
||||
productInfo: {
|
||||
width: "100%",
|
||||
flexDirection: "row",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "space-between",
|
||||
@@ -210,6 +317,7 @@ const styles = StyleSheet.create({
|
||||
paddingVertical: 2,
|
||||
},
|
||||
addButton: {
|
||||
width: 115,
|
||||
marginTop: 12,
|
||||
backgroundColor: "#d4d4d4",
|
||||
borderRadius: 4,
|
||||
|
||||
115
src/components/buildpc/ImageGallery.tsx
Normal file
115
src/components/buildpc/ImageGallery.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import React, { useRef, useState, useCallback } from "react";
|
||||
import {
|
||||
View,
|
||||
Image,
|
||||
FlatList,
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
StyleSheet,
|
||||
} from "react-native";
|
||||
import Carousel from "react-native-reanimated-carousel";
|
||||
|
||||
const { width } = Dimensions.get("window");
|
||||
const THUMB_SIZE = 64;
|
||||
const SPACING = 10;
|
||||
|
||||
const images = [
|
||||
require("../../../assets/images/big-product-detail.png"),
|
||||
require("../../../assets/images/big-product-detail.jpg"),
|
||||
require("../../../assets/images/big-product-detail-2.jpg"),
|
||||
require("../../../assets/images/big-product-detail-3.jpg"),
|
||||
require("../../../assets/images/big-product-detail-4.jpg"),
|
||||
];
|
||||
|
||||
const ImageGallery = () => {
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
const carouselRef = useRef<Carousel<any>>(null);
|
||||
const thumbnailListRef = useRef<FlatList>(null);
|
||||
|
||||
const scrollToThumbnail = useCallback((index: number) => {
|
||||
const offset = index * (THUMB_SIZE + SPACING) - width / 2 + THUMB_SIZE / 2;
|
||||
thumbnailListRef.current?.scrollToOffset({
|
||||
offset: Math.max(0, offset),
|
||||
animated: true,
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onSnapToItem = useCallback(
|
||||
(index: number) => {
|
||||
setActiveIndex(index);
|
||||
scrollToThumbnail(index);
|
||||
},
|
||||
[scrollToThumbnail]
|
||||
);
|
||||
|
||||
const onThumbnailPress = useCallback((index: number) => {
|
||||
carouselRef.current?.scrollTo({ index, animated: true });
|
||||
}, []);
|
||||
|
||||
const renderThumbnail = useCallback(
|
||||
({ item, index }: { item: any; index: number }) => (
|
||||
<TouchableOpacity onPress={() => onThumbnailPress(index)}>
|
||||
<Image
|
||||
source={item}
|
||||
style={[
|
||||
styles.thumbnail,
|
||||
activeIndex === index && styles.activeThumbnail,
|
||||
]}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
),
|
||||
[activeIndex, onThumbnailPress]
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Carousel
|
||||
ref={carouselRef}
|
||||
loop={false}
|
||||
width={width}
|
||||
height={300}
|
||||
data={images}
|
||||
scrollAnimationDuration={400}
|
||||
renderItem={({ item }) => (
|
||||
<Image source={item} style={styles.bigImage} resizeMode="contain" />
|
||||
)}
|
||||
onSnapToItem={onSnapToItem}
|
||||
/>
|
||||
|
||||
<FlatList
|
||||
ref={thumbnailListRef}
|
||||
data={images}
|
||||
horizontal
|
||||
keyExtractor={(_, i) => i.toString()}
|
||||
renderItem={renderThumbnail}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={styles.thumbList}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageGallery;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {},
|
||||
bigImage: {
|
||||
width: width - 40,
|
||||
height: 280,
|
||||
borderWidth: 1,
|
||||
borderColor: "#b1b1b1",
|
||||
borderRadius: 12,
|
||||
},
|
||||
thumbnail: {
|
||||
width: THUMB_SIZE,
|
||||
height: THUMB_SIZE,
|
||||
marginRight: SPACING,
|
||||
borderRadius: 6,
|
||||
borderWidth: 1,
|
||||
borderColor: "#b1b1b1",
|
||||
},
|
||||
activeThumbnail: {
|
||||
borderColor: "#1877F2",
|
||||
},
|
||||
thumbList: {},
|
||||
});
|
||||
@@ -1,98 +1,334 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Modal,
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
TextInput,
|
||||
ScrollView,
|
||||
Image,
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
} from "react-native";
|
||||
import { Ionicons } from "@expo/vector-icons"; // hoặc react-native-vector-icons
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
const { width } = Dimensions.get("window");
|
||||
import FilterDropdown from "@components/product/FilterDropdown";
|
||||
|
||||
interface PopupBuildpcProps {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
export function PopupBuildpc({ show, onClose }) {
|
||||
const productList = Array(10).fill({
|
||||
name: "AMD Ryzen 7 9800x3D 4.7 GHz 8-Core Processor",
|
||||
capacity: "8bg",
|
||||
generation: "5",
|
||||
memory: "GDDR5",
|
||||
noise: "5db",
|
||||
color: "Đen",
|
||||
rating: 4,
|
||||
reviews: 125,
|
||||
price: "3.400.000đ",
|
||||
image: require("../../../assets/images/lienkien-ram.png"),
|
||||
});
|
||||
|
||||
export default function PopupBuildpc({ visible, onClose }: PopupBuildpcProps) {
|
||||
const [selectedAddress, setSelectedAddress] = useState("");
|
||||
const [selectedBrand, setSelectedBrand] = useState("");
|
||||
|
||||
const renderStars = (count: number) => {
|
||||
return (
|
||||
<Modal
|
||||
animationType="fade"
|
||||
transparent={true}
|
||||
visible={visible}
|
||||
onRequestClose={onClose}
|
||||
>
|
||||
<View style={styles.overlay}>
|
||||
<View style={styles.modalContent}>
|
||||
{/* Close button */}
|
||||
<TouchableOpacity style={styles.closeBtn} onPress={onClose}>
|
||||
<Ionicons name="close" size={24} color="#000" />
|
||||
</TouchableOpacity>
|
||||
|
||||
<Text style={styles.title}>Chọn linh kiện thay thế</Text>
|
||||
|
||||
{/* List of products (giả lập) */}
|
||||
<ScrollView>
|
||||
{[1, 2, 3].map((item) => (
|
||||
<View key={item} style={styles.item}>
|
||||
<Text style={styles.itemText}>Linh kiện {item}</Text>
|
||||
<TouchableOpacity style={styles.selectButton}>
|
||||
<Text style={styles.selectButtonText}>Chọn</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={{ flexDirection: "row" }}>
|
||||
{Array.from({ length: 5 }).map((_, index) => (
|
||||
<Ionicons
|
||||
key={index}
|
||||
name="star"
|
||||
size={10}
|
||||
color={index < count ? "#ff7a00" : "#d9d9d9"}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal visible={show} transparent animationType="fade">
|
||||
<TouchableOpacity
|
||||
style={styles.overlay}
|
||||
onPress={onClose}
|
||||
activeOpacity={1}
|
||||
/>
|
||||
<View style={styles.modalContent}>
|
||||
<View style={styles.header}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
width: "100%",
|
||||
marginBottom: 15,
|
||||
}}
|
||||
>
|
||||
<Text style={styles.title}>Chọn linh kiện</Text>
|
||||
<TouchableOpacity onPress={onClose}>
|
||||
<Ionicons name="close" size={24} color="#fff" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.searchBox}>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="Bạn cần tìm linh kiện gì..."
|
||||
/>
|
||||
<TouchableOpacity style={styles.searchButton}>
|
||||
<Ionicons name="search" size={24} color="#000" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
<ScrollView>
|
||||
<View style={styles.body}>
|
||||
<View style={styles.sidebar}>
|
||||
<Text style={{ fontWeight: 700 }}>230 sản phẩm</Text>
|
||||
<View style={styles.actionsRow}>
|
||||
<Text style={styles.actionText}>Chọn tất cả</Text>
|
||||
<Text style={styles.actionText}>Bỏ chọn tất cả</Text>
|
||||
<Text style={styles.actionText}>So sánh sản phẩm đã chọn</Text>
|
||||
</View>
|
||||
<View style={styles.BoxFilter}>
|
||||
<View style={styles.titleFilter}>
|
||||
<Text>Bộ lọc</Text>
|
||||
<Ionicons name="filter" size={24} color="black" />
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.listFilter}>
|
||||
<FilterDropdown
|
||||
placeholder="Địa chỉ"
|
||||
options={["Hà Nội", "TP.HCM", "Đà Nẵng"]}
|
||||
selected={selectedAddress}
|
||||
onSelect={setSelectedAddress}
|
||||
/>
|
||||
<FilterDropdown
|
||||
placeholder="Thương hiệu"
|
||||
options={["Dell", "HP", "Lenovo"]}
|
||||
selected={selectedBrand}
|
||||
onSelect={setSelectedBrand}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.mainContent}>
|
||||
<FlatList
|
||||
data={productList}
|
||||
keyExtractor={(_, index) => index.toString()}
|
||||
style={styles.productList}
|
||||
renderItem={({ item }) => (
|
||||
<View style={styles.productItem}>
|
||||
<View style={styles.productInfo}>
|
||||
<View
|
||||
style={{ flexDirection: "row", alignItems: "center" }}
|
||||
>
|
||||
<Image
|
||||
source={item.image}
|
||||
style={styles.productImage}
|
||||
/>
|
||||
<Text style={styles.productName}>{item.name}</Text>
|
||||
</View>
|
||||
<Text style={styles.proPrice}>{item.price}</Text>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
<View style={styles.itemTs}>
|
||||
<Text>Dung lượng:</Text>
|
||||
<Text style={{ marginLeft: 5, fontWeight: 700 }}>
|
||||
{item.capacity}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.itemTs}>
|
||||
<Text>Độ òn</Text>
|
||||
<Text style={{ marginLeft: 5, fontWeight: 700 }}>
|
||||
{item.generation}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.itemTs}>
|
||||
<Text>Thế hệ</Text>
|
||||
<Text style={{ marginLeft: 5, fontWeight: 700 }}>
|
||||
{item.memory}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.itemTs}>
|
||||
<Text>Màu sắc</Text>
|
||||
<Text style={{ marginLeft: 5, fontWeight: 700 }}>
|
||||
{item.color}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.itemTs}>
|
||||
<Text>Bộ nhớ</Text>
|
||||
<Text style={{ marginLeft: 5, fontWeight: 700 }}>
|
||||
{item.noise}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Text style={{ marginRight: 5 }}>Đánh giá</Text>
|
||||
{renderStars(item.rating)}
|
||||
<Text style={{ fontWeight: 700, marginLeft: 5 }}>
|
||||
({item.reviews})
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<TouchableOpacity style={styles.addButton}>
|
||||
<Text style={styles.addButtonText}>Add</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default PopupBuildpc;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
flex: 1,
|
||||
backgroundColor: "rgba(0,0,0,0.4)",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
backgroundColor: "rgba(0,0,0,0.5)",
|
||||
},
|
||||
modalContent: {
|
||||
width: "90%",
|
||||
maxHeight: "80%",
|
||||
backgroundColor: "#fff",
|
||||
borderRadius: 12,
|
||||
padding: 20,
|
||||
position: "relative",
|
||||
},
|
||||
closeBtn: {
|
||||
position: "absolute",
|
||||
right: 16,
|
||||
top: 16,
|
||||
zIndex: 10,
|
||||
top: "5%",
|
||||
left: "2.5%",
|
||||
width: "95%",
|
||||
height: "90%",
|
||||
backgroundColor: "#fff",
|
||||
borderRadius: 8,
|
||||
overflow: "hidden",
|
||||
},
|
||||
header: {
|
||||
backgroundColor: "#462f91",
|
||||
padding: 10,
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
fontWeight: "bold",
|
||||
marginBottom: 16,
|
||||
textAlign: "center",
|
||||
},
|
||||
item: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#e5e7eb",
|
||||
},
|
||||
itemText: {
|
||||
fontSize: 16,
|
||||
},
|
||||
selectButton: {
|
||||
backgroundColor: "#2563eb",
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 4,
|
||||
},
|
||||
selectButtonText: {
|
||||
color: "#fff",
|
||||
fontWeight: "bold",
|
||||
fontSize: 16,
|
||||
},
|
||||
searchBox: {
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
marginHorizontal: 10,
|
||||
backgroundColor: "#fff",
|
||||
borderRadius: 8,
|
||||
alignItems: "center",
|
||||
width: width,
|
||||
marginLeft: 0,
|
||||
marginRight: 5,
|
||||
},
|
||||
listFilter: {
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
marginRight: -5,
|
||||
},
|
||||
input: {
|
||||
flex: 1,
|
||||
padding: 10,
|
||||
},
|
||||
searchButton: {
|
||||
padding: 10,
|
||||
},
|
||||
body: {},
|
||||
sidebar: {
|
||||
padding: 10,
|
||||
},
|
||||
filterList: {
|
||||
marginTop: 10,
|
||||
},
|
||||
filterTitle: {
|
||||
fontWeight: "bold",
|
||||
marginBottom: 5,
|
||||
},
|
||||
filterItem: {
|
||||
paddingVertical: 5,
|
||||
},
|
||||
mainContent: {
|
||||
padding: 10,
|
||||
},
|
||||
actionsRow: {
|
||||
marginTop: 10,
|
||||
flexDirection: "row",
|
||||
marginBottom: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#e3e3e3",
|
||||
paddingBottom: 5,
|
||||
},
|
||||
actionText: {
|
||||
color: "#004aad",
|
||||
fontSize: 12,
|
||||
marginRight: 10,
|
||||
},
|
||||
BoxFilter: {},
|
||||
titleFilter: { flexDirection: "row", alignItems: "center", gap: 5 },
|
||||
productList: {
|
||||
flex: 1,
|
||||
},
|
||||
productItem: {
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#ddd",
|
||||
flexDirection: "row",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "space-between",
|
||||
paddingBottom: 10,
|
||||
},
|
||||
productInfo: {
|
||||
width: width - 120,
|
||||
},
|
||||
productImage: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
marginBottom: 5,
|
||||
},
|
||||
productName: {
|
||||
fontWeight: "bold",
|
||||
marginBottom: 5,
|
||||
},
|
||||
proPrice: {
|
||||
fontWeight: 700,
|
||||
color: "#ff0000",
|
||||
},
|
||||
itemTs: {
|
||||
width: "50%",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 10,
|
||||
},
|
||||
addButton: {
|
||||
marginTop: 5,
|
||||
backgroundColor: "#004aad",
|
||||
padding: 8,
|
||||
borderRadius: 4,
|
||||
},
|
||||
addButtonText: {
|
||||
color: "#fff",
|
||||
textAlign: "center",
|
||||
},
|
||||
});
|
||||
|
||||
84
src/components/buildpc/ProductSpecs.tsx
Normal file
84
src/components/buildpc/ProductSpecs.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import React from "react";
|
||||
import { View, Text, FlatList, StyleSheet } from "react-native";
|
||||
|
||||
const specs = [
|
||||
{ key: "Manufacturer", value: "AMD" },
|
||||
{
|
||||
key: "Part #",
|
||||
value: ["100-1000001084WOF", "AMD Ryzen 7 9800X3D", "100-100001084WOF"],
|
||||
},
|
||||
{ key: "Series", value: "AMD Ryzen 7" },
|
||||
{ key: "Microarchitecture", value: "Zen 5" },
|
||||
{ key: "Core Family", value: "Granite Ridge" },
|
||||
{ key: "Socket", value: "AM5" },
|
||||
{ key: "Core", value: "8" },
|
||||
{ key: "Thread Count", value: "16" },
|
||||
{ key: "Performance Core Clock", value: "4.7 GHz" },
|
||||
{ key: "Performance Core Boost Clock", value: "5.2 GHz" },
|
||||
{ key: "L2 Cache", value: "8 MB" },
|
||||
{ key: "L3 Cache", value: "96 MB" },
|
||||
{ key: "TDP", value: "120 W" },
|
||||
{ key: "Integrated Graphics", value: "Radeon" },
|
||||
];
|
||||
|
||||
export default function ProductSpecs() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>Thông số kỹ thuật</Text>
|
||||
<FlatList
|
||||
data={specs}
|
||||
keyExtractor={(item, index) => index.toString()}
|
||||
renderItem={({ item, index }) => (
|
||||
<View
|
||||
style={[styles.item, index < specs.length - 1 && styles.itemBorder]}
|
||||
>
|
||||
<Text style={styles.label}>{item.key}</Text>
|
||||
{Array.isArray(item.value) ? (
|
||||
<View style={styles.list}>
|
||||
{item.value.map((v, i) => (
|
||||
<Text key={i} style={styles.value}>
|
||||
{v}
|
||||
</Text>
|
||||
))}
|
||||
</View>
|
||||
) : (
|
||||
<Text style={styles.value}>{item.value}</Text>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: "#fff",
|
||||
padding: 12,
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
fontWeight: "bold",
|
||||
paddingBottom: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#ababab",
|
||||
},
|
||||
item: {
|
||||
paddingVertical: 10,
|
||||
},
|
||||
itemBorder: {
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#e5e5e5",
|
||||
},
|
||||
label: {
|
||||
fontWeight: "bold",
|
||||
marginBottom: 4,
|
||||
fontSize: 14,
|
||||
},
|
||||
value: {
|
||||
fontSize: 14,
|
||||
color: "#444",
|
||||
},
|
||||
list: {
|
||||
gap: 2,
|
||||
},
|
||||
});
|
||||
140
src/components/buildpc/ProvidersList.tsx
Normal file
140
src/components/buildpc/ProvidersList.tsx
Normal file
@@ -0,0 +1,140 @@
|
||||
import React from "react";
|
||||
import { View, Text, Image, TouchableOpacity, StyleSheet } from "react-native";
|
||||
|
||||
const providers = [
|
||||
{
|
||||
logo: require("../../../assets/images/logo-hacom.png"),
|
||||
old: "3.700.000 Vnđ",
|
||||
deal: "20%",
|
||||
status: "Còn hàng",
|
||||
ship: "Liên hệ",
|
||||
total: "3.000.000 Vnđ",
|
||||
},
|
||||
{
|
||||
logo: require("../../../assets/images/logo-hacom.png"),
|
||||
old: "3.700.000 Vnđ",
|
||||
deal: "20%",
|
||||
status: "Còn hàng",
|
||||
ship: "free",
|
||||
total: "3.000.000 Vnđ",
|
||||
},
|
||||
];
|
||||
|
||||
export function ProvidersList() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{providers.map((p, i) => (
|
||||
<View key={i} style={styles.row}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
<Image source={p.logo} style={styles.logo} resizeMode="contain" />
|
||||
<TouchableOpacity style={styles.buyBtn}>
|
||||
<Text style={styles.buyText}>Mua ngay</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.flexBox}>
|
||||
<Text style={styles.textFlex}>Giá sản phẩm:</Text>
|
||||
<Text style={styles.price}>4.700.000 Vnđ</Text>
|
||||
<Text style={styles.oldPrice}>4.700.000 Vnđ</Text>
|
||||
</View>
|
||||
<View style={styles.flexBox}>
|
||||
<Text style={styles.textFlex}>Khuyến mãi:</Text>
|
||||
<Text style={styles.discount}>20%</Text>
|
||||
</View>
|
||||
<View style={styles.flexBox}>
|
||||
<Text style={styles.textFlex}>Giao hàng:</Text>
|
||||
<Text style={styles.ship}>Liên hệ</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
export default ProvidersList;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: "#fff",
|
||||
padding: 10,
|
||||
},
|
||||
row: {
|
||||
paddingVertical: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#eee",
|
||||
},
|
||||
logo: {
|
||||
width: 60,
|
||||
height: 30,
|
||||
resizeMode: "contain",
|
||||
},
|
||||
oldPrice: {
|
||||
flex: 1,
|
||||
textDecorationLine: "line-through",
|
||||
color: "#999",
|
||||
fontSize: 13,
|
||||
marginLeft: 10,
|
||||
},
|
||||
deal: {
|
||||
flex: 1,
|
||||
color: "#e11d48",
|
||||
fontWeight: "bold",
|
||||
fontSize: 13,
|
||||
},
|
||||
status: {
|
||||
flex: 1,
|
||||
fontSize: 13,
|
||||
fontWeight: "500",
|
||||
},
|
||||
green: {
|
||||
color: "#22c55e",
|
||||
},
|
||||
price: {
|
||||
color: "#ff0000",
|
||||
fontWeight: 700,
|
||||
},
|
||||
ship: {
|
||||
flex: 1,
|
||||
fontSize: 13,
|
||||
fontWeight: 700,
|
||||
},
|
||||
cellWide: {
|
||||
flex: 1.5,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
total: {
|
||||
fontWeight: "bold",
|
||||
fontSize: 14,
|
||||
color: "#111",
|
||||
marginBottom: 4,
|
||||
},
|
||||
buyBtn: {
|
||||
backgroundColor: "#1877f2",
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 6,
|
||||
},
|
||||
buyText: {
|
||||
color: "#fff",
|
||||
fontSize: 13,
|
||||
fontWeight: "bold",
|
||||
},
|
||||
flexBox: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 5,
|
||||
},
|
||||
textFlex: {
|
||||
width: 100,
|
||||
},
|
||||
discount: {
|
||||
fontWeight: 700,
|
||||
},
|
||||
});
|
||||
175
src/components/buildpc/ReviewList.tsx
Normal file
175
src/components/buildpc/ReviewList.tsx
Normal file
@@ -0,0 +1,175 @@
|
||||
import React from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
Image,
|
||||
StyleSheet,
|
||||
FlatList,
|
||||
TouchableOpacity,
|
||||
} from "react-native";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
|
||||
|
||||
const reviews = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Dino",
|
||||
avatar: require("../../../assets/images/avartar-review-1.png"),
|
||||
time: "10:00pm 20/02/2025",
|
||||
content: `Lorem Ipsum is simply dummy text of the printing and typesetting industry...`,
|
||||
views: 120,
|
||||
comments: 120,
|
||||
},
|
||||
// Thêm các review khác nếu có
|
||||
];
|
||||
|
||||
const renderStars = (count: number) => {
|
||||
return (
|
||||
<View style={{ flexDirection: "row" }}>
|
||||
{Array.from({ length: 5 }).map((_, index) => (
|
||||
<Ionicons
|
||||
key={index}
|
||||
name="star"
|
||||
size={13}
|
||||
color={index < count ? "#ff7a00" : "#d9d9d9"}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default function ReviewList() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.title}>Đánh giá</Text>
|
||||
</View>
|
||||
|
||||
{/* List */}
|
||||
<FlatList
|
||||
style={styles.list}
|
||||
data={reviews}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
renderItem={({ item }) => (
|
||||
<View style={styles.item}>
|
||||
<View style={styles.avatarBox}>
|
||||
<Image source={item.avatar} style={styles.avatar} />
|
||||
<Text style={styles.name}>{item.name}</Text>
|
||||
<Text style={styles.time}>{item.time}</Text>
|
||||
{renderStars(4)}
|
||||
</View>
|
||||
<View style={styles.contentBox}>
|
||||
<Text style={styles.content}>{item.content}</Text>
|
||||
<View style={styles.stats}>
|
||||
<View style={styles.statItem}>
|
||||
<Text style={styles.statNumber}>{item.views}</Text>
|
||||
<Text style={styles.icon}>
|
||||
<Ionicons name="eye-outline" size={20} color="black" />
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.statItem}>
|
||||
<Text style={styles.statNumber}>{item.comments}</Text>
|
||||
<Text style={styles.icon}>
|
||||
<MaterialCommunityIcons
|
||||
name="comment-processing-outline"
|
||||
size={20}
|
||||
color="black"
|
||||
/>
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
<TouchableOpacity style={styles.button}>
|
||||
<Text style={styles.buttonText}>Xem tất cả bình luận</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: "#fff",
|
||||
padding: 10,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
paddingBottom: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#ababab",
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
},
|
||||
button: {
|
||||
backgroundColor: "#2563eb",
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 4,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
buttonText: {
|
||||
color: "#fff",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
list: {
|
||||
marginTop: 12,
|
||||
},
|
||||
item: {
|
||||
marginBottom: 15,
|
||||
paddingBottom: 15,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#e4e4e4",
|
||||
},
|
||||
avatarBox: {
|
||||
marginBottom: 10,
|
||||
alignItems: "center",
|
||||
flexDirection: "row",
|
||||
},
|
||||
avatar: {
|
||||
width: 25,
|
||||
height: 25,
|
||||
borderRadius: 40,
|
||||
},
|
||||
starBox: {},
|
||||
contentBox: {
|
||||
flex: 1,
|
||||
},
|
||||
name: {
|
||||
fontWeight: "bold",
|
||||
marginLeft: 6,
|
||||
},
|
||||
time: {
|
||||
color: "#747474",
|
||||
marginLeft: 6,
|
||||
marginRight: 6,
|
||||
},
|
||||
content: {
|
||||
marginBottom: 5,
|
||||
color: "#333",
|
||||
},
|
||||
stats: {
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
},
|
||||
statItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginRight: 10,
|
||||
},
|
||||
statNumber: {
|
||||
marginRight: 5,
|
||||
fontWeight: "bold",
|
||||
},
|
||||
icon: {
|
||||
fontSize: 14,
|
||||
},
|
||||
});
|
||||
@@ -7,6 +7,8 @@ import ProductListBig from "../screens/product/ProductListBig";
|
||||
import ProductList from "../screens/product/ProductList";
|
||||
import ProductDetail from "../screens/product/ProductDetail";
|
||||
import Buildpc from "../screens/buildpc/Buildpc";
|
||||
import CompareBuildpc from "../screens/buildpc/CompareBuildpc";
|
||||
import BuildpcDeail from "../screens/buildpc/BuildpcDetail";
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
@@ -21,6 +23,8 @@ const AppNavigator: React.FC = () => {
|
||||
<Stack.Screen name="productlistmain" component={ProductList} />
|
||||
<Stack.Screen name="productdetail" component={ProductDetail} />
|
||||
<Stack.Screen name="buildpc" component={Buildpc} />
|
||||
<Stack.Screen name="comparebuildpc" component={CompareBuildpc} />
|
||||
<Stack.Screen name="buildpcdetail" component={BuildpcDeail} />
|
||||
</Stack.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,16 +8,20 @@ import {
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
} from "react-native";
|
||||
import { useNavigation, NavigationProp } from "@react-navigation/native";
|
||||
import AppLayout from "@layouts/AppLayout";
|
||||
import { Ionicons } from "@expo/vector-icons"; // hoặc icon_2025 nếu bạn có icon font riêng
|
||||
import CreateBuildpc from "@components/buildpc/CreateBuildpc"; // component con bạn tự tạo
|
||||
const { width } = Dimensions.get("window");
|
||||
import Octicons from "@expo/vector-icons/Octicons";
|
||||
import Footer from "@components/footer/Footer";
|
||||
|
||||
export default function Buildpc() {
|
||||
const navigation = useNavigation<NavigationProp<any>>();
|
||||
return (
|
||||
<AppLayout activeTab="buildpc">
|
||||
<ScrollView style={styles.container}>
|
||||
<ScrollView>
|
||||
<View style={styles.container}>
|
||||
{/* Breadcrumb */}
|
||||
<View style={styles.breadcrumb}>
|
||||
<View style={styles.breadcrumbItem}>
|
||||
@@ -38,10 +42,16 @@ export default function Buildpc() {
|
||||
|
||||
{/* Buttons Bắt đầu/So sánh */}
|
||||
<View style={styles.buttonWrapper}>
|
||||
<TouchableOpacity style={styles.primaryButton}>
|
||||
<TouchableOpacity
|
||||
style={styles.primaryButton}
|
||||
onPress={() => navigation?.navigate("buildpc")}
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>Bắt đầu tạo</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.secondaryButton}>
|
||||
<TouchableOpacity
|
||||
style={styles.secondaryButton}
|
||||
onPress={() => navigation?.navigate("comparebuildpc")}
|
||||
>
|
||||
<Text style={styles.secondaryButtonText}>
|
||||
So sánh giá tại các cửa hàng
|
||||
</Text>
|
||||
@@ -81,6 +91,8 @@ export default function Buildpc() {
|
||||
|
||||
{/* Buildpc Content */}
|
||||
<CreateBuildpc />
|
||||
</View>
|
||||
<Footer navigation={navigation} />
|
||||
</ScrollView>
|
||||
</AppLayout>
|
||||
);
|
||||
@@ -97,7 +109,6 @@ function ActionButton({ icon, label }: { icon: string; label: string }) {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingBottom: 100,
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
breadcrumb: {
|
||||
|
||||
126
src/screens/buildpc/BuildpcDetail.tsx
Normal file
126
src/screens/buildpc/BuildpcDetail.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import React from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
} from "react-native";
|
||||
import { globalStyles } from "styles/globalStyles";
|
||||
import { useNavigation, NavigationProp } from "@react-navigation/native";
|
||||
import AppLayout from "@layouts/AppLayout";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import ImageGallery from "@components/buildpc/ImageGallery";
|
||||
import Footer from "@components/footer/Footer";
|
||||
import ProvidersList from "@components/buildpc/ProvidersList";
|
||||
import ProductSpecs from "@components/buildpc/ProductSpecs";
|
||||
import ReviewList from "@components/buildpc/ReviewList";
|
||||
|
||||
const stars = [5, 4, 3, 2, 1];
|
||||
|
||||
export function BuildpcDeail() {
|
||||
const navigation = useNavigation<NavigationProp<any>>();
|
||||
|
||||
return (
|
||||
<AppLayout activeTab="buildpcdetail">
|
||||
<ScrollView>
|
||||
<View style={styles.container}>
|
||||
{/* Breadcrumb */}
|
||||
<View style={globalStyles.breadcrumb}>
|
||||
<TouchableOpacity
|
||||
style={globalStyles.breadcrumbItem}
|
||||
onPress={() => navigation.navigate("homepage" as never)}
|
||||
>
|
||||
<Ionicons name="home-outline" size={20} color="#637381" />
|
||||
</TouchableOpacity>
|
||||
<Ionicons name="chevron-forward-outline" size={14} color="#999" />
|
||||
<Text style={[globalStyles.breadcrumbText, { fontWeight: "600" }]}>
|
||||
Màn hình máy tính
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
padding: 10,
|
||||
backgroundColor: "#fff",
|
||||
marginTop: 5,
|
||||
}}
|
||||
>
|
||||
<ImageGallery />
|
||||
|
||||
<View style={{ marginTop: 10 }}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
<Text style={{ marginRight: 5, fontWeight: 700 }}>
|
||||
Nguời dùng đánh giá
|
||||
</Text>
|
||||
<Text>(40 ratings, 4.9)</Text>
|
||||
</View>
|
||||
{stars.map((star) => (
|
||||
<View key={star} style={styles.row}>
|
||||
<Text style={styles.starLabel}>{star} sao</Text>
|
||||
<View style={styles.barBackground}>
|
||||
<View style={[styles.barFill, { width: "90%" }]} />
|
||||
</View>
|
||||
<Text style={styles.percent}>90%</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
{/* nhà cung cấp */}
|
||||
<ProvidersList />
|
||||
{/* thông số kỹ thuật */}
|
||||
<ProductSpecs />
|
||||
{/* đánh giá */}
|
||||
<ReviewList />
|
||||
</View>
|
||||
<Footer navigation={navigation} />
|
||||
</ScrollView>
|
||||
</AppLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export default BuildpcDeail;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 10,
|
||||
backgroundColor: "#efefef",
|
||||
paddingBottom: 10,
|
||||
},
|
||||
row: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 8,
|
||||
},
|
||||
starLabel: {
|
||||
width: 50,
|
||||
fontSize: 14,
|
||||
color: "#1877f2",
|
||||
},
|
||||
barBackground: {
|
||||
flex: 1,
|
||||
height: 8,
|
||||
backgroundColor: "#eee",
|
||||
borderRadius: 4,
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
barFill: {
|
||||
height: 8,
|
||||
backgroundColor: "#ff960b",
|
||||
},
|
||||
percent: {
|
||||
width: 40,
|
||||
fontSize: 12,
|
||||
textAlign: "right",
|
||||
color: "#1877f2",
|
||||
},
|
||||
});
|
||||
210
src/screens/buildpc/CompareBuildpc.tsx
Normal file
210
src/screens/buildpc/CompareBuildpc.tsx
Normal file
@@ -0,0 +1,210 @@
|
||||
import React from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
} from "react-native";
|
||||
import { useNavigation, NavigationProp } from "@react-navigation/native";
|
||||
import AppLayout from "@layouts/AppLayout";
|
||||
import Footer from "@components/footer/Footer";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import ListCompare from "./ListCompare";
|
||||
|
||||
export function CompareBuildpc() {
|
||||
const navigation = useNavigation<NavigationProp<any>>();
|
||||
|
||||
return (
|
||||
<AppLayout activeTab="buildpc">
|
||||
<ScrollView style={styles.page}>
|
||||
<View style={styles.wrapper}>
|
||||
{/* Breadcrumb */}
|
||||
<View style={styles.breadcrumb}>
|
||||
<View style={styles.breadcrumbItem}>
|
||||
<TouchableOpacity>
|
||||
<Ionicons
|
||||
name="home"
|
||||
size={16}
|
||||
color="#637381"
|
||||
style={styles.icon}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.angle}>›</Text>
|
||||
</View>
|
||||
<View style={styles.breadcrumbItem}>
|
||||
<Text style={styles.text}>Tạo máy tính riêng của bạn</Text>
|
||||
</View>
|
||||
</View>
|
||||
{/* Buttons Bắt đầu/So sánh */}
|
||||
<View style={styles.buttonWrapper}>
|
||||
<TouchableOpacity
|
||||
style={styles.primaryButton}
|
||||
onPress={() => navigation?.navigate("buildpc")}
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>Bắt đầu tạo</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.secondaryButton}
|
||||
onPress={() => navigation?.navigate("comparebuildpc")}
|
||||
>
|
||||
<Text style={styles.secondaryButtonText}>
|
||||
So sánh giá tại các cửa hàng
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<ListCompare />
|
||||
</View>
|
||||
<Footer navigation={navigation} />
|
||||
</ScrollView>
|
||||
</AppLayout>
|
||||
);
|
||||
}
|
||||
export default CompareBuildpc;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
page: {
|
||||
backgroundColor: "#F4F4F4",
|
||||
},
|
||||
breadcrumb: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
flexWrap: "wrap",
|
||||
},
|
||||
breadcrumbItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginRight: 8,
|
||||
},
|
||||
text: {
|
||||
color: "#000",
|
||||
},
|
||||
icon: {
|
||||
marginRight: 5,
|
||||
},
|
||||
angle: {
|
||||
marginLeft: 12,
|
||||
color: "#888",
|
||||
},
|
||||
wrapper: {
|
||||
paddingHorizontal: 12,
|
||||
},
|
||||
actionBar: {
|
||||
backgroundColor: "#fff",
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 8,
|
||||
marginTop: 12,
|
||||
},
|
||||
actionRow: {
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
marginBottom: 10,
|
||||
},
|
||||
urlInput: {
|
||||
flex: 4,
|
||||
height: 48,
|
||||
borderRadius: 6,
|
||||
borderWidth: 1,
|
||||
borderColor: "#ddd",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
iconWrapper: {
|
||||
width: 24,
|
||||
marginLeft: 10,
|
||||
},
|
||||
input: {
|
||||
flex: 1,
|
||||
padding: 10,
|
||||
},
|
||||
nameInput: {
|
||||
flex: 3,
|
||||
height: 48,
|
||||
borderRadius: 6,
|
||||
borderWidth: 1,
|
||||
borderColor: "#ddd",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
label: {
|
||||
marginLeft: 10,
|
||||
},
|
||||
buttonWrapper: {
|
||||
backgroundColor: "#fff",
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
alignItems: "center",
|
||||
},
|
||||
primaryButton: {
|
||||
backgroundColor: "#ddd",
|
||||
padding: 10,
|
||||
borderRadius: 4,
|
||||
marginRight: 5,
|
||||
},
|
||||
primaryButtonText: {
|
||||
color: "#666",
|
||||
fontWeight: "bold",
|
||||
textAlign: "center",
|
||||
},
|
||||
secondaryButton: {
|
||||
backgroundColor: "#5B21B6",
|
||||
padding: 10,
|
||||
borderRadius: 4,
|
||||
},
|
||||
secondaryButtonText: {
|
||||
color: "#fff",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
buttonRow: {
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
},
|
||||
iconButton: {
|
||||
flex: 1,
|
||||
height: 48,
|
||||
borderRadius: 6,
|
||||
borderWidth: 1,
|
||||
borderColor: "#ddd",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "row",
|
||||
},
|
||||
iconButtonText: {
|
||||
marginLeft: 5,
|
||||
},
|
||||
bottomPanel: {
|
||||
backgroundColor: "#fff",
|
||||
padding: 15,
|
||||
marginTop: 15,
|
||||
},
|
||||
buttonGroup: {
|
||||
flexDirection: "row",
|
||||
gap: 10,
|
||||
marginBottom: 10,
|
||||
},
|
||||
btnGrey: {
|
||||
backgroundColor: "#f4f4f4",
|
||||
paddingHorizontal: 24,
|
||||
paddingVertical: 10,
|
||||
borderRadius: 8,
|
||||
},
|
||||
btnGreyText: {
|
||||
fontWeight: "bold",
|
||||
color: "#6b7280",
|
||||
},
|
||||
btnPrimary: {
|
||||
backgroundColor: "#6D28D9",
|
||||
paddingHorizontal: 24,
|
||||
paddingVertical: 10,
|
||||
borderRadius: 8,
|
||||
},
|
||||
btnPrimaryText: {
|
||||
fontWeight: "bold",
|
||||
color: "#fff",
|
||||
},
|
||||
});
|
||||
216
src/screens/buildpc/ListCompare.tsx
Normal file
216
src/screens/buildpc/ListCompare.tsx
Normal file
@@ -0,0 +1,216 @@
|
||||
import React from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
Image,
|
||||
TouchableOpacity,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
} from "react-native";
|
||||
const { width } = Dimensions.get("window");
|
||||
import { useNavigation, NavigationProp } from "@react-navigation/native";
|
||||
|
||||
export function ListCompare() {
|
||||
const navigation = useNavigation<NavigationProp<any>>();
|
||||
|
||||
const storeLogo = require("../../../assets/images/logo-hacom.png");
|
||||
const productImg = require("../../../assets/images/lienkien-ram.png");
|
||||
|
||||
const stores = [1, 2]; // giả lập 2 nhà cung cấp
|
||||
const products = [1, 2]; // giả lập 2 sản phẩm mỗi nhà cung cấp
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.boxList}>
|
||||
{stores.map((store, storeIdx) => (
|
||||
<View style={styles.storeBox} key={storeIdx}>
|
||||
{/* Header */}
|
||||
<View style={styles.storeHeader}>
|
||||
<View style={styles.logoBox}>
|
||||
<Image
|
||||
source={storeLogo}
|
||||
style={styles.logo}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Products */}
|
||||
{products.map((product, index) => (
|
||||
<View style={styles.productRow} key={index}>
|
||||
<Text style={styles.productName}>CPU Cooler</Text>
|
||||
<View style={styles.productGrid}>
|
||||
{/* Product Info */}
|
||||
<View style={styles.productInfo}>
|
||||
<View style={styles.infoRow}>
|
||||
<Image source={productImg} style={styles.productImg} />
|
||||
<Text
|
||||
style={styles.productTitle}
|
||||
onPress={() => navigation?.navigate("buildpcdetail")}
|
||||
>
|
||||
AMD Ryzen 7 9800x3D 4.7 GHz 8-Core Processor
|
||||
</Text>
|
||||
</View>
|
||||
<TouchableOpacity style={styles.buyNowBtn}>
|
||||
<Text style={styles.buyNowText}>Mua ngay</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.flexBox}>
|
||||
<Text style={styles.textFlex}>Giá sản phẩm:</Text>
|
||||
<Text style={styles.price}>4.700.000 Vnđ</Text>
|
||||
<Text style={styles.oldPrice}>4.700.000 Vnđ</Text>
|
||||
</View>
|
||||
<View style={styles.flexBox}>
|
||||
<Text style={styles.textFlex}>Khuyến mãi:</Text>
|
||||
<Text style={styles.discount}>20%</Text>
|
||||
</View>
|
||||
<View style={styles.flexBox}>
|
||||
<Text style={styles.textFlex}>Giao hàng:</Text>
|
||||
<Text style={styles.ship}>Liên hệ</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{/* Footer tổng tiền */}
|
||||
<View style={styles.totalRow}>
|
||||
<Text style={styles.totalLabel}>Tổng tiền (2 sản phẩm) :</Text>
|
||||
<Text style={styles.totalAmount}>6.000.000 Vnđ</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
export default ListCompare;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxList: {
|
||||
padding: 10,
|
||||
backgroundColor: "#fff",
|
||||
marginTop: 10,
|
||||
borderRadius: 4,
|
||||
},
|
||||
storeBox: {
|
||||
marginBottom: 20,
|
||||
},
|
||||
storeHeader: {
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#e5e7eb",
|
||||
paddingBottom: 12,
|
||||
},
|
||||
logoBox: {
|
||||
width: 90,
|
||||
},
|
||||
logo: {
|
||||
width: 90,
|
||||
height: 32,
|
||||
},
|
||||
headerGrid: {
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
},
|
||||
gridTitle: {
|
||||
width: "12.5%",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
gridTitleTotal: {
|
||||
width: "25%",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
productRow: {
|
||||
paddingVertical: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#e5e7eb",
|
||||
},
|
||||
productName: {
|
||||
width: 200,
|
||||
fontWeight: 700,
|
||||
marginBottom: 10,
|
||||
},
|
||||
productGrid: {},
|
||||
productInfo: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
marginBottom: 10,
|
||||
},
|
||||
infoRow: {
|
||||
width: width - 120,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
productImg: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
borderWidth: 1,
|
||||
borderColor: "#e5e7eb",
|
||||
marginRight: 10,
|
||||
padding: 5,
|
||||
},
|
||||
productTitle: {
|
||||
flex: 1,
|
||||
color: "#111",
|
||||
fontWeight: 700,
|
||||
},
|
||||
oldPrice: {
|
||||
textDecorationLine: "line-through",
|
||||
marginLeft: 5,
|
||||
color: "#f5f5f5",
|
||||
},
|
||||
price: {
|
||||
color: "#ff0000",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
discount: { fontWeight: "bold" },
|
||||
ship: {
|
||||
textDecorationLine: "underline",
|
||||
color: "#33c600",
|
||||
},
|
||||
totalBox: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
total: {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
buyNowBtn: {
|
||||
backgroundColor: "#2563eb",
|
||||
borderRadius: 6,
|
||||
width: 80,
|
||||
height: 32,
|
||||
lineHeight: 32,
|
||||
textAlign: "center",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
buyNowText: {
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
totalRow: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "flex-end",
|
||||
alignItems: "center",
|
||||
marginTop: 20,
|
||||
},
|
||||
totalLabel: {
|
||||
fontWeight: "bold",
|
||||
marginRight: 10,
|
||||
},
|
||||
totalAmount: {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
flexBox: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 5,
|
||||
},
|
||||
textFlex: {
|
||||
width: 100,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user