Skip to content

Commit

Permalink
details
Browse files Browse the repository at this point in the history
  • Loading branch information
medomy committed Jan 27, 2023
1 parent bbe803c commit 81c9962
Show file tree
Hide file tree
Showing 15 changed files with 286 additions and 5 deletions.
Binary file added assets/images/star.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
import React from 'react'
import styles from './styles'

interface props {
title: string,
subTitle: string
}
const MostPopularSecHeader = ({ title, subTitle }: props) => {
return (
<View style={styles.container}>
<Text style={styles.title}>{title}</Text>
<TouchableOpacity>
<Text style={styles.subTitle}>{subTitle}</Text>
</TouchableOpacity>
</View>
)
}

export default MostPopularSecHeader
15 changes: 15 additions & 0 deletions src/components/HomeComponents/mostPopularSec/mostPopuler.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { View, Text } from 'react-native'
import React from 'react'
import { useGetLimitedProductsQuery } from '../../../store/slices/productSlice'
import MostPopularSecHeader from './mostPopularSecHeader'
import ProductsList from '../productsList'

export default function MostPopular() {
const { data } = useGetLimitedProductsQuery(5)
return (
<View style={{ flex: 1 }}>
<MostPopularSecHeader title='most popular' subTitle='see all' />
{data && <ProductsList products={data!} />}
</View>
)
}
27 changes: 27 additions & 0 deletions src/components/HomeComponents/mostPopularSec/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { StyleSheet } from "react-native";
import { COLORS, FONTS, SIZES } from "../../../constants";

const styles = StyleSheet.create({
container: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
width: SIZES.fullWidth,
paddingHorizontal: 1.5 * SIZES.padding2,
paddingVertical: SIZES.padding,
marginVertical: SIZES.margin
},
title: {
...FONTS.h2,
fontWeight: "bold",
color: COLORS.black
},
subTitle: {
...FONTS.body4,
color: COLORS.darkgray,
fontWeight: "700"
}

});

export default styles;
10 changes: 9 additions & 1 deletion src/components/HomeComponents/productCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,21 @@ import { IconButton } from '@react-native-material/core'
import Icon from 'react-native-vector-icons/FontAwesome'
import { Image } from 'react-native'
import { SIZES } from '../../../constants'
import { useNavigation } from '@react-navigation/native'

