- Backend: GET /api/export/{tasks,users,activities}?month=YYYY-MM
- Frontend: Export panel on Reports page (CEO/CTO/Manager only)
- API: apiExportCsv helper for browser download
138 lines
4.0 KiB
TypeScript
138 lines
4.0 KiB
TypeScript
const API_BASE = '/api';
|
|
|
|
async function request(url: string, options?: RequestInit) {
|
|
const res = await fetch(`${API_BASE}${url}`, {
|
|
headers: { 'Content-Type': 'application/json' },
|
|
...options,
|
|
});
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
throw new Error(err.error || 'Request failed');
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
// Auth
|
|
export async function apiLogin(email: string, password: string) {
|
|
return request('/auth/login', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ email, password }),
|
|
});
|
|
}
|
|
|
|
export async function apiRegister(data: {
|
|
name: string; email: string; password: string; role?: string; dept?: string;
|
|
}) {
|
|
return request('/auth/register', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
}
|
|
|
|
export async function apiFetchUsers() {
|
|
return request('/auth/users');
|
|
}
|
|
|
|
export async function apiCreateUser(data: {
|
|
name: string; email: string; password: string; role?: string; dept?: string;
|
|
}) {
|
|
return request('/auth/users', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
}
|
|
|
|
export async function apiDeleteUser(id: string) {
|
|
return request(`/auth/users/${id}`, {
|
|
method: 'DELETE',
|
|
});
|
|
}
|
|
|
|
export async function apiExportCsv(type: 'tasks' | 'users' | 'activities', month?: string) {
|
|
const params = month ? `?month=${month}` : '';
|
|
const res = await fetch(`${API_BASE}/export/${type}${params}`);
|
|
if (!res.ok) throw new Error('Export failed');
|
|
const blob = await res.blob();
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = month ? `${type}_${month}.csv` : `${type}_all.csv`;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
// Tasks
|
|
export async function apiFetchTasks() {
|
|
return request('/tasks');
|
|
}
|
|
|
|
export async function apiCreateTask(task: {
|
|
title: string; description?: string; status?: string; priority?: string;
|
|
assignee?: string; reporter?: string; dueDate?: string; tags?: string[];
|
|
subtasks?: { title: string; done: boolean }[];
|
|
dependencies?: { dependsOnUserId: string; description: string }[];
|
|
}) {
|
|
return request('/tasks', {
|
|
method: 'POST',
|
|
body: JSON.stringify(task),
|
|
});
|
|
}
|
|
|
|
export async function apiUpdateTask(id: string, updates: Record<string, unknown>) {
|
|
return request(`/tasks/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(updates),
|
|
});
|
|
}
|
|
|
|
export async function apiAddSubtask(taskId: string, title: string) {
|
|
return request(`/tasks/${taskId}/subtasks`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ title }),
|
|
});
|
|
}
|
|
|
|
export async function apiToggleSubtask(taskId: string, subtaskId: string, done: boolean) {
|
|
return request(`/tasks/${taskId}/subtasks/${subtaskId}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ done }),
|
|
});
|
|
}
|
|
|
|
export async function apiAddComment(taskId: string, userId: string, text: string) {
|
|
return request(`/tasks/${taskId}/comments`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ userId, text }),
|
|
});
|
|
}
|
|
|
|
export async function apiAddActivity(taskId: string, text: string) {
|
|
return request(`/tasks/${taskId}/activity`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ text }),
|
|
});
|
|
}
|
|
|
|
// Dependencies
|
|
export async function apiAddDependency(taskId: string, dep: { dependsOnUserId: string; description: string }) {
|
|
return request(`/tasks/${taskId}/dependencies`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(dep),
|
|
});
|
|
}
|
|
|
|
export async function apiToggleDependency(taskId: string, depId: string, resolved: boolean) {
|
|
return request(`/tasks/${taskId}/dependencies/${depId}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ resolved }),
|
|
});
|
|
}
|
|
|
|
export async function apiRemoveDependency(taskId: string, depId: string) {
|
|
return request(`/tasks/${taskId}/dependencies/${depId}`, {
|
|
method: 'DELETE',
|
|
});
|
|
}
|