// API Client for SimpleNote Web const API_BASE = '/api/v1'; class ApiClient { constructor() { this.token = localStorage.getItem('sn_token'); } setToken(token) { this.token = token; if (token) { localStorage.setItem('sn_token', token); } else { localStorage.removeItem('sn_token'); } } getHeaders() { const headers = { 'Content-Type': 'application/json' }; if (this.token) { headers['Authorization'] = `Bearer ${this.token}`; } return headers; } async request(method, path, body = null) { const options = { method, headers: this.getHeaders() }; if (body) { options.body = JSON.stringify(body); } const response = await fetch(`${API_BASE}${path}`, options); if (!response.ok) { const error = await response.json().catch(() => ({ message: 'Request failed' })); throw new Error(error.message || `HTTP ${response.status}`); } return response.json(); } get(path) { return this.request('GET', path); } post(path, body) { return this.request('POST', path, body); } put(path, body) { return this.request('PUT', path, body); } delete(path) { return this.request('DELETE', path); } // ===== Auth ===== async login(token) { try { this.setToken(token); // Set token BEFORE making request const data = await this.get('/auth/verify'); return data; } catch (e) { this.setToken(null); throw e; } } // ===== Documents ===== getDocuments(params = {}) { const query = new URLSearchParams(params).toString(); return this.get(`/documents${query ? '?' + query : ''}`); } getDocument(id) { return this.get(`/documents/${id}`); } createDocument(data) { return this.post('/documents', data); } updateDocument(id, data) { return this.put(`/documents/${id}`, data); } deleteDocument(id) { return this.delete(`/documents/${id}`); } exportDocument(id) { return fetch(`${API_BASE}/documents/${id}/export`, { headers: this.getHeaders() }).then(r => r.text()); } addDocumentTags(documentId, tags) { return this.post(`/documents/${documentId}/tags`, { tags }); } moveDocumentToFolder(documentId, folderId) { return this.put(`/documents/${documentId}`, { folderId }); } // ===== Tags ===== getTags() { return this.get('/tags'); } // GET /tags/:tag - get documents by tag getDocumentsByTag(tag) { return this.get(`/tags/${encodeURIComponent(tag)}`); } // ===== Libraries ===== getLibraries() { return this.get('/libraries'); } getLibrary(id) { return this.get(`/libraries/${id}`); } createLibrary(data) { return this.post('/libraries', data); } updateLibrary(id, data) { return this.put(`/libraries/${id}`, data); } deleteLibrary(id) { return this.delete(`/libraries/${id}`); } // GET /libraries/:id/tree getLibraryTree(id) { return this.get(`/libraries/${id}/tree`); } // GET /libraries/:id/documents getLibraryDocuments(id) { return this.get(`/libraries/${id}/documents`); } // ===== Projects ===== getProjects() { return this.get('/projects'); } getProject(id) { return this.get(`/projects/${id}`); } createProject(data) { return this.post('/projects', data); } updateProject(id, data) { return this.put(`/projects/${id}`, data); } deleteProject(id) { return this.delete(`/projects/${id}`); } // GET /projects/:id/tree getProjectTree(id) { return this.get(`/projects/${id}/tree`); } // GET /projects/:id/documents getProjectDocuments(id) { return this.get(`/projects/${id}/documents`); } // ===== Folders ===== getFolders(project = null, parentId = null) { const params = new URLSearchParams(); if (project) params.append('project', project); if (parentId) params.append('parentId', parentId); const query = params.toString(); return this.get(`/folders${query ? '?' + query : ''}`); } getFolder(id) { return this.get(`/folders/${id}`); } createFolder(data) { return this.post('/folders', data); } updateFolder(id, data) { return this.put(`/folders/${id}`, data); } deleteFolder(id) { return this.delete(`/folders/${id}`); } // GET /folders/:id/documents getFolderDocuments(id) { return this.get(`/folders/${id}/documents`); } // GET /folders/:id/tree getFolderTree(id) { return this.get(`/folders/${id}/tree`); } } export const api = new ApiClient();