managarten/apps-archived/mail/apps/mobile/utils/api.ts
Till-JS ace7fa8f7f chore: archive finance, mail, moodlit apps and rename voxel-lava
- Move finance, mail, moodlit to apps-archived for later development
- Rename games/voxel-lava to games/voxelava

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 13:13:15 +01:00

169 lines
6 KiB
TypeScript

const BACKEND_URL = process.env.EXPO_PUBLIC_BACKEND_URL || 'http://localhost:3017';
interface ApiResponse<T> {
data?: T;
error?: { message: string; statusCode?: number };
}
export async function fetchApi<T>(
endpoint: string,
options: RequestInit & { token?: string } = {}
): Promise<ApiResponse<T>> {
const { token, ...fetchOptions } = options;
const headers: HeadersInit = {
'Content-Type': 'application/json',
...fetchOptions.headers,
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
try {
const response = await fetch(`${BACKEND_URL}/api/v1${endpoint}`, {
...fetchOptions,
headers,
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
return {
error: {
message: errorData.message || `HTTP error ${response.status}`,
statusCode: response.status,
},
};
}
const data = await response.json();
return { data };
} catch (error: any) {
return {
error: {
message: error.message || 'Network error',
},
};
}
}
// Email Account API
export const accountsApi = {
list: (token: string) => fetchApi<{ accounts: any[] }>('/accounts', { token }),
get: (id: string, token: string) => fetchApi<{ account: any }>(`/accounts/${id}`, { token }),
create: (data: any, token: string) =>
fetchApi<{ account: any }>('/accounts', { method: 'POST', body: JSON.stringify(data), token }),
update: (id: string, data: any, token: string) =>
fetchApi<{ account: any }>(`/accounts/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
token,
}),
delete: (id: string, token: string) =>
fetchApi<void>(`/accounts/${id}`, { method: 'DELETE', token }),
sync: (id: string, token: string) =>
fetchApi<{ success: boolean }>(`/accounts/${id}/sync`, { method: 'POST', token }),
setDefault: (id: string, token: string) =>
fetchApi<{ account: any }>(`/accounts/${id}/default`, { method: 'POST', token }),
};
// Folders API
export const foldersApi = {
list: (accountId: string, token: string) =>
fetchApi<{ folders: any[] }>(`/folders?accountId=${accountId}`, { token }),
get: (id: string, token: string) => fetchApi<{ folder: any }>(`/folders/${id}`, { token }),
};
// Emails API
export const emailsApi = {
list: (
params: { accountId?: string; folderId?: string; page?: number; limit?: number },
token: string
) => {
const searchParams = new URLSearchParams();
if (params.accountId) searchParams.set('accountId', params.accountId);
if (params.folderId) searchParams.set('folderId', params.folderId);
if (params.page) searchParams.set('page', String(params.page));
if (params.limit) searchParams.set('limit', String(params.limit));
return fetchApi<{ emails: any[]; total: number; page: number; limit: number }>(
`/emails?${searchParams.toString()}`,
{ token }
);
},
get: (id: string, token: string) => fetchApi<{ email: any }>(`/emails/${id}`, { token }),
update: (id: string, data: { isRead?: boolean; isStarred?: boolean }, token: string) =>
fetchApi<{ email: any }>(`/emails/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
token,
}),
delete: (id: string, token: string) =>
fetchApi<void>(`/emails/${id}`, { method: 'DELETE', token }),
move: (id: string, folderId: string, token: string) =>
fetchApi<{ email: any }>(`/emails/${id}/move`, {
method: 'POST',
body: JSON.stringify({ folderId }),
token,
}),
search: (query: string, accountId: string | undefined, token: string) => {
const searchParams = new URLSearchParams({ q: query });
if (accountId) searchParams.set('accountId', accountId);
return fetchApi<{ emails: any[] }>(`/emails/search?${searchParams.toString()}`, { token });
},
};
// Compose/Drafts API
export const composeApi = {
listDrafts: (accountId: string | undefined, token: string) => {
const params = accountId ? `?accountId=${accountId}` : '';
return fetchApi<{ drafts: any[] }>(`/drafts${params}`, { token });
},
getDraft: (id: string, token: string) => fetchApi<{ draft: any }>(`/drafts/${id}`, { token }),
createDraft: (data: any, token: string) =>
fetchApi<{ draft: any }>('/drafts', { method: 'POST', body: JSON.stringify(data), token }),
updateDraft: (id: string, data: any, token: string) =>
fetchApi<{ draft: any }>(`/drafts/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
token,
}),
deleteDraft: (id: string, token: string) =>
fetchApi<void>(`/drafts/${id}`, { method: 'DELETE', token }),
sendDraft: (id: string, token: string) =>
fetchApi<{ success: boolean }>(`/drafts/${id}/send`, { method: 'POST', token }),
send: (data: any, token: string) =>
fetchApi<{ success: boolean }>('/send', { method: 'POST', body: JSON.stringify(data), token }),
createReply: (emailId: string, token: string) =>
fetchApi<{ draft: any }>(`/emails/${emailId}/reply`, { method: 'POST', token }),
createReplyAll: (emailId: string, token: string) =>
fetchApi<{ draft: any }>(`/emails/${emailId}/reply-all`, { method: 'POST', token }),
createForward: (emailId: string, token: string) =>
fetchApi<{ draft: any }>(`/emails/${emailId}/forward`, { method: 'POST', token }),
};
// Labels API
export const labelsApi = {
list: (token: string) => fetchApi<{ labels: any[] }>('/labels', { token }),
create: (data: { name: string; color: string }, token: string) =>
fetchApi<{ label: any }>('/labels', { method: 'POST', body: JSON.stringify(data), token }),
update: (id: string, data: { name?: string; color?: string }, token: string) =>
fetchApi<{ label: any }>(`/labels/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
token,
}),
delete: (id: string, token: string) =>
fetchApi<void>(`/labels/${id}`, { method: 'DELETE', token }),
addToEmail: (emailId: string, labelIds: string[], token: string) =>
fetchApi<void>(`/labels/email/${emailId}/add`, {
method: 'POST',
body: JSON.stringify({ labelIds }),
token,
}),
removeFromEmail: (emailId: string, labelIds: string[], token: string) =>
fetchApi<void>(`/labels/email/${emailId}/remove`, {
method: 'POST',
body: JSON.stringify({ labelIds }),
token,
}),
};