2026-02-09 21:39:14 +07:00
|
|
|
import { goto } from '$app/navigation';
|
|
|
|
|
import { auth } from '$lib/stores/auth.js';
|
|
|
|
|
|
2026-02-10 06:43:07 +07:00
|
|
|
const API_URL = import.meta.env.VITE_API_URL || '';
|
2026-02-09 21:39:14 +07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Base API client with JWT handling
|
|
|
|
|
* @param {string} endpoint - API endpoint (without base URL)
|
|
|
|
|
* @param {Object} options - Fetch options
|
|
|
|
|
* @returns {Promise<any>} - JSON response
|
|
|
|
|
*/
|
|
|
|
|
export async function apiClient(endpoint, options = {}) {
|
|
|
|
|
// Get token from store
|
|
|
|
|
let token = null;
|
|
|
|
|
auth.subscribe((authState) => {
|
|
|
|
|
token = authState.token;
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
// Build headers
|
|
|
|
|
const headers = {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
...options.headers,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Add Authorization header if token exists
|
|
|
|
|
if (token) {
|
|
|
|
|
headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build full URL
|
|
|
|
|
const url = `${API_URL}${endpoint}`;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(url, {
|
|
|
|
|
...options,
|
|
|
|
|
headers,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Handle 401 Unauthorized
|
|
|
|
|
if (response.status === 401) {
|
|
|
|
|
auth.logout();
|
|
|
|
|
goto('/login');
|
|
|
|
|
throw new Error('Unauthorized');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle other errors
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
const error = await response.json().catch(() => ({ message: 'An error occurred' }));
|
|
|
|
|
throw new Error(error.message || `HTTP error! status: ${response.status}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse JSON response
|
|
|
|
|
return await response.json();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('API Error:', error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* GET request helper
|
|
|
|
|
* @param {string} endpoint
|
|
|
|
|
* @param {Object} options
|
|
|
|
|
*/
|
|
|
|
|
export function get(endpoint, options = {}) {
|
|
|
|
|
return apiClient(endpoint, { ...options, method: 'GET' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* POST request helper
|
|
|
|
|
* @param {string} endpoint
|
|
|
|
|
* @param {Object} body
|
|
|
|
|
* @param {Object} options
|
|
|
|
|
*/
|
|
|
|
|
export function post(endpoint, body, options = {}) {
|
|
|
|
|
return apiClient(endpoint, {
|
|
|
|
|
...options,
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* PUT request helper
|
|
|
|
|
* @param {string} endpoint
|
|
|
|
|
* @param {Object} body
|
|
|
|
|
* @param {Object} options
|
|
|
|
|
*/
|
|
|
|
|
export function put(endpoint, body, options = {}) {
|
|
|
|
|
return apiClient(endpoint, {
|
|
|
|
|
...options,
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* DELETE request helper
|
|
|
|
|
* @param {string} endpoint
|
|
|
|
|
* @param {Object} options
|
|
|
|
|
*/
|
|
|
|
|
export function del(endpoint, options = {}) {
|
|
|
|
|
return apiClient(endpoint, { ...options, method: 'DELETE' });
|
|
|
|
|
}
|