Files
whats-the-point/frontend/src/api.js

177 lines
3.9 KiB
JavaScript

const API_URL = import.meta.env.VITE_API_URL || '/api';
class API {
constructor() {
this.token = localStorage.getItem('token');
}
setToken(token) {
this.token = token;
if (token) {
localStorage.setItem('token', token);
} else {
localStorage.removeItem('token');
}
}
async request(endpoint, options = {}) {
const headers = {
'Content-Type': 'application/json',
...options.headers
};
if (this.token) {
headers.Authorization = `Bearer ${this.token}`;
}
const response = await fetch(`${API_URL}${endpoint}`, {
...options,
headers
});
if (!response.ok) {
const error = await response.json().catch(() => ({ error: 'Request failed' }));
throw new Error(error.error || 'Request failed');
}
return response.json();
}
// Auth
async register(email, username, password) {
const data = await this.request('/auth/register', {
method: 'POST',
body: JSON.stringify({ email, username, password })
});
this.setToken(data.token);
return data;
}
async login(email, password) {
const data = await this.request('/auth/login', {
method: 'POST',
body: JSON.stringify({ email, password })
});
this.setToken(data.token);
return data;
}
async getMe() {
return this.request('/auth/me');
}
// Challenges
async getChallenges() {
return this.request('/challenges');
}
async getChallenge(id) {
return this.request(`/challenges/${id}`);
}
async createChallenge(data) {
return this.request('/challenges', {
method: 'POST',
body: JSON.stringify(data)
});
}
async inviteToChallenge(challengeId, data) {
return this.request(`/challenges/${challengeId}/invite`, {
method: 'POST',
body: JSON.stringify(data)
});
}
async respondToChallenge(challengeId, status) {
return this.request(`/challenges/${challengeId}/respond`, {
method: 'POST',
body: JSON.stringify({ status })
});
}
// Predictions
async getPredictions(challengeId) {
return this.request(`/predictions/challenge/${challengeId}`);
}
async createPrediction(data) {
return this.request('/predictions', {
method: 'POST',
body: JSON.stringify(data)
});
}
async validatePrediction(predictionId, status) {
return this.request(`/predictions/${predictionId}/validate`, {
method: 'POST',
body: JSON.stringify({ status })
});
}
// Friends
async getFriends() {
return this.request('/friends');
}
async searchUsers(query) {
return this.request(`/friends/search?q=${encodeURIComponent(query)}`);
}
async sendFriendRequest(userId) {
return this.request('/friends/request', {
method: 'POST',
body: JSON.stringify({ user_id: userId })
});
}
async respondToFriendRequest(friendshipId, status) {
return this.request('/friends/respond', {
method: 'POST',
body: JSON.stringify({ friendship_id: friendshipId, status })
});
}
async getFriendRequests() {
return this.request('/friends/requests');
}
async removeFriend(friendId) {
return this.request(`/friends/${friendId}`, {
method: 'DELETE'
});
}
async deleteChallenge(challengeId) {
return this.request(`/challenges/${challengeId}`, {
method: 'DELETE'
});
}
async leaveChallenge(challengeId) {
return this.request(`/challenges/${challengeId}/leave`, {
method: 'POST'
});
}
// TMDB
async searchShows(query) {
return this.request(`/tmdb/search?q=${encodeURIComponent(query)}`);
}
// Leaderboard
async getChallengeLeaderboard(challengeId) {
return this.request(`/leaderboard/challenge/${challengeId}`);
}
async getGlobalLeaderboard() {
return this.request('/leaderboard/global');
}
async getProfile(userId) {
return this.request(`/leaderboard/profile${userId ? `/${userId}` : ''}`);
}
}
export default new API();