From cc29aaabb4c59eb3eae793a6da49660843928ef3 Mon Sep 17 00:00:00 2001 From: Tieptk Date: Mon, 21 Jul 2025 09:00:48 +0700 Subject: [PATCH] update --- src/components/buildpc/CreateBuildpc.tsx | 126 +++++++- src/components/buildpc/ImageGallery.tsx | 115 +++++++ src/components/buildpc/PopupBuildpc.tsx | 376 ++++++++++++++++++----- src/components/buildpc/ProductSpecs.tsx | 84 +++++ src/components/buildpc/ProvidersList.tsx | 140 +++++++++ src/components/buildpc/ReviewList.tsx | 175 +++++++++++ src/navigation/AppNavigator.tsx | 4 + src/screens/buildpc/Buildpc.tsx | 133 ++++---- src/screens/buildpc/BuildpcDetail.tsx | 126 ++++++++ src/screens/buildpc/CompareBuildpc.tsx | 210 +++++++++++++ src/screens/buildpc/ListCompare.tsx | 216 +++++++++++++ 11 files changed, 1565 insertions(+), 140 deletions(-) create mode 100644 src/components/buildpc/ImageGallery.tsx create mode 100644 src/components/buildpc/ProductSpecs.tsx create mode 100644 src/components/buildpc/ProvidersList.tsx create mode 100644 src/components/buildpc/ReviewList.tsx create mode 100644 src/screens/buildpc/BuildpcDetail.tsx create mode 100644 src/screens/buildpc/CompareBuildpc.tsx create mode 100644 src/screens/buildpc/ListCompare.tsx diff --git a/src/components/buildpc/CreateBuildpc.tsx b/src/components/buildpc/CreateBuildpc.tsx index 6f84e0a..f974e12 100644 --- a/src/components/buildpc/CreateBuildpc.tsx +++ b/src/components/buildpc/CreateBuildpc.tsx @@ -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>(); + const [showPopup, setShowPopup] = useState(false); return ( @@ -30,14 +33,17 @@ export function CreateBuildpc() { style={styles.productImage} resizeMode="contain" /> - + navigation?.navigate("buildpcdetail")} + > AMD Ryzen 7 9800x3D 4.7 GHz 8-Core Processor Số lượng + {/* Thêm lựa chọn CPU */} + setShowPopup(true)} + > + + Chọn thêm CPU + - {/* Thêm lựa chọn CPU */} - setShowPopup(true)} - > - + Chọn thêm CPU - + + {/* Item CPU */} + + CPU + + + + + navigation?.navigate("buildpcdetail")} + > + AMD Ryzen 7 9800x3D 4.7 GHz 8-Core Processor + + + + Số lượng + + + + Giá bán: + 4.700.000 Vnđ + + + Khuyến mãi: + 20% + + + Thành tiền: + 4.000.000đ + + + + Nhà cung cấp + + + + + + + + + + + + + + {/* Thêm lựa chọn CPU */} + setShowPopup(true)} + > + + Chọn thêm CPU + + + + {/* item gcu */} + + + CPU + {/* Thêm lựa chọn CPU */} + setShowPopup(true)} + > + + Chọn sản phẩm + + + {/* Tổng tiền */} Tổng tiền 2 sản phẩm: 8.000.000đ @@ -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, diff --git a/src/components/buildpc/ImageGallery.tsx b/src/components/buildpc/ImageGallery.tsx new file mode 100644 index 0000000..9f70caf --- /dev/null +++ b/src/components/buildpc/ImageGallery.tsx @@ -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>(null); + const thumbnailListRef = useRef(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 }) => ( + onThumbnailPress(index)}> + + + ), + [activeIndex, onThumbnailPress] + ); + + return ( + + ( + + )} + onSnapToItem={onSnapToItem} + /> + + i.toString()} + renderItem={renderThumbnail} + showsHorizontalScrollIndicator={false} + contentContainerStyle={styles.thumbList} + /> + + ); +}; + +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: {}, +}); diff --git a/src/components/buildpc/PopupBuildpc.tsx b/src/components/buildpc/PopupBuildpc.tsx index 1e33547..4332642 100644 --- a/src/components/buildpc/PopupBuildpc.tsx +++ b/src/components/buildpc/PopupBuildpc.tsx @@ -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"), + }); + + const [selectedAddress, setSelectedAddress] = useState(""); + const [selectedBrand, setSelectedBrand] = useState(""); + + const renderStars = (count: number) => { + return ( + + {Array.from({ length: 5 }).map((_, index) => ( + + ))} + + ); + }; -export default function PopupBuildpc({ visible, onClose }: PopupBuildpcProps) { return ( - - - - {/* Close button */} - - - - - Chọn linh kiện thay thế - - {/* List of products (giả lập) */} - - {[1, 2, 3].map((item) => ( - - Linh kiện {item} - - Chọn - - - ))} - + + + + + + Chọn linh kiện + + + + + + + + + + + + + + 230 sản phẩm + + Chọn tất cả + Bỏ chọn tất cả + So sánh sản phẩm đã chọn + + + + Bộ lọc + + + + + + + + + + + index.toString()} + style={styles.productList} + renderItem={({ item }) => ( + + + + + {item.name} + + {item.price} + + + Dung lượng: + + {item.capacity} + + + + Độ òn + + {item.generation} + + + + Thế hệ + + {item.memory} + + + + Màu sắc + + {item.color} + + + + Bộ nhớ + + {item.noise} + + + + + + + Đánh giá + {renderStars(item.rating)} + + ({item.reviews}) + + + + + + Add + + + )} + /> + + + ); } +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", }, }); diff --git a/src/components/buildpc/ProductSpecs.tsx b/src/components/buildpc/ProductSpecs.tsx new file mode 100644 index 0000000..3821da3 --- /dev/null +++ b/src/components/buildpc/ProductSpecs.tsx @@ -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 ( + + Thông số kỹ thuật + index.toString()} + renderItem={({ item, index }) => ( + + {item.key} + {Array.isArray(item.value) ? ( + + {item.value.map((v, i) => ( + + {v} + + ))} + + ) : ( + {item.value} + )} + + )} + /> + + ); +} +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, + }, +}); diff --git a/src/components/buildpc/ProvidersList.tsx b/src/components/buildpc/ProvidersList.tsx new file mode 100644 index 0000000..a875323 --- /dev/null +++ b/src/components/buildpc/ProvidersList.tsx @@ -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 ( + + {providers.map((p, i) => ( + + + + + Mua ngay + + + + + Giá sản phẩm: + 4.700.000 Vnđ + 4.700.000 Vnđ + + + Khuyến mãi: + 20% + + + Giao hàng: + Liên hệ + + + ))} + + ); +} +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, + }, +}); diff --git a/src/components/buildpc/ReviewList.tsx b/src/components/buildpc/ReviewList.tsx new file mode 100644 index 0000000..422bb66 --- /dev/null +++ b/src/components/buildpc/ReviewList.tsx @@ -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 ( + + {Array.from({ length: 5 }).map((_, index) => ( + + ))} + + ); +}; + +export default function ReviewList() { + return ( + + {/* Header */} + + Đánh giá + + + {/* List */} + item.id.toString()} + renderItem={({ item }) => ( + + + + {item.name} + {item.time} + {renderStars(4)} + + + {item.content} + + + {item.views} + + + + + + {item.comments} + + + + + + + + )} + /> + + Xem tất cả bình luận + + + ); +} + +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, + }, +}); diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx index 820cbab..811fe89 100644 --- a/src/navigation/AppNavigator.tsx +++ b/src/navigation/AppNavigator.tsx @@ -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 = () => { + + ); }; diff --git a/src/screens/buildpc/Buildpc.tsx b/src/screens/buildpc/Buildpc.tsx index 99d590b..292c60b 100644 --- a/src/screens/buildpc/Buildpc.tsx +++ b/src/screens/buildpc/Buildpc.tsx @@ -8,79 +8,91 @@ 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>(); return ( - - {/* Breadcrumb */} - - - - + + + {/* Breadcrumb */} + + + + + + + + + Tạo máy tính riêng của bạn + + + + {/* Buttons Bắt đầu/So sánh */} + + navigation?.navigate("buildpc")} + > + Bắt đầu tạo + + navigation?.navigate("comparebuildpc")} + > + + So sánh giá tại các cửa hàng + - - - Tạo máy tính riêng của bạn + + {/* Action Bar */} + + {/* Share link */} + + + + + + {/* Đặt tên */} + + Đặt tên: + + + + {/* Buttons */} + + + + + + + {/* Buildpc Content */} + - - {/* Buttons Bắt đầu/So sánh */} - - - Bắt đầu tạo - - - - So sánh giá tại các cửa hàng - - - - - {/* Action Bar */} - - {/* Share link */} - - - - - - {/* Đặt tên */} - - Đặt tên: - - - - {/* Buttons */} - - - - - - - - {/* Buildpc Content */} - +