import PocketBase from 'pocketbase'; import type { Post } from '../globalInterfaces'; const PB_URL = import.meta.env.POCKETBASE_URL || 'http://127.0.0.1:8090'; export const pb = new PocketBase(PB_URL); if (typeof window !== 'undefined') { const token = localStorage.getItem('auth_token'); const userStr = localStorage.getItem('user'); // Инициализируем куку из localStorage если её нет if (token && !document.cookie.includes('pb_auth')) { document.cookie = `pb_auth=${token}; path=/; max-age=${7 * 24 * 60 * 60}; SameSite=Lax`; } if (token && userStr) { try { const user = JSON.parse(userStr); pb.authStore.save(token, user); } catch (e) { console.error('Failed to restore auth:', e); } } } export interface PostVotes { id: string; post_id: string; user_id: string; vote_type: 'like' | 'dislike'; created: string; updated: string; } export interface VoteStats { likes: number; dislikes: number; userVote: 'like' | 'dislike' | null; } export async function getPostVotes(postId: string): Promise { const votes = await pb.collection('post_votes').getList(1, 1000, { filter: `post_id="${postId}"`, }); const likes = votes.items.filter((v) => v.vote_type === 'like').length; const dislikes = votes.items.filter((v) => v.vote_type === 'dislike').length; let userVote: 'like' | 'dislike' | null = null; if (pb.authStore.isValid) { const userId = pb.authStore.model?.id; const userVoteRecord = votes.items.find((v) => v.user_id === userId); if (userVoteRecord) { userVote = userVoteRecord.vote_type as 'like' | 'dislike'; } } return { likes, dislikes, userVote }; } export async function getPostVotesStats(postId: string): Promise<{ likes: number; dislikes: number }> { // Получаем данные из коллекции голосов const votes = await pb.collection('post_votes').getList(1, 1000, { filter: `post="${postId}"`, }); const likes = votes.items.filter((v: any) => v.vote_type === 'like').length; const dislikes = votes.items.filter((v: any) => v.vote_type === 'dislike').length; return { likes, dislikes }; } export async function vote(postId: string, voteType: 'like' | 'dislike'): Promise { const userId = pb.authStore.model?.id; if (!userId) { throw new Error('Требуется авторизация'); } const existingVotes = await pb.collection('post_votes').getList(1, 1, { filter: `post_id="${postId}" && user_id="${userId}"`, }); if (existingVotes.items.length > 0) { const existingVote = existingVotes.items[0] as unknown as PostVotes; if (existingVote.vote_type === voteType) { await pb.collection('post_votes').delete(existingVote.id); } else { await pb.collection('post_votes').update(existingVote.id, { vote_type: voteType, }); } } else { await pb.collection('post_votes').create({ post_id: postId, user_id: userId, vote_type: voteType, }); } return getPostVotes(postId); } export async function getPosts(options?: { page?: number; perPage?: number; category?: string; search?: string; }): Promise<{ posts: Post[]; total: number; page: number; totalPages: number }> { const page = options?.page || 1; const perPage = options?.perPage || 10; const filter: string[] = ['draft = false']; if (options?.category && options.category !== 'Все') { filter.push(`category = "${options.category}"`); } if (options?.search) { filter.push(`(title ~ "${options.search}" || description ~ "${options.search}")`); } const result = await pb.collection('posts').getList(page, perPage, { filter: filter.join(' && '), sort: '-date', }); return { posts: (result.items || []) as unknown as Post[], total: result.totalItems || 0, page: result.page || 1, totalPages: result.totalPages || 1, }; } export async function getPostBySlug(slug: string): Promise { const result = await pb.collection('posts').getList(1, 1, { filter: `slug="${slug}" && draft = false`, }); if (!result.items || result.totalItems === 0) { return null; } return result.items[0] as unknown as Post; } export const FIXED_BLOG_CATEGORIES = [ 'ДТП', 'Лишение прав', 'Страховые споры', 'Штрафы ГИБДД', 'Возмещение ущерба', 'Судебные дела', ]; export async function getAllCategories(): Promise { return ['Все', ...FIXED_BLOG_CATEGORIES]; } export function getPostImageUrl(post: { image?: string }): string { if (post.image) { const fileUrl = pb.files.getUrl(post, post.image); if (fileUrl.startsWith('/')) { return `${PB_URL}${fileUrl}`; } return fileUrl; } return '/images/blog/default.avif'; } export async function getPostViews(postId: string): Promise { try { const post = await pb.collection('posts').getOne(postId); return post.views || 0; } catch { return 0; } } export async function incrementPostViews(postId: string): Promise { const post = await pb.collection('posts').getOne(postId); const newViews = (post.views || 0) + 1; await pb.collection('posts').update(postId, { views: newViews }); return newViews; }