- {[
- "Atmos Capital",
- "Celerity Risk",
- "Metis Trading",
- "Aviation Hedge",
- ].map((name) => (
-
- {name}
-
- ))}
+ {/* Sleek Terminal Preview Widget */}
+
+
+
+
+
+ {isEn ? "Runway 02L Settlement" : "跑道 02L 官方结算"}
+
+
+
LIVE
+
+
+
+
+ {isEn ? "Current Temp:" : "当前气温:"}
+ 28.8°C
+
+
+ {isEn ? "UMA Threshold:" : "UMA 结算阈值:"}
+ 30.0°C
+
+
+ {isEn ? "Model Probability:" : "模型预测概率:"}
+ 88.5%
+
+
+ {isEn ? "Market Price:" : "市场买卖价差:"}
+ $10.00
-
-
⭐⭐⭐⭐⭐
-
4.9 out of 5 stars (G2 rating)
+ {/* Sparkline visualization */}
+
+
+ {[30, 45, 38, 52, 68, 85, 78, 92, 88].map((h, i) => (
+
+ ))}
+
diff --git a/frontend/components/dashboard/ScanTerminalDashboard.tsx b/frontend/components/dashboard/ScanTerminalDashboard.tsx
index 4e25a356..19e52035 100644
--- a/frontend/components/dashboard/ScanTerminalDashboard.tsx
+++ b/frontend/components/dashboard/ScanTerminalDashboard.tsx
@@ -936,47 +936,6 @@ function ScanTerminalScreen() {
);
const generatedText = useRelativeTime(terminalData?.generated_at ?? null);
- const refreshAuth = useCallback(() => {
- fetch("/api/auth/me", {
- cache: "no-store",
- headers: { Accept: "application/json" },
- })
- .then(async (response) => {
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
- return response.json() as Promise<{
- authenticated?: boolean;
- user_id?: string | null;
- subscription_active?: boolean | null;
- subscription_plan_code?: string | null;
- subscription_expires_at?: string | null;
- subscription_total_expires_at?: string | null;
- subscription_queued_days?: number | null;
- points?: number | null;
- }>;
- })
- .then((payload) => {
- setProAccess({
- loading: false,
- authenticated: Boolean(payload.authenticated),
- userId: payload.user_id ?? null,
- subscriptionActive: payload.subscription_active === true,
- subscriptionPlanCode: payload.subscription_plan_code ?? null,
- subscriptionExpiresAt: payload.subscription_expires_at ?? null,
- subscriptionTotalExpiresAt:
- payload.subscription_total_expires_at ??
- payload.subscription_expires_at ??
- null,
- subscriptionQueuedDays: Math.max(
- 0,
- Number(payload.subscription_queued_days ?? 0),
- ),
- points: Number(payload.points ?? 0),
- error: null,
- });
- })
- .catch(() => {}); // keep current state on error
- }, []);
-
if (!hydrated || (proAccess.loading && !canUseLocalFullAccess)) {
return (
);
diff --git a/frontend/components/dashboard/scan-terminal/ProductAccessRequired.tsx b/frontend/components/dashboard/scan-terminal/ProductAccessRequired.tsx
index fa2546a5..454be7f3 100644
--- a/frontend/components/dashboard/scan-terminal/ProductAccessRequired.tsx
+++ b/frontend/components/dashboard/scan-terminal/ProductAccessRequired.tsx
@@ -1,10 +1,7 @@
"use client";
-import { useState } from "react";
import Link from "next/link";
import { LockKeyhole, CreditCard, LogIn } from "lucide-react";
-import { UnlockProOverlay } from "@/components/subscription/UnlockProOverlay";
-import { useTerminalPay } from "@/components/subscription/useTerminalPay";
const ACCESS_TERM = {
signInToContinue: { en: "Sign in to continue", zh: "请先登录" },
@@ -19,42 +16,7 @@ function t(key: keyof typeof ACCESS_TERM, isEn: boolean) {
}
// ─── Layer 2: Authenticated but no active subscription ───────────────────────
-function SubscriptionGate({
- isEn,
- points,
- onPaid,
-}: {
- isEn: boolean;
- points: number;
- onPaid: () => void;
-}) {
- const [showOverlay, setShowOverlay] = useState(false);
- const {
- billing,
- usePoints,
- setUsePoints,
- payBusy,
- errorText,
- infoText,
- txHash,
- chainId,
- tokenSymbol,
- walletAddress,
- handlePay,
- } = useTerminalPay({
- points,
- planPriceUsd: 10,
- onPaid: () => {
- setShowOverlay(false);
- onPaid();
- },
- isEn,
- });
-
- const handleSubscribeClick = () => {
- setShowOverlay(true);
- };
-
+function SubscriptionGate({ isEn }: { isEn: boolean }) {
const features = isEn
? [
"Real-time METAR observations across 500+ stations",
@@ -72,7 +34,6 @@ function SubscriptionGate({
return (
- {/* Header badge */}
@@ -80,9 +41,7 @@ function SubscriptionGate({
- {/* Main card */}
- {/* Card top band */}
{isEn
@@ -97,7 +56,6 @@ function SubscriptionGate({
- {/* Price */}
$10
@@ -105,7 +63,6 @@ function SubscriptionGate({
- {/* Feature list */}
{features.map((f) => (
-
@@ -119,15 +76,13 @@ function SubscriptionGate({
))}
- {/* CTA */}
-
+
{isEn
@@ -137,7 +92,6 @@ function SubscriptionGate({
- {/* Back link */}
-
- {/* Payment overlay */}
- {showOverlay && (
-
- setUsePoints((prev) => !prev)}
- onPay={() => void handlePay()}
- onClose={() => setShowOverlay(false)}
- payBusy={payBusy}
- payLabel={
- walletAddress
- ? isEn
- ? "Subscribe & Activate"
- : "立即订阅并激活服务"
- : isEn
- ? "Connect Wallet & Subscribe"
- : "连接钱包并订阅"
- }
- errorText={errorText || undefined}
- infoText={infoText || undefined}
- txHash={txHash || undefined}
- chainId={chainId}
- paymentTokenLabel={tokenSymbol}
- locale={isEn ? "en-US" : "zh-CN"}
- faqHref="/subscription-help"
- />
-
- )}
);
}
@@ -241,18 +163,13 @@ function UnauthenticatedGate({
);
}
-/** Unified access gate — routes to the correct layer based on auth state */
export function ProductAccessRequired({
isAuthenticated,
isEn,
- points,
- onPaid,
userLocalTime,
}: {
isAuthenticated: boolean;
isEn: boolean;
- points: number;
- onPaid: () => void;
userLocalTime: string;
}) {
if (!isAuthenticated) {
@@ -269,7 +186,7 @@ export function ProductAccessRequired({
{userLocalTime}
-
+
);
diff --git a/frontend/components/subscription/useTerminalPay.ts b/frontend/components/subscription/useTerminalPay.ts
deleted file mode 100644
index f0452cce..00000000
--- a/frontend/components/subscription/useTerminalPay.ts
+++ /dev/null
@@ -1,418 +0,0 @@
-"use client";
-
-import { useCallback, useEffect, useMemo, useState } from "react";
-import type { UnlockProBilling } from "@/components/subscription/UnlockProOverlay";
-import { computeBilling } from "@/lib/billing-utils";
-import {
- WALLETCONNECT_POLYGON_RPC_URL,
- WALLET_TRANSACTION_REQUEST_TIMEOUT_MS,
-} from "@/components/account/constants";
-import {
- buildAllowanceCalldata,
- buildApproveCalldata,
- buildBalanceOfCalldata,
- requestWalletWithTimeout,
-} from "@/components/account/payment-utils";
-import { isPaymentHostAllowed, getCurrentPaymentHost } from "@/lib/payment-host";
-import {
- getEvmProvider,
- getEvmWalletLabel,
- getWalletConnectProvider,
-} from "@/components/account/wallet";
-import { getSupabaseBrowserClient } from "@/lib/supabase/client";
-import type { EvmProvider, CreatedIntent } from "@/components/account/types";
-
-const DEFAULT_CHAIN_ID = 137;
-const INTENT_POLL_INTERVAL_MS = 5000;
-const INTENT_POLL_TIMEOUT_MS = 180_000;
-
-function normalizePaymentError(err: unknown, fallback: string): string {
- if (!err) return fallback;
- const e = err as Record