// API сервис для работы с бэкендом const API_URL = import.meta.env.VITE_API_URL || "http://localhost:3001"; // ============ AUTH ============ export interface User { id: string; discordId: string; username: string; email: string; avatar: string | null; } export function getDiscordLoginUrl(): string { return `${API_URL}/auth/discord`; } export async function getCurrentUser(): Promise { try { const response = await fetch(`${API_URL}/auth/me`, { credentials: "include", }); const data = await response.json(); return data.user; } catch (error) { console.error("Failed to get current user:", error); return null; } } export async function logout(): Promise { try { const response = await fetch(`${API_URL}/auth/logout`, { method: "POST", credentials: "include", }); return response.ok; } catch (error) { console.error("Failed to logout:", error); return false; } } export function getDiscordAvatarUrl(user: User): string { if (user.avatar) { return `https://cdn.discordapp.com/avatars/${user.discordId}/${user.avatar}.png`; } // Default Discord avatar const defaultAvatarIndex = parseInt(user.discordId) % 5; return `https://cdn.discordapp.com/embed/avatars/${defaultAvatarIndex}.png`; } // ============ STORIES ============ import type { Story } from "../types"; export async function getStories(): Promise { try { const response = await fetch(`${API_URL}/api/stories`, { credentials: "include", }); if (response.status === 401) { return []; } if (!response.ok) { throw new Error("Failed to fetch stories"); } return await response.json(); } catch (error) { console.error("Failed to get stories:", error); return []; } } export async function getStory(id: string): Promise { try { const response = await fetch(`${API_URL}/api/stories/${id}`, { credentials: "include", }); if (!response.ok) { return null; } return await response.json(); } catch (error) { console.error("Failed to get story:", error); return null; } } export async function createStory( story: Omit, ): Promise { try { const response = await fetch(`${API_URL}/api/stories`, { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify(story), }); if (!response.ok) { throw new Error("Failed to create story"); } const data = await response.json(); return { ...data, id: data._id }; } catch (error) { console.error("Failed to create story:", error); return null; } } export async function updateStory( id: string, story: Partial, ): Promise { try { const response = await fetch(`${API_URL}/api/stories/${id}`, { method: "PUT", headers: { "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify(story), }); return response.ok; } catch (error) { console.error("Failed to update story:", error); return false; } } export async function deleteStory(id: string): Promise { try { const response = await fetch(`${API_URL}/api/stories/${id}`, { method: "DELETE", credentials: "include", }); return response.ok; } catch (error) { console.error("Failed to delete story:", error); return false; } } // ============ GAME SESSIONS ============ import type { GameSession } from "../types"; export async function getSession(storyId: string): Promise { try { const response = await fetch(`${API_URL}/api/sessions/${storyId}`, { credentials: "include", }); if (!response.ok) { return null; } return await response.json(); } catch (error) { console.error("Failed to get session:", error); return null; } } export async function saveSession( storyId: string, session: Omit, ): Promise { try { const response = await fetch(`${API_URL}/api/sessions/${storyId}`, { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify(session), }); return response.ok; } catch (error) { console.error("Failed to save session:", error); return false; } } // ============ PLAYER CHARACTERS ============ import type { PlayerCharacter } from "../types"; export async function getPlayerCharacters(): Promise { try { const response = await fetch(`${API_URL}/api/characters`, { credentials: "include", }); if (response.status === 401) { return []; } if (!response.ok) { throw new Error("Failed to fetch characters"); } const data = await response.json(); return data.map((c: any) => ({ ...c, id: c._id || c.id })); } catch (error) { console.error("Failed to get characters:", error); return []; } } export async function getPlayerCharacter( id: string, ): Promise { try { const response = await fetch(`${API_URL}/api/characters/${id}`, { credentials: "include", }); if (!response.ok) { return null; } const data = await response.json(); return { ...data, id: data._id || data.id }; } catch (error) { console.error("Failed to get character:", error); return null; } } export async function createPlayerCharacter( character: Omit, ): Promise { try { const response = await fetch(`${API_URL}/api/characters`, { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify(character), }); if (!response.ok) { throw new Error("Failed to create character"); } const data = await response.json(); return { ...data, id: data._id }; } catch (error) { console.error("Failed to create character:", error); return null; } } export async function updatePlayerCharacter( id: string, character: Partial, ): Promise { try { const response = await fetch(`${API_URL}/api/characters/${id}`, { method: "PUT", headers: { "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify(character), }); return response.ok; } catch (error) { console.error("Failed to update character:", error); return false; } } export async function deletePlayerCharacter(id: string): Promise { try { const response = await fetch(`${API_URL}/api/characters/${id}`, { method: "DELETE", credentials: "include", }); return response.ok; } catch (error) { console.error("Failed to delete character:", error); return false; } } // ============ ADMIN STATS ============ interface StoryStats { id: string; title: string; messageCount: number; tokens: number; lastPlayed: string | null; } interface AdminStats { totalStories: number; totalSessions: number; totalTokens: number; stories: StoryStats[]; } export async function getAdminStats(): Promise { try { const response = await fetch(`${API_URL}/api/admin/stats`, { credentials: "include", }); if (!response.ok) { return null; } return await response.json(); } catch (error) { console.error("Failed to get admin stats:", error); return null; } }