import type { CampaignPreview, CampaignProcessSummary, CampaignQueueSummary, DashboardAnalytics, DateRange, OrderData, RfmAnalytics, StockData } from './types'; import { formatDateParam } from './dateRanges'; const API_URL = import.meta.env.VITE_API_URL || '/api'; export const login = async (email: string, password: string): Promise => { try { const response = await fetch(`${API_URL}/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password }), }); if (response.ok) { const data = await response.json(); localStorage.setItem('auth_token', data.token); return true; } return false; } catch (error) { console.error('Login failed', error); return false; } }; export const logout = () => { localStorage.removeItem('auth_token'); window.location.href = '/#/login'; }; export const isAuthenticated = (): boolean => { return !!localStorage.getItem('auth_token'); }; export const fetchStock = async (): Promise => { try { const token = localStorage.getItem('auth_token'); const response = await fetch(`${API_URL}/stock`, { headers: { 'Authorization': `Bearer ${token}` } }); if (response.status === 401 || response.status === 403) { logout(); return []; } if (!response.ok) return []; return await response.json(); } catch { return []; } }; export const fetchData = async (): Promise => { try { const token = localStorage.getItem('auth_token'); const response = await fetch(`${API_URL}/data`, { headers: { 'Authorization': `Bearer ${token}` } }); if (response.status === 401 || response.status === 403) { logout(); return []; } if (!response.ok) return []; return await response.json(); } catch (error) { console.error("Fetch failed", error); return []; } }; const authFetch = async (path: string, options: RequestInit = {}): Promise => { const token = localStorage.getItem('auth_token'); const response = await fetch(`${API_URL}${path}`, { ...options, headers: { ...(options.headers || {}), 'Authorization': `Bearer ${token}` } }); if (response.status === 401 || response.status === 403) { logout(); } return response; }; export const fetchDashboardAnalytics = async (dateRange: DateRange): Promise => { try { const params = new URLSearchParams({ start: formatDateParam(dateRange.start), end: formatDateParam(dateRange.end) }); const response = await authFetch(`/analytics/dashboard?${params.toString()}`); if (!response.ok) return null; return await response.json(); } catch (error) { console.error('Fetch dashboard analytics failed', error); return null; } }; export const fetchRfmAnalytics = async (dateRange: DateRange): Promise => { try { const params = new URLSearchParams({ start: formatDateParam(dateRange.start), end: formatDateParam(dateRange.end) }); const response = await authFetch(`/analytics/rfm?${params.toString()}`); if (!response.ok) return null; return await response.json(); } catch (error) { console.error('Fetch RFM analytics failed', error); return null; } }; export const fetchCampaigns = async (): Promise => { try { const response = await authFetch('/campaigns'); if (!response.ok) return null; return await response.json(); } catch (error) { console.error('Fetch campaigns failed', error); return null; } }; export const fetchCampaignPreview = async (): Promise => { try { const response = await authFetch('/campaigns/preview'); if (!response.ok) return null; return await response.json(); } catch (error) { console.error('Fetch campaign preview failed', error); return null; } }; export const processCampaignsNow = async (): Promise => { try { const response = await authFetch('/campaigns/process', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }); if (!response.ok) return null; return await response.json(); } catch (error) { console.error('Process campaigns failed', error); return null; } }; export const retryCampaignGroup = async (baseProductName: string): Promise => { try { const response = await authFetch('/campaigns/retry', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ baseProductName }) }); return response.ok; } catch (error) { console.error('Retry campaign failed', error); return false; } }; export const parseOrderDate = (dateStr: string): Date => { if (!dateStr) return new Date(0); if (dateStr.includes('T')) return new Date(dateStr); const parts = dateStr.split(/[-/]/); if (parts.length === 3) { if (parts[0].length === 4) { // YYYY-MM-DD return new Date(Number(parts[0]), Number(parts[1]) - 1, Number(parts[2])); } else { // DD-MM-YYYY return new Date(Number(parts[2]), Number(parts[1]) - 1, Number(parts[0])); } } const fallback = new Date(dateStr); return isNaN(fallback.getTime()) ? new Date(0) : fallback; }; export const exportToCSV = (data: Record[], filename: string) => { if (!data || !data.length) return; const headers = Object.keys(data[0]); const csvRows = []; // Add headers csvRows.push(headers.join(',')); // Add rows for (const row of data) { const values = headers.map(header => { const val = row[header]; const escaped = String(val ?? '').replace(/"/g, '""'); return `"${escaped}"`; }); csvRows.push(values.join(',')); } const csvString = csvRows.join('\n'); const blob = new Blob([csvString], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); if (link.download !== undefined) { const url = URL.createObjectURL(blob); link.setAttribute('href', url); link.setAttribute('download', filename); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } };