mirror of
https://github.com/OHV-IT/collabrix.git
synced 2025-12-16 00:58:37 +01:00
391 lines
12 KiB
TypeScript
391 lines
12 KiB
TypeScript
import axios from 'axios';
|
|
import type { LoginRequest, RegisterRequest, AuthResponse, User, Language, TranslationGroup } from '../types';
|
|
|
|
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
|
|
|
|
// Helper function to get full API URL for resources like images
|
|
export const getApiUrl = (path: string) => {
|
|
return `${API_URL}${path.startsWith('/') ? path : '/' + path}`;
|
|
};
|
|
|
|
const api = axios.create({
|
|
baseURL: API_URL,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
|
|
// Add auth token to requests
|
|
api.interceptors.request.use((config) => {
|
|
const token = localStorage.getItem('token');
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`;
|
|
}
|
|
return config;
|
|
});
|
|
|
|
// Handle 401 responses (token expired/invalid)
|
|
api.interceptors.response.use(
|
|
(response) => response,
|
|
(error) => {
|
|
if (error.response?.status === 401) {
|
|
// Token is invalid or expired, logout user
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('lastVisitedPath');
|
|
sessionStorage.removeItem('routeRestored');
|
|
// Dispatch event to notify AuthContext
|
|
window.dispatchEvent(new CustomEvent('sessionExpired'));
|
|
}
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
|
|
export const authAPI = {
|
|
login: async (data: LoginRequest): Promise<AuthResponse> => {
|
|
const response = await api.post('/auth/login', data);
|
|
return response.data;
|
|
},
|
|
|
|
register: async (data: RegisterRequest): Promise<User> => {
|
|
const response = await api.post('/auth/register', data);
|
|
return response.data;
|
|
},
|
|
|
|
getCurrentUser: async (): Promise<User> => {
|
|
const response = await api.get('/auth/me');
|
|
return response.data;
|
|
},
|
|
|
|
updateProfile: async (data: { email?: string; full_name?: string; password?: string; theme?: string }): Promise<User> => {
|
|
const response = await api.put('/auth/me', data);
|
|
return response.data;
|
|
},
|
|
|
|
uploadProfilePicture: async (file: File): Promise<User> => {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
const response = await api.post('/auth/me/profile-picture', formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
});
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const departmentsAPI = {
|
|
getAll: async () => {
|
|
const response = await api.get('/departments/');
|
|
return response.data;
|
|
},
|
|
|
|
getMy: async () => {
|
|
const response = await api.get('/departments/my');
|
|
return response.data;
|
|
},
|
|
|
|
create: async (data: { name: string; description?: string }) => {
|
|
const response = await api.post('/departments/', data);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const channelsAPI = {
|
|
getMy: async () => {
|
|
const response = await api.get('/channels/');
|
|
return response.data;
|
|
},
|
|
|
|
getByDepartment: async (departmentId: number) => {
|
|
const response = await api.get(`/channels/department/${departmentId}`);
|
|
return response.data;
|
|
},
|
|
|
|
create: async (data: { name: string; description?: string; department_id: number }) => {
|
|
const response = await api.post('/channels/', data);
|
|
return response.data;
|
|
},
|
|
|
|
delete: async (channelId: number) => {
|
|
const response = await api.delete(`/channels/${channelId}`);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const messagesAPI = {
|
|
getChannelMessages: async (channelId: number, limit = 50, offset = 0) => {
|
|
const response = await api.get(`/messages/channel/${channelId}`, {
|
|
params: { limit, offset },
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
create: async (data: { content: string; channel_id: number; snippet_id?: number | null; reply_to_id?: number | null }) => {
|
|
const response = await api.post('/messages/', data);
|
|
return response.data;
|
|
},
|
|
|
|
delete: async (messageId: number) => {
|
|
const response = await api.delete(`/messages/${messageId}`);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const filesAPI = {
|
|
upload: async (messageId: number, file: File, permission: string = 'read') => {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
formData.append('permission', permission);
|
|
const response = await api.post(`/files/upload/${messageId}`, formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
uploadWithMessage: async (channelId: number, file: File, permission: string = 'read', content: string = '', replyToId?: number) => {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
formData.append('permission', permission);
|
|
formData.append('content', content);
|
|
if (replyToId) {
|
|
formData.append('reply_to_id', replyToId.toString());
|
|
}
|
|
const response = await api.post(`/files/upload-with-message/${channelId}`, formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
download: async (fileId: number) => {
|
|
const response = await api.get(`/files/download/${fileId}`, {
|
|
responseType: 'blob',
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
getOfficeUri: async (fileId: number) => {
|
|
const response = await api.get(`/files/office-uri/${fileId}`);
|
|
return response.data;
|
|
},
|
|
|
|
updatePermission: async (fileId: number, permission: string) => {
|
|
const formData = new FormData();
|
|
formData.append('permission', permission);
|
|
const response = await api.put(`/files/${fileId}/permission`, formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
});
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const snippetsAPI = {
|
|
getAll: async (params?: {
|
|
language?: string;
|
|
tags?: string;
|
|
search?: string;
|
|
visibility?: string;
|
|
}) => {
|
|
const response = await api.get('/snippets/', { params });
|
|
return response.data;
|
|
},
|
|
|
|
getById: async (id: number) => {
|
|
const response = await api.get(`/snippets/${id}`);
|
|
return response.data;
|
|
},
|
|
|
|
create: async (data: any) => {
|
|
const response = await api.post('/snippets/', data);
|
|
return response.data;
|
|
},
|
|
|
|
update: async (id: number, data: any) => {
|
|
const response = await api.put(`/snippets/${id}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
delete: async (id: number) => {
|
|
const response = await api.delete(`/snippets/${id}`);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const adminLanguagesAPI = {
|
|
getAll: async (): Promise<Language[]> => {
|
|
const response = await api.get('/admin/languages');
|
|
return response.data;
|
|
},
|
|
|
|
create: async (data: { code: string; name: string }): Promise<Language> => {
|
|
const response = await api.post('/admin/languages', data);
|
|
return response.data;
|
|
},
|
|
|
|
delete: async (id: number) => {
|
|
const response = await api.delete(`/admin/languages/${id}`);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const adminTranslationsAPI = {
|
|
getAll: async (): Promise<TranslationGroup[]> => {
|
|
const response = await api.get('/admin/translations');
|
|
return response.data;
|
|
},
|
|
|
|
update: async (data: { translation_id: number; value: string }) => {
|
|
const response = await api.put('/admin/translations', data);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const directMessagesAPI = {
|
|
getConversation: async (userId: number, limit: number = 50, offset: number = 0) => {
|
|
const response = await api.get(`/direct-messages/conversation/${userId}`, {
|
|
params: { limit, offset }
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
getConversations: async () => {
|
|
const response = await api.get('/direct-messages/conversations');
|
|
return response.data;
|
|
},
|
|
|
|
create: async (data: { content: string; receiver_id: number; snippet_id?: number }) => {
|
|
const response = await api.post('/direct-messages/', data);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const kanbanAPI = {
|
|
// Board operations
|
|
createBoard: async (data: { channel_id: number; name?: string }) => {
|
|
const response = await api.post('/kanban/boards', data);
|
|
return response.data;
|
|
},
|
|
|
|
getBoardByChannel: async (channelId: number) => {
|
|
const response = await api.get(`/kanban/boards/${channelId}`);
|
|
return response.data;
|
|
},
|
|
|
|
updateBoard: async (boardId: number, data: { name?: string }) => {
|
|
const response = await api.put(`/kanban/boards/${boardId}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
// Column operations
|
|
createColumn: async (data: { board_id: number; name: string; position: number; color?: string }) => {
|
|
const response = await api.post('/kanban/columns', data);
|
|
return response.data;
|
|
},
|
|
|
|
updateColumn: async (columnId: number, data: { name?: string; position?: number; color?: string }) => {
|
|
const response = await api.put(`/kanban/columns/${columnId}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
deleteColumn: async (columnId: number) => {
|
|
const response = await api.delete(`/kanban/columns/${columnId}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Card operations
|
|
createCard: async (data: {
|
|
column_id: number;
|
|
title: string;
|
|
description?: string;
|
|
assignee_id?: number;
|
|
position: number;
|
|
due_date?: string;
|
|
priority?: 'low' | 'medium' | 'high';
|
|
labels?: string;
|
|
}) => {
|
|
const response = await api.post('/kanban/cards', data);
|
|
return response.data;
|
|
},
|
|
|
|
updateCard: async (cardId: number, data: {
|
|
title?: string;
|
|
description?: string;
|
|
assignee_id?: number;
|
|
position?: number;
|
|
due_date?: string;
|
|
priority?: 'low' | 'medium' | 'high';
|
|
labels?: string;
|
|
}) => {
|
|
const response = await api.put(`/kanban/cards/${cardId}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
deleteCard: async (cardId: number) => {
|
|
const response = await api.delete(`/kanban/cards/${cardId}`);
|
|
return response.data;
|
|
},
|
|
|
|
moveCard: async (cardId: number, targetColumnId: number, newPosition: number) => {
|
|
const response = await api.put(`/kanban/cards/${cardId}/move`, null, {
|
|
params: { target_column_id: targetColumnId, new_position: newPosition }
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
// Checklist API
|
|
createChecklist: async (data: { card_id: number; title: string; position: number }) => {
|
|
const response = await api.post('/kanban/checklists', data);
|
|
return response.data;
|
|
},
|
|
|
|
getCardChecklists: async (cardId: number) => {
|
|
const response = await api.get(`/kanban/cards/${cardId}/checklists`);
|
|
return response.data;
|
|
},
|
|
|
|
getChecklist: async (checklistId: number) => {
|
|
const response = await api.get(`/kanban/checklists/${checklistId}`);
|
|
return response.data;
|
|
},
|
|
|
|
updateChecklist: async (checklistId: number, data: { title?: string; position?: number }) => {
|
|
const response = await api.put(`/kanban/checklists/${checklistId}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
deleteChecklist: async (checklistId: number) => {
|
|
const response = await api.delete(`/kanban/checklists/${checklistId}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Checklist Item API
|
|
createChecklistItem: async (data: { checklist_id: number; title: string; is_completed?: boolean; position: number }) => {
|
|
const response = await api.post('/kanban/checklist-items', data);
|
|
return response.data;
|
|
},
|
|
|
|
updateChecklistItem: async (itemId: number, data: { title?: string; is_completed?: boolean; position?: number }) => {
|
|
const response = await api.put(`/kanban/checklist-items/${itemId}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
deleteChecklistItem: async (itemId: number) => {
|
|
const response = await api.delete(`/kanban/checklist-items/${itemId}`);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export const userStatusAPI = {
|
|
getUserStatuses: async (): Promise<Array<{user_id: number, username: string, full_name: string, status: string}>> => {
|
|
const response = await api.get('/user-status');
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export default api;
|