interface props {
product: Product
}
export default function ProductCard({ product }: props) {
const navigation = useNavigation();

const goToDetails = () => {
navigation.navigate("details" as never, {
productId: product.id
} as never)
}
return (
<Pressable style={styles.procuctCard}>
<Pressable style={styles.procuctCard} onPress={goToDetails}>
<View style={styles.imgContainer}>
<IconButton icon={<Icon name='heart-o' size={SIZES.iconSize} />} style={styles.iconBtn} />
<Image
Expand Down
28 changes: 28 additions & 0 deletions src/components/detailsComponents/detailsTitleAndRating/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { View, Text, Image } from 'react-native'
import React from 'react'
import styles from './styles'
import { COLORS, images } from '../../../constants'

interface props {
title: string,
rating: number,
reviews: number,
price: number
}
export default function TitleAndRatingDetails({ title, rating, reviews, price }: props) {
return (
<View style={styles.container}>
<Text style={[styles.title, { color: COLORS.black }]}>{title}</Text>
<View style={styles.ratingAndPrice}>
<Text style={[styles.price, { color: COLORS.black }]}>${price}</Text>
<View style={styles.ratingSec}>
<Image
source={images.startImg}
style={styles.ratingImg} />
<Text style={[styles.rating, { color: COLORS.black }]}>{rating}</Text>
<Text style={[styles.rating, { color: COLORS.darkgray }]}>({reviews} reviews)</Text>
</View>
</View>
</View>
)
}
40 changes: 40 additions & 0 deletions src/components/detailsComponents/detailsTitleAndRating/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { StyleSheet } from "react-native";
import { COLORS, FONTS, SIZES } from "../../../constants";

const styles = StyleSheet.create({
container: {
paddingHorizontal: 1.5 * SIZES.padding2,
width: SIZES.fullWidth,
marginVertical:2* SIZES.margin2
},
title: {
...FONTS.h3,
fontWeight: "bold",
},
ratingAndPrice: {
flexDirection: "row",
width: "60%",
justifyContent: "space-between",
marginVertical : SIZES.margin

},
price: {
...FONTS.body3,
color: COLORS.darkgray
},
ratingSec: {
flexDirection: "row",
alignItems: "center",
},
ratingImg: {
width: SIZES.iconSize2,
height: SIZES.iconSize2,
marginRight: 0.5 * SIZES.margin,
resizeMode: "contain"
},
rating: {
...FONTS.body4,
},
});

export default styles;
28 changes: 28 additions & 0 deletions src/components/detailsComponents/header/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { View, Text, TouchableOpacity } from 'react-native'
import React from 'react'
import styles from './styles'
import Icon from 'react-native-vector-icons/Ionicons'
import { COLORS, SIZES } from '../../../constants'
import { useNavigation } from '@react-navigation/native'

export default function DetailsHeader() {
const navigation = useNavigation();
const goBack = () => {
navigation.goBack();
}
return (
<View style={styles.headerContainer}>
<TouchableOpacity style={styles.btn} onPress={goBack}>
<Icon name='arrow-back' size={SIZES.iconSize} color={COLORS.black}/>
</TouchableOpacity>
<View style={styles.row}>
<TouchableOpacity style={styles.btn}>
<Icon name='heart-outline' size={SIZES.iconSize} color={COLORS.black}/>
</TouchableOpacity>
<TouchableOpacity style={styles.btn}>
<Icon name='md-cloud-upload-outline' size={SIZES.iconSize} color={COLORS.black}/>
</TouchableOpacity>
</View>
</View>
)
}
28 changes: 28 additions & 0 deletions src/components/detailsComponents/header/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { StyleSheet } from "react-native";
import { COLORS, SIZES } from "../../../constants";

const styles = StyleSheet.create({
headerContainer: {
position: "absolute",
top: 2 * SIZES.margin2,
flexDirection: "row",
paddingHorizontal: 1.5 * SIZES.padding2,
justifyContent: "space-between",
width : SIZES.fullWidth
},
btn: {
width: 2 * SIZES.iconSize2,
height: 2 * SIZES.iconSize2,
borderRadius: SIZES.iconSize2,
justifyContent: "center",
alignItems: "center",
backgroundColor: COLORS.white,
marginHorizontal: SIZES.margin
},
row: {
flexDirection: "row"
}

});

export default styles;
20 changes: 20 additions & 0 deletions src/components/detailsComponents/imgSec/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { View, Text, Image } from 'react-native'
import React from 'react'
import { Product } from '../../../types/product'
import styles from './styles'
import DetailsHeader from '../header'

interface props {
product: Product
}
export default function ImgSecDetails({ product }: props) {
return (
<View style={styles.container}>
<DetailsHeader />
<Image
source={{ uri: product.image }}
style={styles.img}
/>
</View>
)
}
20 changes: 20 additions & 0 deletions src/components/detailsComponents/imgSec/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { StyleSheet } from "react-native";
import { COLORS, SIZES } from "../../../constants";

const styles = StyleSheet.create({
container: {
backgroundColor: COLORS.socendry,
width: SIZES.fullWidth,
height: 0.5 * SIZES.fullScreenHeight,
alignItems: "center",
justifyContent: "flex-end",
position: "relative"
},
img: {
width: "60%",
height: 0.4 * SIZES.fullScreenHeight,
resizeMode: "contain"
}
});

export default styles;
4 changes: 2 additions & 2 deletions src/constants/images.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const discountImg = require('../../assets/images/discountPic.png');


export const startImg = require('../../assets/images/star.png');
export default {
discountImg,
startImg
}
2 changes: 2 additions & 0 deletions src/navigation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import LoginScreen from '../screens/loginScreen';
import MainTabBar from './bottomTabBar/bottomTabBar';
import { useSignedUser } from '../hooks/useSignedUser';
import LoadingMainScreenMyScreen from '../screens/loadingScreen';
import DetailsScreen from '../screens/details';

const StackNavigation = createNativeStackNavigator();
export default function Navigation() {
Expand All @@ -20,6 +21,7 @@ export default function Navigation() {
<StackNavigation.Screen name='_loading' component={LoadingMainScreenMyScreen} />
<StackNavigation.Screen name='login' component={LoginScreen} />
<StackNavigation.Screen name='root' component={MainTabBar} />
<StackNavigation.Screen name='details' component={DetailsScreen} />
</StackNavigation.Navigator>
</NavigationContainer>
)
Expand Down
37 changes: 37 additions & 0 deletions src/screens/details/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ScrollView, StyleSheet, Text, View } from 'react-native'
import React from 'react'
import { useRoute } from '@react-navigation/native'
import { useGetProductByIdQuery } from '../../store/slices/productSlice'
import LoadingScreen from '../../components/loadingScreen/loadingScreen'
import ImgSecDetails from '../../components/detailsComponents/imgSec'
import TitleAndRatingDetails from '../../components/detailsComponents/detailsTitleAndRating'

type RouteParams = {
productId: number
}
const DetailsScreen = () => {
const route = useRoute();
const params = route.params as RouteParams;

const { data, isLoading } = useGetProductByIdQuery(params.productId)

if (isLoading || data === undefined) {
return (
<LoadingScreen />
)
}
else {
return (
<View style={{ flex: 1 }}>
<ScrollView>
<ImgSecDetails product={data} />
<TitleAndRatingDetails title={data.title} rating={data.rating.rate} reviews={data.rating.count} price={data.price} />
</ScrollView>
</View>
)
}
}

export default DetailsScreen

const styles = StyleSheet.create({})
12 changes: 10 additions & 2 deletions src/screens/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import CategoriesList from '../../components/HomeComponents/categoriesList'
import { useGetAllProductsQuery } from '../../store/slices/productSlice'
import ProductsList from '../../components/HomeComponents/productsList'
import { filterProducts } from '../../utils/filterProducts'
import MostPopular from '../../components/HomeComponents/mostPopularSec/mostPopuler'

const Home = () => {
const { data } = useGetAllProductsQuery();
Expand All @@ -19,16 +20,23 @@ const Home = () => {
<View style={{ flex: 1 }}>
<HomeHeader />
<ScrollView
showsVerticalScrollIndicator = {false}>
showsVerticalScrollIndicator={false}
>
<HeaderTitle title='Find Your Clothes' />
<DiscountSec />
<CategoriesList selected={selectedCategory} setSelected={changeSelectedCategory} />
{data && <ProductsList products={filterProducts(selectedCategory, data)} />}
{data && <MostPopular />}
<View style={styles.emptyViewFooter}></View>
</ScrollView>
</View>
)
}

export default Home

const styles = StyleSheet.create({})
const styles = StyleSheet.create({
emptyViewFooter: {
height: 100,
}
})

0 comments on commit 81c9962

Please sign in to comment.