import React from 'react';
import ProductList from './components/ProductList';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import ProductDetails from './components/ProductDetails';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const Stack = createNativeStackNavigator();
function App(): React.JSX.Element {
return (
<Provider store={store}>
<GestureHandlerRootView style={{ flex: 1 }}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={ProductList} options={{headerShown:false}}/>
<Stack.Screen name='details' component={ProductDetails} options={{headerShown:false}}/>
</Stack.Navigator>
</NavigationContainer>
</GestureHandlerRootView>
</Provider>
);
}
export default App;
This is Landing Page
import { ScrollView, StyleSheet,FlatList, Text, View, TouchableOpacity } from 'react-native';
import React, { useEffect, useState } from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
import axios from 'axios';
import SingleProduct from './SingleProduct';
import { useSelector, useDispatch } from 'react-redux'
import { category } from '../slices/CategorySlice';
import { RootState } from '../store/store';
const ProductList = ({ navigation }) => {
const [category, setCategory] = useState([]);
const [allproduct , setAllProduct] = useState([]);
const singlecategory = useSelector((state: RootState) => state.category.value)
const dispatch = useDispatch()
useEffect(() => {
const fetchData = async () => {
const data = await axios.get('https://fakestoreapi.com/products/categories');
setCategory(data.data);
};
fetchData();
fetch('https://fakestoreapi.com/products').then(res=>res.json()).then((data)=>{setAllProduct(data)})
}, []);
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.maintitle}>
<Text style={styles.title}>MY STORE</Text>
</View>
<View>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
{category.map((data, index) => (
<Text key={index} style={styles.each_cat}>{data}</Text>
))}
</ScrollView>
</View>
<View style={{ flex: 1 }}>
<FlatList
data={allproduct}
keyExtractor={(item)=>item.id}
renderItem={({item}) =>item? <TouchableOpacity onPress={() => navigation.navigate('details',{item:item.id})}><SingleProduct data={item}/></TouchableOpacity>:null}
numColumns={2}
contentContainerStyle={styles.mylist}
/>
</View>
</SafeAreaView>
);
};
export default ProductList;
const styles = StyleSheet.create({
mylist: {
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
},
each_cat: {
backgroundColor: '#3B1E54',
height: 50,
margin: 10,
color: '#EEEEEE',
textAlign: 'center',
paddingTop: 15,
borderRadius: 7,
padding: 10,
fontWeight: 'bold',
},
maintitle: {
justifyContent: 'center',
alignItems: 'center',
margin: 10,
},
title: {
height: 40,
width: '100%',
margin: 10,
textAlign: 'center',
lineHeight: 40,
fontSize: 40,
fontFamily: 'cursive',
color: 'brown',
},
});
This is Single Product Page
import { Button, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
import React from 'react'
import { SafeAreaView } from 'react-native-safe-area-context'
const SingleProduct = ({data}) => {
return (
<SafeAreaView>
<View style={styles.card_view}>
<View style={styles.image_view}>
<Image
style={styles.image}
source={{ uri: `${data.image}` }}
/>
</View>
<Text style={{fontSize:17,fontWeight:'500',paddingLeft:10,}}>{data.title.slice(0,21)}</Text>
<Text style={{fontSize:17,fontWeight:'500',paddingLeft:10, backgroundColor:'#D7C3F1', width:'60%', borderColor:'#C8A1E0',borderWidth:3, borderRadius:4,marginLeft:8,marginTop:5}}>$ {data.price}</Text>
<View style={styles.start_count}>
<Text style={{marginLeft:4}}>({data.rating.rate})</Text>
<Image source={require('../assets/icons/fill_star.png')} style={styles.star_img}/>
<Text style={{marginLeft:4}}>({data.rating.count})</Text>
</View>
</View>
</SafeAreaView>
)
}
export default SingleProduct
const styles = StyleSheet.create({
buttons:{
height:10,
width:40
},
card_view:{
shadowColor: 'red',
backgroundColor:'white',
borderColor:'gery',
borderRadius:10,
borderWidth:1,
width: 160,
margin:5
},
image_view :{
alignItems:'center',
justifyContent:'center',
marginTop:5,
},
image:{
height:140,
width:'90%',
borderBlockColor:"black",
margin:3,
borderRadius:10,
objectFit:'contain',
aspectRatio:'1/1',
},
star_img:{
height:20,
width:20
},
start_count:{
flexDirection:'row',
alignItems:'center',
justifyContent:'flex-start',
marginTop:8,
marginBottom:5,
marginLeft:5,
}
})
This is Product Details Page
import { StyleSheet, Text, View ,Image, ActivityIndicator} from 'react-native'
import React, { useState,useEffect } from 'react';
import { useRoute } from '@react-navigation/native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { ScrollView } from 'react-native-gesture-handler';
const ProductDetails = () => {
const route = useRoute()
const id = route.params?.item
const [details , setDetails] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetch(`https://fakestoreapi.com/products/${id}`)
.then((response) => response.json())
.then((data) => {
setDetails(data);
setIsLoading(false);
})
.catch((error) => {
console.error("Error fetching product details:", error);
setIsLoading(false);
});
}, [id]);
if (isLoading) {
return (
<SafeAreaView style={{flex:1,justifyContent:'center'}}>
<ActivityIndicator size="large" color="grey" />
</SafeAreaView>
);
}
return (
<SafeAreaView>
<View style={{backgroundColor:'white',alignItems:'center'}}>
<Image source={{ uri: details?.image }} resizeMode="contain" height={350} width={350} />
</View>
<View style={styles.textContainer}>
<Text style={styles.title}>{details.title}</Text>
</View>
<View style={styles.ratingContainer}>
<View style={{backgroundColor:'green' , flexDirection:'row',alignItems:'center',padding:5,borderRadius:5,height:30,}}>
<Text style={{width:30, color:'white',}}>{details?.rating.rate}</Text>
<Image source={require('../assets/icons/fill_star.png')} style={{width:15,height:15}}/>
</View>
<Text style={{margin:5,fontSize:20,color:'grey'}}>{`(${details?.rating.count})`}</Text>
<Text style={{fontSize:18,fontWeight:500,backgroundColor:'#FADA7A', borderColor:'#F29F58',borderWidth:3,borderRadius:7,padding:3}}>{details?.category}</Text>
</View>
<View>
<Text style={styles.price}>{`$${details.price}`}</Text>
</View>
<View style={styles.descriptionContainer}>
<Text style={styles.descriptionTitle}>Description</Text>
<ScrollView style={{height:150,padding:9}}>
<Text style={styles.descriptionText}>{details.description}</Text>
</ScrollView>
</View>
</SafeAreaView>
)
}
export default ProductDetails
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 10,
},
imageContainer: {
alignItems: 'center',
marginBottom: 20,
},
image: {
width: 350,
height: 350,
},
textContainer: {
flexDirection:'row',
alignItems: 'center',
marginBottom: 3,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginLeft:10,
marginTop:10,
marginBottom:10
},
price: {
marginLeft:10,
fontWeight:800,
fontSize: 20,
color: 'black',
},
ratingContainer: {
flexDirection:'row',
width:'100%',
marginBottom: 5,
marginLeft:10,
alignItems:'center'
},
descriptionContainer: {
},
descriptionTitle: {
fontWeight: 700,
marginLeft:10,
fontSize:17,
marginTop:5
},
descriptionText: {
margin:10,
fontSize: 16,
color: 'gray',
},
});