Add folders and files.
1
2
3
4
5
6
7
8
9
10
11
12
| Apps
├── Compoents
│ ├── Slider.jsx
│ ├── PostItem.jsx
│ ├── Categories.jsx
│ ├── Header.jsx
│ └── LatestItemList.cs
├── Screens
│ ├── HomeScreen.jsx
│ ├── ExploreScreen.jsx
│ ├── ProfileScreen.jsx
│ └── AddPostScreen.cs
|
Add dependency folder and file in a tailwind.config.js (to recognize tailwind css in those files)
1
2
3
4
5
6
7
8
9
| /** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./App.{js,jsx,ts,tsx}", "./Apps/**/*.{js,jsx,ts,tsx}",
"./Components/Homescreen/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
|
Add a basic code by rnf (reactNativeFunctionalCompoents)
1
2
3
4
5
6
7
8
9
10
| import { View, Text } from 'react-native'
import React from 'react'
export default function Header() {
return (
<View>
<Text>Header</Text>
</View>
)
}
|
1
2
3
4
5
6
| import { useUser } from '@clerk/clerk-expo'
...
export default function Header() {
const {user} = useUser();
|
Show the information on the information section
1
2
3
4
5
6
7
8
9
10
11
12
| return (
<View>
{/* User infor sectiion */}
<View className="flex flex-row items-center gap-4">
<Image source=
className="rounded-full w-12 h-12"
/>
<View>
<Text className="text-[16px]">Welcome</Text>
<Text className="text-[20px] font-bold">{user?.fullName}</Text>
</View>
</View>
|
1
2
3
4
5
6
7
8
| {/* Search bar section */}
<View className="p-2 px-5 mt-5 flex flex-row bg-white rounded-full border-[2px] border-blue-300">
<EvilIcons name="search" size={24} color="gray" />
<TextInput placeholder='Search'
className="ml-2 text-[18px]"
onChangeText={(value) => console.log(value)}
/>
</View>
|
Include Header component in Homescreen.jsx
1
2
3
| <View className="py-8 px-6 bg-white flex-1">
<Header />
</View>
|
Slider
- make new collection for images in firestore database
{image:”url”}
Add code in slider component
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| import { View, Text, FlatList, Image } from 'react-native'
import React from 'react'
export default function Slider({sliderList}) {
return (
<View className="mt-5">
<FlatList
data={sliderList}
horizontal={true}
showsHorizontalScrollIndicator={false}
renderItem={({item,index})=>(
<View>
<Image source=
className="h-[200px] w-[330px] mr-3 rounded-lg object-contain"
/>
</View>
)}
/>
</View>
)
}
|
- Attach Slider at Homescreen
1
2
3
| import Slider from '../../Components/Homescreen/Slider'
import {collection, getDocs, getFirestore} from 'firebase/firestore';
import {app} from '../../firebaseConfig';
|
1
| const db = getFirestore(app); // get firestore database
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // loading slider data
const [sliderList,setSliderList]=useState([]);
useEffect(()=>{
getSliders();
},[])
const getSliders= async ()=>{
setSliderList([]);
const querySnapshot = await getDocs(collection(db, "Sliders"));
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
setSliderList(sliderList=>[...sliderList,doc.data()]);
});
}
|
1
2
3
4
5
6
| return (
<View className="py-8 px-6 bg-white flex-1">
<Header />
<Slider sliderList={sliderList}/>
</View>
)
|
categoryList
homescreen
1
| import Categories from '../../Components/Homescreen/Categories';
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| const [sliderList,setSliderList]=useState([]);
const [categoryList,setCategoryList]=useState([]);
useEffect(()=>{
getSliders();
getCategoryList();
},[])
const getCategoryList=async()=>{
setCategoryList([]);
const querySnapshot = await getDocs(collection(db, 'Category'));
querySnapshot.forEach((doc)=> {
console.log("Docs:", doc.data());
setCategoryList(categoryList=>[...categoryList,doc.data()]);
})
return (
<View className="py-8 px-6 bg-white flex-1">
<Header />
<Slider sliderList={sliderList}/>
<Categories categoryList={categoryList}/>
</View>
)
|
categories.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| import { View, Text, FlatList, Image, TouchableOpacity } from 'react-native'
import React from 'react'
export default function Categories({categoryList}) { // {value} should be object
return (
<View className="mt-3">
<Text className="font-bold textz-[20px]">Categories</Text>
<FlatList
data={categoryList}
numColumns={4}
renderItem={({item,index})=>(
<TouchableOpacity className="flex-1 items-center justify-center p-2 border-[1px] border-gray-300 m-1 h-[80px] rounded-lg">
<Image source= // source=
className="w-[40px] h-[40px]"
/>
<Text className="text-[12px] mt-1">{item.name}</Text>
</TouchableOpacity>
)}
/>
</View>
)
}
|
Product list
→ install moment (moment.js.com) to format date
npm install moment - - save
→ add “createdAt” field in AddPostScreen.jsx
→ getLatestsItemList
1
2
3
4
5
6
7
8
| const getLatestItemList=async()=>{
setLatestItemList([]);
const querySnapshot=await getDocs(collection(db, 'UserPost'), orderBy('createdAt', 'desc'));
querySnapshot.forEach((doc) => {
console.log("Docs:", doc.data());
setLatestItemList(latestItemList=>[...latestItemList,doc.data()]);
})
}
|
→ call getLatestItemList
1
2
3
4
5
6
| const [latestItemList,setLatestItemList]=useState([]);
useEffect(()=>{
getSliders();
getCategoryList();
getLatestItemList();
},[])
|
→ call the component
1
2
3
4
5
6
7
8
| return (
<ScrollView className="py-8 px-6 bg-white flex-1">
<Header />
<Slider sliderList={sliderList}/>
<Categories categoryList={categoryList}/>
<LatestItemList latestItemList={latestItemList}/>
</ScrollView>
)
|
LatestItemList component
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| import { View, Text, FlatList, Image, TouchableOpacity } from 'react-native'
import React from 'react'
import PostItem from './PostItem'
export default function LatestItemList({latestItemList}) {
return (
<View className="mt-3">
<Text className="font-bold text-[20px]">Latest Items</Text>
<FlatList
data={latestItemList}
numColumns={2}
renderItem={({item,index})=>(
<PostItem item={item} />
)}
/>
</View>
)
}
|
PostItem (reusable component)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| import { View, Text, TouchableOpacity, Image} from 'react-native'
import React from 'react'
export default function PostItem({item}) {
return (
<TouchableOpacity className="flex-1 m-2 p-2 rounded-lg border-[1px] border-slate-200">
<Image source=
className="w-full h-[140px] rounded-lg "
/>
<View>
<Text className="text-[15px] font-bold mt-2">{item.title}</Text>
<Text className="text-[20px] font-bold text-blue-500">$ {item.price}</Text>
<Text className="text-blue-500 bg-blue-200 mt-1 p-1 text-center rounded-full px-1 text-[10px] w-[70px]">{item.category}</Text>
</View>
</TouchableOpacity>
)
}
|