fitst commit
This commit is contained in:
33
api/URLs.ts
Normal file
33
api/URLs.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
export const BASE_URL = 'https://api.infotarget.uz/';
|
||||
|
||||
export const API_URLS = {
|
||||
LOGIN: 'login/send_code/',
|
||||
LoginConfirm: 'login/confirm/',
|
||||
REFRESH: 'auth/token/refresh/',
|
||||
DASHBOARD_ADS: '/api/dashboard-ads/',
|
||||
DASHBOARD_ADS_DETAIL: (id: number) => `/api/dashboard-ads/${id}`,
|
||||
ResendOTP: 'login/resend/',
|
||||
Register: 'auth/register/',
|
||||
Register_Confirm: 'auth/confirm/',
|
||||
Register_Resend: 'auth/resend/',
|
||||
Get_Products: 'api/product-service/',
|
||||
Detail_Products: (id: number) => `api/product-service/${id}/`,
|
||||
Delete_Products: (id: number) => `api/product-service/${id}/`,
|
||||
Get_Company: 'api/product-service/product-service-legal-entity/',
|
||||
Get_Countries: 'api/product-service/product-service-country/',
|
||||
Get_States: 'api/countries/',
|
||||
Get_Categories: 'api/category/',
|
||||
Get_Categories_Child: (id: number) => `api/category/${id}/`,
|
||||
Business_About: 'api/business-about/',
|
||||
Business_About_Detail: (id: number) => `api/business-about/${id}/`,
|
||||
Price_Calculation: `api/price-calculation/`,
|
||||
Add_Ads: 'api/ad/',
|
||||
Payment_Ads: (paymentType: 'payme' | 'referral', adId: number) =>
|
||||
`api/payments/${paymentType}/${adId}/`,
|
||||
Get_Me: 'auth/me/',
|
||||
User_Update: 'auth/user-update/',
|
||||
Employee_List: 'api/employee/',
|
||||
My_Ads: 'api/my-ads/',
|
||||
My_Ads_Detail: (id: number) => `api/my-ads/${id}`,
|
||||
My_Bonuses: 'api/cashback/',
|
||||
};
|
||||
106
api/httpClient.ts
Normal file
106
api/httpClient.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import axios from 'axios';
|
||||
import { API_URLS, BASE_URL } from './URLs';
|
||||
|
||||
import { getToken } from '@/hooks/storage.native';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { router } from 'expo-router';
|
||||
|
||||
const httpClient = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
timeout: 60000,
|
||||
});
|
||||
|
||||
httpClient.interceptors.request.use(async (config) => {
|
||||
const token = await getToken();
|
||||
const lang = await AsyncStorage.getItem('lang');
|
||||
|
||||
config.headers['Accept-Language'] = lang;
|
||||
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
let isRefreshing = false;
|
||||
let failedQueue: Array<{ resolve: (value: any) => void; reject: (reason?: any) => void }> = [];
|
||||
|
||||
const processQueue = (error: any = null) => {
|
||||
failedQueue.forEach((prom) => {
|
||||
if (error) {
|
||||
prom.reject(error);
|
||||
} else {
|
||||
prom.resolve(null);
|
||||
}
|
||||
});
|
||||
failedQueue = [];
|
||||
};
|
||||
|
||||
httpClient.interceptors.response.use(
|
||||
(response) => response,
|
||||
|
||||
async (error) => {
|
||||
const originalRequest = error.config;
|
||||
|
||||
// Agar 401 bo'lsa va bu refresh so'rovi bo'lmasa
|
||||
if (error.response?.status === 401 && !originalRequest._retry) {
|
||||
if (isRefreshing) {
|
||||
// Agar allaqachon refresh ketayotgan bo'lsa → kutamiz
|
||||
return new Promise((resolve, reject) => {
|
||||
failedQueue.push({ resolve, reject });
|
||||
})
|
||||
.then(() => httpClient(originalRequest))
|
||||
.catch((err) => Promise.reject(err));
|
||||
}
|
||||
|
||||
originalRequest._retry = true;
|
||||
isRefreshing = true;
|
||||
|
||||
try {
|
||||
const refresh = await AsyncStorage.getItem('refresh_token');
|
||||
|
||||
if (!refresh) {
|
||||
throw new Error('Refresh token mavjud emas');
|
||||
}
|
||||
|
||||
// Refresh token so'rovi
|
||||
const { data } = await axios.post(`${BASE_URL}${API_URLS.REFRESH}`, {
|
||||
refresh, // backend odatda { refresh } body kutadi
|
||||
});
|
||||
|
||||
// Yangi tokenlarni saqlaymiz
|
||||
await AsyncStorage.setItem('access_token', data.access);
|
||||
await AsyncStorage.setItem('refresh_token', data.refresh || refresh); // agar yangi refresh kelmasa, eskisini saqlab qolamiz
|
||||
|
||||
// Headerni yangilaymiz
|
||||
originalRequest.headers.Authorization = `Bearer ${data.access}`;
|
||||
|
||||
// Kutgan so'rovlarni qayta yuboramiz
|
||||
processQueue();
|
||||
|
||||
// Original so'rovni qayta yuboramiz
|
||||
return httpClient(originalRequest);
|
||||
} catch (refreshError) {
|
||||
console.error('Refresh token xatosi:', refreshError);
|
||||
|
||||
// Refresh muvaffaqiyatsiz bo'lsa
|
||||
processQueue(refreshError);
|
||||
|
||||
// Tokenlarni o'chirib, logout qilamiz
|
||||
await AsyncStorage.removeItem('access_token');
|
||||
await AsyncStorage.removeItem('refresh_token');
|
||||
|
||||
// Foydalanuvchini login sahifasiga yo'naltiramiz
|
||||
router.replace('/');
|
||||
} finally {
|
||||
isRefreshing = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Boshqa xatolar uchun oddiy reject
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default httpClient;
|
||||
Reference in New Issue
Block a user