Create frontend
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* API service — all backend requests for This OR That.
|
||||
* All endpoints return { result, error } (BaseResponse).
|
||||
*/
|
||||
|
||||
const BASE_URL = process.env.REACT_APP_API_URL || '';
|
||||
|
||||
async function request(method, path, body = null) {
|
||||
const options = {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
};
|
||||
if (body) {
|
||||
options.body = JSON.stringify(body);
|
||||
}
|
||||
|
||||
const response = await fetch(`${BASE_URL}${path}`, options);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
}
|
||||
|
||||
const GET = (path) => request('GET', path);
|
||||
const POST = (path, body) => request('POST', path, body);
|
||||
const PATCH = (path, body) => request('PATCH', path, body);
|
||||
|
||||
export const api = {
|
||||
// Users
|
||||
checkUser: (userId) =>
|
||||
GET(`/check_user?user_id=${userId}`),
|
||||
|
||||
getUser: (userId) =>
|
||||
GET(`/get_user?user_id=${userId}`),
|
||||
|
||||
addUser: ({ user_id, username, first_name, last_name, photo_url }) =>
|
||||
POST('/add_user', { user_id, username, first_name, last_name, photo_url }),
|
||||
|
||||
// Cards
|
||||
getCard: (cardId) =>
|
||||
GET(`/get_card?card_id=${cardId}`),
|
||||
|
||||
getRandomCards: (userId) =>
|
||||
GET(`/get_random_cards?user_id=${userId}`),
|
||||
|
||||
selectChoice: (userId, cardId, choice) =>
|
||||
PATCH('/select_choice', { user_id: userId, card_id: cardId, choice }),
|
||||
|
||||
addCard: (choiceA, choiceB, authorId) =>
|
||||
POST('/add_card', { choice_A: choiceA, choice_B: choiceB, author_id: authorId }),
|
||||
|
||||
// Reactions
|
||||
likeCard: (userId, cardId) =>
|
||||
PATCH('/like_card', { user_id: userId, card_id: cardId }),
|
||||
|
||||
dislikeCard: (userId, cardId) =>
|
||||
PATCH('/dislike_card', { user_id: userId, card_id: cardId }),
|
||||
|
||||
// Comments
|
||||
addComment: (authorId, cardId, commentText) =>
|
||||
POST('/comment', { author_id: authorId, card_id: cardId, comment_text: commentText }),
|
||||
|
||||
// TODO: GET /get_comments — endpoint not yet implemented on backend
|
||||
getComments: (cardId) => {
|
||||
console.warn('GET /get_comments not implemented on backend yet');
|
||||
return Promise.resolve({ result: [], error: false });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Auth service — detects Telegram WebApp user or falls back to mock.
|
||||
* Auto-registers user on backend if not yet registered.
|
||||
*/
|
||||
|
||||
const MOCK_USER = {
|
||||
id: 999995,
|
||||
first_name: 'Dev',
|
||||
last_name: 'User',
|
||||
username: 'devuser',
|
||||
photo_url: '',
|
||||
};
|
||||
|
||||
function getTelegramUser() {
|
||||
try {
|
||||
const tg = window.Telegram?.WebApp;
|
||||
const user = tg?.initDataUnsafe?.user;
|
||||
if (user && user.id) {
|
||||
return {
|
||||
id: user.id,
|
||||
first_name: user.first_name || '',
|
||||
last_name: user.last_name || '',
|
||||
username: user.username || '',
|
||||
photo_url: user.photo_url || '',
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
// Telegram SDK not available
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export const currentUser = getTelegramUser() ?? MOCK_USER;
|
||||
export const isTelegram = !!getTelegramUser();
|
||||
|
||||
export function initTelegramApp() {
|
||||
const tg = window.Telegram?.WebApp;
|
||||
if (tg) {
|
||||
tg.ready();
|
||||
tg.expand();
|
||||
}
|
||||
}
|
||||
|
||||
export function showBackButton(onBack) {
|
||||
const tg = window.Telegram?.WebApp;
|
||||
if (tg?.BackButton) {
|
||||
tg.BackButton.show();
|
||||
tg.BackButton.onClick(onBack);
|
||||
return () => {
|
||||
tg.BackButton.offClick(onBack);
|
||||
tg.BackButton.hide();
|
||||
};
|
||||
}
|
||||
return () => { };
|
||||
}
|
||||
Reference in New Issue
Block a user