feat: MySQL integration, Docker setup, drag-and-drop kanban

This commit is contained in:
tusuii
2026-02-16 10:20:27 +05:30
parent 5d8af1f173
commit 892a2ceba1
24 changed files with 919 additions and 196 deletions

85
src/api.ts Normal file
View File

@@ -0,0 +1,85 @@
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');
}
// 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 }[];
}) {
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 }),
});
}