重构首页为机构落地页,新增终端路由,时区感知 Polymarket 市场发现

This commit is contained in:
2569718930@qq.com
2026-05-25 00:16:53 +08:00
parent 45e9c28437
commit e4d123d94d
23 changed files with 1232 additions and 623 deletions
+13 -1
View File
@@ -4,7 +4,19 @@ import { useEffect } from "react";
export function RegisterSW() {
useEffect(() => {
if ("serviceWorker" in navigator) {
if (process.env.NODE_ENV !== "production") {
if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
navigator.serviceWorker
.getRegistrations()
.then((registrations) =>
Promise.all(registrations.map((registration) => registration.unregister())),
)
.catch(() => {});
}
return;
}
if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
navigator.serviceWorker.register("/sw.js").catch(() => {});
}
}, []);
File diff suppressed because it is too large Load Diff
@@ -102,12 +102,12 @@ export function AiPinnedForecastView({
<div className="scan-ai-workspace empty">
<div className="scan-empty-state">
<div className="scan-empty-title">
{isEn ? "Click a city on the map" : "从分布视图点击城市"}
{isEn ? "Select a city from the market list" : "从市场列表选择城市"}
</div>
<div className="scan-empty-copy">
{isEn
? "Selected cities will appear here as deep analysis blocks."
: "被点击的城市会加入深度分析页,并保留为城市分析区块。"}
: "选中的城市会加入深度分析页,并保留为城市分析区块。"}
</div>
</div>
</div>
@@ -127,8 +127,8 @@ export function AiPinnedForecastView({
</div>
<p>
{isEn
? "Map clicks add cities here. City analysis stays here until you remove it."
: "地图点击会把城市加入这里;城市分析会保留,直到你手动移除。"}
? "Market-list selections add cities here. City analysis stays here until you remove it."
: "市场列表选择会把城市加入这里;城市分析会保留,直到你手动移除。"}
</p>
</div>
<div className="scan-ai-city-jumpbar" aria-label={isEn ? "Selected city shortcuts" : "已选城市快捷跳转"}>
@@ -3,12 +3,12 @@
import clsx from "clsx";
import Link from "next/link";
import type { Dispatch, SetStateAction } from "react";
import { LogIn, MessageCircle, Moon, Sun, UserRound } from "lucide-react";
import { LogIn, UserRound } from "lucide-react";
import { ProFeaturePaywall } from "@/components/dashboard/ProFeaturePaywall";
import { LoadingSignal } from "@/components/dashboard/scan-terminal/LoadingSignal";
import type { Locale } from "@/lib/i18n";
export type ScanTerminalContentView = "city-list" | "analysis" | "map";
export type ScanTerminalContentView = "city-list" | "analysis";
type ThemeMode = "dark" | "light";
@@ -34,8 +34,8 @@ export function ScanTerminalLoadingScreen({
</strong>
<span>
{isEn
? "Start from the map, then open city cards to verify weather evidence"
: "从地图选城市,再打开决策卡验证天气证据"}
? "Loading paid decision cards, city evidence, and market signals"
: "正在加载付费决策卡、城市证据和市场信号"}
</span>
</div>
<div className="scan-topbar-actions">
@@ -91,8 +91,8 @@ export function ScanTerminalTopBar({
</strong>
<span>
{isEn
? "Start from the map, then open city cards to verify weather evidence"
: "从地图选城市,再打开决策卡验证天气证据"}
? "Paid workspace for city evidence, model signals, and weather-market decisions"
: "面向付费用户的城市证据、模型信号与天气市场决策工作区"}
</span>
</div>
<div className="scan-topbar-actions">
@@ -37,6 +37,9 @@ export function useScanTerminalQuery({
showLoading?: boolean;
} = {}) => {
if (proAccessLoading || !isPro) return;
if (typeof fetch !== "function" || typeof AbortController === "undefined") {
return;
}
if (forceRefresh) {
lastForcedScanRefreshAtRef.current = Date.now();
}
@@ -75,6 +78,13 @@ export function useScanTerminalQuery({
useEffect(() => {
if (proAccessLoading || !isPro) return;
if (
typeof window === "undefined" ||
typeof window.setInterval !== "function" ||
typeof window.clearInterval !== "function"
) {
return;
}
const intervalId = window.setInterval(() => {
if (
!shouldRunAutoTerminalRefresh({
@@ -10,6 +10,13 @@ export function useUserLocalClock() {
useEffect(() => {
setUserLocalTime(formatUserLocalTime());
if (
typeof window === "undefined" ||
typeof window.setInterval !== "function" ||
typeof window.clearInterval !== "function"
) {
return;
}
const intervalId = window.setInterval(() => {
setUserLocalTime(formatUserLocalTime());
}, 10_000);