initial
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import axios, { type AxiosInstance } from 'axios'
|
||||
|
||||
export const api: AxiosInstance = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:2000',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('mws_token')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401) {
|
||||
localStorage.removeItem('mws_token')
|
||||
localStorage.removeItem('mws_user')
|
||||
if (!window.location.pathname.startsWith('/login')) {
|
||||
window.location.href = '/login'
|
||||
}
|
||||
}
|
||||
return Promise.reject(error)
|
||||
},
|
||||
)
|
||||
|
||||
export function errorMessage(error: unknown): string {
|
||||
if (axios.isAxiosError(error)) {
|
||||
const data = error.response?.data as { message?: string } | undefined
|
||||
return data?.message ?? error.message ?? 'Request failed'
|
||||
}
|
||||
return 'Request failed'
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import { api } from './api'
|
||||
import type { LoginResponse, Project, ProjectMember, MemberRole, Account, MenuItem, Role, SaveRoleRequest } from '../types'
|
||||
|
||||
export async function login(username: string, password: string): Promise<LoginResponse> {
|
||||
const { data } = await api.post<LoginResponse>('/api/auth/login', { username, password })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getMenu(): Promise<MenuItem[]> {
|
||||
const { data } = await api.get<MenuItem[]>('/api/menu')
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getRoles(): Promise<Role[]> {
|
||||
const { data } = await api.get<Role[]>('/api/roles')
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getRole(id: string): Promise<Role> {
|
||||
const { data } = await api.get<Role>(`/api/roles/${id}`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function createRole(payload: SaveRoleRequest): Promise<Role> {
|
||||
const { data } = await api.post<Role>('/api/roles', payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function updateRole(id: string, payload: SaveRoleRequest): Promise<Role> {
|
||||
const { data } = await api.put<Role>(`/api/roles/${id}`, payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function deleteRole(id: string): Promise<void> {
|
||||
await api.delete(`/api/roles/${id}`)
|
||||
}
|
||||
|
||||
export async function getProjects(): Promise<Project[]> {
|
||||
const { data } = await api.get<Project[]>('/api/projects')
|
||||
return data
|
||||
}
|
||||
|
||||
export async function searchProjects(q: string): Promise<Project[]> {
|
||||
const { data } = await api.get<Project[]>('/api/projects/search', { params: { q } })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getProject(id: string): Promise<Project> {
|
||||
const { data } = await api.get<Project>(`/api/projects/${id}`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getProjectOverview(id: string) {
|
||||
const { data } = await api.get(`/api/projects/${id}/overview`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function createProject(name: string, description?: string): Promise<Project> {
|
||||
const { data } = await api.post<Project>('/api/projects', { name, description })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function updateProject(
|
||||
id: string,
|
||||
payload: { name: string; description: string | null; status: string },
|
||||
): Promise<Project> {
|
||||
const { data } = await api.put<Project>(`/api/projects/${id}`, payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function deleteProject(id: string): Promise<void> {
|
||||
await api.delete(`/api/projects/${id}`)
|
||||
}
|
||||
|
||||
export async function getMembers(projectId: string): Promise<ProjectMember[]> {
|
||||
const { data } = await api.get<ProjectMember[]>(`/api/projects/${projectId}/members`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function addMember(
|
||||
projectId: string,
|
||||
userId: string,
|
||||
role: MemberRole,
|
||||
): Promise<ProjectMember> {
|
||||
const { data } = await api.post<ProjectMember>(`/api/projects/${projectId}/members`, { userId, role })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function removeMember(projectId: string, userId: string): Promise<void> {
|
||||
await api.delete(`/api/projects/${projectId}/members/${userId}`)
|
||||
}
|
||||
|
||||
export async function getUsers(q?: string) {
|
||||
const { data } = await api.get('/api/users', { params: { q } })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getAccounts(q?: string): Promise<Account[]> {
|
||||
const { data } = await api.get<Account[]>('/api/accounts', { params: { q } })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function createAccount(payload: {
|
||||
username: string
|
||||
displayName: string
|
||||
password: string
|
||||
roleId: string
|
||||
}): Promise<Account> {
|
||||
const { data } = await api.post<Account>('/api/accounts', payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function updateAccount(
|
||||
id: string,
|
||||
payload: { displayName: string; roleId: string; isActive: boolean },
|
||||
): Promise<Account> {
|
||||
const { data } = await api.put<Account>(`/api/accounts/${id}`, payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function deleteAccount(id: string): Promise<void> {
|
||||
await api.delete(`/api/accounts/${id}`)
|
||||
}
|
||||
|
||||
export async function resetAccountPassword(id: string, newPassword: string): Promise<void> {
|
||||
await api.post(`/api/accounts/${id}/reset-password`, { newPassword })
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import { api } from './api'
|
||||
import type { DocumentItem, DocumentNode, DocumentType, Task, TaskPriority, TaskStatus } from '../types'
|
||||
|
||||
export async function getDocumentTree(projectId: string): Promise<DocumentNode[]> {
|
||||
const { data } = await api.get<DocumentNode[]>(`/api/projects/${projectId}/documents`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getDocument(id: string): Promise<DocumentItem> {
|
||||
const { data } = await api.get<DocumentItem>(`/api/documents/${id}`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function createDocument(
|
||||
projectId: string,
|
||||
payload: { title: string; type: DocumentType; parentId: string | null; content?: string | null },
|
||||
): Promise<DocumentItem> {
|
||||
const { data } = await api.post<DocumentItem>(`/api/projects/${projectId}/documents`, payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function updateDocument(
|
||||
id: string,
|
||||
payload: { title: string; content?: string | null },
|
||||
): Promise<DocumentItem> {
|
||||
const { data } = await api.put<DocumentItem>(`/api/documents/${id}`, payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function moveDocument(id: string, newParentId: string | null): Promise<DocumentItem> {
|
||||
const { data } = await api.put<DocumentItem>(`/api/documents/${id}/move`, { newParentId })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function deleteDocument(id: string): Promise<void> {
|
||||
await api.delete(`/api/documents/${id}`)
|
||||
}
|
||||
|
||||
export async function searchDocuments(q: string): Promise<DocumentNode[]> {
|
||||
const { data } = await api.get<DocumentNode[]>('/api/documents/search', { params: { q } })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getTasks(
|
||||
projectId: string,
|
||||
filters?: { status?: string; priority?: string; assigneeId?: string },
|
||||
): Promise<Task[]> {
|
||||
const { data } = await api.get<Task[]>(`/api/projects/${projectId}/tasks`, { params: filters })
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getTask(id: string): Promise<Task> {
|
||||
const { data } = await api.get<Task>(`/api/tasks/${id}`)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function createTask(
|
||||
projectId: string,
|
||||
payload: {
|
||||
title: string
|
||||
description?: string | null
|
||||
status?: TaskStatus
|
||||
priority?: TaskPriority
|
||||
assigneeId?: string | null
|
||||
dueDate?: string | null
|
||||
},
|
||||
): Promise<Task> {
|
||||
const { data } = await api.post<Task>(`/api/projects/${projectId}/tasks`, payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function updateTask(
|
||||
id: string,
|
||||
payload: {
|
||||
title: string
|
||||
description: string | null
|
||||
status: TaskStatus
|
||||
priority: TaskPriority
|
||||
assigneeId: string | null
|
||||
dueDate: string | null
|
||||
},
|
||||
): Promise<Task> {
|
||||
const { data } = await api.put<Task>(`/api/tasks/${id}`, payload)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function deleteTask(id: string): Promise<void> {
|
||||
await api.delete(`/api/tasks/${id}`)
|
||||
}
|
||||
|
||||
export async function searchTasks(q: string): Promise<Task[]> {
|
||||
const { data } = await api.get<Task[]>('/api/tasks/search', { params: { q } })
|
||||
return data
|
||||
}
|
||||
Reference in New Issue
Block a user