Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
node_modules/
.expo/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
.env
web-build/

# macOS
.DS_Store

node_modules/
.expo/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
# macOS
.DS_Store
config.bat
124 changes: 62 additions & 62 deletions app/components/SearchBar.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,62 @@
import React from 'react';
import { View, StyleSheet, Text, TouchableOpacity } from 'react-native';
import tailwind from 'tailwind-react-native-classnames';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete'
import { Ionicons } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';

const SearchBar = ({ setCity, city }) => {

return (
<View style={tailwind`flex-row mt-3 px-4 pb-3 border-b border-gray-100 border-b-2`}>
<GooglePlacesAutocomplete
placeholder={city || "Search"}
nearbyPlacesAPI="GooglePlacesSearch"
debounce={400}
onPress={data => setCity(data.structured_formatting.main_text)}
minLength={2}
fetchDetails={true}
returnKeyType={"search"}
onFail={error => console.error(error)}
query={{
key: "GOOGLE_MAP_APIKEY",
language: 'en',
}}
styles={{
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
textInput: {
fontSize: 15,
fontWeight: '700',
backgroundColor: '#F3F4F6',
marginTop: 4
},
textInputContainer: {
backgroundColor: '#F3F4F6',
borderRadius: 40,
justifyContent: 'center',
}
}}
enablePoweredByContainer={false}
renderLeftButton={() => (
<View style={tailwind`self-center ml-3`}>
<Ionicons name="ios-location-sharp" size={24} color="#CCCCCC" />
</View>
)}
renderRightButton={() => (
<TouchableOpacity style={tailwind`self-center ml-3 flex-row items-center bg-white py-2 px-3 rounded-full mr-3`}>
<MaterialCommunityIcons name="clock-time-four" size={13} color="black" />
<Text style={tailwind`ml-1`}>Search</Text>
</TouchableOpacity>
)}
/>
</View>
);
}

const styles = StyleSheet.create({})

export default SearchBar;
import React from 'react';
import { View, StyleSheet, Text, TouchableOpacity } from 'react-native';
import tailwind from 'tailwind-react-native-classnames';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete'
import { Ionicons } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';
const SearchBar = ({ setCity, city }) => {
return (
<View style={tailwind`flex-row mt-3 px-4 pb-3 border-b border-gray-100 border-b-2`}>
<GooglePlacesAutocomplete
placeholder={city || "Search"}
nearbyPlacesAPI="GooglePlacesSearch"
debounce={400}
onPress={data => setCity(data.structured_formatting.main_text)}
minLength={2}
fetchDetails={true}
returnKeyType={"search"}
onFail={error => console.error(error)}
query={{
key: "GOOGLE_MAP_APIKEY",
language: 'en',
}}
styles={{
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
textInput: {
fontSize: 15,
fontWeight: '700',
backgroundColor: '#F3F4F6',
marginTop: 4
},
textInputContainer: {
backgroundColor: '#F3F4F6',
borderRadius: 40,
justifyContent: 'center',
}
}}
enablePoweredByContainer={false}
renderLeftButton={() => (
<View style={tailwind`self-center ml-3`}>
<Ionicons name="ios-location-sharp" size={24} color="#CCCCCC" />
</View>
)}
renderRightButton={() => (
<TouchableOpacity style={tailwind`self-center ml-3 flex-row items-center bg-white py-2 px-3 rounded-full mr-3`}>
<MaterialCommunityIcons name="clock-time-four" size={13} color="black" />
<Text style={tailwind`ml-1`}>Search</Text>
</TouchableOpacity>
)}
/>
</View>
);
}
const styles = StyleSheet.create({})
export default SearchBar;
84 changes: 42 additions & 42 deletions app/navigation/AppNavigator.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
import React, { useEffect } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { useDispatch, useSelector } from 'react-redux';
import { loginUser, logoutUser, selectUser } from '../redux/slices/authSlice';
import AuthNavigator from './AuthNavigator';
import { auth } from '../configs/firebase';
import HomeNavigator from './HomeNavigator';

