Новы глобальные изменения компонентоы

This commit is contained in:
Web-serfer 2026-04-17 17:35:17 +05:00
parent 5d7bb04bf1
commit a269d3459e
43 changed files with 1667 additions and 517 deletions

View file

@ -5,7 +5,101 @@ const PB_URL = import.meta.env.POCKETBASE_URL || 'http://127.0.0.1:8090';
export const pb = new PocketBase(PB_URL);
pb.collection('_superusers').authRefresh().catch(() => {});
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<VoteStats> {
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 }> {
// Получаем данные поста напрямую (likes/dislikes хранятся в самом посте)
const post = await pb.collection('posts').getOne(postId);
return {
likes: post.likes || 0,
dislikes: post.dislikes || 0,
};
}
export async function vote(postId: string, voteType: 'like' | 'dislike'): Promise<VoteStats> {
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;