From e4579507612cf55c08e1e791e2e24552578569dc Mon Sep 17 00:00:00 2001 From: Hachi-R Date: Mon, 20 Jan 2025 12:45:24 -0300 Subject: [PATCH] refactor: migrate profile page styles from VE to SCSS + BEM --- .../edit-profile-modal.scss | 57 ++++++++ .../edit-profile-modal/edit-profile-modal.tsx | 26 +--- .../profile/profile-content/friends-box.scss | 62 ++++++++ .../profile/profile-content/friends-box.tsx | 23 ++- .../profile-content/locked-profile.scss | 24 ++++ .../profile-content/locked-profile.tsx | 7 +- .../profile-content/profile-content.scss | 89 ++++++++++++ .../profile-content/profile-content.tsx | 26 ++-- .../profile-content/recent-games-box.scss | 71 ++++++++++ .../profile-content/recent-games-box.tsx | 21 ++- .../user-library-game-card.scss | 134 ++++++++++++++++++ .../user-library-game-card.tsx | 93 ++---------- .../profile-content/user-stats-box.scss | 75 ++++++++++ .../profile-content/user-stats-box.tsx | 45 +++--- .../profile/profile-hero/profile-hero.scss | 124 ++++++++++++++++ .../profile/profile-hero/profile-hero.tsx | 70 ++++----- src/renderer/src/pages/profile/profile.scss | 10 ++ src/renderer/src/pages/profile/profile.tsx | 8 +- .../report-profile/report-profile.scss | 24 ++++ .../profile/report-profile/report-profile.tsx | 15 +- .../upload-background-image-button.scss | 11 ++ .../upload-background-image-button.tsx | 8 +- 22 files changed, 786 insertions(+), 237 deletions(-) create mode 100644 src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.scss create mode 100644 src/renderer/src/pages/profile/profile-content/friends-box.scss create mode 100644 src/renderer/src/pages/profile/profile-content/locked-profile.scss create mode 100644 src/renderer/src/pages/profile/profile-content/profile-content.scss create mode 100644 src/renderer/src/pages/profile/profile-content/recent-games-box.scss create mode 100644 src/renderer/src/pages/profile/profile-content/user-library-game-card.scss create mode 100644 src/renderer/src/pages/profile/profile-content/user-stats-box.scss create mode 100644 src/renderer/src/pages/profile/profile-hero/profile-hero.scss create mode 100644 src/renderer/src/pages/profile/profile.scss create mode 100644 src/renderer/src/pages/profile/report-profile/report-profile.scss create mode 100644 src/renderer/src/pages/profile/upload-background-image-button/upload-background-image-button.scss diff --git a/src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.scss b/src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.scss new file mode 100644 index 00000000..2575def1 --- /dev/null +++ b/src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.scss @@ -0,0 +1,57 @@ +@use "../../../scss/globals.scss"; + +.edit-profile-modal { + &__form { + display: flex; + flex-direction: column; + justify-content: center; + width: 350px; + } + + &__content { + gap: calc(globals.$spacing-unit * 3); + display: flex; + flex-direction: column; + } + + &__hint { + margin-top: calc(globals.$spacing-unit * 2); + } + + &__submit { + align-self: end; + margin-top: calc(globals.$spacing-unit * 3); + width: 100%; + } + + &__avatar-container { + align-self: center; + display: flex; + color: globals.$body-color; + justify-content: center; + align-items: center; + background-color: globals.$background-color; + position: relative; + cursor: pointer; + } + + &__avatar-overlay { + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + color: globals.$muted-color; + z-index: 1; + cursor: pointer; + display: flex; + justify-content: center; + transition: all ease 0.2s; + align-items: center; + border-radius: 4px; + opacity: 0; + } + + &__avatar-container:hover &__avatar-overlay { + opacity: 1; + } +} diff --git a/src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.tsx b/src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.tsx index b9e1927f..d5cb12a8 100644 --- a/src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.tsx +++ b/src/renderer/src/pages/profile/edit-profile-modal/edit-profile-modal.tsx @@ -13,13 +13,12 @@ import { } from "@renderer/components"; import { useToast, useUserDetails } from "@renderer/hooks"; -import { SPACING_UNIT } from "@renderer/theme.css"; import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; -import * as styles from "./edit-profile-modal.css"; import { userProfileContext } from "@renderer/context"; +import "./edit-profile-modal.scss"; interface FormValues { profileImageUrl?: string; @@ -80,20 +79,9 @@ export function EditProfileModal(
-
+
-
+
@@ -167,7 +155,7 @@ export function EditProfileModal( />
- + @@ -175,7 +163,7 @@ export function EditProfileModal( diff --git a/src/renderer/src/pages/profile/profile-content/user-stats-box.scss b/src/renderer/src/pages/profile/profile-content/user-stats-box.scss new file mode 100644 index 00000000..c19fb612 --- /dev/null +++ b/src/renderer/src/pages/profile/profile-content/user-stats-box.scss @@ -0,0 +1,75 @@ +@use "../../../scss/globals.scss"; + +.user-stats { + &__box { + background-color: globals.$background-color; + border-radius: 4px; + border: solid 1px globals.$border-color; + padding: calc(globals.$spacing-unit * 2); + } + + &__section-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: calc(globals.$spacing-unit * 2); + } + + &__list { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + gap: calc(globals.$spacing-unit * 2); + } + + &__list-item { + display: flex; + flex-direction: column; + transition: all ease 0.1s; + color: globals.$muted-color; + width: 100%; + overflow: hidden; + border-radius: 4px; + padding: globals.$spacing-unit; + gap: globals.$spacing-unit; + + &:hover { + background-color: rgba(255, 255, 255, 0.15); + text-decoration: none; + } + } + + &__list-title { + font-weight: bold; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + &__list-description { + display: flex; + align-items: center; + gap: globals.$spacing-unit; + } + + &__stats-row { + display: flex; + justify-content: space-between; + } + + &__link { + text-align: start; + color: globals.$body-color; + + &--warning { + color: globals.$warning-color; + } + + &:hover { + text-decoration: underline; + cursor: pointer; + } + } +} diff --git a/src/renderer/src/pages/profile/profile-content/user-stats-box.tsx b/src/renderer/src/pages/profile/profile-content/user-stats-box.tsx index b33afab5..26ec79f4 100644 --- a/src/renderer/src/pages/profile/profile-content/user-stats-box.tsx +++ b/src/renderer/src/pages/profile/profile-content/user-stats-box.tsx @@ -1,4 +1,3 @@ -import * as styles from "./profile-content.css"; import { useCallback, useContext } from "react"; import { userProfileContext } from "@renderer/context"; import { useTranslation } from "react-i18next"; @@ -7,7 +6,7 @@ import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants"; import HydraIcon from "@renderer/assets/icons/hydra.svg?react"; import { useSubscription } from "@renderer/hooks/use-subscription"; import { ClockIcon, TrophyIcon } from "@primer/octicons-react"; -import { vars } from "@renderer/theme.css"; +import "./user-stats-box.scss"; export function UserStatsBox() { const { showHydraCloudModal } = useSubscription(); @@ -36,22 +35,20 @@ export function UserStatsBox() { return (
-
+

{t("stats")}

-
-
    +
    +
      {(isMe || userStats.unlockedAchievementSum !== undefined) && ( -
    • -

      +
    • +

      {t("achievements_unlocked")}

      {userStats.unlockedAchievementSum !== undefined ? ( -
      -

      +

      +

      {userStats.unlockedAchievementSum}{" "} {t("achievements")}

      @@ -60,9 +57,9 @@ export function UserStatsBox() { @@ -71,13 +68,11 @@ export function UserStatsBox() { )} {(isMe || userStats.achievementsPointsEarnedSum !== undefined) && ( -
    • -

      {t("earned_points")}

      +
    • +

      {t("earned_points")}

      {userStats.achievementsPointsEarnedSum !== undefined ? ( -
      -

      +

      +

      {numberFormatter.format( userStats.achievementsPointsEarnedSum.value @@ -94,9 +89,9 @@ export function UserStatsBox() { @@ -104,10 +99,10 @@ export function UserStatsBox() {

    • )} -
    • -

      {t("total_play_time")}

      -
      -

      +

    • +

      {t("total_play_time")}

      +
      +

      {formatPlayTime(userStats.totalPlayTimeInSeconds.value)}

      diff --git a/src/renderer/src/pages/profile/profile-hero/profile-hero.scss b/src/renderer/src/pages/profile/profile-hero/profile-hero.scss new file mode 100644 index 00000000..8be99794 --- /dev/null +++ b/src/renderer/src/pages/profile/profile-hero/profile-hero.scss @@ -0,0 +1,124 @@ +@use "../../../scss/globals.scss"; + +.profile-hero { + &__content-box { + display: flex; + flex-direction: column; + position: relative; + } + + &__background { + &-image { + position: absolute; + width: 100%; + height: 100%; + object-fit: cover; + } + + &-overlay { + width: 100%; + height: 100%; + z-index: 1; + background: linear-gradient(135deg, rgb(0 0 0 / 40%), rgb(0 0 0 / 30%)); + + &--transparent { + background: transparent; + } + } + } + + &__user-information { + display: flex; + padding: calc(globals.$spacing-unit * 7) calc(globals.$spacing-unit * 3); + align-items: center; + gap: calc(globals.$spacing-unit * 2); + } + + &__avatar-button { + width: 96px; + min-width: 96px; + height: 96px; + border-radius: 4px; + display: flex; + justify-content: center; + align-items: center; + background-color: globals.$background-color; + border: solid 1px globals.$border-color; + box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.7); + cursor: pointer; + transition: all ease 0.3s; + color: globals.$muted-color; + position: relative; + + &:hover { + box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.7); + } + } + + &__information { + display: flex; + flex-direction: column; + gap: globals.$spacing-unit; + align-items: flex-start; + color: globals.$muted-color; + z-index: 1; + overflow: hidden; + } + + &__display-name { + font-weight: bold; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; + display: flex; + align-items: center; + position: relative; + text-shadow: 0 0 5px rgb(0 0 0 / 40%); + } + + &__current-game { + &-wrapper { + display: flex; + flex-direction: column; + gap: calc(globals.$spacing-unit / 2); + } + + &-details { + display: flex; + flex-direction: row; + gap: globals.$spacing-unit; + align-items: center; + } + } + + &__hero-panel { + width: 100%; + height: 72px; + min-height: 72px; + padding: calc(globals.$spacing-unit * 2) calc(globals.$spacing-unit * 3); + display: flex; + gap: globals.$spacing-unit; + justify-content: space-between; + backdrop-filter: blur(15px); + border-top: solid 1px rgba(255, 255, 255, 0.1); + box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.5); + background-color: rgba(0, 0, 0, 0.3); + + &--transparent { + background: transparent; + } + } + + &__actions { + display: flex; + gap: globals.$spacing-unit; + justify-content: flex-end; + flex: 1; + } + + &__button { + &--outline { + border-color: globals.$body-color; + } + } +} diff --git a/src/renderer/src/pages/profile/profile-hero/profile-hero.tsx b/src/renderer/src/pages/profile/profile-hero/profile-hero.tsx index 0aaee611..c8225bfb 100644 --- a/src/renderer/src/pages/profile/profile-hero/profile-hero.tsx +++ b/src/renderer/src/pages/profile/profile-hero/profile-hero.tsx @@ -1,6 +1,3 @@ -import { SPACING_UNIT, vars } from "@renderer/theme.css"; - -import * as styles from "./profile-hero.css"; import { useCallback, useContext, useMemo, useState } from "react"; import { userProfileContext } from "@renderer/context"; import { @@ -27,14 +24,12 @@ import type { FriendRequestAction } from "@types"; import { EditProfileModal } from "../edit-profile-modal/edit-profile-modal"; import Skeleton from "react-loading-skeleton"; import { UploadBackgroundImageButton } from "../upload-background-image-button/upload-background-image-button"; +import "./profile-hero.scss"; type FriendAction = | FriendRequestAction | ("BLOCK" | "UNDO_FRIENDSHIP" | "SEND"); -const backgroundImageLayer = - "linear-gradient(135deg, rgb(0 0 0 / 40%), rgb(0 0 0 / 30%))"; - export function ProfileHero() { const [showEditProfileModal, setShowEditProfileModal] = useState(false); const [isPerformingAction, setIsPerformingAction] = useState(false); @@ -127,7 +122,7 @@ export function ProfileHero() { theme="outline" onClick={() => setShowEditProfileModal(true)} disabled={isPerformingAction} - style={{ borderColor: vars.color.body }} + className="profile-hero__button--outline" > {t("edit_profile")} @@ -152,7 +147,7 @@ export function ProfileHero() { theme="outline" onClick={() => handleFriendAction(userProfile.id, "SEND")} disabled={isPerformingAction} - style={{ borderColor: vars.color.body }} + className="profile-hero__button--outline" > {t("add_friend")} @@ -187,7 +182,7 @@ export function ProfileHero() { handleFriendAction(userProfile.id, "UNDO_FRIENDSHIP") } disabled={isPerformingAction} - style={{ borderColor: vars.color.body }} + className="profile-hero__button--outline" > {t("undo_friendship")} @@ -201,10 +196,10 @@ export function ProfileHero() { @@ -219,7 +214,7 @@ export function ProfileHero() { handleFriendAction(userProfile.relation!.AId, "ACCEPTED") } disabled={isPerformingAction} - style={{ borderColor: vars.color.body }} + className="profile-hero__button--outline" > {t("accept_request")} @@ -279,34 +274,28 @@ export function ProfileHero() { />
      {backgroundImage && ( )}
      -
      +
      -
      +
      {userProfile ? ( -

      +

      {userProfile?.displayName}

      ) : ( @@ -326,8 +315,8 @@ export function ProfileHero() { )} {currentGame && ( -
      -
      +
      +
      -
      - {profileActions} -
      +
      {profileActions}
      diff --git a/src/renderer/src/pages/profile/profile.scss b/src/renderer/src/pages/profile/profile.scss new file mode 100644 index 00000000..0e3bcf0a --- /dev/null +++ b/src/renderer/src/pages/profile/profile.scss @@ -0,0 +1,10 @@ +@use "../../scss/globals.scss"; + +.profile { + &__wrapper { + width: 100%; + display: flex; + flex-direction: column; + gap: calc(globals.$spacing-unit * 3); + } +} diff --git a/src/renderer/src/pages/profile/profile.tsx b/src/renderer/src/pages/profile/profile.tsx index e6b4f5b3..d3fb6957 100644 --- a/src/renderer/src/pages/profile/profile.tsx +++ b/src/renderer/src/pages/profile/profile.tsx @@ -1,18 +1,16 @@ import { ProfileContent } from "./profile-content/profile-content"; import { SkeletonTheme } from "react-loading-skeleton"; -import { vars } from "@renderer/theme.css"; - -import * as styles from "./profile.css"; import { UserProfileContextProvider } from "@renderer/context"; import { useParams } from "react-router-dom"; +import "./profile.scss"; export default function Profile() { const { userId } = useParams(); return ( - -
      + +
      diff --git a/src/renderer/src/pages/profile/report-profile/report-profile.scss b/src/renderer/src/pages/profile/report-profile/report-profile.scss new file mode 100644 index 00000000..6c0ca923 --- /dev/null +++ b/src/renderer/src/pages/profile/report-profile/report-profile.scss @@ -0,0 +1,24 @@ +@use "../../../scss/globals.scss"; + +.report-profile { + &__button { + align-self: flex-end; + color: globals.$muted-color; + gap: globals.$spacing-unit; + display: flex; + cursor: pointer; + align-items: center; + font-size: globals.$small-font-size; + } + + &__form { + display: flex; + flex-direction: column; + gap: calc(globals.$spacing-unit * 2); + } + + &__submit { + margin-top: globals.$spacing-unit; + align-self: flex-end; + } +} diff --git a/src/renderer/src/pages/profile/report-profile/report-profile.tsx b/src/renderer/src/pages/profile/report-profile/report-profile.tsx index f859b7f3..04afea51 100644 --- a/src/renderer/src/pages/profile/report-profile/report-profile.tsx +++ b/src/renderer/src/pages/profile/report-profile/report-profile.tsx @@ -1,15 +1,14 @@ import { ReportIcon } from "@primer/octicons-react"; -import * as styles from "./report-profile.css"; import { Button, Modal, SelectField, TextField } from "@renderer/components"; import { useCallback, useContext, useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import * as yup from "yup"; -import { SPACING_UNIT } from "@renderer/theme.css"; import { userProfileContext } from "@renderer/context"; import { yupResolver } from "@hookform/resolvers/yup"; import { useToast } from "@renderer/hooks"; +import "./report-profile.scss"; const reportReasons = ["hate", "sexual_content", "violence", "spam", "other"]; @@ -75,13 +74,7 @@ export function ReportProfile() { title={t("report_profile")} clickOutsideToClose={false} > - +