api.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. const API = (() => {
  2. function getToken() { return localStorage.getItem('token'); }
  3. function getBaseUrl() { return (window.APP_CONFIG?.apiUrl || 'http://localhost:3000'); }
  4. async function request(method, path, body, isFormData) {
  5. const url = getBaseUrl() + path;
  6. const headers = {};
  7. const token = getToken();
  8. if (token) headers['Authorization'] = 'Bearer ' + token;
  9. if (!isFormData && body) headers['Content-Type'] = 'application/json';
  10. const opts = { method, headers };
  11. if (body) {
  12. opts.body = isFormData ? body : JSON.stringify(body);
  13. }
  14. const res = await fetch(url, opts);
  15. if (res.status === 401) {
  16. if (getToken()) {
  17. localStorage.removeItem('token');
  18. window.location.reload();
  19. }
  20. throw new Error('Unauthorized');
  21. }
  22. const data = await res.json().catch(() => ({}));
  23. if (!res.ok) throw new Error(data.error || 'Request failed');
  24. return data;
  25. }
  26. return {
  27. // Auth
  28. login: (login, password) => request('POST', '/api/auth/login', { login, password }),
  29. register: (login, email, password) => request('POST', '/api/auth/register', { login, email, password }),
  30. me: () => request('GET', '/api/auth/me'),
  31. // Directories
  32. getDirs: () => request('GET', '/api/directories'),
  33. getDir: (id) => request('GET', `/api/directories/${id}`),
  34. createDir: (name, parentId) => request('POST', '/api/directories', { name, parentId }),
  35. renameDir: (id, name) => request('PUT', `/api/directories/${id}`, { name }),
  36. moveDir: (id, parentId) => request('PUT', `/api/directories/${id}`, { parentId }),
  37. deleteDir: (id) => request('DELETE', `/api/directories/${id}`),
  38. // Tracks
  39. getTracks: (directoryId) => request('GET', '/api/tracks' + (directoryId !== undefined ? `?directoryId=${directoryId || ''}` : '')),
  40. getTrack: (id) => request('GET', `/api/tracks/${id}`),
  41. getTrackPoints: (id) => request('GET', `/api/tracks/${id}/points`),
  42. uploadTrack: (file, directoryId, name) => {
  43. const fd = new FormData();
  44. fd.append('file', file);
  45. if (directoryId) fd.append('directoryId', directoryId);
  46. if (name) fd.append('name', name);
  47. return request('POST', '/api/tracks/upload', fd, true);
  48. },
  49. updateTrack: (id, data) => request('PUT', `/api/tracks/${id}`, data),
  50. deleteTrack: (id) => request('DELETE', `/api/tracks/${id}`),
  51. createShare: (id) => request('POST', `/api/tracks/${id}/share`),
  52. deleteShare: (id) => request('DELETE', `/api/tracks/${id}/share`),
  53. // Share (public)
  54. getShared: (code) => request('GET', `/api/share/${code}`),
  55. // Stats
  56. getStats: (types) => {
  57. const qs = types && types.length > 0 ? '?type=' + encodeURIComponent(types.join(',')) : '';
  58. return request('GET', '/api/stats' + qs);
  59. },
  60. getDirStats: (id) => request('GET', `/api/stats/directory/${id}`),
  61. // Admin
  62. adminGetUsers: () => request('GET', '/api/admin/users'),
  63. adminActivate: (id, isActive) => request('PUT', `/api/admin/users/${id}/activate`, { isActive }),
  64. adminSetAdmin: (id, isAdmin) => request('PUT', `/api/admin/users/${id}/admin`, { isAdmin }),
  65. adminDeleteUser: (id) => request('DELETE', `/api/admin/users/${id}`),
  66. adminGetUserTracks: (id) => request('GET', `/api/admin/users/${id}/tracks`),
  67. };
  68. })();