Spaces:
Sleeping
Sleeping
| const BASE = import.meta.env.DEV ? '/api' : '' | |
| function getToken() { | |
| return localStorage.getItem('leadgen_token') | |
| } | |
| async function request(path, options = {}) { | |
| const token = getToken() | |
| const headers = { ...(options.headers || {}) } | |
| if (token) headers['Authorization'] = `Bearer ${token}` | |
| if (options.body && !(options.body instanceof FormData)) { | |
| headers['Content-Type'] = headers['Content-Type'] || 'application/json' | |
| } | |
| const res = await fetch(`${BASE}${path}`, { ...options, headers }) | |
| if (res.status === 401) { | |
| localStorage.removeItem('leadgen_token') | |
| localStorage.removeItem('leadgen_user') | |
| window.location.href = '/' | |
| return | |
| } | |
| if (!res.ok) { | |
| const err = await res.json().catch(() => ({ detail: res.statusText })) | |
| throw new Error(err.detail || 'Request failed') | |
| } | |
| if (res.status === 204) return null | |
| return res.json() | |
| } | |
| // Projects | |
| export const projectsApi = { | |
| list: () => request('/projects'), | |
| create: (data) => request('/projects', { method: 'POST', body: JSON.stringify(data) }), | |
| update: (id, data) => request(`/projects/${id}`, { method: 'PUT', body: JSON.stringify(data) }), | |
| delete: (id) => request(`/projects/${id}`, { method: 'DELETE' }), | |
| } | |
| // Leads | |
| export const leadsApi = { | |
| list: (params = {}) => { | |
| const qs = new URLSearchParams( | |
| Object.fromEntries(Object.entries(params).filter(([, v]) => v != null && v !== '')) | |
| ).toString() | |
| return request(`/leads${qs ? '?' + qs : ''}`) | |
| }, | |
| get: (id) => request(`/leads/${id}`), | |
| create: (data) => request('/leads', { method: 'POST', body: JSON.stringify(data) }), | |
| update: (id, data) => request(`/leads/${id}`, { method: 'PUT', body: JSON.stringify(data) }), | |
| delete: (id) => request(`/leads/${id}`, { method: 'DELETE' }), | |
| bulkDelete: (ids) => request('/leads', { method: 'DELETE', body: JSON.stringify(ids) }), | |
| } | |
| // Import | |
| export const importApi = { | |
| csv: (file, sourceLabel = 'csv', projectId = null) => { | |
| const fd = new FormData() | |
| fd.append('file', file) | |
| fd.append('source_label', sourceLabel) | |
| if (projectId) fd.append('project_id', projectId) | |
| return request('/import/csv', { method: 'POST', body: fd }) | |
| }, | |
| excel: (file, sourceLabel = 'excel', projectId = null) => { | |
| const fd = new FormData() | |
| fd.append('file', file) | |
| fd.append('source_label', sourceLabel) | |
| if (projectId) fd.append('project_id', projectId) | |
| return request('/import/excel', { method: 'POST', body: fd }) | |
| }, | |
| linkedin: (file, projectId = null) => { | |
| const fd = new FormData() | |
| fd.append('file', file) | |
| if (projectId) fd.append('project_id', projectId) | |
| return request('/import/linkedin', { method: 'POST', body: fd }) | |
| }, | |
| } | |
| // Scraping | |
| export const scrapingApi = { | |
| scrapeUrl: (config) => request('/scrape/url', { method: 'POST', body: JSON.stringify(config) }), | |
| scrapeBulk: (urls) => request('/scrape/bulk', { method: 'POST', body: JSON.stringify(urls) }), | |
| listJobs: () => request('/scrape/jobs'), | |
| getJob: (id) => request(`/scrape/jobs/${id}`), | |
| } | |
| // Export — direct download links with token | |
| export const exportApi = { | |
| csvUrl: (params = {}) => { | |
| const token = getToken() | |
| const qs = new URLSearchParams( | |
| Object.fromEntries(Object.entries({ ...params, token }).filter(([, v]) => v != null && v !== '')) | |
| ).toString() | |
| return `${BASE}/export/csv${qs ? '?' + qs : ''}` | |
| }, | |
| excelUrl: (params = {}) => { | |
| const token = getToken() | |
| const qs = new URLSearchParams( | |
| Object.fromEntries(Object.entries({ ...params, token }).filter(([, v]) => v != null && v !== '')) | |
| ).toString() | |
| return `${BASE}/export/excel${qs ? '?' + qs : ''}` | |
| }, | |
| } | |
| // Analytics | |
| export const analyticsApi = { | |
| get: (projectId = null) => { | |
| const qs = projectId ? `?project_id=${projectId}` : '' | |
| return request(`/analytics${qs}`) | |
| }, | |
| } | |