diff --git a/src/renderer/components/commentSection.tsx b/src/renderer/components/commentSection.tsx new file mode 100644 index 0000000..ad22b8e --- /dev/null +++ b/src/renderer/components/commentSection.tsx @@ -0,0 +1,122 @@ +'use client'; +import { useState, useEffect } from 'react'; +import { + Pagination, + PaginationContent, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, +} from '@/components/ui/pagination'; +import { Avatar } from '@/components/ui/avatar'; +import { Separator } from '@/components/ui/separator'; + +import RatingDisplay from './ratingDisplay'; +import Jazzicon from 'react-jazzicon'; + +import { useGamesStore } from '../lib/stores/gameStore'; +import { base58Decode } from '../lib/utils'; +import { fetchComments } from '../lib/api'; + +export default function CommentSection({ game }: { game: Game }) { + const [comments, setComments] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [totalPages, setTotalPages] = useState(1); + const [currentLimit, setCurrentLimit] = useState(10); + const [totalComments, setTotalComments] = useState(0); + const [isLoading, setIsLoading] = useState(false); + const [postTrigger, setPostTrigger] = useState(false); + const gameStore = useGamesStore(); + + useEffect(() => { + const loadComments = async () => { + setIsLoading(true); + try { + const { comments, totalComments, totalPages } = await fetchComments( + game.gameId, + currentPage, + currentLimit, + ); + + setComments(comments); + setTotalPages(totalPages); + setTotalComments(totalComments); + } catch (error) { + console.error('Failed to fetch comments:', error); + } finally { + setIsLoading(false); + } + }; + + loadComments(); + }, [game.gameId, currentPage, postTrigger]); + + return ( +
+

+ Comments ( {totalComments} ) +

+ +
+ {comments.length > 0 ? ( + comments.map((comment) => ( +
+ + + +
+
+ + {comment.user.publicKey.slice(0, 4) + + ' ... ' + + comment.user.publicKey.slice(-4)} + + + {new Date(comment.createdAt).toLocaleString()} + +
+ +

{comment.content}

+
+
+ )) + ) : ( +

No comments yet. Be the first to comment!

+ )} + {isLoading &&

Loading comments...

} +
+ {currentPage <= totalPages && ( + + + + { + if (currentPage > 1) { + setCurrentPage((prevPage) => prevPage - 1); + setPostTrigger((prev) => !prev); + } + }} + /> + + + {currentPage} + + + { + if (currentPage < totalPages) { + setCurrentPage((prevPage) => prevPage + 1); + setPostTrigger((prev) => !prev); + } + }} + /> + + + + )} +
+ ); +} diff --git a/src/renderer/components/featured.tsx b/src/renderer/components/featured.tsx index 1755a1b..bb24d89 100644 --- a/src/renderer/components/featured.tsx +++ b/src/renderer/components/featured.tsx @@ -80,25 +80,18 @@ export default function Featured() { className=" w-5 h-5 inline-block" /> - - {!userStore.library.includes(game.gameId || -1) ? ( - - ) : ( -
- Owned -
- )} + diff --git a/src/renderer/components/game-detail.tsx b/src/renderer/components/game-detail.tsx index 6a6dbb4..73491c0 100644 --- a/src/renderer/components/game-detail.tsx +++ b/src/renderer/components/game-detail.tsx @@ -3,13 +3,15 @@ import { CarouselContent, CarouselItem, } from '@/components/ui/carousel'; -import { ChevronLeft, Download } from 'lucide-react'; +import { ChevronLeft } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { useNavigate, useParams } from 'react-router-dom'; import { useGamesStore } from '../lib/stores/gameStore'; import { Separator } from '@/components/ui/separator'; import { API_URL } from '@/env'; +import RatingDisplay from './ratingDisplay'; +import CommentSection from './commentSection'; export default function GameDetail() { const { gameName } = useParams(); @@ -19,8 +21,6 @@ export default function GameDetail() { const game = gameStore.games.find((game) => game.name === gameName); const imageCount = game?.imageCount || 1; - const handleDownload = () => {}; - return (
@@ -68,7 +68,15 @@ export default function GameDetail() {

{game?.name}

{game?.description}
-
Total Reviews: 5 (4.3)
+
+ +
+ Total Reviews: {game?.ratingCount} +
+
{Array.from(game?.tags || []).map((tag, index) => ( @@ -114,13 +122,9 @@ export default function GameDetail() { ); }} > - Buy Game + Visit Store
-
@@ -158,7 +162,7 @@ export default function GameDetail() {
- {/* */} + ); } diff --git a/src/renderer/components/ratingDisplay.tsx b/src/renderer/components/ratingDisplay.tsx new file mode 100644 index 0000000..eb0f475 --- /dev/null +++ b/src/renderer/components/ratingDisplay.tsx @@ -0,0 +1,32 @@ +import { Star } from 'lucide-react'; + +export default function RatingDisplay({ + rating, + decimals, +}: { + rating: number; + decimals: boolean; +}) { + return ( +
+
+ {[1, 2, 3, 4, 5].map((star) => { + const fillPercentage = Math.min(Math.max(rating - (star - 1), 0), 1); + + return ( +
+ +
+ +
+
+ ); + })} +
+ {decimals &&
({rating.toFixed(1)})
} +
+ ); +}