From c1439f5fe0c5e3298e919043400d2b7e13547955 Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Thu, 14 Aug 2025 16:37:00 +0330 Subject: [PATCH] feat: add axtios instanse and useApi hook --- index.html | 56 +++++++++++++++++++++----------------------- src/hooks/useApi.ts | 24 +++++++++++++++++++ src/lib/apiClient.ts | 56 ++++++++++++++++++++++++++++++++++++++++++++ vite.config.d.ts | 2 +- vite.config.js | 10 ++++---- 5 files changed, 113 insertions(+), 35 deletions(-) create mode 100644 src/hooks/useApi.ts create mode 100644 src/lib/apiClient.ts diff --git a/index.html b/index.html index c4f15da..6255f17 100644 --- a/index.html +++ b/index.html @@ -1,32 +1,30 @@ + + + + + Harmony club + + + - - - - - Harmony club - - - - - -
- - - - \ No newline at end of file + +
+ + + diff --git a/src/hooks/useApi.ts b/src/hooks/useApi.ts new file mode 100644 index 0000000..e5c3cee --- /dev/null +++ b/src/hooks/useApi.ts @@ -0,0 +1,24 @@ +import { useState } from 'react'; + +type ApiFunction = (params?: P) => Promise<{ data: T }>; + +export function useApi(apiFunction: ApiFunction) { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const execute = async (params?: P) => { + setLoading(true); + setError(null); + try { + const response = await apiFunction(params); + setData(response.data); + } catch (err) { + setError(err); + } finally { + setLoading(false); + } + }; + + return { data, loading, error, execute }; +} diff --git a/src/lib/apiClient.ts b/src/lib/apiClient.ts new file mode 100644 index 0000000..76be7cf --- /dev/null +++ b/src/lib/apiClient.ts @@ -0,0 +1,56 @@ +import axios from 'axios'; + +// Function to get the token from local storage or state management +const getToken = () => localStorage.getItem('authToken'); + +const apiClient = axios.create({ + // Define the base URL for all API requests + baseURL: 'https://accounts.business-harmony.com/swagger/index.html', + + // Set a timeout for requests (e.g., 10 seconds) + timeout: 10000, + + // Set default headers + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, +}); + +// --- Request Interceptor --- +// This runs BEFORE each request is sent +apiClient.interceptors.request.use( + (config) => { + const token = getToken(); + if (token) { + // Add the authorization token to the headers + config.headers.Authorization = `Bearer ${token}`; + } + return config; + }, + (error) => { + // Handle request errors + return Promise.reject(error); + }, +); + +// --- Response Interceptor --- +// This runs AFTER a response is received +// TODO: set global post api logic +// apiClient.interceptors.response.use( +// (response) => { +// // Any status code within the 2xx range will trigger this function +// return response; +// }, +// (error) => { +// // Handle common errors globally +// if (error.response?.status === 401) { +// // e.g., redirect to login page if unauthorized +// console.error("Unauthorized! Redirecting to login..."); +// // window.location.href = '/login'; +// } +// return Promise.reject(error); +// } +// ); + +export default apiClient; diff --git a/vite.config.d.ts b/vite.config.d.ts index 340562a..2c646ae 100644 --- a/vite.config.d.ts +++ b/vite.config.d.ts @@ -1,2 +1,2 @@ -declare const _default: import("vite").UserConfig; +declare const _default: import('vite').UserConfig; export default _default; diff --git a/vite.config.js b/vite.config.js index 70ef262..e7bba8d 100644 --- a/vite.config.js +++ b/vite.config.js @@ -3,10 +3,10 @@ import react from '@vitejs/plugin-react'; import path from 'path'; // https://vite.dev/config/ export default defineConfig({ - plugins: [react()], - resolve: { - alias: { - '@': path.resolve(__dirname, './src'), - }, + plugins: [react()], + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), }, + }, });