export default function AppNavigator() {
const user = useSelector(selectUser)
const dispatch = useDispatch()

useEffect(() => {
const unlisten = auth.onAuthStateChanged(authUser => {
if (authUser) {
const user = {
name: authUser.displayName,
image: authUser.photoURL,
email: authUser.email
}
dispatch(loginUser(user))
}
else {
dispatch(logoutUser())
}
})
return () => {
unlisten();
}
}, [])

return (
<NavigationContainer>
{user ? (
<HomeNavigator />
) : (
<AuthNavigator />
)}
</NavigationContainer>
)


import React, { useEffect } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { useDispatch, useSelector } from 'react-redux';
import { loginUser, logoutUser, selectUser } from '../redux/slices/authSlice';
import AuthNavigator from './AuthNavigator';
import { auth } from '../configs/firebase';
import HomeNavigator from './HomeNavigator';
export default function AppNavigator() {
const user = useSelector(selectUser)
const dispatch = useDispatch()
useEffect(() => {
const unlisten = auth.onAuthStateChanged(authUser => {
if (authUser) {
const user = {
name: authUser.displayName,
image: authUser.photoURL,
email: authUser.email
}
dispatch(loginUser(user))
}
else {
dispatch(logoutUser())
}
})
return () => {
unlisten();
}
}, [])
return (
<NavigationContainer>
{user ? (
<HomeNavigator />
) : (
<AuthNavigator />
)}
</NavigationContainer>
)
}
122 changes: 61 additions & 61 deletions app/screens/HomeScreen.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, Alert, ActivityIndicator } from 'react-native';
import HeaderTabs from '../components/HeaderTabs';
import Screen from '../components/Screen'
import Categories from '../components/Categories'
import SearchBar from '../components/SearchBar'
import RestaurantItem from '../components/RestaurantItem'
import tailwind from 'tailwind-react-native-classnames';
import { localRestaurants } from '../data/localRestaurants';
import colors from '../configs/colors'

const YELP_API_KEY = "YELP_API_KEY";

const HomeScreen = () => {
const [restaurantData, setRestaurantData] = useState(localRestaurants)
const [city, setCity] = useState("San Francisco")
const [activeTab, setActiveTab] = useState("Delivery");
const [loading, setLoading] = useState(false)

const getRestaurantsFromYelp = () => {
const yelpUrl = `https://api.yelp.com/v3/businesses/search?term=restaurants&location=${city}`;

const apiOptions = {
headers: {
Authorization: `Bearer ${YELP_API_KEY}`,
},
};
setLoading(true)
return fetch(yelpUrl, apiOptions)
.then((res) => res.json())
.then((json) => {
setLoading(false)
if(json.error) return Alert.alert('Sorry', json.error.description);
setRestaurantData(
json?.businesses?.filter((business) =>
business.transactions.includes(activeTab.toLowerCase())
)
)
}
);
};

useEffect(() => {
getRestaurantsFromYelp();
}, [city, activeTab]);


return (
<Screen style={tailwind`bg-white flex-1`}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar setCity={setCity} city={city} />
<ScrollView style={tailwind`flex-1`} showsVerticalScrollIndicator={false}>
<Categories />
{loading && <ActivityIndicator size="large" color={colors.primary} style={tailwind`mt-2 mb-6`} />}
<RestaurantItem restaurantData={restaurantData} />
</ScrollView>
</Screen>
);
}

export default HomeScreen;
import React, { useEffect, useState } from 'react';
import { ScrollView, Alert, ActivityIndicator } from 'react-native';
import HeaderTabs from '../components/HeaderTabs';
import Screen from '../components/Screen'
import Categories from '../components/Categories'
import SearchBar from '../components/SearchBar'
import RestaurantItem from '../components/RestaurantItem'
import tailwind from 'tailwind-react-native-classnames';
import { localRestaurants } from '../data/localRestaurants';
import colors from '../configs/colors'
const YELP_API_KEY = "YELP_API_KEY";
const HomeScreen = () => {
const [restaurantData, setRestaurantData] = useState(localRestaurants)
const [city, setCity] = useState("San Francisco")
const [activeTab, setActiveTab] = useState("Delivery");
const [loading, setLoading] = useState(false)
const getRestaurantsFromYelp = () => {
const yelpUrl = `https://api.yelp.com/v3/businesses/search?term=restaurants&location=${city}`;
const apiOptions = {
headers: {
Authorization: `Bearer ${YELP_API_KEY}`,
},
};
setLoading(true)
return fetch(yelpUrl, apiOptions)
.then((res) => res.json())
.then((json) => {
setLoading(false)
if(json.error) return Alert.alert('Sorry', json.error.description);
setRestaurantData(
json?.businesses?.filter((business) =>
business.transactions.includes(activeTab.toLowerCase())
)
)
}
);
};
useEffect(() => {
getRestaurantsFromYelp();
}, [city, activeTab]);
return (
<Screen style={tailwind`bg-white flex-1`}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar setCity={setCity} city={city} />
<ScrollView style={tailwind`flex-1`} showsVerticalScrollIndicator={false}>
<Categories />
{loading && <ActivityIndicator size="large" color={colors.primary} style={tailwind`mt-2 mb-6`} />}
<RestaurantItem restaurantData={restaurantData} />
</ScrollView>
</Screen>
);
}
export default HomeScreen;
30 changes: 15 additions & 15 deletions babel.config.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading