This commit is contained in:
keyhan
2026-04-05 15:22:01 +03:30
commit 33be1649c4
82 changed files with 23956 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
import axios from 'axios';
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';
const api = axios.create({
baseURL: `${API_URL}/api/v1`,
headers: {
'Content-Type': 'application/json',
},
});
// Request interceptor to add auth token
api.interceptors.request.use((config) => {
if (typeof window !== 'undefined') {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
}
return config;
});
// Response interceptor for token refresh
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const refreshToken = localStorage.getItem('refreshToken');
if (!refreshToken) throw new Error('No refresh token');
const { data } = await axios.post(`${API_URL}/api/v1/auth/refresh`, {
refreshToken,
});
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
originalRequest.headers.Authorization = `Bearer ${data.accessToken}`;
return api(originalRequest);
} catch {
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
if (typeof window !== 'undefined') {
window.location.href = '/login';
}
}
}
return Promise.reject(error);
},
);
export default api;
+55
View File
@@ -0,0 +1,55 @@
'use client';
import { create } from 'zustand';
import api from '@/lib/api';
import type { User, AuthResponse } from '@/types';
interface AuthState {
user: User | null;
isLoading: boolean;
isAuthenticated: boolean;
login: (email: string, password: string) => Promise<void>;
register: (data: { email: string; password: string; firstName: string; lastName: string }) => Promise<void>;
logout: () => void;
loadUser: () => Promise<void>;
}
export const useAuthStore = create<AuthState>((set) => ({
user: null,
isLoading: true,
isAuthenticated: false,
login: async (email, password) => {
const { data } = await api.post<AuthResponse>('/auth/login', { email, password });
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
set({ user: data.user, isAuthenticated: true });
},
register: async (registerData) => {
const { data } = await api.post<AuthResponse>('/auth/register', registerData);
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
set({ user: data.user, isAuthenticated: true });
},
logout: () => {
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
set({ user: null, isAuthenticated: false });
},
loadUser: async () => {
try {
const token = localStorage.getItem('accessToken');
if (!token) {
set({ isLoading: false });
return;
}
const { data } = await api.get<User>('/users/me');
set({ user: data, isAuthenticated: true, isLoading: false });
} catch {
set({ user: null, isAuthenticated: false, isLoading: false });
}
},
}));