// ============================================================ // Elegant Work — API.js // All requests use POST with token in body // ============================================================ const API = (() => { const BASE = './api'; /** * Core POST request. Token is always included in body. * @param {string} endpoint e.g. 'auth/login' * @param {object} data Form data (without token - added automatically) */ async function post(endpoint, data = {}) { const token = Auth.getToken(); const formData = new URLSearchParams(); // Always include token if we have one if (token) formData.append('token', token); // Add all other data — arrays/objects are JSON-encoded for (const [key, value] of Object.entries(data)) { if (value !== null && value !== undefined) { formData.append(key, (typeof value === 'object') ? JSON.stringify(value) : value); } } try { const response = await fetch(`${BASE}/${endpoint}.php`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: formData.toString(), }); const json = await response.json(); // Auto-handle 401 (token expired) if (response.status === 401 && endpoint !== 'auth/login') { Auth.clearSession(); Router.navigate('login'); Toast.show('Session expired. Please log in again.', 'error'); throw new Error('Unauthenticated'); } return json; } catch (err) { if (err.message === 'Unauthenticated') throw err; console.error(`API error [${endpoint}]:`, err); throw err; } } /** * Upload files via FormData (multipart) */ async function upload(endpoint, formDataObj) { const token = Auth.getToken(); if (token) formDataObj.append('token', token); const response = await fetch(`${BASE}/${endpoint}.php`, { method: 'POST', body: formDataObj, }); return response.json(); } /** * postForm — multipart FormData upload (use for file + data combined) * Token is auto-appended. */ async function postForm(endpoint, formDataObj) { const token = Auth.getToken(); if (token) formDataObj.append('token', token); try { const response = await fetch(`${BASE}/${endpoint}.php`, { method: 'POST', body: formDataObj }); return response.json(); } catch (err) { console.error(`API postForm error [${endpoint}]:`, err); throw err; } } // baseUrl helper for building asset URLs const baseUrl = window.location.origin + window.location.pathname.replace(/\/[^/]*$/, '/api/'); return { post, upload, postForm, baseUrl }; })();