initial: add login
This commit is contained in:
28
config/auth.ts
Normal file
28
config/auth.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Router } from "expo-router";
|
||||
|
||||
let routerInstance: Router | null = null;
|
||||
|
||||
/**
|
||||
* Set router instance để dùng trong non-component context
|
||||
*/
|
||||
export const setRouterInstance = (router: Router) => {
|
||||
routerInstance = router;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle 401 error - redirect to login
|
||||
*/
|
||||
export const handle401 = () => {
|
||||
if (routerInstance) {
|
||||
(routerInstance as any).replace("/login");
|
||||
} else {
|
||||
console.warn("Router instance not set, cannot redirect to login");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear router instance (optional, for cleanup)
|
||||
*/
|
||||
export const clearRouterInstance = () => {
|
||||
routerInstance = null;
|
||||
};
|
||||
70
config/axios.ts
Normal file
70
config/axios.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import axios, { AxiosInstance } from "axios";
|
||||
import { handle401 } from "./auth";
|
||||
import { showToastError } from "./toast";
|
||||
|
||||
const codeMessage = {
|
||||
200: "The server successfully returned the requested data。",
|
||||
201: "New or modified data succeeded。",
|
||||
202: "A request has been queued in the background (asynchronous task)。",
|
||||
204: "Data deleted successfully。",
|
||||
400: "There is an error in the request sent, the server did not perform the operation of creating or modifying data。",
|
||||
401: "The user does not have permission (token, username, password is wrong) 。",
|
||||
403: "User is authorized, but access is prohibited。",
|
||||
404: "The request issued was for a non-existent record, the server did not operate。",
|
||||
406: "The requested format is not available。",
|
||||
410: "The requested resource is permanently deleted and will no longer be available。",
|
||||
422: "When creating an object, a validation error occurred。",
|
||||
500: "Server error, please check the server。",
|
||||
502: "Gateway error。",
|
||||
503: "Service unavailable, server temporarily overloaded or maintained。",
|
||||
504: "Gateway timeout。",
|
||||
};
|
||||
|
||||
// Tạo instance axios với cấu hình cơ bản
|
||||
const api: AxiosInstance = axios.create({
|
||||
baseURL: "http://192.168.30.102:81", // Thay bằng API thật của bạn
|
||||
timeout: 10000, // Timeout 10 giây
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
// Interceptor cho request (thêm token nếu cần)
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
// Thêm auth token nếu có
|
||||
// const token = getTokenFromStorage();
|
||||
// if (token) {
|
||||
// config.headers.Authorization = `Bearer ${token}`;
|
||||
// }
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// Interceptor cho response (xử lý lỗi chung)
|
||||
api.interceptors.response.use(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
// Xử lý lỗi chung, ví dụ: redirect login nếu 401
|
||||
const { status, statusText, data } = error.response;
|
||||
|
||||
// Ưu tiên: codeMessage → backend message → statusText
|
||||
const errMsg =
|
||||
codeMessage[status as keyof typeof codeMessage] ||
|
||||
data?.message ||
|
||||
statusText ||
|
||||
"Unknown error";
|
||||
showToastError(errMsg);
|
||||
if (error.response?.status === 401) {
|
||||
handle401();
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default api;
|
||||
3
config/index.ts
Normal file
3
config/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./auth";
|
||||
export { default as api } from "./axios";
|
||||
export * from "./toast";
|
||||
79
config/toast.ts
Normal file
79
config/toast.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export enum ToastType {
|
||||
SUCCESS = "success",
|
||||
ERROR = "error",
|
||||
WARNING = "error", // react-native-toast-message không có 'warning', dùng 'error'
|
||||
INFO = "info",
|
||||
}
|
||||
|
||||
/**
|
||||
* Success toast
|
||||
*/
|
||||
export const showToastSuccess = (message: string, title?: string): void => {
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: title || "Success",
|
||||
text2: message,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Error toast
|
||||
*/
|
||||
export const showToastError = (message: string, title?: string): void => {
|
||||
Toast.show({
|
||||
type: ToastType.ERROR,
|
||||
text1: title || ToastType.ERROR,
|
||||
text2: message,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Info toast
|
||||
*/
|
||||
export const showToastInfo = (message: string, title?: string): void => {
|
||||
Toast.show({
|
||||
type: ToastType.INFO,
|
||||
text1: title || ToastType.INFO,
|
||||
text2: message,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Warning toast
|
||||
*/
|
||||
export const showToastWarning = (message: string, title?: string): void => {
|
||||
Toast.show({
|
||||
type: ToastType.WARNING,
|
||||
text1: title || ToastType.WARNING,
|
||||
text2: message,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Default toast
|
||||
*/
|
||||
export const showToastDefault = (message: string, title?: string): void => {
|
||||
Toast.show({
|
||||
type: ToastType.INFO,
|
||||
text1: title || ToastType.INFO,
|
||||
text2: message,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom toast với type tùy chọn
|
||||
*/
|
||||
export const show = (
|
||||
message: string,
|
||||
type: ToastType,
|
||||
title?: string
|
||||
): void => {
|
||||
const titleText = title || type.charAt(0).toUpperCase() + type.slice(1);
|
||||
Toast.show({
|
||||
type,
|
||||
text1: titleText,
|
||||
text2: message,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user