diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 46bdb28c..e578b251 100755 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -223,6 +223,7 @@ "show_more": "Show more", "show_less": "Show less", "reviews": "Reviews", + "played_for": "Played for", "leave_a_review": "Leave a Review", "write_review_placeholder": "Share your thoughts about this game...", "sort_newest": "Newest", diff --git a/src/renderer/src/pages/game-details/review-item.scss b/src/renderer/src/pages/game-details/review-item.scss index d4f2d38c..b3577a75 100644 --- a/src/renderer/src/pages/game-details/review-item.scss +++ b/src/renderer/src/pages/game-details/review-item.scss @@ -22,7 +22,13 @@ &__review-user-info { display: flex; flex-direction: column; - gap: calc(globals.$spacing-unit * 0.25); + gap: calc(globals.$spacing-unit * 0.45); + } + + &__review-meta-row { + display: flex; + align-items: center; + gap: calc(globals.$spacing-unit * 0.75); } &__review-display-name { @@ -157,28 +163,28 @@ &__review-score-stars { display: flex; align-items: center; - gap: 2px; + gap: 4px; + background: rgba(255, 255, 255, 0.05); + border-radius: 8px; + padding: 2px 6px; + border: 1px solid rgba(255, 255, 255, 0.1); + font-size: 11px; + font-weight: 500; + } + + &__review-right { + display: flex; + flex-direction: column; + align-items: flex-end; } &__review-star { - color: #666666; + color: rgba(255, 255, 255, 0.7); transition: color 0.2s ease; cursor: default; &--filled { - color: #ffffff; - - &.game-details__review-score--red { - color: #fca5a5; - } - - &.game-details__review-score--yellow { - color: #fcd34d; - } - - &.game-details__review-score--green { - color: #86efac; - } + color: rgba(255, 255, 255, 0.7); } &--empty { @@ -198,6 +204,24 @@ font-size: globals.$small-font-size; } + &__review-playtime { + display: flex; + align-items: center; + gap: 4px; + color: rgba(255, 255, 255, 0.7); + font-size: 11px; + font-weight: 500; + background: rgba(255, 255, 255, 0.05); + border-radius: 8px; + padding: 2px 6px; + border: 1px solid rgba(255, 255, 255, 0.1); + margin-top: 0; + + svg { + color: rgba(255, 255, 255, 0.6); + } + } + &__review-content { color: globals.$body-color; line-height: 1.5; diff --git a/src/renderer/src/pages/game-details/review-item.tsx b/src/renderer/src/pages/game-details/review-item.tsx index f5e3528a..d6b9fd9c 100644 --- a/src/renderer/src/pages/game-details/review-item.tsx +++ b/src/renderer/src/pages/game-details/review-item.tsx @@ -7,9 +7,10 @@ import { useState } from "react"; import type { GameReview } from "@types"; import { sanitizeHtml } from "@shared"; -import { useDate } from "@renderer/hooks"; +import { useDate, useFormat } from "@renderer/hooks"; import { formatNumber } from "@renderer/helpers"; import { Avatar } from "@renderer/components"; +import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants"; import "./review-item.scss"; @@ -29,12 +30,7 @@ interface ReviewItemProps { ) => void; } -const getScoreColorClass = (score: number): string => { - if (score >= 1 && score <= 2) return "game-details__review-score--red"; - if (score >= 3 && score <= 3) return "game-details__review-score--yellow"; - if (score >= 4 && score <= 5) return "game-details__review-score--green"; - return ""; -}; + const getRatingText = (score: number, t: (key: string) => string): string => { switch (score) { @@ -68,6 +64,7 @@ export function ReviewItem({ const navigate = useNavigate(); const { t, i18n } = useTranslation("game_details"); const { formatDistance } = useDate(); + const { numberFormatter } = useFormat(); const [showOriginal, setShowOriginal] = useState(false); @@ -100,6 +97,20 @@ export function ReviewItem({ } }; + // Format playtime similar to hero panel + const formatPlayTime = (playTimeInSeconds: number) => { + const minutes = playTimeInSeconds / 60; + + if (minutes < MAX_MINUTES_TO_SHOW_IN_PLAYTIME) { + return t("amount_minutes", { + amount: minutes.toFixed(0), + }); + } + + const hours = minutes / 60; + return t("amount_hours", { amount: numberFormatter.format(hours) }); + }; + // Determine which content to show - always show original for own reviews const displayContent = needsTranslation ? review.translations[i18n.language] @@ -144,34 +155,37 @@ export function ReviewItem({ > {review.user.displayName || "Anonymous"} -