demo app hanoicomputer home category productdetail cart
This commit is contained in:
108
components/EditScreenInfo.tsx
Normal file
108
components/EditScreenInfo.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import * as WebBrowser from 'expo-web-browser';
|
||||
import React from 'react';
|
||||
import { StyleSheet, TouchableOpacity } from 'react-native';
|
||||
|
||||
import Colors from '../constants/Colors';
|
||||
import { MonoText } from './StyledText';
|
||||
import { Text, View } from './Themed';
|
||||
|
||||
export default function EditScreenInfo({ path }: { path: string }) {
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.getStartedContainer}>
|
||||
<Text
|
||||
style={styles.getStartedText}
|
||||
lightColor="rgba(0,0,0,0.8)"
|
||||
darkColor="rgba(255,255,255,0.8)">
|
||||
Open up the code for this screen:
|
||||
</Text>
|
||||
|
||||
<View
|
||||
style={[styles.codeHighlightContainer, styles.homeScreenFilename]}
|
||||
darkColor="rgba(255,255,255,0.05)"
|
||||
lightColor="rgba(0,0,0,0.05)">
|
||||
<MonoText>{path}</MonoText>
|
||||
</View>
|
||||
|
||||
<Text
|
||||
style={styles.getStartedText}
|
||||
lightColor="rgba(0,0,0,0.8)"
|
||||
darkColor="rgba(255,255,255,0.8)">
|
||||
Change any of the text, save the file, and your app will automatically update.
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.helpContainer}>
|
||||
<TouchableOpacity onPress={handleHelpPress} style={styles.helpLink}>
|
||||
<Text style={styles.helpLinkText} lightColor={Colors.light.tint}>
|
||||
Tap here if your app doesn't automatically update after making changes
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
function handleHelpPress() {
|
||||
WebBrowser.openBrowserAsync(
|
||||
'https://docs.expo.io/get-started/create-a-new-app/#opening-the-app-on-your-phonetablet'
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
developmentModeText: {
|
||||
marginBottom: 20,
|
||||
fontSize: 14,
|
||||
lineHeight: 19,
|
||||
textAlign: 'center',
|
||||
},
|
||||
contentContainer: {
|
||||
paddingTop: 30,
|
||||
},
|
||||
welcomeContainer: {
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
marginBottom: 20,
|
||||
},
|
||||
welcomeImage: {
|
||||
width: 100,
|
||||
height: 80,
|
||||
resizeMode: 'contain',
|
||||
marginTop: 3,
|
||||
marginLeft: -10,
|
||||
},
|
||||
getStartedContainer: {
|
||||
alignItems: 'center',
|
||||
marginHorizontal: 50,
|
||||
},
|
||||
homeScreenFilename: {
|
||||
marginVertical: 7,
|
||||
},
|
||||
codeHighlightText: {
|
||||
color: 'rgba(96,100,109, 0.8)',
|
||||
},
|
||||
codeHighlightContainer: {
|
||||
borderRadius: 3,
|
||||
paddingHorizontal: 4,
|
||||
},
|
||||
getStartedText: {
|
||||
fontSize: 17,
|
||||
lineHeight: 24,
|
||||
textAlign: 'center',
|
||||
},
|
||||
helpContainer: {
|
||||
marginTop: 15,
|
||||
marginHorizontal: 20,
|
||||
alignItems: 'center',
|
||||
},
|
||||
helpLink: {
|
||||
paddingVertical: 15,
|
||||
},
|
||||
helpLinkText: {
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
7
components/StyledText.tsx
Normal file
7
components/StyledText.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Text, TextProps } from './Themed';
|
||||
|
||||
export function MonoText(props: TextProps) {
|
||||
return <Text {...props} style={[props.style, { fontFamily: 'space-mono' }]} />;
|
||||
}
|
||||
41
components/Themed.tsx
Normal file
41
components/Themed.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import * as React from 'react';
|
||||
import { Text as DefaultText, View as DefaultView } from 'react-native';
|
||||
|
||||
import Colors from '../constants/Colors';
|
||||
import useColorScheme from '../hooks/useColorScheme';
|
||||
|
||||
export function useThemeColor(
|
||||
props: { light?: string; dark?: string },
|
||||
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
|
||||
) {
|
||||
const theme = useColorScheme();
|
||||
const colorFromProps = props[theme];
|
||||
|
||||
if (colorFromProps) {
|
||||
return colorFromProps;
|
||||
} else {
|
||||
return Colors[theme][colorName];
|
||||
}
|
||||
}
|
||||
|
||||
type ThemeProps = {
|
||||
lightColor?: string;
|
||||
darkColor?: string;
|
||||
};
|
||||
|
||||
export type TextProps = ThemeProps & DefaultText['props'];
|
||||
export type ViewProps = ThemeProps & DefaultView['props'];
|
||||
|
||||
export function Text(props: TextProps) {
|
||||
const { style, lightColor, darkColor, ...otherProps } = props;
|
||||
const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
|
||||
|
||||
return <DefaultText style={[{ color }, style]} {...otherProps} />;
|
||||
}
|
||||
|
||||
export function View(props: ViewProps) {
|
||||
const { style, lightColor, darkColor, ...otherProps } = props;
|
||||
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
|
||||
|
||||
return <DefaultView style={[{ backgroundColor }, style]} {...otherProps} />;
|
||||
}
|
||||
10
components/__tests__/StyledText-test.js
Normal file
10
components/__tests__/StyledText-test.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
import { MonoText } from '../StyledText';
|
||||
|
||||
it(`renders correctly`, () => {
|
||||
const tree = renderer.create(<MonoText>Snapshot test!</MonoText>).toJSON();
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
369
components/footer/footerMain.tsx
Normal file
369
components/footer/footerMain.tsx
Normal file
@@ -0,0 +1,369 @@
|
||||
import * as React from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Alert, Button, Image, StyleSheet, Dimensions, SafeAreaView, ScrollView, TouchableOpacity } from 'react-native';
|
||||
import { Text, View, } from '../Themed';
|
||||
import { TextInput } from 'react-native-gesture-handler';
|
||||
import { Ionicons, FontAwesome } from '@expo/vector-icons';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
|
||||
const PolicyFooter = () => {
|
||||
return (
|
||||
<View style={styles.homePolicy}>
|
||||
<LinearGradient colors={['#243a76', '#ed1b24']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.bgLinearGradient}>
|
||||
<Text style={styles.homePolicyTitle}>
|
||||
Chính sách bán hàng
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
<View style={styles.homePolicyList}>
|
||||
<View style={styles.homePolicyItem}>
|
||||
<FontAwesome style={styles.homePolicyIcon} name="truck" size={25} />
|
||||
<View>
|
||||
<Text style={styles.homePolicyTextSt}>CHÍNH SÁCH GIAO HÀNG</Text>
|
||||
<Text style={styles.homePolicyTextNd}>Nhận hàng và thanh toán tại nhà</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.homePolicyItem}>
|
||||
<FontAwesome style={styles.homePolicyIcon} name="refresh" size={25} />
|
||||
<View>
|
||||
<Text style={styles.homePolicyTextSt}>ĐỔI TRẢ DỄ DÀNG</Text>
|
||||
<Text style={styles.homePolicyTextNd}>Dùng thử trong vòng 3 ngày</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.homePolicyItem}>
|
||||
<FontAwesome style={styles.homePolicyIcon} name="credit-card" size={25} />
|
||||
<View>
|
||||
<Text style={styles.homePolicyTextSt}>THANH TOÁN TIỆN LỢI</Text>
|
||||
<Text style={styles.homePolicyTextNd}>Trả tiền mặt, CK, trả góp 0%</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.homePolicyItem}>
|
||||
<FontAwesome style={styles.homePolicyIcon} name="comments-o" size={25} />
|
||||
<View>
|
||||
<Text style={styles.homePolicyTextSt}>HỖ TRỢ NHIỆT TÌNH</Text>
|
||||
<Text style={styles.homePolicyTextNd}>Tư vấn, giải đáp mọi thắc mắc</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const Social = () => {
|
||||
return (
|
||||
<View style={styles.homeSocial}>
|
||||
<LinearGradient colors={['#243a76', '#ed1b24']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.bgLinearGradient}>
|
||||
<Text style={styles.homePolicyTitle}>
|
||||
Kết nối với chúng tôi
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
<View style={styles.homeSocialList}>
|
||||
<View style={styles.homeSocialItem}>
|
||||
<FontAwesome style={styles.homeSocialIconFace} name="facebook" size={25} />
|
||||
</View>
|
||||
<View style={styles.homeSocialItem}>
|
||||
<FontAwesome style={styles.homeSocialIconYoutube} name="youtube-play" size={25} />
|
||||
</View>
|
||||
<View style={styles.homeSocialItem}>
|
||||
<LinearGradient colors={['#f09433', '#e6683c', '#dc2743', '#cc2366', '#bc1888']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.homeSocialItemBg}>
|
||||
<FontAwesome style={styles.homeSocialIconInsta} name="instagram" size={25} />
|
||||
</LinearGradient>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const ShowroomList = () => {
|
||||
const [showFooter, setFooter] = useState('');
|
||||
|
||||
const ShowroomData = [
|
||||
{
|
||||
id: 'id1',
|
||||
title: 'HANOICOMPUTER - HAI BÀ TRƯNG',
|
||||
address: '- 129+131 Lê Thanh Nghị - Đồng Tâm - Hai Bà Trưng - Hà Nội\n- Tel: (024) 36282024\n- Email: kinhdoanhle.lethanhnghi@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id2',
|
||||
title: 'HANOICOMPUTER - ĐỐNG ĐA',
|
||||
address: '- 43 Thái Hà - Trung Liệt - Đống Đa - Hà Nội\n- Tel: 1900 1903 (máy lẻ 201) - (024) 35380088\n- Email: kinhdoanhle.thaiha@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id3',
|
||||
title: 'HANOICOMPUTER - CẦU GIẤY',
|
||||
address: '- 79 Nguyễn Văn Huyên - Cầu Giấy - Hà Nội\n- Tel: 1900 1903 (máy lẻ 503) - (024) 38610088\n- Email: kinhdoanhle.caugiay@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id4',
|
||||
title: 'HANOICOMPUTER - HÀ ĐÔNG',
|
||||
address: '- 511+513 Quang Trung - Hà Đông - Hà Nội\n- Tel: 1900 1903 (máy lẻ 600) - (024) 38580088\n- Email: kinhdoanhle.hadong@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id5',
|
||||
title: 'HANOICOMPUTER - HẢI PHÒNG',
|
||||
address: '- A1-6 Lô 8A, Lê Hồng Phong, Quận Ngô Quyền, Hải Phòng\n- Tel: 1900 1903 (máy lẻ 301) - (022) 58830013\n- Email: kinhdoanhle.haiphong@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id6',
|
||||
title: 'HANOICOMPUTER - TP. HỒ CHÍ MINH',
|
||||
address: '- 520 Cách Mạng Tháng Tám - Phường 11 - Quận 3 - TP. Hồ Chí Minh\n- Tel: 1900 1903 (máy lẻ 710) - (028) 73078877\n- Email: kd.hcmq3@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id7',
|
||||
title: 'HANOICOMPUTER - LONG BIÊN',
|
||||
address: '- Số 398 Nguyễn Văn Cừ - Long Biên - Hà Nội\n- Tel: 19001903 (máy lẻ 808) - (024) 73088877\n- Email: kinhdoanh.longbien@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id8',
|
||||
title: 'PHÒNG CAMERA & TB AN NINH',
|
||||
address: '- 43 Thái Hà - Trung Liệt - Đống Đa - Hà Nội\n- Phụ trách: Anh Nguyễn Văn Hiển\n- Mobile: 096.411.0606\n- Email: hiennv@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id9',
|
||||
title: 'PHÒNG BÁN HÀNG DỰ ÁN',
|
||||
address: '- 129 + 131 Lê Thanh Nghị, Đồng Tâm, Hai Bà Trưng, Hà Nội\n- Tel: 0913.226.335\n- Email: diepnm@hanoicomputer.com\n\n'
|
||||
},
|
||||
{
|
||||
id: 'id10',
|
||||
title: 'PHÒNG BÁN HÀNG TRỰC TUYẾN',
|
||||
address: '- 129 + 131 Lê Thanh Nghị, Đồng Tâm, Hai Bà Trưng, Hà Nội\n- Tel: 098.33033.90 / 096.266.0316\n- Email: thuydb@hanoicomputer.com\n\n'
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<View style={styles.homeShowrrom}>
|
||||
<LinearGradient colors={['#243a76', '#ed1b24']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.bgLinearGradient}>
|
||||
<Text style={styles.homePolicyTitle}>
|
||||
Hệ thông showroom
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
<View style={styles.homeShowrromList}>
|
||||
|
||||
{
|
||||
ShowroomData.map(item => <ShowroomOneItem key={item.id}
|
||||
title={item.title} id={item.id} setFooter={setFooter} address={item.address} current_show_id={showFooter} />)
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const ShowroomOneItem = (props: { id: string, current_show_id: string, title: string, address: string, setFooter: (id: string) => void }) => {
|
||||
|
||||
const { id, current_show_id, title, address, setFooter } = props;
|
||||
|
||||
return (
|
||||
<View style={styles.homeShowrromItem}>
|
||||
<TouchableOpacity onPress={() => setFooter(id)} style={styles.homeShowrromItemTitle}>
|
||||
<Text style={styles.homeShowrromItemTitleText}>{title}</Text>
|
||||
<Text style={styles.homeShowrromItemTitleIcon}>{current_show_id == id ? '-' : '+'}</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={current_show_id == id ? styles.homeShowrromItemContentHienThi : styles.homeShowrromItemContent}>
|
||||
<Text>
|
||||
{address}
|
||||
<TouchableOpacity onPress={() => Alert.alert('Go to map')} style={styles.homeShowrromItemContentMap}>
|
||||
<Text style={styles.homeShowrromItemContentMapText}>- Xem bản đồ</Text>
|
||||
</TouchableOpacity>
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const FooterInfo = () => {
|
||||
return (
|
||||
<View style={styles.footer}>
|
||||
<Text style={styles.footerBold}>© 2020 Công Ty Cổ Phần Máy Tính Hà Nội</Text>
|
||||
<Text style={styles.footerText}>
|
||||
Địa chỉ: Số 129 + 131, phố Lê Thanh Nghị, Phường Đồng Tâm, Quận Hai Bà Trưng, Hà Nội{'\n'}{'\n'}
|
||||
GPĐKKD số 0101161194 do Sở KHĐT Tp.Hà Nội cấp ngày 31/8/2001{'\n'}{'\n'}
|
||||
Email: hnc@hanoicomputer.com. Điện thoại: 1900 1903
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export { PolicyFooter, Social, ShowroomList, FooterInfo }
|
||||
|
||||
let winWidth = Dimensions.get('window').width; //full width
|
||||
let winHeight = Dimensions.get('window').height; //full height
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
bgLinearGradient: {
|
||||
marginBottom: 20,
|
||||
borderRadius: 5,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
homePolicy: {
|
||||
width: winWidth,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
},
|
||||
homePolicyTitle: {
|
||||
width: '100%',
|
||||
fontSize: 15,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
borderRadius: 3,
|
||||
lineHeight: 40,
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: '700',
|
||||
color: '#fff',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
homePolicyList: {
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
homePolicyItem: {
|
||||
marginBottom: 10,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
padding: 10,
|
||||
borderWidth: 1,
|
||||
borderColor: '#d9d9d9',
|
||||
borderRadius: 5,
|
||||
alignItems: 'center',
|
||||
},
|
||||
homePolicyIcon: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
lineHeight: 50,
|
||||
borderRadius: 25,
|
||||
backgroundColor: '#2b3179',
|
||||
color: '#fff',
|
||||
fontSize: 23,
|
||||
overflow: 'hidden',
|
||||
marginRight: 10.
|
||||
},
|
||||
homePolicyTextSt: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 5,
|
||||
},
|
||||
homePolicyTextNd: {
|
||||
fontSize: 13,
|
||||
},
|
||||
homeSocial: {
|
||||
marginBottom: 20,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
},
|
||||
homeSocialList: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
homeSocialItem: {
|
||||
marginRight: 10,
|
||||
},
|
||||
homeSocialIconFace: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
lineHeight: 50,
|
||||
borderRadius: 25,
|
||||
backgroundColor: '#2b3179',
|
||||
color: '#fff',
|
||||
fontSize: 23,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
homeSocialIconYoutube: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
lineHeight: 50,
|
||||
borderRadius: 25,
|
||||
backgroundColor: '#ff0000',
|
||||
color: '#fff',
|
||||
fontSize: 23,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
homeSocialIconInsta: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
lineHeight: 50,
|
||||
borderRadius: 25,
|
||||
color: '#fff',
|
||||
fontSize: 23,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
homeSocialItemBg: {
|
||||
width: 50,
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
lineHeight: 50,
|
||||
borderRadius: 25,
|
||||
color: '#fff',
|
||||
fontSize: 23,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
homeShowrrom: {
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
marginBottom: 20,
|
||||
},
|
||||
homeShowrromList: {
|
||||
borderWidth: 1,
|
||||
borderRadius: 5,
|
||||
borderColor: '#d9d9d9',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
homeShowrromItem: {
|
||||
|
||||
},
|
||||
homeShowrromItemTitle: {
|
||||
position: 'relative',
|
||||
backgroundColor: '#fff',
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
borderColor: '#d9d9d9',
|
||||
borderBottomWidth: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
homeShowrromItemTitleText: {
|
||||
color: '#333',
|
||||
lineHeight: 40,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
homeShowrromItemTitleIcon: {
|
||||
color: '#333',
|
||||
lineHeight: 40,
|
||||
fontSize: 16,
|
||||
},
|
||||
homeShowrromItemContent: {
|
||||
padding: 10,
|
||||
fontSize: 12,
|
||||
borderColor: '#d9d9d9',
|
||||
borderBottomWidth: 1,
|
||||
overflow: 'hidden',
|
||||
display: 'none',
|
||||
},
|
||||
homeShowrromItemContentHienThi: {
|
||||
padding: 10,
|
||||
fontSize: 12,
|
||||
borderColor: '#d9d9d9',
|
||||
borderBottomWidth: 1,
|
||||
},
|
||||
homeShowrromItemContentMap: {},
|
||||
homeShowrromItemContentMapText: {
|
||||
color: '#0063C3'
|
||||
},
|
||||
footer: {
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
},
|
||||
footerBold: {
|
||||
textAlign: 'center',
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
footerText: {
|
||||
textAlign: 'center',
|
||||
fontSize: 14,
|
||||
},
|
||||
})
|
||||
144
components/header/headerMain.tsx
Normal file
144
components/header/headerMain.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
import 'react-native-gesture-handler';
|
||||
import * as React from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Alert, Button, Image, StyleSheet, Dimensions, SafeAreaView, ScrollView, TouchableOpacity } from 'react-native';
|
||||
import { Text, View, } from '../Themed';
|
||||
import { TextInput } from 'react-native-gesture-handler';
|
||||
import { Ionicons, FontAwesome } from '@expo/vector-icons';
|
||||
import { createDrawerNavigator, DrawerItemList, DrawerItem, DrawerContentScrollView } from '@react-navigation/drawer';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import Animated, { Easing } from 'react-native-reanimated';
|
||||
|
||||
const Header = ({props} : {props : any}) => {
|
||||
const toggleDrawer = () => {
|
||||
//Props to open/close the drawer
|
||||
props.toggleDrawer();
|
||||
};
|
||||
return (
|
||||
<View style={styles.headerAll}>
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={toggleDrawer} style={styles.menu}>
|
||||
<Ionicons style={styles.iconMenu} name="md-list" size={32} />
|
||||
</TouchableOpacity>
|
||||
<View style={styles.bgNone}>
|
||||
<Image style={styles.img} source={{ uri: 'https://www.hanoicomputer.vn/media/lib/logo-trang.png' }} />
|
||||
</View>
|
||||
<View style={styles.headerCart}>
|
||||
<Ionicons style={styles.iconMenu} name="cart-outline" size={32} />
|
||||
<Text style={styles.countCart}>0</Text>
|
||||
</View>
|
||||
</View>
|
||||
<MainSeach />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const MainSeach = () => {
|
||||
return (
|
||||
<View style={styles.boxSearch}>
|
||||
<View style={styles.boxSearchBo}>
|
||||
<TextInput style={styles.inputSearch} placeholder="Nhập tên, mã sản phẩm" autoCapitalize="none" />
|
||||
<Ionicons style={styles.buttonSearch} onPress={() => { Alert.alert('aaaaaaaaaa') }} name="search-outline" size={26} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export { Header, MainSeach };
|
||||
|
||||
let winWidth = Dimensions.get('window').width; //full width
|
||||
let winHeight = Dimensions.get('window').height; //full height
|
||||
const styles = StyleSheet.create({
|
||||
headerAll: {
|
||||
width: winWidth,
|
||||
flex: 1,
|
||||
},
|
||||
bgNone: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0)',
|
||||
},
|
||||
header: {
|
||||
backgroundColor: '#243a76',
|
||||
height: 53,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: winWidth,
|
||||
padding: 10,
|
||||
},
|
||||
menu: {
|
||||
backgroundColor: '#243a76',
|
||||
},
|
||||
iconMenu: {
|
||||
color: '#fff',
|
||||
},
|
||||
headerCart: {
|
||||
backgroundColor: 'rgba(0,0,0,0)',
|
||||
position: 'relative',
|
||||
},
|
||||
countCart: {
|
||||
position: 'absolute',
|
||||
top: -5,
|
||||
right: -5,
|
||||
zIndex: 1,
|
||||
width: 20,
|
||||
height: 20,
|
||||
backgroundColor: '#ffe100',
|
||||
borderRadius: 10,
|
||||
textAlign: 'center',
|
||||
lineHeight: 20,
|
||||
fontSize: 13,
|
||||
color: '#000',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
img: {
|
||||
height: 40,
|
||||
width: 100,
|
||||
},
|
||||
boxSearch: {
|
||||
position: 'relative',
|
||||
padding: 10,
|
||||
backgroundColor: '#fff',
|
||||
width: winWidth,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 1,
|
||||
},
|
||||
shadowOpacity: 0.18,
|
||||
shadowRadius: 1.00,
|
||||
elevation: 1,
|
||||
},
|
||||
boxSearchBo: {
|
||||
position: 'relative',
|
||||
flexDirection: 'row',
|
||||
borderWidth: 1,
|
||||
justifyContent: 'space-between',
|
||||
borderStyle: 'solid',
|
||||
alignItems: 'center',
|
||||
borderRadius: 5,
|
||||
display: 'flex',
|
||||
height: 38,
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
},
|
||||
inputSearch: {
|
||||
width: winWidth - 65,
|
||||
padding: 10,
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
height: 36,
|
||||
margin: 0,
|
||||
fontSize: 14,
|
||||
},
|
||||
buttonSearch: {
|
||||
width: 40,
|
||||
textAlign: 'center',
|
||||
height: 36,
|
||||
lineHeight: 36,
|
||||
},
|
||||
})
|
||||
245
components/product/productItem.tsx
Normal file
245
components/product/productItem.tsx
Normal file
@@ -0,0 +1,245 @@
|
||||
import * as React from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Alert, Button, Image, StyleSheet, Dimensions, SafeAreaView, ScrollView, TouchableOpacity, Pressable } from 'react-native';
|
||||
import { Text, View, } from '../Themed';
|
||||
import { Ionicons, FontAwesome } from '@expo/vector-icons';
|
||||
import ProductDetail from '../../screens/ProductDetail';
|
||||
import { createDrawerNavigator, DrawerItemList, DrawerItem, DrawerContentScrollView } from '@react-navigation/drawer';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
|
||||
import { NativeRouter, Route, Link } from "react-router-native";
|
||||
import { TextInput } from 'react-native-gesture-handler';
|
||||
import { Checkbox } from 'react-native-paper';
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
const Drawer = createDrawerNavigator();
|
||||
|
||||
function formatCurrency(price: string | number) {
|
||||
let priceConvert = parseFloat(`${price}`).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1.").toString();
|
||||
let len = priceConvert.length;
|
||||
return priceConvert.substring(0, len - 3);
|
||||
}
|
||||
|
||||
const ShowProductItem = (props: { id: number, productName: string, productSKU: string, productImage: { small: string, medium: string, large: string, original: string }, price: number, marketPrice: number, quantity: number, privateStyle: object }) => {
|
||||
|
||||
const { id, productName, productSKU, productImage, price, marketPrice, quantity, privateStyle } = props;
|
||||
const discount = Math.ceil(100 - (price / marketPrice * 100));
|
||||
|
||||
|
||||
return (
|
||||
<View style={[styles.itemProduct, privateStyle]}>
|
||||
<View style={styles.pBloxImgProduct}>
|
||||
<Text style={styles.pSkuProduct}>{productSKU}</Text>
|
||||
<Text style={styles.pDiscountProduct}>-{discount}%</Text>
|
||||
<View style={styles.pBloxImgProductBao}>
|
||||
<Image style={styles.pImgProduct} source={{ uri: productImage.large }} />
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.pNameProduct} numberOfLines={2}>
|
||||
{productName}
|
||||
</Text>
|
||||
<Text style={styles.priceProduct}>{formatCurrency(price)} đ</Text>
|
||||
<Text style={styles.oldPriceProduct}>{formatCurrency(marketPrice)} đ</Text>
|
||||
<View style={styles.pBottonProduct}>
|
||||
<Text style={styles.pStatusProduct}>
|
||||
{quantity > 0 ? <Ionicons style={styles.pStatusProductIcon} name="checkmark-outline" size={13} /> : <Ionicons style={styles.pStatusProductIcon} name="close-outline" size={13} />}
|
||||
{quantity > 0 ? 'Còn hàng' : 'Hết hàng'}
|
||||
</Text>
|
||||
<Text style={styles.pCartProduct}><Ionicons style={styles.pCartProductIcon} name="cart-outline" size={13} />Giỏ hàng</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const ItemComboSet = (props: { id: number, productName: string, productSKU: string, productImage: { small: string, medium: string, large: string, original: string }, price: number, marketPrice: number, quantity: number }) => {
|
||||
|
||||
const { id, productName, productSKU, productImage, price, marketPrice, quantity } = props;
|
||||
const discountCombo = Math.ceil(100 - (price / marketPrice * 100));
|
||||
const [checked, setChecked] = React.useState(false);
|
||||
return (
|
||||
<View style={[styles.itemProductCombo]}>
|
||||
<View style={styles.pBloxImgProduct}>
|
||||
<View style={styles.pBloxImgProductBao}>
|
||||
<Image style={styles.pImgProduct} source={{ uri: productImage.large }} />
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.pNameProductAll}>
|
||||
<Checkbox.IOS status={checked ? 'checked' : 'unchecked'} onPress={() => setChecked(!checked)} style={styles.inputComboCheck} />
|
||||
<Text style={[styles.pNameProduct, styles.pNameProductCombo]} numberOfLines={2}>
|
||||
{productName}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.priceProductAll}>
|
||||
<Text style={[styles.priceProduct, styles.priceProductCombo]}>{formatCurrency(price)} đ</Text>
|
||||
<Text style={[styles.oldPriceProduct, styles.oldPriceProductCombo]}>{formatCurrency(marketPrice)} đ</Text>
|
||||
<Text style={styles.pDiscountProductCombo}>-{discountCombo}%</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => Alert.alert('popup product')} >
|
||||
<Text>Chọn tai nghe khác</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const ItemComboSetProDetail = (props: { id: number, productName: string, productSKU: string, productImage: { small: string, medium: string, large: string, original: string }, price: number, marketPrice: number, quantity: number }) => {
|
||||
|
||||
const { id, productName, productSKU, productImage, price, marketPrice, quantity } = props;
|
||||
const discountCombo = Math.ceil(100 - (price / marketPrice * 100));
|
||||
return (
|
||||
<View style={[styles.itemProductCombo]}>
|
||||
<View style={styles.pBloxImgProduct}>
|
||||
<View style={styles.pBloxImgProductBao}>
|
||||
<Image style={styles.pImgProduct} source={{ uri: productImage.large }} />
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.pNameProduct} numberOfLines={2}>
|
||||
{productName}
|
||||
</Text>
|
||||
<Text style={styles.priceProduct}>{formatCurrency(price)} đ</Text>
|
||||
<Text style={styles.oldPriceProduct}>{formatCurrency(marketPrice)} đ</Text>
|
||||
<Text style={styles.pDiscountProductCombo}>-{discountCombo}%</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export { ShowProductItem, ItemComboSet, ItemComboSetProDetail };
|
||||
|
||||
let winWidth = Dimensions.get('window').width; //full width
|
||||
let winHeight = Dimensions.get('window').height; //full height
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
itemProduct: {
|
||||
padding: 10,
|
||||
},
|
||||
pBloxImgProduct: {
|
||||
position: 'relative',
|
||||
marginBottom: 10,
|
||||
},
|
||||
pSkuProduct: {
|
||||
position: 'absolute',
|
||||
fontSize: 12,
|
||||
color: '#e00',
|
||||
top: 0,
|
||||
left: 0,
|
||||
lineHeight: 36,
|
||||
zIndex: 10,
|
||||
},
|
||||
pDiscountProduct: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
backgroundColor: '#e00',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
color: '#fff',
|
||||
textAlign: 'center',
|
||||
lineHeight: 36,
|
||||
borderRadius: 18,
|
||||
overflow: 'hidden',
|
||||
fontSize: 12,
|
||||
zIndex: 10,
|
||||
},
|
||||
pBloxImgProductBao: {
|
||||
position: 'relative',
|
||||
paddingTop: '100%',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
pImgProduct: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: '5%',
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
maxHeight: 500,
|
||||
width: '90%',
|
||||
},
|
||||
pNameProduct: {
|
||||
height: 40,
|
||||
lineHeight: 20,
|
||||
overflow: 'hidden',
|
||||
fontSize: 14,
|
||||
color: '#111',
|
||||
marginBottom: 5,
|
||||
},
|
||||
priceProduct: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#f10000',
|
||||
marginBottom: 5,
|
||||
},
|
||||
oldPriceProduct: {
|
||||
fontSize: 14,
|
||||
color: '#b7b7b7',
|
||||
marginBottom: 5,
|
||||
height: 24,
|
||||
lineHeight: 24,
|
||||
overflow: 'hidden',
|
||||
textDecorationLine: 'line-through',
|
||||
},
|
||||
pBottonProduct: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
marginTop: 5,
|
||||
},
|
||||
pStatusProduct: {
|
||||
fontSize: 13,
|
||||
color: '#00a706',
|
||||
},
|
||||
pCartProduct: {
|
||||
fontSize: 13,
|
||||
color: '#333',
|
||||
},
|
||||
pStatusProductIcon: {
|
||||
fontSize: 15,
|
||||
},
|
||||
pCartProductIcon: {
|
||||
fontSize: 15
|
||||
},
|
||||
itemProductCombo: {
|
||||
width: '100%',
|
||||
marginBottom: 10,
|
||||
borderWidth: 1,
|
||||
borderColor: '#e1e1e1',
|
||||
padding: 10,
|
||||
},
|
||||
inputComboCheck: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderColor: '#222',
|
||||
borderWidth: 1,
|
||||
borderRadius: 3,
|
||||
alignSelf: 'center',
|
||||
backgroundColor: '#e0c',
|
||||
},
|
||||
pDiscountProductCombo: {
|
||||
textDecorationLine: 'line-through'
|
||||
},
|
||||
priceProductAll: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'baseline'
|
||||
},
|
||||
pNameProductCombo: {
|
||||
paddingLeft: 10,
|
||||
width: winWidth - 70,
|
||||
},
|
||||
pNameProductAll: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
priceProductCombo: {
|
||||
lineHeight: 22,
|
||||
},
|
||||
oldPriceProductCombo: {
|
||||
lineHeight: 22,
|
||||
marginHorizontal: 10
|
||||
},
|
||||
|
||||
})
|
||||
Reference in New Issue
Block a user