we-superapp / apps /web /src /api.js
nenbuj
Initial deploy: «МЫ» супер-апп
c562e21
Raw History Blame Contribute Delete
3.74 kB
// Пусто = тот же origin (фронт отдаётся самим API → один туннель для Telegram).
// Для dev в браузере (Vite на :5173) задай VITE_API_URL=http://localhost:3000 в apps/web/.env
const BASE_URL = import.meta.env.VITE_API_URL ?? '';
async function request(path, options = {}) {
const token = localStorage.getItem('token');
const headers = {
'Content-Type': 'application/json',
...(options.headers || {}),
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const config = {
...options,
headers,
};
try {
const response = await fetch(`${BASE_URL}${path}`, config);
let data = {};
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
data = await response.json();
}
if (!response.ok) {
if (data.error) {
throw data.error;
}
throw {
code: 'HTTP_ERROR',
message: data.message || `Request failed with status ${response.status}`,
};
}
return data;
} catch (error) {
console.error(`API Error on ${path}:`, error);
if (error.code && error.message) {
throw error;
}
throw {
code: 'NETWORK_ERROR',
message: error.message || 'Ошибка сети или бэкенд недоступен',
};
}
}
export const api = {
// Auth
authTelegram: (initData) => request('/auth/telegram', {
method: 'POST',
body: JSON.stringify({ initData }),
}),
authRegister: (email, password, name) => request('/auth/register', {
method: 'POST',
body: JSON.stringify({ email, password, name }),
}),
authLogin: (email, password) => request('/auth/login', {
method: 'POST',
body: JSON.stringify({ email, password }),
}),
authMe: () => request('/auth/me', {
method: 'GET',
}),
// Spaces
getSpaces: () => request('/spaces', {
method: 'GET',
}),
createSpace: (name, type) => request('/spaces', {
method: 'POST',
body: JSON.stringify({ name, type }),
}),
getSpace: (id) => request(`/spaces/${id}`, {
method: 'GET',
}),
joinSpace: (id) => request(`/spaces/${id}/join`, {
method: 'POST',
}),
getSpaceMembers: (id) => request(`/spaces/${id}/members`, {
method: 'GET',
}),
// Finance
getTransactions: (spaceId) => request(`/spaces/${spaceId}/transactions`, {
method: 'GET',
}),
createTransaction: (spaceId, { title, amount, paid_by, split }) => request(`/spaces/${spaceId}/transactions`, {
method: 'POST',
body: JSON.stringify({ title, amount, paid_by, split }),
}),
getBalance: (spaceId) => request(`/spaces/${spaceId}/balance`, {
method: 'GET',
}),
// Tasks
getTasks: (spaceId) => request(`/spaces/${spaceId}/tasks`, {
method: 'GET',
}),
createTask: (spaceId, { title, assignee_id, due_at }) => request(`/spaces/${spaceId}/tasks`, {
method: 'POST',
body: JSON.stringify({ title, assignee_id, due_at }),
}),
updateTask: (spaceId, taskId, { done, assignee_id, title }) => request(`/spaces/${spaceId}/tasks/${taskId}`, {
method: 'PATCH',
body: JSON.stringify({ done, assignee_id, title }),
}),
// Feed (posts)
getPosts: (spaceId) => request(`/spaces/${spaceId}/posts`, {
method: 'GET',
}),
createPost: (spaceId, { text }) => request(`/spaces/${spaceId}/posts`, {
method: 'POST',
body: JSON.stringify({ text }),
}),
// Calendar (events)
getEvents: (spaceId) => request(`/spaces/${spaceId}/events`, {
method: 'GET',
}),
createEvent: (spaceId, { title, start_at }) => request(`/spaces/${spaceId}/events`, {
method: 'POST',
body: JSON.stringify({ title, start_at }),
}),
};