553 lines
13 KiB
TypeScript
553 lines
13 KiB
TypeScript
import React from 'react';
|
|
import { t } from '@/i18n';
|
|
// Taro mini-program component
|
|
|
|
/**
|
|
* H5 Activity / Campaign Landing Page
|
|
*
|
|
* 活动落地页 - 通过微信/社交媒体分享的促销活动页面
|
|
* 包含:倒计时、优惠券卡片、活动规则、分享栏
|
|
*/
|
|
|
|
const H5ActivityPage: React.FC = () => {
|
|
return (
|
|
<view className="activity-page">
|
|
{/* Hero Banner */}
|
|
<view className="hero-banner">
|
|
<view className="hero-badge">
|
|
<text className="hero-badge-icon">🔥</text>
|
|
<text className="hero-badge-text">{t('activity_flash')}</text>
|
|
</view>
|
|
<text className="hero-title">{t('activity_title')}</text>
|
|
<text className="hero-subtitle">{t('activity_subtitle')}</text>
|
|
|
|
{/* Countdown Timer */}
|
|
<view className="countdown-section">
|
|
<text className="countdown-label">{t('activity_countdown')}</text>
|
|
<view className="countdown-timer">
|
|
<view className="countdown-block">
|
|
<text className="countdown-num">02</text>
|
|
</view>
|
|
<text className="countdown-sep">:</text>
|
|
<view className="countdown-block">
|
|
<text className="countdown-num">18</text>
|
|
</view>
|
|
<text className="countdown-sep">:</text>
|
|
<view className="countdown-block">
|
|
<text className="countdown-num">45</text>
|
|
</view>
|
|
<text className="countdown-sep">:</text>
|
|
<view className="countdown-block countdown-block-ms">
|
|
<text className="countdown-num-ms">32</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
{/* Featured Coupon Cards */}
|
|
<view className="coupon-section">
|
|
<view className="section-header">
|
|
<text className="section-title">{t('activity_featured')}</text>
|
|
<text className="section-subtitle">{t('activity_limited')}</text>
|
|
</view>
|
|
|
|
{[
|
|
{
|
|
brand: 'Starbucks',
|
|
brandInitial: 'S',
|
|
name: '星巴克 ¥50 礼品卡',
|
|
originalPrice: '¥50.00',
|
|
discountPrice: '¥35.00',
|
|
discount: '7折',
|
|
tag: t('activity_tag_hot'),
|
|
},
|
|
{
|
|
brand: 'Amazon',
|
|
brandInitial: 'A',
|
|
name: 'Amazon ¥200 购物券',
|
|
originalPrice: '¥200.00',
|
|
discountPrice: '¥156.00',
|
|
discount: '7.8折',
|
|
tag: t('activity_tag_selling'),
|
|
},
|
|
{
|
|
brand: 'Nike',
|
|
brandInitial: 'N',
|
|
name: 'Nike ¥100 运动券',
|
|
originalPrice: '¥100.00',
|
|
discountPrice: '¥72.00',
|
|
discount: '7.2折',
|
|
tag: t('activity_tag_new'),
|
|
},
|
|
].map((coupon, i) => (
|
|
<view key={i} className="coupon-card">
|
|
{/* Discount Badge */}
|
|
<view className="coupon-badge">
|
|
<text className="coupon-badge-text">{coupon.tag}</text>
|
|
</view>
|
|
|
|
{/* Card Top: Brand + Image */}
|
|
<view className="coupon-card-top">
|
|
<view className="coupon-image-area">
|
|
<text className="coupon-image-icon">🎫</text>
|
|
</view>
|
|
<view className="coupon-discount-tag">
|
|
<text className="coupon-discount-text">{coupon.discount}</text>
|
|
</view>
|
|
</view>
|
|
|
|
{/* Card Body */}
|
|
<view className="coupon-card-body">
|
|
<view className="coupon-brand-row">
|
|
<view className="coupon-brand-avatar">
|
|
<text className="coupon-brand-initial">{coupon.brandInitial}</text>
|
|
</view>
|
|
<text className="coupon-brand-name">{coupon.brand}</text>
|
|
</view>
|
|
<text className="coupon-name">{coupon.name}</text>
|
|
<view className="coupon-price-row">
|
|
<text className="coupon-price-symbol">¥</text>
|
|
<text className="coupon-price-value">{coupon.discountPrice.replace('¥', '')}</text>
|
|
<text className="coupon-original-price">{coupon.originalPrice}</text>
|
|
</view>
|
|
</view>
|
|
|
|
{/* Buy Button */}
|
|
<view className="coupon-buy-btn">
|
|
<text className="coupon-buy-text">{t('activity_buy_now')}</text>
|
|
</view>
|
|
</view>
|
|
))}
|
|
</view>
|
|
|
|
{/* Activity Rules */}
|
|
<view className="rules-section">
|
|
<view className="rules-header">
|
|
<view className="rules-icon">
|
|
<text className="rules-icon-text">📋</text>
|
|
</view>
|
|
<text className="rules-title">{t('activity_rules')}</text>
|
|
</view>
|
|
|
|
<view className="rules-list">
|
|
{[
|
|
t('activity_rule_1'),
|
|
t('activity_rule_2'),
|
|
t('activity_rule_3'),
|
|
t('activity_rule_4'),
|
|
t('activity_rule_5'),
|
|
t('activity_rule_6'),
|
|
t('activity_rule_7'),
|
|
].map((rule, i) => (
|
|
<view key={i} className="rule-item">
|
|
<view className="rule-dot" />
|
|
<text className="rule-text">{rule}</text>
|
|
</view>
|
|
))}
|
|
</view>
|
|
</view>
|
|
|
|
{/* Share Bar */}
|
|
<view className="share-bar">
|
|
<view className="share-info">
|
|
<text className="share-count-icon">👥</text>
|
|
<text className="share-count-text">已有 2,386 人参与</text>
|
|
</view>
|
|
<view className="share-btn">
|
|
<text className="share-btn-icon">📤</text>
|
|
<text className="share-btn-text">{t('share_to_friends')}</text>
|
|
</view>
|
|
</view>
|
|
|
|
{/* Brand Footer */}
|
|
<view className="brand-footer">
|
|
<view className="footer-logo">
|
|
<view className="footer-logo-box">
|
|
<text className="footer-logo-text">G</text>
|
|
</view>
|
|
<text className="footer-logo-name">Genex</text>
|
|
</view>
|
|
<text className="footer-slogan">{t('app_platform_slogan')}</text>
|
|
<text className="footer-copyright">© 2026 Genex. All rights reserved.</text>
|
|
</view>
|
|
</view>
|
|
);
|
|
};
|
|
|
|
export default H5ActivityPage;
|
|
|
|
/*
|
|
CSS (H5活动页样式 - 对应 index.scss):
|
|
|
|
.activity-page {
|
|
min-height: 100vh;
|
|
background: #F8F9FC;
|
|
padding-bottom: 180rpx;
|
|
}
|
|
|
|
/* === Hero Banner === */
|
|
.hero-banner {
|
|
background: linear-gradient(135deg, #6C5CE7 0%, #9B8FFF 100%);
|
|
padding: 80rpx 40rpx 60rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
border-radius: 0 0 40rpx 40rpx;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
.hero-banner::after {
|
|
content: '';
|
|
position: absolute;
|
|
width: 400rpx; height: 400rpx;
|
|
background: rgba(255,255,255,0.06);
|
|
border-radius: 50%;
|
|
top: -100rpx; right: -80rpx;
|
|
}
|
|
.hero-badge {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 8rpx 24rpx;
|
|
background: rgba(255,255,255,0.2);
|
|
border-radius: 999rpx;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
.hero-badge-icon { font-size: 24rpx; margin-right: 8rpx; }
|
|
.hero-badge-text { font-size: 24rpx; color: white; font-weight: 500; }
|
|
|
|
.hero-title {
|
|
font-size: 44rpx;
|
|
font-weight: 700;
|
|
color: white;
|
|
text-align: center;
|
|
letter-spacing: 2rpx;
|
|
}
|
|
.hero-subtitle {
|
|
font-size: 28rpx;
|
|
color: rgba(255,255,255,0.8);
|
|
margin-top: 12rpx;
|
|
text-align: center;
|
|
}
|
|
|
|
/* Countdown */
|
|
.countdown-section {
|
|
margin-top: 40rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
.countdown-label {
|
|
font-size: 24rpx;
|
|
color: rgba(255,255,255,0.7);
|
|
margin-bottom: 16rpx;
|
|
}
|
|
.countdown-timer {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.countdown-block {
|
|
width: 72rpx; height: 72rpx;
|
|
background: rgba(0,0,0,0.25);
|
|
border-radius: 12rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.countdown-block-ms {
|
|
width: 60rpx; height: 60rpx;
|
|
background: rgba(0,0,0,0.15);
|
|
border-radius: 10rpx;
|
|
}
|
|
.countdown-num {
|
|
font-size: 36rpx;
|
|
font-weight: 700;
|
|
color: white;
|
|
font-family: 'DIN Alternate', 'Roboto Mono', monospace;
|
|
}
|
|
.countdown-num-ms {
|
|
font-size: 28rpx;
|
|
font-weight: 700;
|
|
color: rgba(255,255,255,0.8);
|
|
font-family: 'DIN Alternate', 'Roboto Mono', monospace;
|
|
}
|
|
.countdown-sep {
|
|
font-size: 28rpx;
|
|
font-weight: 700;
|
|
color: rgba(255,255,255,0.6);
|
|
margin: 0 8rpx;
|
|
}
|
|
|
|
/* === Coupon Section === */
|
|
.coupon-section {
|
|
padding: 32rpx;
|
|
}
|
|
.section-header {
|
|
margin-bottom: 24rpx;
|
|
}
|
|
.section-title {
|
|
font-size: 36rpx;
|
|
font-weight: 700;
|
|
color: #141723;
|
|
display: block;
|
|
}
|
|
.section-subtitle {
|
|
font-size: 24rpx;
|
|
color: #A0A8BE;
|
|
margin-top: 4rpx;
|
|
display: block;
|
|
}
|
|
|
|
.coupon-card {
|
|
background: white;
|
|
border-radius: 24rpx;
|
|
margin-bottom: 24rpx;
|
|
border: 1rpx solid #F1F3F8;
|
|
overflow: hidden;
|
|
position: relative;
|
|
box-shadow: 0 4rpx 24rpx rgba(0,0,0,0.04);
|
|
}
|
|
.coupon-badge {
|
|
position: absolute;
|
|
top: 0; left: 0;
|
|
background: linear-gradient(135deg, #FF6B6B, #FF8E8E);
|
|
padding: 6rpx 20rpx 6rpx 16rpx;
|
|
border-radius: 0 0 16rpx 0;
|
|
z-index: 2;
|
|
}
|
|
.coupon-badge-text {
|
|
font-size: 22rpx;
|
|
font-weight: 700;
|
|
color: white;
|
|
}
|
|
|
|
.coupon-card-top {
|
|
height: 200rpx;
|
|
background: linear-gradient(135deg, #F3F1FF 0%, #E8E4FF 100%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
}
|
|
.coupon-image-area {
|
|
width: 160rpx; height: 160rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.coupon-image-icon { font-size: 80rpx; opacity: 0.5; }
|
|
.coupon-discount-tag {
|
|
position: absolute;
|
|
top: 16rpx; right: 16rpx;
|
|
background: linear-gradient(135deg, #6C5CE7, #9B8FFF);
|
|
padding: 8rpx 20rpx;
|
|
border-radius: 999rpx;
|
|
}
|
|
.coupon-discount-text {
|
|
font-size: 24rpx;
|
|
font-weight: 700;
|
|
color: white;
|
|
}
|
|
|
|
.coupon-card-body {
|
|
padding: 24rpx 28rpx;
|
|
}
|
|
.coupon-brand-row {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 12rpx;
|
|
}
|
|
.coupon-brand-avatar {
|
|
width: 40rpx; height: 40rpx;
|
|
background: #F1F3F8;
|
|
border-radius: 8rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 12rpx;
|
|
}
|
|
.coupon-brand-initial {
|
|
font-size: 22rpx;
|
|
font-weight: 700;
|
|
color: #6C5CE7;
|
|
}
|
|
.coupon-brand-name {
|
|
font-size: 24rpx;
|
|
color: #5C6478;
|
|
}
|
|
.coupon-name {
|
|
font-size: 30rpx;
|
|
font-weight: 600;
|
|
color: #141723;
|
|
display: block;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
.coupon-price-row {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
}
|
|
.coupon-price-symbol {
|
|
font-size: 24rpx;
|
|
font-weight: 700;
|
|
color: #6C5CE7;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
.coupon-price-value {
|
|
font-size: 40rpx;
|
|
font-weight: 700;
|
|
color: #6C5CE7;
|
|
line-height: 1;
|
|
margin-right: 12rpx;
|
|
}
|
|
.coupon-original-price {
|
|
font-size: 24rpx;
|
|
color: #A0A8BE;
|
|
text-decoration: line-through;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
|
|
.coupon-buy-btn {
|
|
margin: 0 28rpx 28rpx;
|
|
height: 80rpx;
|
|
background: linear-gradient(135deg, #6C5CE7, #9B8FFF);
|
|
border-radius: 16rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.coupon-buy-text {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: white;
|
|
letter-spacing: 2rpx;
|
|
}
|
|
|
|
/* === Rules Section === */
|
|
.rules-section {
|
|
margin: 0 32rpx;
|
|
background: white;
|
|
border-radius: 24rpx;
|
|
padding: 32rpx;
|
|
border: 1rpx solid #F1F3F8;
|
|
}
|
|
.rules-header {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 24rpx;
|
|
padding-bottom: 20rpx;
|
|
border-bottom: 1rpx solid #F1F3F8;
|
|
}
|
|
.rules-icon {
|
|
width: 48rpx; height: 48rpx;
|
|
background: #F3F1FF;
|
|
border-radius: 12rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 16rpx;
|
|
}
|
|
.rules-icon-text { font-size: 28rpx; }
|
|
.rules-title {
|
|
font-size: 30rpx;
|
|
font-weight: 600;
|
|
color: #141723;
|
|
}
|
|
|
|
.rules-list { padding: 0; }
|
|
.rule-item {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
.rule-dot {
|
|
width: 10rpx; height: 10rpx;
|
|
background: #6C5CE7;
|
|
border-radius: 50%;
|
|
margin-top: 14rpx;
|
|
margin-right: 16rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
.rule-text {
|
|
font-size: 24rpx;
|
|
color: #5C6478;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
/* === Share Bar === */
|
|
.share-bar {
|
|
position: fixed;
|
|
bottom: 0; left: 0; right: 0;
|
|
height: 120rpx;
|
|
background: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 32rpx;
|
|
border-top: 1rpx solid #F1F3F8;
|
|
box-shadow: 0 -4rpx 24rpx rgba(0,0,0,0.06);
|
|
z-index: 100;
|
|
}
|
|
.share-info {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.share-count-icon { font-size: 32rpx; margin-right: 8rpx; }
|
|
.share-count-text {
|
|
font-size: 24rpx;
|
|
color: #5C6478;
|
|
}
|
|
.share-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 16rpx 40rpx;
|
|
background: linear-gradient(135deg, #6C5CE7, #9B8FFF);
|
|
border-radius: 999rpx;
|
|
}
|
|
.share-btn-icon { font-size: 28rpx; margin-right: 8rpx; }
|
|
.share-btn-text {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: white;
|
|
}
|
|
|
|
/* === Brand Footer === */
|
|
.brand-footer {
|
|
padding: 60rpx 32rpx 40rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
.footer-logo {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 12rpx;
|
|
}
|
|
.footer-logo-box {
|
|
width: 48rpx; height: 48rpx;
|
|
background: linear-gradient(135deg, #6C5CE7, #9B8FFF);
|
|
border-radius: 12rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 12rpx;
|
|
}
|
|
.footer-logo-text {
|
|
font-size: 28rpx;
|
|
font-weight: 700;
|
|
color: white;
|
|
}
|
|
.footer-logo-name {
|
|
font-size: 30rpx;
|
|
font-weight: 600;
|
|
color: #141723;
|
|
}
|
|
.footer-slogan {
|
|
font-size: 22rpx;
|
|
color: #A0A8BE;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
.footer-copyright {
|
|
font-size: 20rpx;
|
|
color: #C8CDDA;
|
|
}
|
|
*/
|