[251012] fix: PlayerPanel turnback , Focus Policy
🕐 커밋 시간: 2025. 10. 12. 22:02:25 📊 변경 통계: • 총 파일: 12개 • 추가: +239줄 • 삭제: -78줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.js ~ com.twin.app.shoptime/src/views/DetailPanel/DetailPanelSkeleton/DetailPanelSkeleton.module.less ~ com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.module.less ~ com.twin.app.shoptime/src/views/IntroPanel/IntroPanel.new.module.less ~ com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/TermsOfService/OptionalTermsInfo.module.less ~ com.twin.app.shoptime/src/views/MyPagePanel/MyPageSub/TermsOfService/TermsOfService.module.less ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowButton.module.less ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.module.less ~ com.twin.app.shoptime/src/views/UserReview/components/UserReviewsList.module.less 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx (javascript): 🔄 Modified: SpotlightContainerDecorator() 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx (javascript): 🔄 Modified: Spottable() 🔧 주요 변경 내용: • UI 컴포넌트 아키텍처 개선 • API 서비스 레이어 개선
This commit is contained in:
@@ -859,28 +859,6 @@ const VideoPlayerBase = class extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
// TabContainerV2와 mediaControls 동기화
|
||||
if (
|
||||
this.props.tabContainerVersion === 2 &&
|
||||
this.props.belowContentsVisible !== undefined &&
|
||||
prevProps.belowContentsVisible !== this.props.belowContentsVisible
|
||||
) {
|
||||
console.log('[VideoPlayer] belowContentsVisible 변경 감지:', {
|
||||
prev: prevProps.belowContentsVisible,
|
||||
current: this.props.belowContentsVisible,
|
||||
mediaControlsVisible: this.state.mediaControlsVisible,
|
||||
});
|
||||
|
||||
if (this.props.belowContentsVisible && !this.state.mediaControlsVisible) {
|
||||
// TabContainerV2가 표시될 때 controls도 표시
|
||||
console.log('[VideoPlayer] TabContainerV2 표시 - controls 강제 표시');
|
||||
this.showControls();
|
||||
} else if (!this.props.belowContentsVisible && this.state.mediaControlsVisible) {
|
||||
// TabContainerV2가 숨겨질 때 controls도 숨김
|
||||
console.log('[VideoPlayer] TabContainerV2 숨김 - controls 숨김');
|
||||
this.hideControls();
|
||||
}
|
||||
}
|
||||
if (
|
||||
(!this.state.mediaControlsVisible &&
|
||||
prevState.mediaControlsVisible !== this.state.mediaControlsVisible) ||
|
||||
@@ -1044,12 +1022,6 @@ const VideoPlayerBase = class extends React.Component {
|
||||
// detection of when "more" is pressed vs when the state is updated is mismatched. Using an
|
||||
// instance variable that's only set and used for this express purpose seems cleanest.
|
||||
|
||||
// TabContainerV2가 표시 중이면 자동으로 닫지 않음
|
||||
if (this.props.tabContainerVersion === 2 && this.props.belowContentsVisible) {
|
||||
console.log('[VideoPlayer] TabContainerV2 표시 중 - autoClose 비활성화');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.props.autoCloseTimeout && !this.props.sideContentsVisible) {
|
||||
this.autoCloseJob.startAfter(this.props.autoCloseTimeout);
|
||||
}
|
||||
@@ -1981,15 +1953,6 @@ const VideoPlayerBase = class extends React.Component {
|
||||
return;
|
||||
}
|
||||
|
||||
// tabContainerVersion === 2일 때 belowContentsVisible도 함께 토글
|
||||
if (this.props.tabContainerVersion === 2 && this.props.setBelowContentsVisible) {
|
||||
const willShowControls = !this.state.mediaControlsVisible;
|
||||
console.log('[VideoPlayer] 클릭 - 상태 동기화 토글:', willShowControls);
|
||||
|
||||
// belowContentsVisible을 먼저 변경 (componentDidUpdate에서 mediaControls 동기화됨)
|
||||
this.props.setBelowContentsVisible(willShowControls);
|
||||
}
|
||||
|
||||
this.toggleControls();
|
||||
};
|
||||
|
||||
|
||||
@@ -157,7 +157,13 @@
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
> * {
|
||||
margin-bottom: 10px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonTitle {
|
||||
@@ -190,8 +196,14 @@
|
||||
.skeletonButtons {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
|
||||
> * {
|
||||
margin-right: 10px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonShopButton {
|
||||
@@ -218,7 +230,13 @@
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
> * {
|
||||
margin-bottom: 5px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonActionButton {
|
||||
@@ -248,7 +266,13 @@
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
|
||||
> * {
|
||||
margin-bottom: 15px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonDescTitle {
|
||||
@@ -274,7 +298,13 @@
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
> * {
|
||||
margin-bottom: 20px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonReviewTitle {
|
||||
@@ -286,8 +316,14 @@
|
||||
.skeletonReviewItem {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
align-items: flex-start;
|
||||
|
||||
> * {
|
||||
margin-right: 15px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonReviewAvatar {
|
||||
@@ -302,7 +338,13 @@
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
> * {
|
||||
margin-bottom: 10px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonReviewHeader {
|
||||
@@ -328,7 +370,13 @@
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 25px;
|
||||
|
||||
> * {
|
||||
margin-bottom: 25px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonYouMayLikeTitle {
|
||||
@@ -340,16 +388,28 @@
|
||||
.skeletonProductGrid {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: flex-start;
|
||||
|
||||
> * {
|
||||
margin-right: 20px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonProductCard {
|
||||
width: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
|
||||
> * {
|
||||
margin-bottom: 10px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skeletonProductImage {
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
// 스크롤바 thumb에 hover 효과 적용
|
||||
&:hover::-webkit-scrollbar-thumb {
|
||||
background: #c72054;
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,15 +280,24 @@
|
||||
}
|
||||
|
||||
// 포커스 상태 추가
|
||||
&:focus,
|
||||
&.active {
|
||||
&:focus {
|
||||
background: @PRIMARY_COLOR_RED !important; // 포커스시 빨간색 배경
|
||||
outline: 2px solid @PRIMARY_COLOR_RED !important;
|
||||
animation: focusShadowPulse 0.4s ease-out !important;
|
||||
|
||||
.shopByMobileText {
|
||||
color: white !important; // 포커스시에도 텍스트는 흰색 유지
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: @PRIMARY_COLOR_RED !important;
|
||||
outline: 2px solid @PRIMARY_COLOR_RED !important;
|
||||
|
||||
.shopByMobileText {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.favoriteBtnWrapper {
|
||||
@@ -398,9 +407,13 @@
|
||||
font-weight: 400; // Bold에서 Regular로 변경
|
||||
line-height: 35px;
|
||||
|
||||
&:focus,
|
||||
&:focus {
|
||||
background: @PRIMARY_COLOR_RED; // 포커스시만 빨간색
|
||||
animation: focusShadowPulse 0.4s ease-out;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #c72054; // 포커스시만 빨간색
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,7 +425,8 @@
|
||||
margin-top: 10px;
|
||||
|
||||
&:focus {
|
||||
background: #c72054;
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
animation: focusShadowPulse 0.4s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,7 +625,7 @@
|
||||
|
||||
// 스크롤바 thumb에 hover 효과 적용
|
||||
&:hover::-webkit-scrollbar-thumb {
|
||||
background: #c72054;
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,6 +764,7 @@
|
||||
&:focus {
|
||||
background: @PRIMARY_COLOR_RED !important; // 포커스시 빨간색 배경
|
||||
outline: 2px solid @PRIMARY_COLOR_RED !important;
|
||||
animation: focusShadowPulse 0.4s ease-out !important;
|
||||
|
||||
.shopByMobileText {
|
||||
color: white !important; // 포커스시에도 텍스트는 흰색 유지
|
||||
@@ -864,7 +879,8 @@
|
||||
line-height: 35px;
|
||||
|
||||
&:focus {
|
||||
background: #c72054; // 포커스시만 빨간색
|
||||
background: @PRIMARY_COLOR_RED; // 포커스시만 빨간색
|
||||
animation: focusShadowPulse 0.4s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -876,7 +892,8 @@
|
||||
margin-top: 10px;
|
||||
|
||||
&:focus {
|
||||
background: #c72054;
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
animation: focusShadowPulse 0.4s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,7 +1016,13 @@
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
> * {
|
||||
margin-right: 10px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.buyNowButton {
|
||||
@@ -1026,6 +1049,7 @@
|
||||
&:focus {
|
||||
background: @PRIMARY_COLOR_RED !important;
|
||||
outline: 2px solid @PRIMARY_COLOR_RED !important;
|
||||
animation: focusShadowPulse 0.4s ease-out !important;
|
||||
|
||||
.buyNowText {
|
||||
color: white !important;
|
||||
@@ -1057,6 +1081,7 @@
|
||||
&:focus {
|
||||
background: @PRIMARY_COLOR_RED !important;
|
||||
outline: 2px solid @PRIMARY_COLOR_RED !important;
|
||||
animation: focusShadowPulse 0.4s ease-out !important;
|
||||
|
||||
.addToCartText {
|
||||
color: white !important;
|
||||
@@ -1072,3 +1097,16 @@
|
||||
// PlayerPanel 모달이 이 영역에서만 재생되도록 설정
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// 포커스 Pulse 애니메이션 - Box Shadow 방식
|
||||
@keyframes focusShadowPulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 @PRIMARY_COLOR_RED;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 0 6px fade(@PRIMARY_COLOR_RED, 50%);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 @PRIMARY_COLOR_RED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,26 +26,44 @@
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 40px;
|
||||
display: inline-flex;
|
||||
background-color: @BG_COLOR_03;
|
||||
|
||||
> * {
|
||||
margin-bottom: 40px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 첫 번째 영역: 헤더 섹션 (타이틀 + 설명)
|
||||
.headerSection {
|
||||
width: 1834px;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: 40px;
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
margin-bottom: 40px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.titleContainer {
|
||||
align-self: stretch;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
display: inline-flex;
|
||||
|
||||
> * {
|
||||
margin-right: 14px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.welcomeText {
|
||||
color: #807f81;
|
||||
font-size: 62px;
|
||||
@@ -89,9 +107,15 @@
|
||||
align-self: stretch;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
display: inline-flex;
|
||||
|
||||
> * {
|
||||
margin-right: 10px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.descriptionText {
|
||||
width: 1012.49px;
|
||||
text-align: center;
|
||||
@@ -225,9 +249,15 @@
|
||||
height: 100px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
justify-content: center;
|
||||
|
||||
> * {
|
||||
margin-right: 40px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.agreeButton,
|
||||
.disagreeButton {
|
||||
width: 450px;
|
||||
|
||||
@@ -67,8 +67,15 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
> * {
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.benefitImage {
|
||||
|
||||
@@ -159,14 +159,26 @@
|
||||
.popup_container {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
gap: 30px !important;
|
||||
|
||||
> * {
|
||||
margin-bottom: 30px !important;
|
||||
&:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button_container {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
justify-content: center !important;
|
||||
gap: 12px !important;
|
||||
|
||||
> * {
|
||||
margin-right: 12px !important;
|
||||
&:last-child {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 380px !important;
|
||||
@@ -187,8 +199,14 @@
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 30px;
|
||||
box-sizing: border-box;
|
||||
|
||||
> * {
|
||||
margin-bottom: 30px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.disagreePopupText {
|
||||
@@ -202,7 +220,13 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
|
||||
> * {
|
||||
margin-right: 12px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.disagreePopupButton {
|
||||
|
||||
@@ -42,6 +42,12 @@ export default function PlayerOverlayContents({
|
||||
const cntry_cd = useSelector((state) => state.common.httpHeader?.cntry_cd);
|
||||
const dispatch = useDispatch();
|
||||
const onClickBack = (ev) => {
|
||||
// TabContainerV2가 표시된 상태에서 백버튼 클릭 시 이벤트 버블링 방지
|
||||
// (Overlay의 onClick으로 전파되어 toggleControls()가 호출되는 것을 막음)
|
||||
if (tabContainerVersion === 2 && belowContentsVisible) {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
if (onClick) {
|
||||
onClick(ev);
|
||||
}
|
||||
|
||||
@@ -835,9 +835,14 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
(ev, isEnd) => {
|
||||
//modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감.
|
||||
|
||||
if (sideContentsVisible && !videoVerticalVisible && panelInfo.shptmBanrTpNm !== 'MEDIA') {
|
||||
// TabContainer(v1)만: Side Contents가 보이는 경우 먼저 숨기고 return
|
||||
if (
|
||||
tabContainerVersion === 1 &&
|
||||
sideContentsVisible &&
|
||||
!videoVerticalVisible &&
|
||||
panelInfo.shptmBanrTpNm !== 'MEDIA'
|
||||
) {
|
||||
setSideContentsVisible(false);
|
||||
setBelowContentsVisible(false);
|
||||
ev?.stopPropagation();
|
||||
// ev?.preventDefault();
|
||||
return;
|
||||
@@ -888,9 +893,10 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
nowMenu,
|
||||
videoPlayer,
|
||||
sideContentsVisible,
|
||||
setBelowContentsVisible,
|
||||
videoVerticalVisible,
|
||||
backupInitialIndex,
|
||||
panels,
|
||||
tabContainerVersion,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -21,18 +21,29 @@
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
> * {
|
||||
margin-right: 10px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-color: rgba(234, 234, 234, 0.7);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba(199, 8, 80, 0.2);
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
border-color: @PRIMARY_COLOR_RED;
|
||||
|
||||
.buttonText {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
|
||||
@@ -102,9 +102,14 @@ export default function TabContainerV2({
|
||||
Spotlight.focus(SpotlightIds.PLAYER_BACK_BUTTON);
|
||||
}, []);
|
||||
|
||||
// useEffect(()=>{
|
||||
// console.log('[tabIndex]',tabIndex)
|
||||
// },[tabIndex])
|
||||
// tabIndex가 2(ShopNowButton)로 변경되면 자동으로 포커스 이동
|
||||
useEffect(() => {
|
||||
if (tabIndex === 2) {
|
||||
setTimeout(() => {
|
||||
Spotlight.focus('below-tab-shop-now-button');
|
||||
}, 100);
|
||||
}
|
||||
}, [tabIndex]);
|
||||
|
||||
return (
|
||||
<Container
|
||||
|
||||
@@ -149,8 +149,9 @@
|
||||
color: white;
|
||||
}
|
||||
&:focus {
|
||||
background: rgba(199, 8, 80, 0.2);
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
border-color: @PRIMARY_COLOR_RED;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,9 +191,13 @@
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba(199, 8, 80, 0.2);
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
border-color: @PRIMARY_COLOR_RED;
|
||||
|
||||
.buttonText {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 100px);
|
||||
}
|
||||
|
||||
@@ -82,8 +82,14 @@
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
background-color: @COLOR_WHITE;
|
||||
|
||||
> * {
|
||||
margin-bottom: 10px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.noReviews {
|
||||
|
||||
Reference in New Issue
Block a user