const API = (() => { function getToken() { return localStorage.getItem('token'); } function getBaseUrl() { return (window.APP_CONFIG?.apiUrl || 'http://localhost:3000'); } async function request(method, path, body, isFormData) { const url = getBaseUrl() + path; const headers = {}; const token = getToken(); if (token) headers['Authorization'] = 'Bearer ' + token; if (!isFormData && body) headers['Content-Type'] = 'application/json'; const opts = { method, headers }; if (body) { opts.body = isFormData ? body : JSON.stringify(body); } const res = await fetch(url, opts); if (res.status === 401) { localStorage.removeItem('token'); window.location.reload(); throw new Error('Unauthorized'); } const data = await res.json().catch(() => ({})); if (!res.ok) throw new Error(data.error || 'Request failed'); return data; } return { // Auth login: (login, password) => request('POST', '/api/auth/login', { login, password }), register: (login, email, password) => request('POST', '/api/auth/register', { login, email, password }), me: () => request('GET', '/api/auth/me'), // Directories getDirs: () => request('GET', '/api/directories'), getDir: (id) => request('GET', `/api/directories/${id}`), createDir: (name, parentId) => request('POST', '/api/directories', { name, parentId }), renameDir: (id, name) => request('PUT', `/api/directories/${id}`, { name }), deleteDir: (id) => request('DELETE', `/api/directories/${id}`), // Tracks getTracks: (directoryId) => request('GET', '/api/tracks' + (directoryId !== undefined ? `?directoryId=${directoryId || ''}` : '')), getTrack: (id) => request('GET', `/api/tracks/${id}`), getTrackPoints: (id) => request('GET', `/api/tracks/${id}/points`), uploadTrack: (file, directoryId, name) => { const fd = new FormData(); fd.append('file', file); if (directoryId) fd.append('directoryId', directoryId); if (name) fd.append('name', name); return request('POST', '/api/tracks/upload', fd, true); }, updateTrack: (id, data) => request('PUT', `/api/tracks/${id}`, data), deleteTrack: (id) => request('DELETE', `/api/tracks/${id}`), createShare: (id) => request('POST', `/api/tracks/${id}/share`), deleteShare: (id) => request('DELETE', `/api/tracks/${id}/share`), // Share (public) getShared: (code) => request('GET', `/api/share/${code}`), // Stats getStats: () => request('GET', '/api/stats'), getDirStats: (id) => request('GET', `/api/stats/directory/${id}`), // Admin adminGetUsers: () => request('GET', '/api/admin/users'), adminActivate: (id, isActive) => request('PUT', `/api/admin/users/${id}/activate`, { isActive }), adminSetAdmin: (id, isAdmin) => request('PUT', `/api/admin/users/${id}/admin`, { isAdmin }), adminDeleteUser: (id) => request('DELETE', `/api/admin/users/${id}`), adminGetUserTracks: (id) => request('GET', `/api/admin/users/${id}/tracks`), }; })();