From 3c3ffa12488d2b7c28e84d6a885df842f4750026 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Fri, 13 Mar 2026 09:25:37 +0800 Subject: [PATCH] feat: add UnlockProOverlay component for displaying subscription details, features, and points-based discounts. --- .../subscription/UnlockProOverlay.tsx | 472 ++++++++++++------ 1 file changed, 308 insertions(+), 164 deletions(-) diff --git a/frontend/components/subscription/UnlockProOverlay.tsx b/frontend/components/subscription/UnlockProOverlay.tsx index 62d4ae3a..45c3d8cf 100644 --- a/frontend/components/subscription/UnlockProOverlay.tsx +++ b/frontend/components/subscription/UnlockProOverlay.tsx @@ -10,9 +10,13 @@ import { Loader2, Lock, MessageSquare, + Radar, + Send, + Sparkles, TrendingUp, Wallet, X, + Zap, } from "lucide-react"; export type UnlockProBilling = { @@ -42,6 +46,19 @@ type UnlockProOverlayProps = { telegramGroupUrl?: string; }; +const features = { + "zh-CN": [ + { icon: TrendingUp, label: "15天高精度趋势预报" }, + { icon: Radar, label: "实时多源雷达图" }, + { icon: Send, label: "全平台智能气象推送" }, + ], + "en-US": [ + { icon: TrendingUp, label: "15-day precision forecast" }, + { icon: Radar, label: "Real-time radar panel" }, + { icon: Send, label: "Cross-platform alert push" }, + ], +}; + export function UnlockProOverlay({ points, planPriceUsd, @@ -62,227 +79,354 @@ export function UnlockProOverlay({ const title = isEn ? "Unlock PolyWeather Pro" : "解锁 PolyWeather Pro"; const subtitle = isEn - ? "Get high-precision weather intelligence and full-platform alerts." - : "获取全球最精准的高精度气象推送"; + ? "High-precision weather intelligence, delivered everywhere." + : "全球最精准的高精度气象推送,全平台覆盖"; const finalPayLabel = payLabel || (isEn ? "Subscribe & Activate" : "立即订阅并激活服务"); + const featureList = features[locale] ?? features["zh-CN"]; + + const canUsePoints = billing.pointsEnabled && billing.isEligible; + return ( -
-
-
- UI v0313 +
+ {/* Ambient background */} +
+
+
+
+ + {/* Close button */} {onClose && ( )} -
-
-
- +
+ {/* Header */} +
+ {/* Badge */} +
+ + + Pro +
-

+ +

{title}

-

+

{subtitle}

-
-
-
-
- - STANDARD PRO - -
- - ${planPriceUsd.toFixed(2)} + + {/* Main content grid */} +
+ {/* Left: Plan card */} +
+ {/* Inner glow */} +
+ +
+
+ + + Standard Pro - + / {isEn ? "mo" : "月"}
-
    - {(isEn - ? [ - "15-day high precision trend", - "Realtime radar panel", - "Cross-platform alert push", - ] - : ["15天趋势预报", "实时雷达图", "全平台推送"] - ).map((item, i) => ( -
  • - {item} -
  • + +
    + + ${planPriceUsd.toFixed(2)} + +
    + +
    + {featureList.map(({ icon: Icon, label }, i) => ( +
    +
    + +
    + {label} +
    ))} -
+
- {billing.pointsEnabled && billing.isEligible ? ( + {/* Right: Points card */} + {canUsePoints ? (
-
-
-
- +
+ +
+ {/* Header row */} +
+
+
+ +
+ + {isEn ? "Points Credit" : "积分抵扣"} +
- - {isEn ? "Points Credit" : "积分抵扣"} + + {/* Toggle */} + +
+ + {/* Discount display */} +
+ + -${billing.discountAmount.toFixed(2)} + + + off + +
+ +

+ {usePoints + ? isEn + ? `Using ${billing.pointsUsed} pts · saves $${billing.discountAmount.toFixed(2)}` + : `已消耗 ${billing.pointsUsed} 积分 · 省 $${billing.discountAmount.toFixed(2)}` + : isEn + ? `Toggle to save up to $${billing.maxDiscountUsd.toFixed(2)}` + : `开启可最多抵扣 $${billing.maxDiscountUsd.toFixed(2)}`} +

+ + {/* Points balance */} +
+ + + {isEn ? "Your balance:" : "当前积分:"}{" "} + + {points} +
-
-
- - -${billing.discountAmount.toFixed(2)} - - - DISCOUNT - -
-

- {usePoints - ? isEn - ? `Using ${billing.pointsUsed} points from your account` - : `已自动消耗账户内 ${billing.pointsUsed} 积分` - : isEn - ? `Enable to save up to $${billing.maxDiscountUsd.toFixed(2)}` - : `开启后最多可抵扣 $${billing.maxDiscountUsd.toFixed(2)}`} -

) : ( -
-
-
-
- + /* Not eligible / points disabled */ +
+
+ {/* Top */} +
+
+
+ +
+ + {!billing.pointsEnabled + ? isEn + ? "Points Disabled" + : "积分未开启" + : isEn + ? "Insufficient Points" + : "积分不足"} +
- + +

+ {isEn ? "Earn Points & Save" : "赚取积分,抵扣订阅"} +

+

{!billing.pointsEnabled ? isEn - ? "Points Disabled" - : "积分未开启" + ? "Points redemption is unavailable for this plan." + : "当前套餐暂不支持积分抵扣。" : isEn - ? "Not Enough Points" - : "积分不足"} - + ? `Need ${billing.pointsPerUsd} pts minimum. You have: ${points}` + : `至少需要 ${billing.pointsPerUsd} 积分,当前仅有 ${points}`} +

-

- {isEn ? "Earn Credits in Community" : "活跃赚取抵扣"} -

-

- {!billing.pointsEnabled - ? isEn - ? "Points redemption is currently unavailable for this plan." - : "当前套餐未开启积分抵扣。" - : isEn - ? `Need at least ${billing.pointsPerUsd} points. Current: ${points}` - : `需要至少 ${billing.pointsPerUsd} 积分,当前 ${points}`} -

-
-
- {telegramGroupUrl ? ( - - {isEn ? "Open Telegram" : "前往电报群"} - - - ) : ( - - {isEn ? "Open Telegram" : "前往电报群"} - - + + {/* Progress bar */} + {billing.pointsEnabled && ( +
+
+ + {points} / {billing.pointsPerUsd} + + + {Math.min( + 100, + Math.round((points / billing.pointsPerUsd) * 100), + )} + % + +
+
+
+
+
)} + + {/* Bottom CTA */} +
+ {telegramGroupUrl ? ( + + + {isEn ? "Join Telegram to earn" : "加入电报群赚取积分"} + + + ) : ( + + + {isEn + ? "Join community to earn points" + : "加入社群即可赚取积分"} + + )} +
)}
-
-
- - {isEn ? "Total Due" : "应付总计"} - -
- + {/* Payment summary */} +
+ {/* Summary row */} +
+
+

+ {isEn ? "Total Due Today" : "今日应付"} +

+ {billing.discountAmount > 0 && usePoints && ( +

+ ${planPriceUsd.toFixed(2)} USD +

+ )} +
+
+ ${billing.finalPrice.toFixed(2)} - + USD
- - -
- - Secure Payment - - +
+ {/* Shimmer */} +
- {errorText ? ( -
- {errorText} -
- ) : null} - {infoText ? ( -
- {infoText} -
- ) : null} + {payBusy ? ( + + ) : ( + <> + + {finalPayLabel} + + + )} + +
+ + {/* Footer links */} +
+ + + {isEn ? "Secure Payment" : "安全付款"} + + · + + + {isEn ? "Subscription FAQ" : "订阅说明"} + +
+ + {/* Error / Info messages */} + {errorText && ( +
+
+ +
+

{errorText}

+
+ )} + {infoText && ( +
+
+ +
+

{infoText}

+
+ )}
);