2025-11-03 20:35:01 +00:00
|
|
|
|
import axios from 'axios'
|
2025-11-04 21:51:05 +00:00
|
|
|
|
import { getTelegramInitData } from './telegram'
|
2025-11-03 20:35:01 +00:00
|
|
|
|
|
|
|
|
|
|
// API URL из переменных окружения
|
|
|
|
|
|
const API_URL = import.meta.env.VITE_API_URL || (
|
|
|
|
|
|
import.meta.env.DEV
|
|
|
|
|
|
? 'http://localhost:3000/api'
|
|
|
|
|
|
: '/api' // Для production используем относительный путь
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Создать инстанс axios с настройками
|
|
|
|
|
|
const api = axios.create({
|
|
|
|
|
|
baseURL: API_URL,
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// Добавить interceptor для добавления Telegram Init Data
|
|
|
|
|
|
api.interceptors.request.use((config) => {
|
|
|
|
|
|
const initData = getTelegramInitData()
|
|
|
|
|
|
|
2025-11-04 21:51:05 +00:00
|
|
|
|
// Отправляем initData только если есть
|
|
|
|
|
|
if (initData) {
|
2025-11-03 20:35:01 +00:00
|
|
|
|
config.headers['x-telegram-init-data'] = initData
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return config
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// Auth API
|
|
|
|
|
|
export const verifyAuth = async () => {
|
|
|
|
|
|
const response = await api.post('/auth/verify')
|
|
|
|
|
|
return response.data.user
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-04 21:51:05 +00:00
|
|
|
|
// Авторизация через Telegram OAuth (Login Widget)
|
|
|
|
|
|
export const authWithTelegramOAuth = async (userData) => {
|
|
|
|
|
|
// userData от Telegram Login Widget содержит: id, first_name, last_name, username, photo_url, auth_date, hash
|
|
|
|
|
|
const response = await api.post('/auth/oauth', {
|
|
|
|
|
|
user: {
|
|
|
|
|
|
id: userData.id,
|
|
|
|
|
|
first_name: userData.first_name,
|
|
|
|
|
|
last_name: userData.last_name,
|
|
|
|
|
|
username: userData.username,
|
|
|
|
|
|
photo_url: userData.photo_url
|
|
|
|
|
|
},
|
|
|
|
|
|
auth_date: userData.auth_date,
|
|
|
|
|
|
hash: userData.hash
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data.user
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-03 20:35:01 +00:00
|
|
|
|
// Posts API
|
|
|
|
|
|
export const getPosts = async (params = {}) => {
|
|
|
|
|
|
const response = await api.get('/posts', { params })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const createPost = async (formData) => {
|
|
|
|
|
|
const response = await api.post('/posts', formData, {
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
'Content-Type': 'multipart/form-data'
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data.post
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const likePost = async (postId) => {
|
|
|
|
|
|
const response = await api.post(`/posts/${postId}/like`)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const commentPost = async (postId, content) => {
|
|
|
|
|
|
const response = await api.post(`/posts/${postId}/comment`, { content })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-04 21:51:05 +00:00
|
|
|
|
export const editPost = async (postId, data) => {
|
|
|
|
|
|
const response = await api.put(`/posts/${postId}`, data)
|
|
|
|
|
|
return response.data.post
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const editComment = async (postId, commentId, content) => {
|
|
|
|
|
|
const response = await api.put(`/posts/${postId}/comments/${commentId}`, { content })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const deleteComment = async (postId, commentId) => {
|
|
|
|
|
|
const response = await api.delete(`/posts/${postId}/comments/${commentId}`)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-03 20:35:01 +00:00
|
|
|
|
export const repostPost = async (postId) => {
|
|
|
|
|
|
const response = await api.post(`/posts/${postId}/repost`)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const deletePost = async (postId) => {
|
|
|
|
|
|
const response = await api.delete(`/posts/${postId}`)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Users API
|
|
|
|
|
|
export const getUserProfile = async (userId) => {
|
|
|
|
|
|
const response = await api.get(`/users/${userId}`)
|
|
|
|
|
|
return response.data.user
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const getUserPosts = async (userId, params = {}) => {
|
|
|
|
|
|
const response = await api.get(`/users/${userId}/posts`, { params })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const followUser = async (userId) => {
|
|
|
|
|
|
const response = await api.post(`/users/${userId}/follow`)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const updateProfile = async (data) => {
|
|
|
|
|
|
const response = await api.put('/users/profile', data)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const searchUsers = async (query) => {
|
|
|
|
|
|
const response = await api.get(`/users/search/${query}`)
|
|
|
|
|
|
return response.data.users
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Notifications API
|
|
|
|
|
|
export const getNotifications = async (params = {}) => {
|
|
|
|
|
|
const response = await api.get('/notifications', { params })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const markNotificationRead = async (notificationId) => {
|
|
|
|
|
|
const response = await api.put(`/notifications/${notificationId}/read`)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const markAllNotificationsRead = async () => {
|
|
|
|
|
|
const response = await api.put('/notifications/read-all')
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Search API
|
|
|
|
|
|
export const searchFurry = async (query, params = {}) => {
|
|
|
|
|
|
const response = await api.get('/search/furry', { params: { query, ...params } })
|
|
|
|
|
|
return response.data.posts
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const searchAnime = async (query, params = {}) => {
|
|
|
|
|
|
const response = await api.get('/search/anime', { params: { query, ...params } })
|
|
|
|
|
|
return response.data.posts
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const getFurryTags = async (query) => {
|
|
|
|
|
|
const response = await api.get('/search/furry/tags', { params: { query } })
|
|
|
|
|
|
return response.data.tags
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const getAnimeTags = async (query) => {
|
|
|
|
|
|
const response = await api.get('/search/anime/tags', { params: { query } })
|
|
|
|
|
|
return response.data.tags
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Moderation API
|
|
|
|
|
|
export const reportPost = async (postId, reason) => {
|
|
|
|
|
|
const response = await api.post('/moderation/report', { postId, reason })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const getReports = async (params = {}) => {
|
|
|
|
|
|
const response = await api.get('/moderation/reports', { params })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const updateReport = async (reportId, data) => {
|
|
|
|
|
|
const response = await api.put(`/moderation/reports/${reportId}`, data)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const setPostNSFW = async (postId, isNSFW) => {
|
|
|
|
|
|
const response = await api.put(`/moderation/posts/${postId}/nsfw`, { isNSFW })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const banUser = async (userId, banned, days) => {
|
|
|
|
|
|
const response = await api.put(`/moderation/users/${userId}/ban`, { banned, days })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-04 21:51:05 +00:00
|
|
|
|
// Bot API
|
|
|
|
|
|
export const sendPhotoToTelegram = async (photoUrl) => {
|
|
|
|
|
|
const response = await api.post('/bot/send-photo', { photoUrl })
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-03 20:35:01 +00:00
|
|
|
|
export default api
|
|
|
|
|
|
|