[상품 상세] 쿠폰 노출관련 처리건
- 쿠폰 노출 처리 - 다운로드 할때 중복처리부분 처리 - 기존 다운로드 로직에서 조건 좀 더 추가. - spotlight 추가 및 변경.
This commit is contained in:
BIN
com.twin.app.shoptime/assets/images/icons/coupon.png
Normal file
BIN
com.twin.app.shoptime/assets/images/icons/coupon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -1,30 +1,65 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
// import { throttle } from 'lodash';
|
||||
import { PropTypes } from 'prop-types';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
|
||||
import Spotlight from '@enact/spotlight';
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
// src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx
|
||||
import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import couponImg from '../../../../assets/images/icons/coupon.png';
|
||||
// import Spottable from '@enact/spotlight/Spottable';
|
||||
//image
|
||||
import arrowDown from '../../../../assets/images/icons/ic_arrow_down_3x_new.png';
|
||||
import indicatorDefaultImage from '../../../../assets/images/img-thumb-empty-144@3x.png';
|
||||
import arrowDown
|
||||
from '../../../../assets/images/icons/ic_arrow_down_3x_new.png';
|
||||
import indicatorDefaultImage
|
||||
from '../../../../assets/images/img-thumb-empty-144@3x.png';
|
||||
import {
|
||||
setHidePopup,
|
||||
setShowPopup,
|
||||
} from '../../../actions/commonActions.js';
|
||||
import {
|
||||
getProductCouponDownload,
|
||||
getProductCouponSearch,
|
||||
getProductCouponTotDownload,
|
||||
} from '../../../actions/couponActions.js';
|
||||
// import { pushPanel } from '../../../actions/panelActions';
|
||||
import { minimizeModalMedia, restoreModalMedia } from '../../../actions/mediaActions';
|
||||
import {
|
||||
minimizeModalMedia,
|
||||
restoreModalMedia,
|
||||
} from '../../../actions/mediaActions';
|
||||
import { pauseFullscreenVideo } from '../../../actions/playActions';
|
||||
import { resetShowAllReviews } from '../../../actions/productActions';
|
||||
import { clearAllToasts, removeToast, showToast } from '../../../actions/toastActions';
|
||||
import {
|
||||
clearAllToasts,
|
||||
removeToast,
|
||||
showToast,
|
||||
} from '../../../actions/toastActions';
|
||||
import CustomImage from '../../../components/CustomImage/CustomImage.jsx';
|
||||
// ProductInfoSection imports
|
||||
import TButton from '../../../components/TButton/TButton';
|
||||
import TPopUp from '../../../components/TPopUp/TPopUp.jsx';
|
||||
import TVirtualGridList
|
||||
from '../../../components/TVirtualGridList/TVirtualGridList.jsx';
|
||||
import useReviews from '../../../hooks/useReviews/useReviews';
|
||||
import useScrollTo from '../../../hooks/useScrollTo';
|
||||
import { BUYNOW_CONFIG } from '../../../utils/BuyNowConfig';
|
||||
import { panel_names } from '../../../utils/Config';
|
||||
import * as Config from '../../../utils/Config.js';
|
||||
import {
|
||||
andThen,
|
||||
curry,
|
||||
@@ -51,13 +86,19 @@ import StarRating from '../components/StarRating';
|
||||
// ProductContentSection imports
|
||||
import TScrollerDetail from '../components/TScroller/TScrollerDetail';
|
||||
import DetailPanelSkeleton from '../DetailPanelSkeleton/DetailPanelSkeleton';
|
||||
import ProductDescription from '../ProductContentSection/ProductDescription/ProductDescription';
|
||||
import ProductDetail from '../ProductContentSection/ProductDetail/ProductDetail.new';
|
||||
import { ProductVideoV2 } from '../ProductContentSection/ProductVideo/ProductVideo.v2.jsx';
|
||||
import ProductVideo from '../ProductContentSection/ProductVideo/ProductVideo.v3';
|
||||
import ProductDescription
|
||||
from '../ProductContentSection/ProductDescription/ProductDescription';
|
||||
import ProductDetail
|
||||
from '../ProductContentSection/ProductDetail/ProductDetail.new';
|
||||
import {
|
||||
ProductVideoV2,
|
||||
} from '../ProductContentSection/ProductVideo/ProductVideo.v2.jsx';
|
||||
import ProductVideo
|
||||
from '../ProductContentSection/ProductVideo/ProductVideo.v3';
|
||||
import UserReviews from '../ProductContentSection/UserReviews/UserReviews';
|
||||
// import ViewAllReviewsButton from '../ProductContentSection/UserReviews/ViewAllReviewsButton';
|
||||
import YouMayAlsoLike from '../ProductContentSection/YouMayAlsoLike/YouMayAlsoLike';
|
||||
import YouMayAlsoLike
|
||||
from '../ProductContentSection/YouMayAlsoLike/YouMayAlsoLike';
|
||||
import QRCode from '../ProductInfoSection/QRCode/QRCode';
|
||||
import ProductOverview from '../ProductOverview/ProductOverview';
|
||||
// CSS imports
|
||||
@@ -98,6 +139,8 @@ const HorizontalContainer = SpotlightContainerDecorator(
|
||||
'div'
|
||||
);
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
|
||||
const getProductData = curry((productType, themeProductInfo, productInfo) =>
|
||||
pipe(
|
||||
when(
|
||||
@@ -148,7 +191,16 @@ export default function ProductAllSection({
|
||||
|
||||
// YouMayLike 데이터는 API 응답 시간이 걸리므로 직접 구독
|
||||
const youmaylikeData = useSelector((state) => state.main.youmaylikeData);
|
||||
|
||||
//coupon
|
||||
const { partnerCoupon } = useSelector(
|
||||
(state) => state.coupon.productCouponSearchData
|
||||
);
|
||||
const { userNumber } = useSelector(
|
||||
(state) => state.common.appStatus.loginUserData
|
||||
);
|
||||
const { popupVisible, activePopup } = useSelector(
|
||||
(state) => state.common.popup
|
||||
);
|
||||
// ProductVideo 버전 관리 (1: 기존 modal 방식, 2: 내장 방식 , 3: 비디오 생략)
|
||||
const [productVideoVersion, setProductVideoVersion] = useState(1);
|
||||
// 비디오 재생 여부 flag (재생 전에는 minimize/restore 로직 비활성화)
|
||||
@@ -177,6 +229,215 @@ export default function ProductAllSection({
|
||||
|
||||
// 스크롤 위치에 따른 MediaPanel 제어 상태
|
||||
const [shouldMinimizeMedia, setShouldMinimizeMedia] = useState(false);
|
||||
//coupon
|
||||
const [promotions, setPromotions] = useState([]);
|
||||
const [selectedCouponIndex, setSelectedCouponIndex] = useState(0);
|
||||
const [selectedCoupon, setSelectedCoupon] = useState();
|
||||
const [downloadCouponArr, setDownloadCouponArr] = useState([]);
|
||||
const [couponTypes, setCouponTypes] = useState(null);
|
||||
const [couponCodes, setCouponCodes] = useState("");
|
||||
const [focused, setFocused] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
dispatch(
|
||||
getProductCouponSearch({
|
||||
patnrId: selectedPatnrId,
|
||||
prdtId: selectedPrdtId,
|
||||
mbrNo: userNumber,
|
||||
})
|
||||
);
|
||||
},[dispatch])
|
||||
|
||||
const getCouponCode = () => {
|
||||
const snoArray = [];
|
||||
|
||||
for (let i = 0; i < selectedCoupon.length; i++) {
|
||||
if (selectedCoupon[i].downloadYn === "Y") {
|
||||
snoArray.push(selectedCoupon[i].cpnSno);
|
||||
}
|
||||
}
|
||||
|
||||
setCouponCodes(snoArray.join(", "));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCoupon) {
|
||||
getCouponCode();
|
||||
}
|
||||
}, [selectedCoupon]);
|
||||
|
||||
useEffect(() => {
|
||||
const newPromotions = [];
|
||||
if (partnerCoupon && partnerCoupon.length > 0) {
|
||||
newPromotions.push($L("SPECIAL PROMOTION"));
|
||||
}
|
||||
setPromotions(newPromotions);
|
||||
}, [partnerCoupon]);
|
||||
|
||||
const handleCouponClick = useCallback(
|
||||
(idx, promotion) => {
|
||||
if (!userNumber) {
|
||||
dispatch(setShowPopup(Config.ACTIVE_POPUP.loginPopup));
|
||||
return;
|
||||
}
|
||||
if (promotion === "SPECIAL PROMOTION") {
|
||||
setSelectedCoupon(partnerCoupon);
|
||||
}
|
||||
setCouponTypes(idx);
|
||||
dispatch(setShowPopup(Config.ACTIVE_POPUP.couponPopup));
|
||||
},
|
||||
[dispatch, popupVisible, promotions, userNumber]
|
||||
);
|
||||
|
||||
const handleCouponTotDownload = useCallback(() => {
|
||||
if (selectedCoupon && userNumber) {
|
||||
const couponCodesArray = couponCodes
|
||||
.split(",")
|
||||
.map((code) => parseInt(code.trim()));
|
||||
setDownloadCouponArr((prevArr) => [...prevArr, ...couponCodesArray]);
|
||||
|
||||
dispatch(
|
||||
getProductCouponTotDownload({
|
||||
mbrNo: userNumber,
|
||||
cpnSnoAll: couponCodes,
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [dispatch, selectedCoupon, userNumber, couponCodes]);
|
||||
|
||||
const onClose = useCallback(
|
||||
(spotlightId) => {
|
||||
dispatch(setHidePopup());
|
||||
|
||||
let currentSpot;
|
||||
if (typeof spotlightId === "string") {
|
||||
currentSpot = spotlightId;
|
||||
} else {
|
||||
currentSpot = SpotlightIds.DETAIL_BUYNOW;
|
||||
}
|
||||
|
||||
if (currentSpot) {
|
||||
setTimeout(() => {
|
||||
Spotlight.focus(currentSpot);
|
||||
});
|
||||
}
|
||||
},
|
||||
[dispatch]
|
||||
)
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const {
|
||||
cpnDctrt,
|
||||
cpnTtl,
|
||||
cpnAplyMinPurcAmt,
|
||||
cpnAplyMaxDcAmt,
|
||||
cpnAplyStrtDtt,
|
||||
cpnAplyEndDtt,
|
||||
shptmDcTpCd,
|
||||
currSign,
|
||||
downloadYn,
|
||||
cpnSno,
|
||||
dcAmt,
|
||||
duplDwldYn,
|
||||
} = selectedCoupon[index];
|
||||
|
||||
const couponAplyStartDate = cpnAplyStrtDtt.split(" ")[0];
|
||||
const couponAplyEndDate = cpnAplyEndDtt.split(" ")[0];
|
||||
|
||||
const onFocus = (index) => {
|
||||
setSelectedCouponIndex(index);
|
||||
setFocused(true);
|
||||
};
|
||||
|
||||
const onBlur = () => {
|
||||
setFocused(false);
|
||||
};
|
||||
|
||||
const handleDownloadClick = () => {
|
||||
if (
|
||||
downloadCouponArr.length > 0 &&
|
||||
downloadCouponArr.includes(cpnSno) &&
|
||||
(downloadYn === "N" || (duplDwldYn === "Y" && downloadYn === "Y"))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setDownloadCouponArr((prevArr) => [...prevArr, cpnSno]);
|
||||
dispatch(
|
||||
getProductCouponDownload({ mbrNo: userNumber, cpnSno: cpnSno })
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SpottableComponent
|
||||
className={css.couponContainer}
|
||||
spotlightid={`spotlightId-coupon-${index}`}
|
||||
{...rest}
|
||||
onFocus={() => onFocus(index)}
|
||||
onBlur={onBlur}
|
||||
onClick={handleDownloadClick}
|
||||
>
|
||||
<div
|
||||
className={css.couponItem}
|
||||
aria-label={
|
||||
"Purchase over " +
|
||||
cpnAplyMinPurcAmt +
|
||||
"up to " +
|
||||
cpnAplyMaxDcAmt +
|
||||
" off"
|
||||
}
|
||||
>
|
||||
<div className={css.couponTopContents}>
|
||||
{shptmDcTpCd === "CPN00401" && (
|
||||
<span className={css.couponLate}>{`${currSign}${dcAmt}`}</span>
|
||||
)}
|
||||
{shptmDcTpCd === "CPN00402" && (
|
||||
<span className={css.couponLate}>{`${cpnDctrt}%`}</span>
|
||||
)}
|
||||
<span className={css.title} aria-label={cpnTtl}>
|
||||
{cpnTtl}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className={css.couponMiddleContents}>
|
||||
<span>
|
||||
{$L(
|
||||
"Purchase over ${cpnAplyMinPurcAmt} (up to ${cpnAplyMaxDcAmt} off)"
|
||||
)
|
||||
.replace("{cpnAplyMinPurcAmt}", cpnAplyMinPurcAmt)
|
||||
.replace("{cpnAplyMaxDcAmt}", cpnAplyMaxDcAmt)}
|
||||
</span>
|
||||
<span className={classNames(css.content, css.date)}>
|
||||
{couponAplyStartDate}~{couponAplyEndDate}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={classNames(
|
||||
css.couponBottomButton,
|
||||
downloadCouponArr.length > 0 &&
|
||||
downloadCouponArr.includes(cpnSno) &&
|
||||
css.disable,
|
||||
downloadYn === "N" && css.disable,
|
||||
duplDwldYn === "N" && downloadYn === "Y" && css.disable,
|
||||
!downloadCouponArr.includes(cpnSno) &&
|
||||
index === selectedCouponIndex &&
|
||||
focused &&
|
||||
css.focused
|
||||
)}
|
||||
aria-label="Download Button"
|
||||
>
|
||||
{downloadCouponArr.length > 0 &&
|
||||
downloadCouponArr.includes(cpnSno)
|
||||
? $L("DOWNLOAD COMPLETED")
|
||||
: $L("DOWNLOAD")}
|
||||
</div>
|
||||
</div>
|
||||
</SpottableComponent>
|
||||
);
|
||||
},
|
||||
[selectedCoupon, downloadCouponArr, focused, dispatch]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const toggleQRCode = () => {
|
||||
@@ -631,6 +892,16 @@ export default function ProductAllSection({
|
||||
|
||||
// BUY NOW, ADD TO CART 버튼에서 arrow up 시: 항상 헤더 뒤로가기 버튼으로
|
||||
const handleSpotlightUpFromBuyButtons = useCallback((e) => {
|
||||
e.stopPropagation();
|
||||
if(promotions){
|
||||
Spotlight.focus('detail-coupon-button');
|
||||
} else {
|
||||
Spotlight.focus('spotlightId_backBtn');
|
||||
}
|
||||
}, [promotions]);
|
||||
|
||||
|
||||
const handleSpotlightUpFromCouponButtons = useCallback((e) => {
|
||||
e.stopPropagation();
|
||||
Spotlight.focus('spotlightId_backBtn');
|
||||
}, []);
|
||||
@@ -928,6 +1199,8 @@ export default function ProductAllSection({
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
// 초기 로딩 중에는 Skeleton 표시
|
||||
if (isInitialLoading) {
|
||||
return (
|
||||
@@ -936,6 +1209,9 @@ export default function ProductAllSection({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<HorizontalContainer className={css.detailArea} onClick={handleCloseToast}>
|
||||
@@ -983,6 +1259,30 @@ export default function ProductAllSection({
|
||||
</div>
|
||||
</ProductOverview>
|
||||
|
||||
{promotions.map((promotion, idx) => {
|
||||
return(
|
||||
<HorizontalContainer className={css.couponContainer} key={idx}>
|
||||
<div className={css.couponTitleText}>
|
||||
<div className={css.firstTitle}>SPECIAL PROMOTION</div>
|
||||
<div className={css.secondTitle}>Coupon only applicable to this product!</div>
|
||||
</div>
|
||||
<TButton
|
||||
spotlightId="detail-coupon-button"
|
||||
className={css.couponButton}
|
||||
onClick={() => {
|
||||
handleCouponClick(idx, promotion);
|
||||
}}
|
||||
onSpotlightUp={handleSpotlightUpFromCouponButtons}
|
||||
size="detail_very_small"
|
||||
>
|
||||
<div className={css.couponText}>
|
||||
COUPON
|
||||
</div>
|
||||
<img className={css.buttonImg} src={couponImg} />
|
||||
</TButton>
|
||||
</HorizontalContainer>
|
||||
)
|
||||
})}
|
||||
{isBillingProductVisible && (
|
||||
<HorizontalContainer className={css.buyNowCartContainer}>
|
||||
<TButton
|
||||
@@ -1277,6 +1577,38 @@ export default function ProductAllSection({
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{/* COUPON POPUP */}
|
||||
{activePopup === Config.ACTIVE_POPUP.couponPopup && (
|
||||
<TPopUp
|
||||
kind="couponPopup"
|
||||
hasText
|
||||
title={couponTypes === 0 ? promotions[0] : promotions[1]}
|
||||
open={popupVisible}
|
||||
onClick={handleCouponTotDownload}
|
||||
onClose={onClose}
|
||||
hasButton
|
||||
button1Text={$L("DOWNLOAD ALL")}
|
||||
button2Text={$L("CLOSE")}
|
||||
>
|
||||
<Container className={css.itemWrap}>
|
||||
{selectedCoupon && selectedCoupon.length > 0 && (
|
||||
<TVirtualGridList
|
||||
dataSize={selectedCoupon.length}
|
||||
direction="horizontal"
|
||||
autoScroll
|
||||
renderItem={renderItem}
|
||||
itemWidth={440}
|
||||
itemHeight={320}
|
||||
spacing={15}
|
||||
className={css.itemList}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
<div
|
||||
className={css.couponRemain}
|
||||
>{`1/${selectedCoupon?.length}`}</div>
|
||||
</TPopUp>
|
||||
)}
|
||||
</HorizontalContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -407,10 +407,74 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* COUPON 버튼 */
|
||||
.couponContainer {
|
||||
width:100%;
|
||||
display:flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.couponTitleText {
|
||||
width:350px;
|
||||
height:60px;
|
||||
.firstTitle {
|
||||
font-size:25px;
|
||||
font-weight:600;
|
||||
color:@COLOR_WHITE;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
.secondTitle {
|
||||
font-size:22px;
|
||||
font-weight:400;
|
||||
color:@COLOR_WHITE;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.couponButton {
|
||||
flex: 1 1 0% !important;
|
||||
width: auto !important;
|
||||
height: 60px !important;
|
||||
background: rgba(68, 68, 68, 0.5) !important;
|
||||
border-radius: 6px !important;
|
||||
border: none !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
&:focus {
|
||||
background: @PRIMARY_COLOR_RED !important;
|
||||
> div {
|
||||
.couponText {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
> div {
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.couponText {
|
||||
color: white !important;
|
||||
font-size: 25px !important;
|
||||
font-family: @baseFont !important;
|
||||
font-weight: 400 !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
.buttonImg {
|
||||
width:30px;
|
||||
height:24px;
|
||||
margin-left:5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* BUY NOW + ADD TO CART 버튼 스타일 */
|
||||
.buyNowCartContainer {
|
||||
width: 100%;
|
||||
padding-top: 19px;
|
||||
padding-top: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -637,3 +701,128 @@
|
||||
// PlayerPanel 모달이 이 영역에서만 재생되도록 설정
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
//coupon
|
||||
.itemWrap {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
position: absolute;
|
||||
width: 253px;
|
||||
height: 320px;
|
||||
top: 0;
|
||||
content: "";
|
||||
z-index: 2;
|
||||
}
|
||||
&::after {
|
||||
left: 0;
|
||||
background: linear-gradient(to right, #f8f8f8, transparent);
|
||||
}
|
||||
&::before {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, #f8f8f8, transparent);
|
||||
}
|
||||
.itemList {
|
||||
.size(@w: 440px , @h: 320px);
|
||||
height: 320px;
|
||||
}
|
||||
> div > div {
|
||||
margin-left: 253px;
|
||||
}
|
||||
> div {
|
||||
> div:nth-child(2) {
|
||||
left: -253px;
|
||||
}
|
||||
> div:nth-child(3) {
|
||||
right: -520px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.couponRemain {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #808080;
|
||||
text-align: center;
|
||||
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.couponContainer {
|
||||
position: relative;
|
||||
|
||||
&:focus {
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
|
||||
.couponItem {
|
||||
.flex(@direction: column, @justifyCenter: space-between);
|
||||
.size(@w: 440px , @h: 320px);
|
||||
text-align: center;
|
||||
background: @COLOR_WHITE;
|
||||
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
.border-solid(@size:1px,@color:@COLOR_GRAY02);
|
||||
|
||||
.couponTopContents {
|
||||
.couponLate {
|
||||
font-weight: bold;
|
||||
font-size: 32px;
|
||||
color: @PRIMARY_COLOR_RED;
|
||||
line-height: 1.1;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 32px;
|
||||
line-height: 1.1;
|
||||
color: @COLOR_GRAY07;
|
||||
width: 400px;
|
||||
height: 40px;
|
||||
.elip(1);
|
||||
}
|
||||
}
|
||||
|
||||
.couponMiddleContents {
|
||||
.flex(@direction: column, @justifyCenter: space-between);
|
||||
font-weight: normal;
|
||||
font-size: 22px;
|
||||
color: @COLOR_GRAY03;
|
||||
|
||||
> span {
|
||||
min-height: 30px;
|
||||
|
||||
&:nth-child(1) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.couponBottomButton {
|
||||
.flex();
|
||||
.size(@w: 380px , @h: 60px);
|
||||
border-radius: 6px;
|
||||
background-color: #808080;
|
||||
color: #fff;
|
||||
z-index: 1;
|
||||
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
|
||||
&.disable {
|
||||
background-color: #808080;
|
||||
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
&.focused {
|
||||
background-color: @PRIMARY_COLOR_RED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user