upload 09/08

This commit is contained in:
2025-08-09 11:19:34 +07:00
parent 1d804ed722
commit 3d36ac17dd
23 changed files with 1051 additions and 6 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
assets/images/icon_cert.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 905 B

After

Width:  |  Height:  |  Size: 485 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

View File

@@ -10,8 +10,7 @@ import {
} from "react-native"; } from "react-native";
import { globalStyles } from "../../styles/globalStyles"; import { globalStyles } from "../../styles/globalStyles";
var winWidth = Dimensions.get("window").width; //full width const { width } = Dimensions.get("window");
var winHeight = Dimensions.get("window").height;
const ItemProductSave = ({ product }: { product: any }) => { const ItemProductSave = ({ product }: { product: any }) => {
function formatCurrency(a: number | string): string { function formatCurrency(a: number | string): string {
@@ -75,7 +74,7 @@ const ItemProductSave = ({ product }: { product: any }) => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
productItem: { productItem: {
width: winWidth / 2 - 15, width: width / 2 - 20,
}, },
productImage: { productImage: {
width: "100%", width: "100%",

View File

@@ -0,0 +1,389 @@
import React from "react";
import { View, Text, Image, StyleSheet } from "react-native";
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
import Feather from "@expo/vector-icons/Feather";
import Ionicons from "@expo/vector-icons/Ionicons";
interface ServiceProviderCardProps {
name: string;
backgroundImage: any;
favoriteIcon: any;
verifiedIcon?: any;
specialties: string[];
address: string;
phone: string;
website: string;
certifications: Array<{
icon: any;
name: string;
color?: string;
}>;
rating: string;
rate: number;
reviewCount: string;
showroomCount?: string;
isVerified?: boolean;
}
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 const ServiceProviderCard: React.FC<ServiceProviderCardProps> = ({
name,
backgroundImage,
favoriteIcon,
verifiedIcon,
specialties,
address,
phone,
website,
certifications,
rating,
rate,
reviewCount,
showroomCount,
isVerified = false,
}) => {
return (
<View style={styles.container}>
<View style={styles.content}>
<View style={styles.imageContainer}>
<Image source={backgroundImage} style={styles.backgroundImage} />
<Image source={favoriteIcon} style={styles.favoriteIcon} />
</View>
<View style={styles.nameContainer}>
<Text style={styles.name}>{name}</Text>
{verifiedIcon && (
<Image source={verifiedIcon} style={styles.verifiedIcon} />
)}
</View>
<View style={styles.specialtiesContainer}>
<View style={styles.specialtyRow}>
<View style={styles.bgspecialtyIcon}>
<Image
source={require("../../../assets/images/icon_store_blue.png")}
style={styles.specialtyIcon}
/>
</View>
<Text style={styles.specialtyText}>Chuyên sửa chữa</Text>
</View>
{specialties.map((specialty, index) => (
<View key={index} style={styles.tag}>
<Text style={styles.tagText}>{specialty}</Text>
</View>
))}
</View>
<View style={styles.infoRow}>
<Image
source={require("../../../assets/images/icon_location.png")}
style={styles.mapIcon}
/>
<Text style={styles.infoText}>{address}</Text>
</View>
<View style={styles.infoRow}>
<Image
source={require("../../../assets/images/icon_map.png")}
style={styles.mapIcon}
/>
<Text style={styles.mapText}>Google Maps</Text>
<Image
source={require("../../../assets/images/icon_showroom_blue.png")}
style={styles.showroomIcon}
/>
{showroomCount && (
<Text style={styles.showroomText}>{showroomCount}</Text>
)}
</View>
<View style={styles.infoRow}>
<Feather name="phone" size={14} color="black" />
<Text style={styles.infoText}>{phone}</Text>
</View>
<View style={styles.infoRow}>
<MaterialCommunityIcons name="web" size={14} color="black" />
<Text style={styles.websiteText}>
<Text style={styles.websiteLabel}>Website: </Text>
{website}
</Text>
</View>
{certifications.map((cert, index) => (
<View
key={index}
style={[styles.certificationBadge, { backgroundColor: cert.color }]}
>
<Image source={cert.icon} style={styles.certIcon} />
<Text style={styles.certText}>{cert.name}</Text>
</View>
))}
<View style={styles.certificationBadge}>
<Ionicons name="time-outline" size={14} color="black" />
<Text style={{ color: "#000" }}>Hoạt đng từ 2020</Text>
</View>
<View style={styles.ratingContainer}>
{renderStars(rate)}
<Text style={styles.rating}>{rating} </Text>
<Text style={styles.reviewCount}>({reviewCount})</Text>
<Text style={styles.reviewLabel}>Đánh giá</Text>
</View>
</View>
<View style={styles.contactButton}>
<Text style={styles.contactText}>Liên hệ</Text>
<Image
source={require("../../../assets/images/icon-export-link.png")}
style={styles.contactIcon}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
borderWidth: 1,
borderColor: "rgba(240, 240, 240, 1)",
paddingVertical: 8,
flex: 1,
},
content: {
paddingHorizontal: 6,
},
imageContainer: {
position: "relative",
aspectRatio: 1.757,
paddingTop: 2,
paddingHorizontal: 36,
paddingBottom: 77,
},
backgroundImage: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
width: "100%",
height: "100%",
resizeMode: "cover",
},
favoriteIcon: {
width: 13.71,
height: 12.58,
resizeMode: "contain",
position: "absolute",
right: 10,
top: 10,
backgroundColor: "#EFEFEF",
borderRadius: "50%",
padding: 5,
},
nameContainer: {
flexDirection: "row",
alignItems: "center",
gap: 6,
marginTop: 4,
},
name: {
fontSize: 15,
fontWeight: "700",
color: "#303030",
},
verifiedIcon: {
width: 11,
height: 11,
resizeMode: "contain",
},
specialtiesContainer: {
flexDirection: "row",
flexWrap: "wrap",
alignItems: "center",
gap: 5,
marginTop: 5,
},
specialtyRow: {
flexDirection: "row",
alignItems: "center",
gap: 4,
},
specialtyIcon: {
width: 13,
height: 13,
resizeMode: "contain",
},
bgspecialtyIcon: {
padding: 3,
backgroundColor: "#e0ecff",
borderRadius: "50%",
},
specialtyText: {
fontSize: 12,
fontWeight: "400",
color: "#303030",
},
specialtyTag: {
borderRadius: 233,
backgroundColor: "rgba(0, 0, 0, 0.1)",
paddingVertical: 5,
paddingHorizontal: 12,
alignItems: "center",
justifyContent: "center",
},
specialtyTagText: {
fontSize: 12,
fontWeight: "400",
color: "rgba(0, 0, 0, 1)",
textAlign: "center",
},
tagsContainer: {
flexDirection: "row",
gap: 5,
marginTop: 5,
},
tag: {
borderRadius: 222,
backgroundColor: "#F5E3FF",
paddingVertical: 5,
paddingHorizontal: 12,
alignItems: "center",
justifyContent: "center",
},
tagText: {
fontSize: 12,
fontWeight: "500",
color: "rgba(0, 0, 0, 1)",
textAlign: "center",
},
infoRow: {
flexDirection: "row",
alignItems: "flex-start",
gap: 4,
marginTop: 6,
},
infoIcon: {
width: 16,
height: 16,
resizeMode: "contain",
},
infoText: {
fontSize: 12,
fontWeight: "400",
color: "#303030",
lineHeight: 15,
flex: 1,
},
mapIcon: {
width: 11,
height: 16,
resizeMode: "contain",
},
mapText: {
fontSize: 10,
fontWeight: "400",
color: "#FF7A00",
},
showroomIcon: {
width: 17,
height: 17,
resizeMode: "contain",
},
showroomText: {
fontSize: 10,
fontWeight: "700",
color: "rgba(24, 119, 242, 1)",
textDecorationLine: "underline",
},
websiteText: {
fontSize: 12,
fontWeight: "400",
color: "#303030",
flex: 1,
},
websiteLabel: {
color: "rgba(48,48,48,1)",
},
certificationBadge: {
flexDirection: "row",
alignItems: "center",
gap: 4,
borderRadius: 333,
backgroundColor: "#f4f4f4",
color: "#fff",
paddingVertical: 6,
paddingHorizontal: 13,
marginTop: 6,
},
certIcon: {
width: 16,
height: 16,
resizeMode: "contain",
},
certText: {
fontSize: 12,
fontWeight: "400",
color: "rgba(255, 122, 0, 1)",
},
ratingContainer: {
flexDirection: "row",
alignItems: "center",
gap: 4,
alignSelf: "center",
marginTop: 6,
},
rating: {
fontSize: 12,
fontWeight: "400",
color: "rgba(0, 0, 0, 1)",
flex: 1,
},
reviewCount: {
fontSize: 12,
fontWeight: "500",
color: "#303030",
textAlign: "right",
},
reviewLabel: {
fontSize: 12,
fontWeight: "500",
color: "#303030",
textAlign: "right",
textDecorationLine: "underline",
},
contactButton: {
flexDirection: "row",
alignItems: "center",
gap: 4,
marginTop: 9,
marginLeft: 10,
},
contactText: {
fontSize: 12,
fontWeight: "700",
color: "rgba(70, 47, 145, 1)",
textAlign: "left",
textDecorationLine: "underline",
},
contactIcon: {
width: 16,
height: 16,
resizeMode: "contain",
},
});

View File

@@ -11,6 +11,7 @@ import CompareBuildpc from "../screens/buildpc/CompareBuildpc";
import BuildpcDeail from "../screens/buildpc/BuildpcDetail"; import BuildpcDeail from "../screens/buildpc/BuildpcDetail";
import HomeShop from "../screens/shop/HomeShop"; import HomeShop from "../screens/shop/HomeShop";
import DetailShop from "../screens/shop/DetailShop"; import DetailShop from "../screens/shop/DetailShop";
import HomeRepairAddress from "../screens/repair_address/HomeRepairAddress";
const Stack = createStackNavigator(); const Stack = createStackNavigator();
@@ -27,9 +28,9 @@ const AppNavigator: React.FC = () => {
<Stack.Screen name="buildpc" component={Buildpc} /> <Stack.Screen name="buildpc" component={Buildpc} />
<Stack.Screen name="comparebuildpc" component={CompareBuildpc} /> <Stack.Screen name="comparebuildpc" component={CompareBuildpc} />
<Stack.Screen name="buildpcdetail" component={BuildpcDeail} /> <Stack.Screen name="buildpcdetail" component={BuildpcDeail} />
<Stack.Screen name="classifieds" component={BuildpcDeail} /> <Stack.Screen name="classifieds" component={HomeShop} />
<Stack.Screen name="homeshop" component={HomeShop} />
<Stack.Screen name="detailshop" component={DetailShop} /> <Stack.Screen name="detailshop" component={DetailShop} />
<Stack.Screen name="repairaddress" component={HomeRepairAddress} />
</Stack.Navigator> </Stack.Navigator>
); );
}; };

View File

@@ -133,7 +133,7 @@ const BoxMenuHome = () => {
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={styles.MenuItem} style={styles.MenuItem}
onPress={() => navigation.navigate("homeshop" as never)} onPress={() => navigation.navigate("repairaddress" as never)}
> >
<View style={styles.boxIconMenu}> <View style={styles.boxIconMenu}>
<Image <Image

View File

@@ -0,0 +1,116 @@
import React from "react";
import { View, Text, StyleSheet } from "react-native";
interface CategoryButtonProps {
title: string;
isSelected?: boolean;
}
const CategoryButton: React.FC<CategoryButtonProps> = ({
title,
isSelected = false,
}) => {
return (
<View
style={[styles.categoryButton, isSelected && styles.selectedCategory]}
>
<Text
style={[styles.categoryText, isSelected && styles.selectedCategoryText]}
>
{title}
</Text>
</View>
);
};
export default function CategoryFilters() {
const categories = [
{ title: "Máy tính xách tay", selected: true },
{ title: "Màn hình", selected: false },
{ title: "Macbook", selected: false },
{ title: "PC", selected: false },
{ title: "Cài phần mềm", selected: false },
{ title: "Máy in", selected: false },
{ title: "Điện thoại di động", selected: false },
{ title: "Máy photocopy", selected: false },
{ title: "Máy chiếu", selected: false },
{ title: "Ổ cứng", selected: false },
{ title: "Nâng cấp", selected: false },
];
return (
<View style={styles.container}>
<Text style={styles.title}>Tìm theo nhu cầu</Text>
<View style={styles.secondRow}>
{categories.map((item) => (
<CategoryButton title={item.title} isSelected={item.selected} />
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
borderRadius: 4,
borderWidth: 1,
borderColor: "rgba(240, 240, 240, 1)",
paddingTop: 13,
paddingHorizontal: 14,
paddingBottom: 24,
marginTop: 12,
},
title: {
fontSize: 20,
fontWeight: "700",
color: "rgba(0, 0, 0, 1)",
textAlign: "center",
},
firstRow: {
flexDirection: "row",
gap: 8,
marginTop: 12,
marginHorizontal: 20,
},
secondRow: {
flexDirection: "row",
flexWrap: "wrap",
gap: 5,
marginTop: 12,
},
leftColumn: {
flex: 1,
},
rightColumn: {
flex: 1,
},
row: {
flexDirection: "row",
gap: 8,
marginBottom: 12,
},
categoryButton: {
borderRadius: 23,
borderWidth: 1,
borderColor: "rgba(227, 227, 227, 1)",
paddingVertical: 5,
paddingHorizontal: 9,
alignItems: "center",
justifyContent: "center",
minHeight: 24,
},
selectedCategory: {
backgroundColor: "#F6F3FF",
borderColor: "#462F91",
},
categoryText: {
fontSize: 13,
fontWeight: "400",
color: "rgba(89, 89, 89, 1)",
textAlign: "center",
lineHeight: 23,
},
selectedCategoryText: {
color: "#462F91",
},
});

View File

@@ -0,0 +1,110 @@
import React from "react";
import { View, Text, Image, StyleSheet, TextInput } from "react-native";
const ContactForm: React.FC = () => {
return (
<View style={styles.container}>
<View style={styles.headerSection}>
<Image
source={require("../../../assets/images/image-contact.png")}
style={styles.backgroundImage}
/>
<Text style={styles.title}>Liên hệ với chúng tôi </Text>
<Text style={styles.subtitle}>
Bạn cung cấp dịch vụ sửa chữa muốn niêm yết
</Text>
</View>
<View style={styles.formSection}>
<TextInput style={styles.inputField} placeholder="Họ và tên" />
<TextInput style={styles.inputField} placeholder="Số điện thoại" />
<TextInput
style={styles.inputField}
placeholder="Nội dung cần tư vấn"
/>
<View style={styles.submitButton}>
<Text style={styles.submitText}>Đăng </Text>
</View>
</View>
</View>
);
};
export default ContactForm;
const styles = StyleSheet.create({
container: {
marginTop: 56,
},
headerSection: {
position: "relative",
aspectRatio: 1.903,
alignItems: "center",
justifyContent: "center",
paddingVertical: 73,
paddingHorizontal: 77,
},
backgroundImage: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
width: "100%",
height: "100%",
resizeMode: "cover",
},
title: {
fontSize: 20,
fontWeight: "700",
color: "rgba(255, 255, 255, 1)",
textAlign: "center",
zIndex: 1,
},
subtitle: {
fontSize: 16,
fontWeight: "400",
color: "rgba(255, 255, 255, 1)",
textAlign: "center",
marginTop: 7,
zIndex: 1,
},
formSection: {
padding: 12,
},
inputField: {
borderWidth: 1,
borderColor: "rgba(214, 214, 214, 1)",
paddingVertical: 10,
paddingHorizontal: 16,
marginBottom: 8,
justifyContent: "center",
},
textAreaField: {
borderWidth: 1,
borderColor: "rgba(214, 214, 214, 1)",
paddingTop: 10,
paddingHorizontal: 16,
paddingBottom: 40,
marginBottom: 8,
},
inputLabel: {
fontSize: 13,
fontWeight: "400",
color: "rgba(178, 178, 178, 1)",
},
submitButton: {
backgroundColor: "#462F91",
alignItems: "center",
justifyContent: "center",
minHeight: 40,
paddingHorizontal: 24,
paddingBottom: 1,
},
submitText: {
fontSize: 14,
fontWeight: "700",
color: "rgba(255, 255, 255, 1)",
textAlign: "center",
},
});

View File

@@ -0,0 +1,205 @@
import React, { useState } from "react";
import {
View,
Text,
TextInput,
TouchableOpacity,
ScrollView,
Image,
StyleSheet,
Dimensions,
ImageBackground,
} from "react-native";
import { useNavigation, NavigationProp } from "@react-navigation/native";
import AppLayout from "@layouts/AppLayout";
import { Ionicons } from "@expo/vector-icons";
import Feather from "@expo/vector-icons/Feather";
import { url } from "inspector";
import CategoryFilters from "@screens/repair_address/CategoryFilters";
import LocationFilters from "@screens/repair_address/LocationFilters";
import ServiceProviderList from "@screens/repair_address/ServiceProviderList";
import ContactForm from "@screens/repair_address/ContactForm";
const { width } = Dimensions.get("window");
export default function HomeRepairAddress() {
const navigation = useNavigation<NavigationProp<any>>();
return (
<AppLayout activeTab="repairaddress">
<ScrollView>
<View style={styles.container}>
{/* 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}>Đa chỉ sửa chữa</Text>
</View>
</View>
<ImageBackground
source={require("../../../assets/images/backgroundSearch.png")}
style={styles.bgSearch}
resizeMode="cover"
>
<Text style={styles.titleSearch}>
Tìm đa chỉ sửa chữa máy tính, điện thoại
</Text>
<View style={styles.flexSearch}>
<View style={styles.searchBox}>
<TextInput
style={styles.input}
placeholder="Nhập địa chỉ của bạn để tìm địa chỉ.."
/>
<Ionicons
name="search"
size={18}
color="black"
style={styles.iconSearch}
/>
</View>
<TouchableOpacity style={styles.btnFilter}>
<Feather
name="filter"
size={24}
color="black"
style={{ marginTop: 3 }}
/>
</TouchableOpacity>
</View>
<Text style={styles.noteSearch}>
BestPC tổng hợp các đa chỉ sửa chữa máy tính, linh phụ kiện,
thiết bị điện tử,... khắp nơi tại Việt Nam. Nhằm giúp bạn tìm đưc
đa chỉ uy tín đ sửa chữa
</Text>
</ImageBackground>
{/* search */}
<CategoryFilters />
{/* tim theo nhu cau */}
<LocationFilters />
{/* tìm theo tỉnh thành */}
<ServiceProviderList />
{/* địa chỉ nổi bật */}
<ContactForm />
{/* form liên hệ */}
</View>
</ScrollView>
</AppLayout>
);
}
const styles = StyleSheet.create({
container: {
paddingHorizontal: 10,
backgroundColor: "#fff",
},
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",
},
searchBox: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
backgroundColor: "white",
borderRadius: 4,
paddingHorizontal: 10,
gap: 20,
width: width - 90,
},
flexSearch: {
flexDirection: "row",
alignItems: "center",
width: "100%",
},
btnFilter: {
width: 40,
height: 35,
backgroundColor: "#fff",
borderRadius: 8,
marginLeft: 10,
textAlign: "center",
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
lineHeight: 35,
},
placeholder: {
fontSize: 12,
fontWeight: "500",
color: "rgba(169, 169, 169, 1)",
fontFamily: "Roboto",
lineHeight: 21,
},
rightSection: {
flexDirection: "row",
alignItems: "center",
gap: 9,
},
divider: {
width: 1,
height: 20,
backgroundColor: "rgba(179, 179, 179, 1)",
},
searchIcon: {
width: 16,
height: 16,
resizeMode: "contain",
},
bgSearch: {
width: "100%",
padding: 10,
paddingTop: 20,
paddingBottom: 20,
},
titleSearch: {
fontSize: 18,
textAlign: "center",
color: "#fff",
fontWeight: 700,
paddingBottom: 7,
},
noteSearch: {
textAlign: "center",
color: "#fff",
paddingTop: 7,
},
iconSearch: {
width: 24,
paddingLeft: 10,
},
input: {
width: width - 14,
outlineWidth: 0,
height: 35,
},
});

View File

@@ -0,0 +1,126 @@
import React from "react";
import { View, Text, Image, StyleSheet, Dimensions } from "react-native";
const { width } = Dimensions.get("window");
interface LocationButtonProps {
title: string;
}
const LocationButton: React.FC<LocationButtonProps> = ({ title }) => {
return (
<View style={styles.locationButton}>
<Image
source={require("../../../assets/images/icon-map-2.png")}
style={styles.locationIcon}
/>
<Text style={styles.locationText}>{title}</Text>
</View>
);
};
export default function LocationFilters() {
const locations = [
{
title: "Hà Nội",
},
{
title: "TP.HCM",
},
{
title: "Hải Phòng",
},
{
title: "Huế",
},
{
title: "Đà Nẵng",
},
{
title: "Cần Thơ",
},
{
title: "Quảng Ninh",
},
{
title: "Cao Bằng",
},
{
title: "Lào Cai",
},
{
title: "Sơn La",
},
{
title: "Lạng Sơn",
},
{
title: "Hưng Yên",
},
{
title: "Ninh Bình",
},
{
title: "Hà Tĩnh",
},
{
title: "Thanh Hoá",
},
];
return (
<View style={styles.container}>
<Text style={styles.title}>Tìm theo tỉnh thành</Text>
<View style={styles.locationRow}>
{locations.map((location, index) => (
<LocationButton key={index} title={location.title} />
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
borderRadius: 4,
borderWidth: 1,
borderColor: "rgba(240, 240, 240, 1)",
paddingTop: 12,
paddingHorizontal: 10,
paddingBottom: 21,
marginTop: 12,
},
title: {
fontSize: 20,
fontWeight: "700",
color: "rgba(0, 0, 0, 1)",
textAlign: "center",
},
locationRow: {
flexDirection: "row",
flexWrap: "wrap",
gap: 8,
marginTop: 8,
},
locationButton: {
flexDirection: "row",
alignItems: "center",
gap: 5,
borderRadius: 4,
borderWidth: 1,
borderColor: "rgba(227, 227, 227, 1)",
padding: 5,
minHeight: 32,
width: width / 3 - 20,
},
locationIcon: {
width: 20,
height: 20,
resizeMode: "contain",
},
locationText: {
fontSize: 13,
fontWeight: "400",
color: "rgba(89, 89, 89, 1)",
textAlign: "center",
},
});

View File

@@ -0,0 +1,94 @@
import React from "react";
import { View, Text, Image, ScrollView, StyleSheet } from "react-native";
import { ServiceProviderCard } from "@components/repair/ServiceProviderCard";
const ServiceProviderList: React.FC = () => {
const providers = [
{
name: "Gearvn.com",
backgroundImage: require("../../../assets/images/showroom_gearvn.png"),
favoriteIcon: require("../../../assets/images/icon_heart.png"),
verifiedIcon: require("../../../assets/images/verifiedIcon.png"),
specialties: ["Laptop", "Phụ kiện", "+3 Khác"],
address:
"Địa chỉ: Tầng 7, toà nhà số 198 Nguyễn Thị Minh Khai, phường 6, quận 3, TP. Hồ Chí Minh",
phone: "Tel: 1800 6867 - 1800 6865",
website: "https:/ CP.com.vn/",
certifications: [
{
icon: require("../../../assets/images/icon_cert.png"),
name: "CompTIA A+",
color: "#fff8ee",
},
{
icon: require("../../../assets/images/icon_cert.png"),
name: "CompTIA Network+",
color: "#fff8ee",
},
],
rate: 4,
rating: "4.6",
reviewCount: "26",
showroomCount: "Có 7 showroom",
isVerified: true,
},
{
name: "Hoanglongcomputer",
backgroundImage: require("../../../assets/images/showroom_hoanglong.png"),
favoriteIcon: require("../../../assets/images/icon_heart.png"),
specialties: ["Laptop", "Phụ kiện", "+3 Khác"],
address:
"Địa chỉ: Tầng 7, toà nhà số 198 Nguyễn Thị Minh Khai, phường 6, quận 3, TP. Hồ Chí Minh",
phone: "Tel: 1800 6867 - 1800 6865",
website: "https:/ CP.com.vn/",
certifications: [
{
icon: require("../../../assets/images/icon_cert.png"),
name: "CompTIA A+",
color: "#fff8ee",
},
{
icon: require("../../../assets/images/icon_cert.png"),
name: "CompTIA Network+",
color: "#fff8ee",
},
],
rate: 5,
rating: "4.6",
reviewCount: "26",
showroomCount: "Có 7 showroom",
},
];
return (
<View style={styles.providersContainer}>
<Text style={styles.sectionTitle}>Đa chỉ nổi bật</Text>
<View style={styles.providerRow}>
{providers.map((provider, index) => (
<ServiceProviderCard key={index} {...provider} />
))}
</View>
</View>
);
};
export default ServiceProviderList;
const styles = StyleSheet.create({
providersContainer: {
marginTop: 16,
},
sectionTitle: {
fontSize: 20,
fontWeight: "700",
color: "rgba(0, 0, 0, 1)",
textAlign: "center",
marginBottom: 8,
},
providerRow: {
flexDirection: "row",
flexWrap: "wrap",
gap: 10,
marginBottom: 10,
},
});

View File

@@ -8,6 +8,7 @@ import {
Image, Image,
StyleSheet, StyleSheet,
Dimensions, Dimensions,
Linking,
} from "react-native"; } from "react-native";
import { useNavigation, NavigationProp } from "@react-navigation/native"; import { useNavigation, NavigationProp } from "@react-navigation/native";
import AppLayout from "@layouts/AppLayout"; import AppLayout from "@layouts/AppLayout";
@@ -22,6 +23,10 @@ const { width } = Dimensions.get("window");
export default function DetailShop() { export default function DetailShop() {
const navigation = useNavigation<NavigationProp<any>>(); const navigation = useNavigation<NavigationProp<any>>();
const openLink = (url: string) => {
Linking.openURL(url).catch((err) => console.error("Lỗi mở link:", err));
};
return ( return (
<AppLayout activeTab="detailshop"> <AppLayout activeTab="detailshop">
<ScrollView> <ScrollView>