From 035f6e8d24c478d6a6df1df35f669ccb1b6957c4 Mon Sep 17 00:00:00 2001 From: Moyasee Date: Wed, 22 Oct 2025 22:05:05 +0300 Subject: [PATCH] ci: formatting --- .../profile-content/profile-content.scss | 288 +++++++++--------- .../profile-content/profile-content.tsx | 178 ++++++----- 2 files changed, 247 insertions(+), 219 deletions(-) diff --git a/src/renderer/src/pages/profile/profile-content/profile-content.scss b/src/renderer/src/pages/profile/profile-content/profile-content.scss index a9aad402..4cdea61b 100644 --- a/src/renderer/src/pages/profile/profile-content/profile-content.scss +++ b/src/renderer/src/pages/profile/profile-content/profile-content.scss @@ -178,156 +178,156 @@ } } - // Reviews minimal styles - .user-reviews__loading { - padding: calc(globals.$spacing-unit * 2); - color: rgba(255, 255, 255, 0.8); +// Reviews minimal styles +.user-reviews__loading { + padding: calc(globals.$spacing-unit * 2); + color: rgba(255, 255, 255, 0.8); +} + +.user-reviews__empty { + text-align: center; + padding: calc(globals.$spacing-unit * 4) calc(globals.$spacing-unit * 2); + color: rgba(255, 255, 255, 0.6); +} + +.user-reviews__list { + display: flex; + flex-direction: column; + gap: calc(globals.$spacing-unit * 2); +} + +.user-reviews__review-item { + border-radius: 8px; + padding: calc(globals.$spacing-unit * 2); +} + +.user-reviews__review-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: calc(globals.$spacing-unit * 1.5); +} + +.user-reviews__review-game { + display: flex; + align-items: center; + gap: calc(globals.$spacing-unit); +} + +.user-reviews__game-icon { + width: 40px; + height: 40px; + border-radius: 8px; + object-fit: cover; +} + +.user-reviews__game-info { + display: flex; + flex-direction: column; + gap: calc(globals.$spacing-unit * 0.25); +} + +.user-reviews__game-title { + background: none; + border: none; + color: rgba(255, 255, 255, 0.9); + font-weight: 600; + cursor: pointer; + text-align: left; + + &--clickable:hover { + text-decoration: underline; + } +} + +.user-reviews__review-date { + color: rgba(255, 255, 255, 0.6); + font-size: globals.$small-font-size; +} + +.user-reviews__review-score-stars { + display: flex; + gap: calc(globals.$spacing-unit * 0.5); +} + +.user-reviews__review-star-container { + display: flex; + align-items: center; +} + +.user-reviews__review-content { + color: rgba(255, 255, 255, 0.85); + line-height: 1.5; +} + +.user-reviews__review-actions { + margin-top: calc(globals.$spacing-unit * 2); + padding-top: calc(globals.$spacing-unit); + border-top: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + justify-content: space-between; + align-items: center; +} + +.user-reviews__review-votes { + display: flex; + gap: calc(globals.$spacing-unit); +} + +.user-reviews__vote-button { + display: flex; + align-items: center; + gap: 6px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 6px; + padding: 6px 12px; + color: #ccc; + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.2); + color: #ffffff; } - .user-reviews__empty { - text-align: center; - padding: calc(globals.$spacing-unit * 4) calc(globals.$spacing-unit * 2); - color: rgba(255, 255, 255, 0.6); - } + &--active { + color: #ffffff; + border-color: rgba(255, 255, 255, 0.3); - .user-reviews__list { - display: flex; - flex-direction: column; - gap: calc(globals.$spacing-unit * 2); - } - - .user-reviews__review-item { - border-radius: 8px; - padding: calc(globals.$spacing-unit * 2); - } - - .user-reviews__review-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: calc(globals.$spacing-unit * 1.5); - } - - .user-reviews__review-game { - display: flex; - align-items: center; - gap: calc(globals.$spacing-unit); - } - - .user-reviews__game-icon { - width: 40px; - height: 40px; - border-radius: 8px; - object-fit: cover; - } - - .user-reviews__game-info { - display: flex; - flex-direction: column; - gap: calc(globals.$spacing-unit * 0.25); - } - - .user-reviews__game-title { - background: none; - border: none; - color: rgba(255, 255, 255, 0.9); - font-weight: 600; - cursor: pointer; - text-align: left; - - &--clickable:hover { - text-decoration: underline; + svg { + fill: white; } } +} - .user-reviews__review-date { - color: rgba(255, 255, 255, 0.6); - font-size: globals.$small-font-size; +.user-reviews__delete-review-button { + display: flex; + align-items: center; + gap: 6px; + background: rgba(244, 67, 54, 0.1); + border: 1px solid rgba(244, 67, 54, 0.3); + border-radius: 6px; + padding: 6px 10px; + color: #f44336; + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + background: rgba(244, 67, 54, 0.2); + border-color: rgba(244, 67, 54, 0.4); + color: #ff7961; + } +} + +.profile-content { + &__tab-panels { + display: block; } - .user-reviews__review-score-stars { - display: flex; - gap: calc(globals.$spacing-unit * 0.5); - } - - .user-reviews__review-star-container { - display: flex; - align-items: center; - } - - .user-reviews__review-content { - color: rgba(255, 255, 255, 0.85); - line-height: 1.5; - } - - .user-reviews__review-actions { - margin-top: calc(globals.$spacing-unit * 2); - padding-top: calc(globals.$spacing-unit); - border-top: 1px solid rgba(255, 255, 255, 0.1); - display: flex; - justify-content: space-between; - align-items: center; - } - - .user-reviews__review-votes { - display: flex; - gap: calc(globals.$spacing-unit); - } - - .user-reviews__vote-button { - display: flex; - align-items: center; - gap: 6px; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 6px; - padding: 6px 12px; - color: #ccc; - font-size: 14px; - cursor: pointer; - transition: all 0.2s ease; - - &:hover { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.2); - color: #ffffff; - } - - &--active { - color: #ffffff; - border-color: rgba(255, 255, 255, 0.3); - - svg { - fill: white; - } - } - } - - .user-reviews__delete-review-button { - display: flex; - align-items: center; - gap: 6px; - background: rgba(244, 67, 54, 0.1); - border: 1px solid rgba(244, 67, 54, 0.3); - border-radius: 6px; - padding: 6px 10px; - color: #f44336; - cursor: pointer; - transition: all 0.2s ease; - - &:hover { - background: rgba(244, 67, 54, 0.2); - border-color: rgba(244, 67, 54, 0.4); - color: #ff7961; - } - } - - .profile-content { - &__tab-panels { - display: block; - } - - &__tab-panel[hidden] { - display: none; - } + &__tab-panel[hidden] { + display: none; } +} diff --git a/src/renderer/src/pages/profile/profile-content/profile-content.tsx b/src/renderer/src/pages/profile/profile-content/profile-content.tsx index bb4e0025..d245aa5e 100644 --- a/src/renderer/src/pages/profile/profile-content/profile-content.tsx +++ b/src/renderer/src/pages/profile/profile-content/profile-content.tsx @@ -1,7 +1,12 @@ import { userProfileContext } from "@renderer/context"; import { useContext, useEffect, useMemo, useRef, useState } from "react"; import { ProfileHero } from "../profile-hero/profile-hero"; -import { useAppDispatch, useFormat, useDate, useUserDetails } from "@renderer/hooks"; +import { + useAppDispatch, + useFormat, + useDate, + useUserDetails, +} from "@renderer/hooks"; import { setHeaderTitle } from "@renderer/features"; import { TelescopeIcon } from "@primer/octicons-react"; import { useTranslation } from "react-i18next"; @@ -27,7 +32,6 @@ import { } from "./profile-animations"; import "./profile-content.scss"; - type SortOption = "playtime" | "achievementCount" | "playedRecently"; interface UserReview { @@ -79,7 +83,7 @@ export function ProfileContent() { const [isAnimationRunning, setIsAnimationRunning] = useState(true); const [sortBy, setSortBy] = useState("playedRecently"); const statsAnimation = useRef(-1); - + const [activeTab, setActiveTab] = useState<"library" | "reviews">("library"); // User reviews state @@ -116,7 +120,7 @@ export function ProfileContent() { const fetchUserReviews = async () => { if (!userProfile?.id) return; - + setIsLoadingReviews(true); try { const response = await window.electron.hydraApi.get( @@ -134,15 +138,17 @@ export function ProfileContent() { const handleDeleteReview = async (reviewId: string) => { try { - const reviewToDeleteObj = reviews.find(review => review.id === reviewId); + const reviewToDeleteObj = reviews.find( + (review) => review.id === reviewId + ); if (!reviewToDeleteObj) return; - + await window.electron.hydraApi.delete( `/games/${reviewToDeleteObj.game.shop}/${reviewToDeleteObj.game.objectId}/reviews/${reviewId}` ); // Remove the review from the local state - setReviews(prev => prev.filter(review => review.id !== reviewId)); - setReviewsTotalCount(prev => prev - 1); + setReviews((prev) => prev.filter((review) => review.id !== reviewId)); + setReviewsTotalCount((prev) => prev - 1); } catch (error) { console.error("Failed to delete review:", error); } @@ -168,85 +174,89 @@ export function ProfileContent() { const handleVoteReview = async (reviewId: string, isUpvote: boolean) => { if (votingReviews.has(reviewId)) return; - setVotingReviews(prev => new Set(prev).add(reviewId)); + setVotingReviews((prev) => new Set(prev).add(reviewId)); - const review = reviews.find(r => r.id === reviewId); + const review = reviews.find((r) => r.id === reviewId); if (!review) return; const wasUpvoted = review.hasUpvoted; const wasDownvoted = review.hasDownvoted; // Optimistic update - setReviews(prev => prev.map(r => { - if (r.id !== reviewId) return r; + setReviews((prev) => + prev.map((r) => { + if (r.id !== reviewId) return r; - let newUpvotes = r.upvotes; - let newDownvotes = r.downvotes; - let newHasUpvoted = r.hasUpvoted; - let newHasDownvoted = r.hasDownvoted; + let newUpvotes = r.upvotes; + let newDownvotes = r.downvotes; + let newHasUpvoted = r.hasUpvoted; + let newHasDownvoted = r.hasDownvoted; - if (isUpvote) { - if (wasUpvoted) { - // Remove upvote - newUpvotes--; - newHasUpvoted = false; - } else { - // Add upvote - newUpvotes++; - newHasUpvoted = true; - if (wasDownvoted) { - // Remove downvote if it was downvoted - newDownvotes--; - newHasDownvoted = false; - } - } - } else { - if (wasDownvoted) { - // Remove downvote - newDownvotes--; - newHasDownvoted = false; - } else { - // Add downvote - newDownvotes++; - newHasDownvoted = true; + if (isUpvote) { if (wasUpvoted) { - // Remove upvote if it was upvoted + // Remove upvote newUpvotes--; newHasUpvoted = false; + } else { + // Add upvote + newUpvotes++; + newHasUpvoted = true; + if (wasDownvoted) { + // Remove downvote if it was downvoted + newDownvotes--; + newHasDownvoted = false; + } + } + } else { + if (wasDownvoted) { + // Remove downvote + newDownvotes--; + newHasDownvoted = false; + } else { + // Add downvote + newDownvotes++; + newHasDownvoted = true; + if (wasUpvoted) { + // Remove upvote if it was upvoted + newUpvotes--; + newHasUpvoted = false; + } } } - } - return { - ...r, - upvotes: newUpvotes, - downvotes: newDownvotes, - hasUpvoted: newHasUpvoted, - hasDownvoted: newHasDownvoted, - }; - })); + return { + ...r, + upvotes: newUpvotes, + downvotes: newDownvotes, + hasUpvoted: newHasUpvoted, + hasDownvoted: newHasDownvoted, + }; + }) + ); try { - const endpoint = isUpvote ? 'upvote' : 'downvote'; + const endpoint = isUpvote ? "upvote" : "downvote"; await window.electron.hydraApi.put( `/games/${review.game.shop}/${review.game.objectId}/reviews/${reviewId}/${endpoint}` ); } catch (error) { console.error("Failed to vote on review:", error); - + // Rollback optimistic update on error - setReviews(prev => prev.map(r => { - if (r.id !== reviewId) return r; - return { - ...r, - upvotes: review.upvotes, - downvotes: review.downvotes, - hasUpvoted: review.hasUpvoted, - hasDownvoted: review.hasDownvoted, - }; - })); + setReviews((prev) => + prev.map((r) => { + if (r.id !== reviewId) return r; + return { + ...r, + upvotes: review.upvotes, + downvotes: review.downvotes, + hasUpvoted: review.hasUpvoted, + hasDownvoted: review.hasDownvoted, + }; + }) + ); } finally { - setVotingReviews(prev => { + setVotingReviews((prev) => { const newSet = new Set(prev); newSet.delete(reviewId); return newSet; @@ -364,10 +374,7 @@ export function ProfileContent() { {/* render pinned games unconditionally */}
    {pinnedGames?.map((game) => ( -
  • +
  • {t("loading_reviews")} +
    + {t("loading_reviews")} +
    ) : reviews.length === 0 ? (

    {t("no_reviews", "No reviews yet")}

    @@ -461,22 +470,35 @@ export function ProfileContent() {
    - {formatDistance(new Date(review.createdAt), new Date(), { addSuffix: true })} + {formatDistance( + new Date(review.createdAt), + new Date(), + { addSuffix: true } + )}
    {Array.from({ length: 5 }, (_, index) => ( -
    +
    handleVoteReview(review.id, true)} + onClick={() => + handleVoteReview(review.id, true) + } disabled={votingReviews.has(review.id)} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} @@ -518,7 +544,9 @@ export function ProfileContent() { handleVoteReview(review.id, false)} + onClick={() => + handleVoteReview(review.id, false) + } disabled={votingReviews.has(review.id)} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}