diff --git a/.gitignore b/.gitignore index b9a3cf2..edb50ff 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ next-env.d.ts # claude files .claude + +# IntelliJ +.idea/ \ No newline at end of file diff --git a/src/lib/apiClient.ts b/src/lib/apiClient.ts index 1c085f9..bdba392 100644 --- a/src/lib/apiClient.ts +++ b/src/lib/apiClient.ts @@ -1,55 +1,40 @@ -import axios, { AxiosInstance } from 'axios'; +import axios from 'axios'; import Cookies from 'js-cookie'; -let API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8081'; - -const createClient = (baseURL: string): AxiosInstance => { - const client = axios.create({ - baseURL, - headers: { - 'Content-Type': 'application/json', - }, - }); - - // Add a request interceptor to include the auth token - client.interceptors.request.use( - (config) => { - const token = Cookies.get('tt_access_token'); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - return config; - }, - (error) => { - return Promise.reject(error); +// The base URL is now a constant, correctly pointing to the API Gateway. +const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8080/api/v1'; + +const apiClient = axios.create({ + baseURL: API_BASE_URL, + headers: { 'Content-Type': 'application/json' }, +}); + +// Request interceptor (Your existing code is perfect) +apiClient.interceptors.request.use( + (config) => { + const token = Cookies.get('tt_access_token'); + if (token) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + config.headers.Authorization = `Bearer ${token}`; } - ); - - // Add a response interceptor to handle auth errors - client.interceptors.response.use( - (response) => response, - (error) => { - if (error.response?.status === 401) { - // Clear token and redirect to login - Cookies.remove('tt_access_token'); - if (typeof window !== 'undefined') { - window.location.href = '/auth/login'; - } + return config; + }, + (error) => Promise.reject(error) +); + +// Response interceptor (Your existing code is perfect) +apiClient.interceptors.response.use( + (response) => response, + (error) => { + if (error.response?.status === 401) { + Cookies.remove('tt_access_token'); + if (typeof window !== 'undefined') { + window.location.href = '/auth/login'; } - return Promise.reject(error); } - ); - - return client; -}; - -let api = createClient(API_BASE); - -export const setApiBaseUrl = (baseUrl: string) => { - API_BASE = baseUrl; - api = createClient(API_BASE); -}; - -export const getApiBaseUrl = () => API_BASE; + return Promise.reject(error); + } +); -export default api; +export default apiClient; diff --git a/src/services/authService.ts b/src/services/authService.ts index 5c52b1b..bf4bed3 100644 --- a/src/services/authService.ts +++ b/src/services/authService.ts @@ -12,7 +12,8 @@ const TOKEN_COOKIE = 'tt_access_token'; export const authService = { async login(payload: LoginRequest) { - const res = await api.post('/api/v1/auth/login', payload); + // api baseURL already includes '/api/v1' + const res = await api.post('/auth/login', payload); // backend returns token in body const token = res.data?.token || res.data?.accessToken || null; console.log('Login response:', res.data); @@ -26,23 +27,23 @@ export const authService = { async register(payload: RegisterRequest) { - const res = await api.post('/api/v1/auth/register', payload); + const res = await api.post('/auth/register', payload); return res.data; }, async createEmployee(payload: CreateEmployeeRequest) { - const res = await api.post('/api/v1/auth/users/employee', payload); + const res = await api.post('/auth/users/employee', payload); return res.data; }, async createAdmin(payload: CreateAdminRequest) { - const res = await api.post('/api/v1/auth/users/admin', payload); + const res = await api.post('/auth/users/admin', payload); return res.data; }, async testEndpoint() { - const res = await api.get('/api/v1/auth/test'); + const res = await api.get('/auth/test'); return res.data; }, async healthCheck() { - const res = await api.get('/api/v1/auth/health'); + const res = await api.get('/auth/health'); return res.data; }, logout() { @@ -53,18 +54,4 @@ export const authService = { }, }; -// Request interceptor to attach token -api.interceptors.request.use((config) => { - try { - const token = Cookies.get(TOKEN_COOKIE); - if (token && config.headers) { - config.headers['Authorization'] = `Bearer ${token}`; - } - } catch (err) { - // log to help debugging in production builds - console.warn('auth interceptor error', err); - } - return config; -}); - export default authService; diff --git a/src/services/userService.ts b/src/services/userService.ts index ff04a92..2d2083e 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -8,37 +8,41 @@ import type { export const userService = { getCurrentProfile() { - return api.get('/api/v1/users/me'); + // Correct Path: /users/me + return api.get('/users/me'); }, getAllUsers() { - return api.get('/api/v1/users'); + // Correct Path: /users + return api.get('/users'); }, getUserByUsername(username: string) { - return api.get(`/api/v1/users/${encodeURIComponent(username)}`); + // Correct Path: /users/{username} + return api.get(`/users/${encodeURIComponent(username)}`); }, updateUser(username: string, payload: UpdateUserRequest) { - return api.put(`/api/v1/users/${encodeURIComponent(username)}`, payload); + return api.put(`/users/${encodeURIComponent(username)}`, payload); }, deleteUser(username: string) { - return api.delete(`/api/v1/users/${encodeURIComponent(username)}`); + return api.delete(`/users/${encodeURIComponent(username)}`); }, enableUser(username: string) { - return api.post(`/api/v1/users/${encodeURIComponent(username)}/enable`); + return api.post(`/users/${encodeURIComponent(username)}/enable`); }, disableUser(username: string) { - return api.post(`/api/v1/users/${encodeURIComponent(username)}/disable`); + return api.post(`/users/${encodeURIComponent(username)}/disable`); }, unlockUser(username: string) { - return api.post(`/api/v1/users/${encodeURIComponent(username)}/unlock`); + return api.post(`/users/${encodeURIComponent(username)}/unlock`); }, manageUserRole(username: string, payload: RoleAssignmentRequest) { - return api.post(`/api/v1/users/${encodeURIComponent(username)}/roles`, payload); + return api.post(`/users/${encodeURIComponent(username)}/roles`, payload); }, resetUserPassword(username: string, payload: ResetPasswordRequest) { - return api.post(`/api/v1/users/${encodeURIComponent(username)}/reset-password`, payload); + return api.post(`/users/${encodeURIComponent(username)}/reset-password`, payload); }, changeCurrentUserPassword(payload: ChangePasswordRequest) { - return api.post('/api/v1/users/me/change-password', payload); + // Correct Path: /users/me/change-password + return api.post('/users/me/change-password', payload); }, };