Update frontend for new backend

This commit is contained in:
IgorVolochay
2026-09-01 14:31:52 +03:00
parent bdf3d5aec1
commit 008dd1c29e
22 changed files with 1113 additions and 264 deletions
+24 -20
View File
@@ -1,51 +1,54 @@
import React, { useState } from 'react';
import { useApp } from '../../context/AppContext';
import { hapticImpact } from '../../services/auth';
import './BottomBar.css';
export default function BottomBar() {
const { currentCard, chosenCard, likeCard, dislikeCard, setIsCommentsOpen, user } = useApp();
const [reactionState, setReactionState] = useState(null); // 'liked' | 'disliked' | null
const [isSubmitting, setIsSubmitting] = useState(false);
const isRevealed = chosenCard !== null;
// Check if user already reacted to this card
const alreadyLiked = user?.liked_card_ids?.includes(currentCard?.card_id);
const alreadyDisliked = user?.disliked_card_ids?.includes(currentCard?.card_id);
const currentReaction = reactionState || (alreadyLiked ? 'liked' : alreadyDisliked ? 'disliked' : null);
const currentReaction = alreadyLiked ? 'liked' : alreadyDisliked ? 'disliked' : null;
const handleLike = async () => {
if (!isRevealed || currentReaction) return;
const result = await likeCard();
if (result && !result.error) {
setReactionState('liked');
if (!isRevealed || currentReaction || isSubmitting) return;
setIsSubmitting(true);
try {
await likeCard();
} finally {
setIsSubmitting(false);
}
};
const handleDislike = async () => {
if (!isRevealed || currentReaction) return;
const result = await dislikeCard();
if (result && !result.error) {
setReactionState('disliked');
if (!isRevealed || currentReaction || isSubmitting) return;
setIsSubmitting(true);
try {
await dislikeCard();
} finally {
setIsSubmitting(false);
}
};
const handleComments = () => {
hapticImpact('light');
setIsCommentsOpen(true);
};
// Reset reaction state when card changes
React.useEffect(() => {
setReactionState(null);
}, [currentCard?.card_id]);
const likes = (currentCard?.count_likes || 0) + (reactionState === 'liked' ? 1 : 0);
const dislikes = (currentCard?.count_dislikes || 0) + (reactionState === 'disliked' ? 1 : 0);
const likes = currentCard?.count_likes || 0;
const dislikes = currentCard?.count_dislikes || 0;
const commentsCount = currentCard?.comments?.length || 0;
return (
<div className="bottom-bar">
<button
className={`bar-btn bar-btn--dislike ${currentReaction === 'disliked' ? 'bar-btn--active' : ''} ${!isRevealed || currentReaction ? 'bar-btn--disabled' : ''}`}
className={`bar-btn bar-btn--dislike ${currentReaction === 'disliked' ? 'bar-btn--active' : ''} ${!isRevealed || currentReaction || isSubmitting ? 'bar-btn--disabled' : ''}`}
onClick={handleDislike}
disabled={!isRevealed || !!currentReaction || isSubmitting}
aria-label="Дизлайк"
>
<svg className="bar-icon" viewBox="0 0 24 24" fill="currentColor" style={{ transform: 'rotate(180deg)' }}>
@@ -62,12 +65,13 @@ export default function BottomBar() {
<svg className="bar-icon" viewBox="0 0 24 24" fill="currentColor">
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z" />
</svg>
<span className="bar-count">{formatCount(currentCard?.comments?.length || 0)}</span>
<span className="bar-count">{formatCount(commentsCount)}</span>
</button>
<button
className={`bar-btn bar-btn--like ${currentReaction === 'liked' ? 'bar-btn--active' : ''} ${!isRevealed || currentReaction ? 'bar-btn--disabled' : ''}`}
className={`bar-btn bar-btn--like ${currentReaction === 'liked' ? 'bar-btn--active' : ''} ${!isRevealed || currentReaction || isSubmitting ? 'bar-btn--disabled' : ''}`}
onClick={handleLike}
disabled={!isRevealed || !!currentReaction || isSubmitting}
aria-label="Лайк"
>
<svg className="bar-icon" viewBox="0 0 24 24" fill="currentColor">