my redux actions:
<code>export const RESTAURANT_SUCCESS = 'RESTAURANT_SUCCESS';
export const RESTAURANT_FAILURE = 'RESTAURANT_FAILURE';
export const GET_MORE_RESTAURANTS_SUCCESS = 'GET_MORE_RESTAURANTS_SUCCESS';
export const restaurantSuccess = (restaurants) => ({
type: RESTAURANT_SUCCESS,
payload: restaurants,
> });
export const restaurantsFailure = (error) => ({
type: RESTAURANT_FAILURE,
payload: error,
> });
export const getMoreRestaurants = (restaurants, page) => ({
type: GET_MORE_RESTAURANTS_SUCCESS,
payload: { restaurants, page },
</code>
<code>export const RESTAURANT_SUCCESS = 'RESTAURANT_SUCCESS';
export const RESTAURANT_FAILURE = 'RESTAURANT_FAILURE';
export const GET_MORE_RESTAURANTS_SUCCESS = 'GET_MORE_RESTAURANTS_SUCCESS';
export const restaurantSuccess = (restaurants) => ({
type: RESTAURANT_SUCCESS,
payload: restaurants,
> });
export const restaurantsFailure = (error) => ({
type: RESTAURANT_FAILURE,
payload: error,
> });
export const getMoreRestaurants = (restaurants, page) => ({
type: GET_MORE_RESTAURANTS_SUCCESS,
payload: { restaurants, page },
</code>
export const RESTAURANT_SUCCESS = 'RESTAURANT_SUCCESS';
export const RESTAURANT_FAILURE = 'RESTAURANT_FAILURE';
export const GET_MORE_RESTAURANTS_SUCCESS = 'GET_MORE_RESTAURANTS_SUCCESS';
export const restaurantSuccess = (restaurants) => ({
type: RESTAURANT_SUCCESS,
payload: restaurants,
> });
export const restaurantsFailure = (error) => ({
type: RESTAURANT_FAILURE,
payload: error,
> });
export const getMoreRestaurants = (restaurants, page) => ({
type: GET_MORE_RESTAURANTS_SUCCESS,
payload: { restaurants, page },
redux reducer:
<code>import { RESTAURANT_FAILURE, RESTAURANT_SUCCESS, GET_MORE_RESTAURANTS_SUCCESS } from './restaurantActions';
const initialState = {
restaurants: [],
error: null,
page: 1,
};
const restaurantReducer = (state = initialState, action) => {
switch (action.type) {
case RESTAURANT_SUCCESS:
return {
...state,
restaurants: action.payload,
};
case RESTAURANT_FAILURE:
return {
...state,
error: action.payload,
};
case GET_MORE_RESTAURANTS_SUCCESS:
return {
...state,
restaurants: [...state.restaurants, ...action.payload.restaurants],
page: action.payload.page,
};
default:
return state;
}
};
export default restaurantReducer;
</code>
<code>import { RESTAURANT_FAILURE, RESTAURANT_SUCCESS, GET_MORE_RESTAURANTS_SUCCESS } from './restaurantActions';
const initialState = {
restaurants: [],
error: null,
page: 1,
};
const restaurantReducer = (state = initialState, action) => {
switch (action.type) {
case RESTAURANT_SUCCESS:
return {
...state,
restaurants: action.payload,
};
case RESTAURANT_FAILURE:
return {
...state,
error: action.payload,
};
case GET_MORE_RESTAURANTS_SUCCESS:
return {
...state,
restaurants: [...state.restaurants, ...action.payload.restaurants],
page: action.payload.page,
};
default:
return state;
}
};
export default restaurantReducer;
</code>
import { RESTAURANT_FAILURE, RESTAURANT_SUCCESS, GET_MORE_RESTAURANTS_SUCCESS } from './restaurantActions';
const initialState = {
restaurants: [],
error: null,
page: 1,
};
const restaurantReducer = (state = initialState, action) => {
switch (action.type) {
case RESTAURANT_SUCCESS:
return {
...state,
restaurants: action.payload,
};
case RESTAURANT_FAILURE:
return {
...state,
error: action.payload,
};
case GET_MORE_RESTAURANTS_SUCCESS:
return {
...state,
restaurants: [...state.restaurants, ...action.payload.restaurants],
page: action.payload.page,
};
default:
return state;
}
};
export default restaurantReducer;
jsx file:
<code>import { View, Text, SafeAreaView, TouchableOpacity, FlatList, Image, TextInput, ActivityIndicator } from 'react-native';
import React, { useState, useEffect, memo } from 'react';
import Ionicons from '@expo/vector-icons/Ionicons';
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import EvilIcons from '@expo/vector-icons/EvilIcons';
import AntDesign from '@expo/vector-icons/AntDesign';
import Categories from '../components/Categories';
import apiController from '../../axios/apiController';
import { useDispatch, useSelector } from 'react-redux';
import { getStars } from '../utils/ratingUtils';
import { GET_MORE_RESTAURANTS_SUCCESS } from '../../redux/restaurantActions';
const RestaurantItem = memo(({ name, address, image, review, onPress }) => (
<View className="">
<TouchableOpacity onPress={onPress}>
<View style={{ width: 335, height: 60, marginVertical: 10, position: 'relative', marginTop: 16 }}>
<View style={{ width: 70, height: 60, borderRadius: 15, backgroundColor: '#d7d7d7', position: 'absolute', left: 0, top: 0 }}>
<Image source={image} style={{ width: '100%', height: '100%', borderRadius: 15 }} resizeMode='cover' />
</View>
<View style={{ marginLeft: 85, marginTop: 0 }}>
<Text style={{ color: '#3e3e3e', fontSize: 16, fontWeight: 'bold' }}>{name}</Text>
<Text style={{ color: '#a3a3a3', fontSize: 11 }}>{address}</Text>
<View style={{ flexDirection: 'row', alignItems: 'center', marginTop: 2 }}>
<View className="bg-primary" style={{ width: 30, height: 18, borderRadius: 7, justifyContent: 'center', alignItems: 'center', marginRight: 5 }}>
<Text style={{ color: 'white', fontSize: 11, fontWeight: 'normal' }}>{review}</Text>
</View>
<View style={{ flexDirection: 'row' }}>
{getStars(review)}
</View>
</View>
</View>
</View>
</TouchableOpacity>
</View>
));
const ItemSeparator = memo(() => (
<View style={{ height: 1, backgroundColor: '#d3d3d3', marginVertical: 10 }} />
));
const renderLoader = memo(() => (
<View>
<ActivityIndicator size="small" color="gray"/>
</View>
));
const AllRestaurants = ({ navigation }) => {
const dispatch = useDispatch();
const { restaurants, error, page } = useSelector(state => state.restaurant);
const [loadingMore, setLoadingMore] = useState(false);
const [isLastPage, setIsLastPage] = useState(false);
useEffect(() => {
const fetchRestaurants = async () => {
if (loadingMore || isLastPage) return;
setLoadingMore(true);
try {
const response = await apiController.restaurant(page);
if (response.length === 0) {
setIsLastPage(true);
} else {
dispatch({ type: 'GET_MORE_RESTAURANTS_SUCCESS', payload: { restaurants: response, page: page + 1 } });
}
} catch (error) {
dispatch({ type: 'RESTAURANT_FAILURE', payload: error.message });
console.error('Error fetching restaurants:', error);
}
setLoadingMore(false);
};
fetchRestaurants();
}, [dispatch, page, loadingMore, isLastPage]);
const loadMoreItems = () => {
if (!loadingMore && !isLastPage) {
setLoadingMore(true);
}
};
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#f1f0f3' }}>
<View className="bg-white">
<View className="flex-row items-center">
<TouchableOpacity className="ml-2" onPress={() => navigation.goBack()}>
<Ionicons name="chevron-back-outline" size={22} color="gray" />
</TouchableOpacity>
<View style={{ backgroundColor: 'white', flexDirection: 'row', alignItems: 'center', marginHorizontal: 2, marginVertical: 10, borderRadius: 35 }}>
<View style={{ flexDirection: 'row', width: '80%', height: 40, alignItems: 'center', backgroundColor: '#f1f0f3', borderRadius: 20, paddingHorizontal: 10 }}>
<EvilIcons name="search" size={30} color="gray" />
<TextInput
style={{ flex: 1, marginLeft: 10 }}
placeholder="Yemek, mutfak veya restoran arayın"
placeholderTextColor="gray"
/>
</View>
<TouchableOpacity style={{ justifyContent: 'center', alignItems: 'center', width: '15%', backgroundColor: 'white', borderRadius: 20, paddingHorizontal: 10 }}>
<AntDesign name="filter" size={20} color="red" />
<Text style={{ color: '#ff5656', fontSize: 10 }}>Filtrele</Text>
</TouchableOpacity>
</View>
</View>
<View className="mt-4">
<Categories />
</View>
</View>
<FlatList
data={restaurants}
renderItem={({ item }) => <RestaurantItem name={item.name} address={item.address.shortAddress} review={item.rating} onPress={() => navigation.navigate('Restaurant Detail', { place: item })} />}
keyExtractor={(item) => item.id}
contentContainerStyle={{ paddingHorizontal: 10 }}
ItemSeparatorComponent={ItemSeparator}
initialNumToRender={15}
ListFooterComponent={renderLoader}
onEndReached={loadMoreItems}
onEndReachedThreshold={0.5}
/>
</SafeAreaView>
);
}
export default AllRestaurants;
</code>
<code>import { View, Text, SafeAreaView, TouchableOpacity, FlatList, Image, TextInput, ActivityIndicator } from 'react-native';
import React, { useState, useEffect, memo } from 'react';
import Ionicons from '@expo/vector-icons/Ionicons';
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import EvilIcons from '@expo/vector-icons/EvilIcons';
import AntDesign from '@expo/vector-icons/AntDesign';
import Categories from '../components/Categories';
import apiController from '../../axios/apiController';
import { useDispatch, useSelector } from 'react-redux';
import { getStars } from '../utils/ratingUtils';
import { GET_MORE_RESTAURANTS_SUCCESS } from '../../redux/restaurantActions';
const RestaurantItem = memo(({ name, address, image, review, onPress }) => (
<View className="">
<TouchableOpacity onPress={onPress}>
<View style={{ width: 335, height: 60, marginVertical: 10, position: 'relative', marginTop: 16 }}>
<View style={{ width: 70, height: 60, borderRadius: 15, backgroundColor: '#d7d7d7', position: 'absolute', left: 0, top: 0 }}>
<Image source={image} style={{ width: '100%', height: '100%', borderRadius: 15 }} resizeMode='cover' />
</View>
<View style={{ marginLeft: 85, marginTop: 0 }}>
<Text style={{ color: '#3e3e3e', fontSize: 16, fontWeight: 'bold' }}>{name}</Text>
<Text style={{ color: '#a3a3a3', fontSize: 11 }}>{address}</Text>
<View style={{ flexDirection: 'row', alignItems: 'center', marginTop: 2 }}>
<View className="bg-primary" style={{ width: 30, height: 18, borderRadius: 7, justifyContent: 'center', alignItems: 'center', marginRight: 5 }}>
<Text style={{ color: 'white', fontSize: 11, fontWeight: 'normal' }}>{review}</Text>
</View>
<View style={{ flexDirection: 'row' }}>
{getStars(review)}
</View>
</View>
</View>
</View>
</TouchableOpacity>
</View>
));
const ItemSeparator = memo(() => (
<View style={{ height: 1, backgroundColor: '#d3d3d3', marginVertical: 10 }} />
));
const renderLoader = memo(() => (
<View>
<ActivityIndicator size="small" color="gray"/>
</View>
));
const AllRestaurants = ({ navigation }) => {
const dispatch = useDispatch();
const { restaurants, error, page } = useSelector(state => state.restaurant);
const [loadingMore, setLoadingMore] = useState(false);
const [isLastPage, setIsLastPage] = useState(false);
useEffect(() => {
const fetchRestaurants = async () => {
if (loadingMore || isLastPage) return;
setLoadingMore(true);
try {
const response = await apiController.restaurant(page);
if (response.length === 0) {
setIsLastPage(true);
} else {
dispatch({ type: 'GET_MORE_RESTAURANTS_SUCCESS', payload: { restaurants: response, page: page + 1 } });
}
} catch (error) {
dispatch({ type: 'RESTAURANT_FAILURE', payload: error.message });
console.error('Error fetching restaurants:', error);
}
setLoadingMore(false);
};
fetchRestaurants();
}, [dispatch, page, loadingMore, isLastPage]);
const loadMoreItems = () => {
if (!loadingMore && !isLastPage) {
setLoadingMore(true);
}
};
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#f1f0f3' }}>
<View className="bg-white">
<View className="flex-row items-center">
<TouchableOpacity className="ml-2" onPress={() => navigation.goBack()}>
<Ionicons name="chevron-back-outline" size={22} color="gray" />
</TouchableOpacity>
<View style={{ backgroundColor: 'white', flexDirection: 'row', alignItems: 'center', marginHorizontal: 2, marginVertical: 10, borderRadius: 35 }}>
<View style={{ flexDirection: 'row', width: '80%', height: 40, alignItems: 'center', backgroundColor: '#f1f0f3', borderRadius: 20, paddingHorizontal: 10 }}>
<EvilIcons name="search" size={30} color="gray" />
<TextInput
style={{ flex: 1, marginLeft: 10 }}
placeholder="Yemek, mutfak veya restoran arayın"
placeholderTextColor="gray"
/>
</View>
<TouchableOpacity style={{ justifyContent: 'center', alignItems: 'center', width: '15%', backgroundColor: 'white', borderRadius: 20, paddingHorizontal: 10 }}>
<AntDesign name="filter" size={20} color="red" />
<Text style={{ color: '#ff5656', fontSize: 10 }}>Filtrele</Text>
</TouchableOpacity>
</View>
</View>
<View className="mt-4">
<Categories />
</View>
</View>
<FlatList
data={restaurants}
renderItem={({ item }) => <RestaurantItem name={item.name} address={item.address.shortAddress} review={item.rating} onPress={() => navigation.navigate('Restaurant Detail', { place: item })} />}
keyExtractor={(item) => item.id}
contentContainerStyle={{ paddingHorizontal: 10 }}
ItemSeparatorComponent={ItemSeparator}
initialNumToRender={15}
ListFooterComponent={renderLoader}
onEndReached={loadMoreItems}
onEndReachedThreshold={0.5}
/>
</SafeAreaView>
);
}
export default AllRestaurants;
</code>
import { View, Text, SafeAreaView, TouchableOpacity, FlatList, Image, TextInput, ActivityIndicator } from 'react-native';
import React, { useState, useEffect, memo } from 'react';
import Ionicons from '@expo/vector-icons/Ionicons';
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import EvilIcons from '@expo/vector-icons/EvilIcons';
import AntDesign from '@expo/vector-icons/AntDesign';
import Categories from '../components/Categories';
import apiController from '../../axios/apiController';
import { useDispatch, useSelector } from 'react-redux';
import { getStars } from '../utils/ratingUtils';
import { GET_MORE_RESTAURANTS_SUCCESS } from '../../redux/restaurantActions';
const RestaurantItem = memo(({ name, address, image, review, onPress }) => (
<View className="">
<TouchableOpacity onPress={onPress}>
<View style={{ width: 335, height: 60, marginVertical: 10, position: 'relative', marginTop: 16 }}>
<View style={{ width: 70, height: 60, borderRadius: 15, backgroundColor: '#d7d7d7', position: 'absolute', left: 0, top: 0 }}>
<Image source={image} style={{ width: '100%', height: '100%', borderRadius: 15 }} resizeMode='cover' />
</View>
<View style={{ marginLeft: 85, marginTop: 0 }}>
<Text style={{ color: '#3e3e3e', fontSize: 16, fontWeight: 'bold' }}>{name}</Text>
<Text style={{ color: '#a3a3a3', fontSize: 11 }}>{address}</Text>
<View style={{ flexDirection: 'row', alignItems: 'center', marginTop: 2 }}>
<View className="bg-primary" style={{ width: 30, height: 18, borderRadius: 7, justifyContent: 'center', alignItems: 'center', marginRight: 5 }}>
<Text style={{ color: 'white', fontSize: 11, fontWeight: 'normal' }}>{review}</Text>
</View>
<View style={{ flexDirection: 'row' }}>
{getStars(review)}
</View>
</View>
</View>
</View>
</TouchableOpacity>
</View>
));
const ItemSeparator = memo(() => (
<View style={{ height: 1, backgroundColor: '#d3d3d3', marginVertical: 10 }} />
));
const renderLoader = memo(() => (
<View>
<ActivityIndicator size="small" color="gray"/>
</View>
));
const AllRestaurants = ({ navigation }) => {
const dispatch = useDispatch();
const { restaurants, error, page } = useSelector(state => state.restaurant);
const [loadingMore, setLoadingMore] = useState(false);
const [isLastPage, setIsLastPage] = useState(false);
useEffect(() => {
const fetchRestaurants = async () => {
if (loadingMore || isLastPage) return;
setLoadingMore(true);
try {
const response = await apiController.restaurant(page);
if (response.length === 0) {
setIsLastPage(true);
} else {
dispatch({ type: 'GET_MORE_RESTAURANTS_SUCCESS', payload: { restaurants: response, page: page + 1 } });
}
} catch (error) {
dispatch({ type: 'RESTAURANT_FAILURE', payload: error.message });
console.error('Error fetching restaurants:', error);
}
setLoadingMore(false);
};
fetchRestaurants();
}, [dispatch, page, loadingMore, isLastPage]);
const loadMoreItems = () => {
if (!loadingMore && !isLastPage) {
setLoadingMore(true);
}
};
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#f1f0f3' }}>
<View className="bg-white">
<View className="flex-row items-center">
<TouchableOpacity className="ml-2" onPress={() => navigation.goBack()}>
<Ionicons name="chevron-back-outline" size={22} color="gray" />
</TouchableOpacity>
<View style={{ backgroundColor: 'white', flexDirection: 'row', alignItems: 'center', marginHorizontal: 2, marginVertical: 10, borderRadius: 35 }}>
<View style={{ flexDirection: 'row', width: '80%', height: 40, alignItems: 'center', backgroundColor: '#f1f0f3', borderRadius: 20, paddingHorizontal: 10 }}>
<EvilIcons name="search" size={30} color="gray" />
<TextInput
style={{ flex: 1, marginLeft: 10 }}
placeholder="Yemek, mutfak veya restoran arayın"
placeholderTextColor="gray"
/>
</View>
<TouchableOpacity style={{ justifyContent: 'center', alignItems: 'center', width: '15%', backgroundColor: 'white', borderRadius: 20, paddingHorizontal: 10 }}>
<AntDesign name="filter" size={20} color="red" />
<Text style={{ color: '#ff5656', fontSize: 10 }}>Filtrele</Text>
</TouchableOpacity>
</View>
</View>
<View className="mt-4">
<Categories />
</View>
</View>
<FlatList
data={restaurants}
renderItem={({ item }) => <RestaurantItem name={item.name} address={item.address.shortAddress} review={item.rating} onPress={() => navigation.navigate('Restaurant Detail', { place: item })} />}
keyExtractor={(item) => item.id}
contentContainerStyle={{ paddingHorizontal: 10 }}
ItemSeparatorComponent={ItemSeparator}
initialNumToRender={15}
ListFooterComponent={renderLoader}
onEndReached={loadMoreItems}
onEndReachedThreshold={0.5}
/>
</SafeAreaView>
);
}
export default AllRestaurants;
my store:
<code>import { configureStore } from '@reduxjs/toolkit';
import { combineReducers} from 'redux';
import addressReducer from './addressReducer';
import authReducer from './authReducer';
import restaurantReducer from './restaurantReducer';
import locationReducer from './locationReducer';
const rootReducer = combineReducers({
address: addressReducer,
auth: authReducer,
restaurant: restaurantReducer,
location: locationReducer
});
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
immutableCheck: false,
serializableCheck: false,
}),
});
export default store;
</code>
<code>import { configureStore } from '@reduxjs/toolkit';
import { combineReducers} from 'redux';
import addressReducer from './addressReducer';
import authReducer from './authReducer';
import restaurantReducer from './restaurantReducer';
import locationReducer from './locationReducer';
const rootReducer = combineReducers({
address: addressReducer,
auth: authReducer,
restaurant: restaurantReducer,
location: locationReducer
});
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
immutableCheck: false,
serializableCheck: false,
}),
});
export default store;
</code>
import { configureStore } from '@reduxjs/toolkit';
import { combineReducers} from 'redux';
import addressReducer from './addressReducer';
import authReducer from './authReducer';
import restaurantReducer from './restaurantReducer';
import locationReducer from './locationReducer';
const rootReducer = combineReducers({
address: addressReducer,
auth: authReducer,
restaurant: restaurantReducer,
location: locationReducer
});
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
immutableCheck: false,
serializableCheck: false,
}),
});
export default store;
<code>
import apiYakala from "./apiYakala";
import AsyncStorage from '@react-native-async-storage/async-storage';
const registerController = async (body) => {
try {
const response = await apiYakala.post('/api/users', body);
const { token } = response;
await AsyncStorage.setItem('jwtToken', token);
return response;
} catch (error) {
console.error('Registration Error:', error.response?.data || error.message);
throw new Error("Hata kodu: " + error.response?.status);
}
}
const loginController = async (body) => {
const response = await apiYakala.post('/api/users/login', body);
const { token } = response;
await AsyncStorage.setItem('jwtToken', token);
return response;
}
const restaurantController = async(page=1) => {
return await apiYakala.get(`/api/places?page=${page}`);
}
export default {
register: registerController,
login: loginController,
restaurant: restaurantController
};
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
const api = axios.create({
baseURL: "https://api.yaka.la",
timeout: 1000,
responseType: 'json',
withCredentials: true,
headers: {
'Content-Type': 'application/json',
'Accept' : 'application/json'
}
});
api.interceptors.request.use(
async (config) => {
const token = await AsyncStorage.getItem('jwtToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
export default {
post: async (url, body, additionalHeaders = {}) => {
try {
const response = await api.post(url, body, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
},
get: async (url, additionalHeaders = {}) => {
try {
const response = await api.get(url, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
},
patch: async (url, body, additionalHeaders = {}) => {
try {
const response = await api.patch(url, body, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
}
};
</code>
<code>
import apiYakala from "./apiYakala";
import AsyncStorage from '@react-native-async-storage/async-storage';
const registerController = async (body) => {
try {
const response = await apiYakala.post('/api/users', body);
const { token } = response;
await AsyncStorage.setItem('jwtToken', token);
return response;
} catch (error) {
console.error('Registration Error:', error.response?.data || error.message);
throw new Error("Hata kodu: " + error.response?.status);
}
}
const loginController = async (body) => {
const response = await apiYakala.post('/api/users/login', body);
const { token } = response;
await AsyncStorage.setItem('jwtToken', token);
return response;
}
const restaurantController = async(page=1) => {
return await apiYakala.get(`/api/places?page=${page}`);
}
export default {
register: registerController,
login: loginController,
restaurant: restaurantController
};
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
const api = axios.create({
baseURL: "https://api.yaka.la",
timeout: 1000,
responseType: 'json',
withCredentials: true,
headers: {
'Content-Type': 'application/json',
'Accept' : 'application/json'
}
});
api.interceptors.request.use(
async (config) => {
const token = await AsyncStorage.getItem('jwtToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
export default {
post: async (url, body, additionalHeaders = {}) => {
try {
const response = await api.post(url, body, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
},
get: async (url, additionalHeaders = {}) => {
try {
const response = await api.get(url, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
},
patch: async (url, body, additionalHeaders = {}) => {
try {
const response = await api.patch(url, body, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
}
};
</code>
import apiYakala from "./apiYakala";
import AsyncStorage from '@react-native-async-storage/async-storage';
const registerController = async (body) => {
try {
const response = await apiYakala.post('/api/users', body);
const { token } = response;
await AsyncStorage.setItem('jwtToken', token);
return response;
} catch (error) {
console.error('Registration Error:', error.response?.data || error.message);
throw new Error("Hata kodu: " + error.response?.status);
}
}
const loginController = async (body) => {
const response = await apiYakala.post('/api/users/login', body);
const { token } = response;
await AsyncStorage.setItem('jwtToken', token);
return response;
}
const restaurantController = async(page=1) => {
return await apiYakala.get(`/api/places?page=${page}`);
}
export default {
register: registerController,
login: loginController,
restaurant: restaurantController
};
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
const api = axios.create({
baseURL: "https://api.yaka.la",
timeout: 1000,
responseType: 'json',
withCredentials: true,
headers: {
'Content-Type': 'application/json',
'Accept' : 'application/json'
}
});
api.interceptors.request.use(
async (config) => {
const token = await AsyncStorage.getItem('jwtToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
export default {
post: async (url, body, additionalHeaders = {}) => {
try {
const response = await api.post(url, body, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
},
get: async (url, additionalHeaders = {}) => {
try {
const response = await api.get(url, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
},
patch: async (url, body, additionalHeaders = {}) => {
try {
const response = await api.patch(url, body, {
headers: { ...additionalHeaders }
});
return response.data;
} catch (error) {
console.error(error.response.data);
throw new Error("Hata kodu: " + error.response?.status);
}
}
};
I want to add an infinite scrolling to show all restaurants to user when user scrolling up.But when scrolling up, it always re-rendering same restaurants with new ones. İ just want to see the new ones. I couldn’t solve this problem if anyone knows how to deal with this issue please help me.