From f27970f15729fd657fb09e34501fb5aec9aba8ad Mon Sep 17 00:00:00 2001
From: "2569718930@qq.com" <2569718930@qq.com>
Date: Fri, 13 Mar 2026 20:38:10 +0800
Subject: [PATCH] feat: Introduce Pro subscription unlock overlay, paywall, and
related account and help pages.
---
frontend/app/subscription-help/page.tsx | 113 ++++++++++++++++++
frontend/components/account/AccountCenter.tsx | 8 +-
.../dashboard/ProFeaturePaywall.tsx | 10 +-
.../subscription/UnlockProOverlay.tsx | 16 ++-
4 files changed, 139 insertions(+), 8 deletions(-)
create mode 100644 frontend/app/subscription-help/page.tsx
diff --git a/frontend/app/subscription-help/page.tsx b/frontend/app/subscription-help/page.tsx
new file mode 100644
index 00000000..5b0fab8f
--- /dev/null
+++ b/frontend/app/subscription-help/page.tsx
@@ -0,0 +1,113 @@
+import type { Metadata } from "next";
+import Link from "next/link";
+import {
+ ArrowLeft,
+ CheckCircle2,
+ Coins,
+ CreditCard,
+ MessageSquare,
+ ShieldCheck,
+} from "lucide-react";
+
+export const metadata: Metadata = {
+ title: "PolyWeather | 订阅说明",
+ description: "PolyWeather Pro 订阅、积分抵扣与支付方式说明。",
+};
+
+const TELEGRAM_GROUP_URL = String(
+ process.env.NEXT_PUBLIC_TELEGRAM_GROUP_URL ||
+ "https://t.me/+nMG7SjziUKYyZmM1",
+).trim();
+
+const FAQ_ITEMS = [
+ {
+ q: "Pro 包含哪些功能?",
+ a: "开通后可解锁:今日日内深度分析(含高温时段)、历史对账 + 未来日期分析、全平台智能气象推送。",
+ },
+ {
+ q: "当前订阅价格是多少?",
+ a: "目前仅提供月付:5 USDC / 30 天。",
+ },
+ {
+ q: "积分如何抵扣?",
+ a: "满 500 积分起兑,每 500 积分抵 1U,单次最多抵 3U。",
+ },
+ {
+ q: "支持哪些钱包和支付方式?",
+ a: "支持 EVM 浏览器钱包(MetaMask / OKX / Rabby / Bitget 等)及 WalletConnect 扫码钱包(Trust Wallet / Binance Web3 Wallet / TokenPocket 等)。",
+ },
+];
+
+export default function SubscriptionHelpPage() {
+ return (
+
+
+
+
+ 返回账户中心
+
+
+
+
+
+
PolyWeather Pro 订阅说明
+
+
+ 这里是完整的订阅规则和支付说明。你可以先在页面内绑定钱包,再直接开通 Pro。
+
+
+
+
+
+
+ 订阅价格
+
+
5 USDC / 30 天
+
+
+
+
+
+ 社群积分
+
+
+ 加入社群即可赚取积分
+
+
+
+
+
+
+ 常见问题
+
+ {FAQ_ITEMS.map((item) => (
+
+
+
+ {item.q}
+
+ {item.a}
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/frontend/components/account/AccountCenter.tsx b/frontend/components/account/AccountCenter.tsx
index 4437b668..a123b58f 100644
--- a/frontend/components/account/AccountCenter.tsx
+++ b/frontend/components/account/AccountCenter.tsx
@@ -158,6 +158,11 @@ const WALLETCONNECT_POLYGON_RPC_URL = String(
process.env.NEXT_PUBLIC_WALLETCONNECT_POLYGON_RPC_URL ||
"https://polygon-bor-rpc.publicnode.com",
).trim();
+const TELEGRAM_GROUP_URL = String(
+ process.env.NEXT_PUBLIC_TELEGRAM_GROUP_URL ||
+ "https://t.me/+nMG7SjziUKYyZmM1",
+).trim();
+const SUBSCRIPTION_HELP_HREF = "/subscription-help";
let walletConnectProviderCache: EvmProvider | null = null;
let walletConnectProviderChainId: number | null = null;
@@ -1578,7 +1583,8 @@ export function AccountCenter() {
txHash={lastTxHash || undefined}
chainId={paymentConfig?.chain_id || 137}
paymentTokenLabel={selectedTokenLabel}
- faqHref="/account"
+ faqHref={SUBSCRIPTION_HELP_HREF}
+ telegramGroupUrl={TELEGRAM_GROUP_URL}
/>
)}
diff --git a/frontend/components/dashboard/ProFeaturePaywall.tsx b/frontend/components/dashboard/ProFeaturePaywall.tsx
index e11d6921..d8b6c2b3 100644
--- a/frontend/components/dashboard/ProFeaturePaywall.tsx
+++ b/frontend/components/dashboard/ProFeaturePaywall.tsx
@@ -6,6 +6,12 @@ import { useI18n } from "@/hooks/useI18n";
import { useDashboardStore } from "@/hooks/useDashboardStore";
import { UnlockProOverlay } from "@/components/subscription/UnlockProOverlay";
+const TELEGRAM_GROUP_URL = String(
+ process.env.NEXT_PUBLIC_TELEGRAM_GROUP_URL ||
+ "https://t.me/+nMG7SjziUKYyZmM1",
+).trim();
+const SUBSCRIPTION_HELP_HREF = "/subscription-help";
+
type ProFeaturePaywallProps = {
feature: "today" | "history" | "future";
onClose?: () => void;
@@ -75,8 +81,8 @@ export function ProFeaturePaywall({
router.push("/account");
}}
payLabel={payLabel}
- faqHref="/account"
- telegramGroupUrl="https://t.me/+nMG7SjziUKYyZmM1"
+ faqHref={SUBSCRIPTION_HELP_HREF}
+ telegramGroupUrl={TELEGRAM_GROUP_URL}
/>
);
diff --git a/frontend/components/subscription/UnlockProOverlay.tsx b/frontend/components/subscription/UnlockProOverlay.tsx
index 8584484e..6cc53198 100644
--- a/frontend/components/subscription/UnlockProOverlay.tsx
+++ b/frontend/components/subscription/UnlockProOverlay.tsx
@@ -21,6 +21,9 @@ import {
} from "lucide-react";
import s from "./UnlockProOverlay.module.css";
+const DEFAULT_FAQ_HREF = "/subscription-help";
+const DEFAULT_TELEGRAM_GROUP_URL = "https://t.me/+nMG7SjziUKYyZmM1";
+
export type UnlockProBilling = {
pointsEnabled: boolean;
isEligible: boolean;
@@ -77,8 +80,8 @@ export function UnlockProOverlay({
locale = "zh-CN",
errorText,
infoText,
- faqHref = "/account",
- telegramGroupUrl,
+ faqHref = DEFAULT_FAQ_HREF,
+ telegramGroupUrl = DEFAULT_TELEGRAM_GROUP_URL,
txHash,
chainId = 137,
paymentTokenLabel,
@@ -100,6 +103,7 @@ export function UnlockProOverlay({
const progressPct = billing.pointsEnabled
? Math.min(100, Math.round((points / maxPointsForFullDiscount) * 100))
: 0;
+ const resolvedTelegramGroupUrl = String(telegramGroupUrl || "").trim();
const txHref =
txHash && txHash.startsWith("0x")
? `${chainId === 137 ? "https://polygonscan.com" : "https://etherscan.io"}/tx/${txHash}`
@@ -292,14 +296,16 @@ export function UnlockProOverlay({
)}
- {telegramGroupUrl ? (
+ {resolvedTelegramGroupUrl ? (
- {isEn ? "Join Telegram to earn" : "加入电报群赚取积分"}
+ {isEn
+ ? "Join community to earn points"
+ : "加入社群即可赚取积分"}
) : (