// 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()); } // 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}`); } // Tags getTags() { return this.get('/tags'); } // ===== 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}`); } getProjectTree(id) { return this.get(`/projects/${id}/tree`); } // ===== FOLDERS ===== getFolders(projectId, parentId = null) { const params = new URLSearchParams({ projectId }); if (parentId) params.append('parentId', parentId); return this.get(`/folders?${params.toString()}`); } createFolder(data) { return this.post('/folders', data); } updateFolder(id, data) { return this.put(`/folders/${id}`, data); } deleteFolder(id) { return this.delete(`/folders/${id}`); } // ===== Move document to folder ===== moveDocumentToFolder(documentId, folderId) { return this.put(`/documents/${documentId}`, { folderId }); } } export const api = new ApiClient();