[상품 상세] 리뷰 및 디테일 변경건.#2

- 디테일부분에 대한 figma 부분과 동일하게 스타일 처리.
 - 리뷰부분 및 리뷰 팝업 부분 처리
 - 포커스시 확대부분 확인이후 재처리가능성있음.
 - 주로 리뷰 팝업부분 스타일 및 디테일 우측화면 스타일 작업
This commit is contained in:
junghoon86.park
2025-09-10 09:28:35 +09:00
parent 8fea52fb32
commit d2a9388bd5
14 changed files with 182 additions and 155 deletions

View File

@@ -239,6 +239,9 @@
width: 100%;
display: flex;
align-items: center;
> div:last-child {
margin-left: 10px;
}
}
// 모바일 쇼핑 섹션 (mobileSection 참고)
@@ -449,7 +452,7 @@
// LayoutSample 포커스 테스트용 스타일
.layoutSample {
width: 1124px;
width: 1114px;
height: 300px;
background-color: yellow;
margin-bottom: 20px;
@@ -597,7 +600,7 @@
width: 1210px; // 절대 크기 지정
height: 100%;
// 좌측 30px, 우측 66px(스크롤바) 패딩을 명시적으로 적용
padding: 0 10px 0 30px;
padding: 0 15px 0 30px;
box-sizing: border-box;
margin: 0;
overflow-y: auto;
@@ -920,7 +923,7 @@
// LayoutSample 포커스 테스트용 스타일
.layoutSample {
width: 1124px;
width: 1114px;
height: 300px;
background-color: yellow;
margin-bottom: 20px;

View File

@@ -4,9 +4,9 @@
// 단일 이미지용 ProductDetail 컨테이너 - 명확한 1054px 크기
.rollingWrap {
position: relative;
width: 1124px; // 고정 크기 (Description, UserReviews와 동일)
max-width: 1124px;
height: 680px; // 고정 높이로 각 이미지가 한 화면 차지
width: 1114px; // 고정 크기 (Description, UserReviews와 동일)
max-width: 1114px;
height: 670px; // 고정 높이로 각 이미지가 한 화면 차지
background-color: rgba(255, 255, 255, 1);
border-radius: 12px;
margin-bottom: 30px; // 다음 ProductDetail과의 간격
@@ -70,8 +70,8 @@
.thumbnailWrapper {
position: relative;
width: 100%;
height: 100%; // 부모 itemBox의 680px 전체 사용
width: 658px;
height: 610px;
display: flex;
align-items: center;
justify-content: center;

View File

@@ -9,7 +9,9 @@
display: flex;
justify-content: center;
align-items: center;
:focus {
border: none;
}
// 좌측 화살표 (이전 리뷰) - detailpanel PNG 사용
.leftArrow {
width: 50px;
@@ -23,7 +25,7 @@
// 화살표 아이콘 (< 모양, 17px x 29px)
&::before {
content: '';
content: "";
width: 17px;
height: 29px;
background-image: url("../../../../../../assets/images/detailpanel/left-arrow.svg");
@@ -34,15 +36,11 @@
}
&:focus {
outline: none;
outline: 4px solid @PRIMARY_COLOR_RED !important;
&::before {
background-image: url("../../../../../../assets/images/detailpanel/left-arrow-red.svg");
}
&::after {
.focused(@boxShadow: 0px, @borderRadius: 4px);
}
}
&:hover {
@@ -66,7 +64,7 @@
flex: 1;
align-self: stretch;
padding: 30px;
background: #F8F8F8;
background: #f8f8f8;
border-radius: 12px;
display: flex;
justify-content: flex-start;
@@ -163,7 +161,7 @@
width: 6px;
align-self: stretch;
position: relative;
background: #E7E7E7;
background: #e7e7e7;
overflow: hidden;
.scrollTrack {
@@ -172,7 +170,7 @@
left: 0;
top: 0;
position: absolute;
background: #7A808D;
background: #7a808d;
}
}
}
@@ -190,7 +188,7 @@
// 화살표 아이콘 (> 모양, 17px x 29px)
&::before {
content: '';
content: "";
width: 17px;
height: 29px;
background-image: url("../../../../../../assets/images/detailpanel/right-arrow.svg");
@@ -201,15 +199,11 @@
}
&:focus {
outline: none;
outline: 4px solid @PRIMARY_COLOR_RED !important;
&::before {
background-image: url("../../../../../../assets/images/detailpanel/right-arrow-red.svg");
}
&::after {
.focused(@boxShadow: 0px, @borderRadius: 4px);
}
}
&:hover {

View File

@@ -15,8 +15,8 @@
.tVerticalPagenator {
.size(@w: 1114px, @h: auto); // 마진 포함 전체 크기 (1054px + 60px)
max-width: 1114px;
padding-left: 30px; // 좌측 30px 마진
padding-right: 30px; // 우측 30px 마진
// padding-left: 30px; // 좌측 30px 마진
// padding-right: 30px; // 우측 30px 마진
box-sizing: border-box;
// .sectionTitle {
@@ -28,8 +28,8 @@
// }
.tHeader {
background: transparent;
.size(@w: 1054px, @h: 36px); // 마진 제외 콘텐츠 크기
max-width: 1054px;
.size(@w: 1144px, @h: 36px); // 마진 제외 콘텐츠 크기
max-width: 1144px;
margin-bottom: 20px;
> div {
@@ -58,20 +58,20 @@
// }
.renderCardContainer {
width: auto;
width: 1144px;
display: flex;
flex-wrap: wrap;
// margin-top: 34px;
> div {
/* item card */
margin: 0 15px 15px 0;
.size(@w:300px,@h:435px);
.size(@w:360px,@h:494px);
background-color: rgba(51, 51, 51, 0.95);
border: none;
> div:nth-child(1) {
/* img wrapper*/
.size(@w:264px,@h:264px);
.size(@w:323px,@h:323px);
> img {
.size(@w:100%,@h:100%);
@@ -79,18 +79,17 @@
}
> div:nth-child(2) {
margin-top: 15px;
/* desc wrapper */
> div > h3 {
/* title */
color: rgba(234, 234, 234, 1);
margin-top: 15px;
.size(@w:100%,@h:62px);
.size(@w:100%,@h:64px);
line-height: 31px;
}
> p {
/* priceInfo */
height: 43px;
line-height: 35px;
text-align: center;
> span {

View File

@@ -1,5 +1,6 @@
import React, { useMemo } from 'react';
import classNames from 'classnames';
import { useSelector } from 'react-redux';
import TQRCode from '../../../../components/TQRCode/TQRCode';
@@ -56,7 +57,7 @@ export default function QRCode({
}, [productInfo, isShopByMobile, detailUrl]);
return (
<div className={css.qrcode}>
<div className={classNames(css.qrcode, kind ? css.detailQrcode : "")}>
{/* {qrCodeUrl && <TQRCode text={qrCodeUrl} width="190" height="190" />} */}
{kind === "detail" ? (
<TQRCode text={qrCodeUrl} width="240" height="240" />

View File

@@ -9,4 +9,10 @@
border: solid 1px #dadada;
margin: 0 auto;
}
&.detailQrcode {
> div:first-child {
width: 240px;
height: 240px;
}
}
}

View File

@@ -52,7 +52,7 @@
font-size: 40px;
font-weight: bold;
line-height: 1;
color: #808080;
color: @COLOR_WHITE;
padding-bottom: 5px;
}
.discountedPrc {

View File

@@ -136,15 +136,17 @@ export default function ShopByMobilePriceDisplay({
} else if (TYPE_CASE.case3) {
return (
<div className={css.wrapper}>
<span className={css.name}>
{patncNm
? patncNm + " " + $L("Price")
: patnrName + " " + $L("Price")}
</span>
<div className={css.topLayer}>
<span className={css.name}>
{patncNm
? patncNm + " " + $L("Price")
: patnrName + " " + $L("Price")}
</span>
</div>
{discountRate && Number(discountRate.replace("%", "")) > 4 && (
<div className={css.rateTag}>{discountRate}</div>
)}
<div className={css.btmLayer}>
{discountRate && Number(discountRate.replace("%", "")) > 4 && (
<div className={css.rateTag}>{discountRate}</div>
)}
<span className={css.price}>
{isDiscountedPriceEmpty ? offerInfo : discountedPrice}
</span>

View File

@@ -52,7 +52,7 @@
font-size: 40px;
font-weight: bold;
line-height: 1;
color: #808080;
color: @COLOR_WHITE;
padding-bottom: 5px;
}
.discountedPrc {

View File

@@ -2,14 +2,13 @@
@import "../../style/utils.module.less";
.userReviewPanel {
background-color: #fff;
background-color: @BG_COLOR_02;
display: flex;
flex-direction: column;
height: 100%;
}
.header {
background-color: #fff;
// border-bottom: 1px solid #e0e0e0; // 가로선 제거
display: flex;
width: 100%;
@@ -28,7 +27,7 @@
position: relative;
display: flex;
flex-direction: column;
background-color: #fff;
background-color: @BG_COLOR_02;
// padding: 60px;
flex: 1;
}
@@ -86,10 +85,10 @@
// Info 섹션 (제품 정보)
.infoSection {
width: calc(100% - 120px);
padding: 18px ;
padding: 18px;
background: white;
border-radius: 12px;
border: 1px solid #DADADA;
border: 1px solid #dadada;
box-sizing: border-box;
display: flex;
justify-content: flex-start;
@@ -97,7 +96,7 @@
// margin-bottom: 40px;
margin-left: 60px;
margin-right: 60px;
margin-bottom: 30px;
&__productImage {
width: 150px;
height: 150px;
@@ -129,7 +128,7 @@
&__productId {
color: #808080;
font-size: 24px;
font-family: 'LG Smart UI';
font-family: "LG Smart UI";
font-weight: 600;
line-height: 18px;
}
@@ -146,7 +145,7 @@
flex: 1;
color: black;
font-size: 30px;
font-family: 'LG Smart UI';
font-family: "LG Smart UI";
font-weight: 700;
line-height: 32px;
word-wrap: break-word;
@@ -169,7 +168,7 @@
&__reviewCount {
color: #333333;
font-size: 24px;
font-family: 'LG Smart UI';
font-family: "LG Smart UI";
font-weight: 400;
line-height: 31px;
}
@@ -180,7 +179,7 @@
// Reviews 섹션 (필터 + 리뷰 리스트)
.reviewsSection {
width: 100%;
padding: 30px 60px 60px 60px; // 위쪽만 30px, 나머지는 60px
padding: 60px 60px 30px 60px; // 위쪽만 30px, 나머지는 60px
background: white;
display: flex;
justify-content: flex-start;
@@ -192,7 +191,7 @@
align-self: stretch;
padding-bottom: 60px;
padding-right: 60px;
border-right: 1px solid #DADADA;
border-right: 1px solid #dadada;
display: flex;
flex-direction: column;
justify-content: flex-start;
@@ -210,7 +209,7 @@
text-align: center;
color: black;
font-size: 42px;
font-family: 'LG Smart UI';
font-family: "LG Smart UI";
font-weight: 700;
line-height: 42px;
margin-right: 12px;
@@ -227,7 +226,7 @@
text-align: center;
color: black;
font-size: 28px;
font-family: 'LG Smart UI';
font-family: "LG Smart UI";
font-weight: 600;
line-height: 42px;
margin-right: 12px;

View File

@@ -4,15 +4,15 @@
.reviewContentContainer {
// 📝 15px 오버플로우 방지: 100%에서 15px 줄임
width: calc(100% - 15px);
width: 885px;
height: 168px;
// Light theme으로 변경: 어두운 회색에서 밝은 색상으로
background-color: rgba(255, 255, 255, 0.95);
background-color: @BG_COLOR_02;
border: 1px solid rgba(230, 230, 230, 1);
border-radius: 12px;
margin: 0 0 10px 0; // 📝 좌우 마진 제거, 아래쪽만 유지
.flex(@justifyCenter:flex-start);
padding: 20px 15px; // 📝 패딩 복원 (상하 20px, 좌우 15px)
padding: 30px; // 📝 패딩 복원 (상하 20px, 좌우 15px)
position: relative;
// 📝 부모 영역 오버플로우 방지를 위한 box-sizing 설정
box-sizing: border-box;
@@ -35,48 +35,48 @@
.reviewContent {
// 📝 이미지 크기 변경에 맞춰 높이 조정 (108px -> 90px)
.size(@w: 100%,@h:90px);
.size(@w: 100%,@h:108px);
// 📝 이미지와 마진을 고려한 실제 사용 가능한 넓이로 제한
flex: 1;
min-width: 0; // flex item이 축소될 수 있도록 설정
// 📝 오른쪽 마진 제거 (패딩이 있으므로 중복 여백 방지)
.reviewMeta {
.size(@w:100%, @h:31px);
display: flex;
justify-content: flex-start;
align-items: center;
.reviewMeta {
.size(@w:100%, @h:31px);
display: flex;
justify-content: flex-start;
align-items: center;
> * {
margin-right: 20px;
> * {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
// StarRating 컴포넌트 스타일 - Light theme에 맞게 조정
:global(.star-rating) {
width: 160px !important;
height: 32px !important;
}
.reviewAuthor {
// Light theme: 어두운 회색으로 변경
color: rgba(100, 100, 100, 1);
.font(@fontFamily: @baseFont, @fontSize: 22px);
font-weight: 400;
}
.reviewDate {
// Light theme: 어두운 색상으로 변경
color: rgba(60, 60, 60, 1);
.font(@fontFamily: @baseFont, @fontSize: 24px);
font-weight: 400;
margin-left: auto;
&:last-child {
margin-right: 0;
}
}
// StarRating 컴포넌트 스타일 - Light theme에 맞게 조정
:global(.star-rating) {
width: 160px !important;
height: 32px !important;
}
.reviewAuthor {
// Light theme: 어두운 회색으로 변경
color: rgba(100, 100, 100, 1);
.font(@fontFamily: @baseFont, @fontSize: 22px);
font-weight: 400;
}
.reviewDate {
// Light theme: 어두운 색상으로 변경
color: rgba(60, 60, 60, 1);
.font(@fontFamily: @baseFont, @fontSize: 24px);
font-weight: 400;
margin-left: auto;
}
}
.reviewText {
.font(@fontFamily: @baseFont, @fontSize: 24px);
font-weight: 400;

View File

@@ -1,20 +1,27 @@
// Light theme 리뷰 리스트 컴포넌트
import React, { useCallback, useEffect, useState } from "react";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import UserReviewItem from "./UserReviewItem";
import UserReviewsScroller from "./UserReviewsScroller";
import { $L } from "../../../utils/helperMethods";
import css from "./UserReviewsList.module.less";
import React, {
useCallback,
useEffect,
useState,
} from 'react';
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import { $L } from '../../../utils/helperMethods';
import UserReviewItem from './UserReviewItem';
import css from './UserReviewsList.module.less';
import UserReviewsScroller from './UserReviewsScroller';
const Container = SpotlightContainerDecorator(
{
enterTo: "default-element",
preserveId: true,
leaveFor: {
left: "filter-all-stars"
left: "filter-all-stars",
},
restrict: "none",
spotlightDirection: "vertical"
spotlightDirection: "vertical",
},
"div"
);
@@ -29,8 +36,8 @@ const UserReviewsList = ({
reviewsData = [], // UserReviewPanel에서 전달받은 필터링된 처음 4개 리뷰
totalReviewCount = 0, // 전체 리뷰 개수
filteredReviewCount = 0, // 필터링된 리뷰 개수
currentFilter = { type: 'rating', value: 'all' }, // Single Filter 구조
showAllReviews = true
currentFilter = { type: "rating", value: "all" }, // Single Filter 구조
showAllReviews = true,
}) => {
const [selectedReviewIndex, setSelectedReviewIndex] = useState(null);
@@ -39,7 +46,7 @@ const UserReviewsList = ({
console.log("[UserReviewsList] Review item clicked:", {
rvwId: review.rvwId,
index: index,
review: review
review: review,
});
setSelectedReviewIndex(index);
}, []);
@@ -55,9 +62,15 @@ const UserReviewsList = ({
hasData: reviewsData && reviewsData.length > 0,
prdtId: prdtId,
dataSource: "props", // Redux가 아닌 props에서 받음
isFiltered: currentFilter.value !== 'all'
isFiltered: currentFilter.value !== "all",
});
}, [reviewsData, totalReviewCount, filteredReviewCount, currentFilter, prdtId]);
}, [
reviewsData,
totalReviewCount,
filteredReviewCount,
currentFilter,
prdtId,
]);
return (
<Container className={css.reviewsListContainer}>
@@ -65,20 +78,24 @@ const UserReviewsList = ({
<div className={css.reviewsListHeader}>
<div className={css.reviewsListHeaderText}>
<span className={css.reviewsListHeaderCount}>
{currentFilter.value !== 'all' ? filteredReviewCount : totalReviewCount}
</span> Customer Reviews
{currentFilter.value !== "all"
? filteredReviewCount
: totalReviewCount}
</span>{" "}
Customer Reviews
</div>
</div>
{/* 리뷰 스크롤러 */}
<UserReviewsScroller className={css.reviewsScroller}>
{/*
<div className={css.showReviewsText}>
{$L(
currentFilter.value !== 'all' ?
`Showing ${reviewsData ? reviewsData.length : 0} out of ${filteredReviewCount} filtered reviews` :
`Showing ${reviewsData ? reviewsData.length : 0} out of ${totalReviewCount} reviews`
)}
</div>
</div> */}
{/* 리뷰 아이템들 - props로 받은 데이터 사용 (이미 4개로 제한됨) */}
<div className={css.reviewItems}>
@@ -97,7 +114,9 @@ const UserReviewsList = ({
})
) : (
<div className={css.noReviews}>
{totalReviewCount === 0 ? 'No reviews available' : 'Loading reviews...'}
{totalReviewCount === 0
? "No reviews available"
: "Loading reviews..."}
</div>
)}
</div>

View File

@@ -8,9 +8,9 @@
display: flex;
flex-direction: column;
// Light theme: 밝은 배경
background-color: rgba(250, 250, 250, 1);
background-color: @COLOR_WHITE;
border-radius: 12px;
padding: 20px;
padding: 0 0px 20px 40px;
}
.reviewsListHeader {
@@ -19,8 +19,8 @@
display: flex;
align-items: center;
margin-bottom: 20px;
border-bottom: 1px solid rgba(230, 230, 230, 1);
padding-bottom: 15px;
// border-bottom: 1px solid rgba(230, 230, 230, 1);
// padding-bottom: 15px;
.reviewsListHeaderText {
.font(@fontFamily: @baseFont, @fontSize: 28px);
@@ -38,7 +38,7 @@
.reviewsScroller {
flex: 1;
width: 100%;
width: 885px;
height: 100%;
overflow-y: auto;
@@ -57,6 +57,7 @@
display: flex;
flex-direction: column;
gap: 10px;
background-color: @COLOR_WHITE;
}
.noReviews {

View File

@@ -18,7 +18,9 @@
// Light theme: 밝은 배경
background-color: rgba(255, 255, 255, 1);
border-radius: 8px;
> div:nth-child(1) {
padding-right: 0;
}
.tScroller {
width: 100%;
height: auto;
@@ -27,6 +29,7 @@
// Light theme 스크롤바 스타일
> div:nth-child(2) {
width: 0;
padding: 0;
> div:nth-child(1) {
background-color: @verTrackColor;
@@ -44,7 +47,7 @@
}
&.preventScroll {
>div{
> div {
overflow: hidden !important;
}
}