Production polish: i18n shelved, PWA icons, SEO/GEO cleanup, UX fixes

Big-picture changes since 01be8e7:

New routes — /trump /btc /kol /trades /analytics /archive plus four
SEO landing pages (/methodology /glossary /case-studies /contact),
all served under /[locale]. Each has dedicated metadata + JSON-LD.

KOL page (new) — DigestWidget + OnchainWidget + TalkVsTradesWidget,
filter by handle/ticker, click-through to per-post detail with the
original AI-extracted ticker/conviction/quote.

BTC page (new) — tabbed: macro-bottom (AHR999 + 200WMA + Pi Cycle)
and funding-rate reversal, with live sparkline + threshold bands.

Telegram card on Settings — wallet-link code generation, status,
disconnect. Preferences moved into the bot itself (/trump /btc etc.)
so the card stays minimal.

SignalMonitor (new) — ETH/LINK Bollinger breakout monitor in its own
component, shares the singleton WsProvider so no second WS opens.

WS singleton refactor (lib/wsContext) — shared WsProvider + useWsSubscribe
hook. Cleanup now actively closes the socket on unmount; previously the
local `ws` couldn't be reached from cleanup and leaked one connection
per StrictMode remount.

OpenPositions polling no longer pops MetaMask in the background —
splits into load('first') for user-initiated and load('poll') that
uses getCachedViewEnvelope without signing.

i18n shelved — proxy.ts (Next 16 middleware rename) wires next-intl
but only Navbar + layout footer have translations. Rest of UI used
isZh ternary scattered across 28 files. All `const isZh = locale === 'zh'`
flipped to `const isZh = false` so every site renders English; Chinese
branches kept as dead code so revival is one regex away.
LanguageSwitch hidden but file kept. zh-CN hreflang removed from
metadata + sitemap to avoid duplicate-content penalties.

Wallet error handling — lib/walletError.ts: isUserRejection walks EIP-1193
code 4001 + .cause chain; previous string-match for "reject"/"denied"
broke for users running MetaMask in non-English UIs. 12 call sites
migrated across 5 components.

PWA icons — app/icon.tsx + app/apple-icon.tsx render the brand "α" via
Next's ImageResponse so no static PNG asset is required. manifest.ts
references /icon and /apple-icon dynamic routes.

OG image + sitemap + robots — dynamic 1200×630 OG card; robots blocks
both /en/settings and /zh/settings; sitemap only emits /en routes;
JSON-LD covers SoftwareApplication + Organization + 10-Q FAQPage.

Landing page polish — Launch Dashboard button stripped of magnetic
hover + shimmer + lift + glow expansion (multiple users found it busy);
hero scramble alphabet swapped to alphanumeric (was block characters);
"15 KOL feeds" copy updated to 19 in 5 places.

PostCards source icons — new entries for btc_bottom_reversal,
funding_reversal, kol_divergence so they no longer fall through to
the generic "first letter" fallback.

Archive page filter — excludes funding_reversal + kol_divergence
(previously only excluded truth + btc_bottom_reversal so new live
signals leaked into the legacy archive).

Cache + skeleton loading — lib/cache.ts SWR module with per-key TTL,
applied across the major pages so navigation feels instant.

SignConfirmSheet — 4 hardcoded Chinese strings translated to English
(English users were seeing zh-only "需要钱包签名" etc).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
k
2026-05-25 00:53:27 +08:00
parent 01be8e790b
commit d72323b1c6
67 changed files with 11735 additions and 2530 deletions
+425
View File
@@ -0,0 +1,425 @@
import type { Metadata } from 'next'
import Link from 'next/link'
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://trumpsignal.com'
interface CaseStudy {
id: string
date: string
source: string
title: string
summary: string
signal: 'LONG' | 'SHORT' | 'DIVERGENCE'
asset: string
priceImpact: string
impactWindow: string
detail: string
evidence: string
externalUrl?: string
}
type CaseStudiesCopy = {
title: string
description: string
keywords: string[]
ogTitle: string
ogDescription: string
heroTitle: string
heroSubtitle: string
intro: string
statAsset: string
statImpact: string
statWindow: string
evidenceLabel: string
footer: string
footerMethodology: string
footerGlossary: string
cases: CaseStudy[]
}
function getCopy(locale: string): CaseStudiesCopy {
const isZh = false // i18n shelved — Chinese branches kept as dead code for future revival; see messages/zh.json
if (isZh) {
return {
title: '案例研究 - Trump Alpha',
description:
'整理 Trump Truth Social 帖子如何影响比特币与加密市场的公开案例,包括战略储备公告、链上大额抢跑交易、风险偏好切换以及 KOL 言行偏离样本。',
keywords: [
'Trump 加密市场影响',
'Truth Social 比特币',
'Trump 帖子行情',
'加密市场案例研究',
'KOL 言行偏离案例',
'BTC 底部案例',
],
ogTitle: 'Case Studies | Trump Alpha',
ogDescription:
'记录过往真正推动市场的帖子、仓位和链上证据,解释这些信号为什么值得跟踪。',
heroTitle: '案例研究',
heroSubtitle: '把历史上真正推动市场的帖子、仓位和价格反应摊开来看',
intro:
'这不是收益展示页,而是证据页。每个案例都尽量回答三个问题:发生了什么、市场怎么动、为什么这件事支持某个信号引擎的存在。',
statAsset: '资产',
statImpact: '价格影响',
statWindow: '观察窗口',
evidenceLabel: '证据',
footer: '这些案例用于说明信号背后的历史依据,不构成前瞻性收益承诺。',
footerMethodology: '方法论',
footerGlossary: '术语表',
cases: [
{
id: 'strategic-reserve-2025',
date: '2025 年 3 月 2 日',
source: 'Trump Truth Social',
title: '美国“战略加密储备”表态',
summary: 'Trump 在 Truth Social 上确认美国战略加密储备将涵盖 BTC、ETH、SOL、XRP 和 ADA。',
signal: 'LONG',
asset: 'BTC / ETH',
priceImpact: 'BTC +8.2%ETH +10%+',
impactWindow: '24 小时',
detail:
'这条帖子之所以重要,不只是因为点名了多个资产,而是因为它把“政府政策支持”从模糊口风变成了明确承诺。Trump Alpha 的语义引擎会把这种带有具体资产清单和国家层面措辞的内容识别为高置信度 LONG 事件。',
evidence:
'CNBC 和 Al Jazeera 均报道了该消息后的市场反应。链上和交易所数据也出现了明显的动量资金流入。',
externalUrl:
'https://www.cnbc.com/2025/03/02/trump-announces-strategic-crypto-reserve-including-bitcoin-solana-xrp-and-more.html',
},
{
id: 'whale-6m-perp',
date: '2025 年 3 月',
source: '链上 / Truth Social',
title: '战略储备帖子前后出现 680 万美元抢跑收益',
summary:
'一只匿名地址在战略储备帖子发布前后快速建立 50 倍 BTC/ETH 杠杆仓位,并在当天平仓,获利约 680 万美元。',
signal: 'LONG',
asset: 'BTC',
priceImpact: '+680 万美元',
impactWindow: '当日',
detail:
'这个案例说明了两件事:第一,Trump 帖子确实能形成足够大的短线价格冲击;第二,在这种事件中,反应速度本身就是边际优势。无论这笔交易是抢跑还是极快的自动化反应,它都证明了“帖子 -> 交易 -> 盈亏”链条是真实存在的。',
evidence:
'Raw Story / NewsBreak 对这笔交易做了记录,TIME 也提到相关监管层面的质疑与讨论。',
externalUrl:
'https://www.newsbreak.com/raw-story-2096750/4286876592634-that-s-the-maga-playbook-crypto-trade-made-moments-before-trump-post-raises-eyebrows',
},
{
id: 'tariff-china-2025',
date: '2025 年 4 月',
source: 'Trump Truth Social',
title: '关税升级帖子引发风险偏好下移',
summary: 'Trump 发文谈及对中国加征大规模关税,这类表态通常被市场解读为短线 risk-off。',
signal: 'SHORT',
asset: 'BTC',
priceImpact: 'BTC -4.1%',
impactWindow: '4 小时',
detail:
'并不是每条 Trump 帖子都偏利多。带有贸易摩擦、关税升级、监管收紧或避险语义的内容,往往会压缩风险资产偏好。这个案例支持了信号系统中 SHORT 方向存在的必要性。',
evidence:
'CoinDesk 曾整理过多次 Trump 发言影响 BTC 的案例,这次关税语境下的风险偏好回落与其历史模式一致。',
externalUrl:
'https://www.coindesk.com/markets/2026/04/20/five-times-president-trump-made-a-statement-that-moved-bitcoin-and-why-it-might-happen-again-this-week',
},
{
id: 'kol-divergence-example',
date: '示意型复合案例',
source: 'KOL 文章 + 链上地址',
title: '公开看多 ETH,但钱包在减仓',
summary:
'某位被追踪的 KOL 发布看多 ETH 的长文,随后 5 天内其钱包减少约 18 万美元 ETH 仓位,构成典型言行偏离。',
signal: 'DIVERGENCE',
asset: 'ETH',
priceImpact: 'N/A',
impactWindow: '±7 天',
detail:
'这个案例不是在讲单条帖子多会拉盘,而是在讲“公开叙事”和“真实仓位”可能不是一回事。对于研究型用户,这类偏离通常比单纯看多或看空更有信息增量。',
evidence:
'言行偏离的判定逻辑来自平台内部交叉信号系统,方法在 Methodology 页面有完整说明。',
},
{
id: 'btc-bottom-nov-2022',
date: '2022 年 11 月',
source: '历史 BTC 周期底部参考',
title: 'FTX 崩盘后的 1.55 万美元区域',
summary:
'FTX 事件后 BTC 跌入约 1.55 万美元区域,随后在 18 个月内回升至 6.9 万美元附近。这是 BTC 周期底部系统试图捕捉的环境类型。',
signal: 'LONG',
asset: 'BTC',
priceImpact: '+345%',
impactWindow: '18 个月',
detail:
'当前线上 BTC 系统并不是去回放旧版链上触发器,而是用 AHR999、200 周均线和 Pi Cycle Bottom 去逼近同一种市场结构:深度杀估值、长期趋势支撑和长期情绪出清同时出现。',
evidence:
'公开历史行情和长期图表都把 FTX 洗盘区间视为该轮熊市的底部核心区域。',
},
],
}
}
return {
title: 'Case Studies — Documented Trump Posts That Moved Crypto',
description:
'Documented cases where Trump Truth Social posts, KOL positioning, or macro-bottom conditions moved Bitcoin and crypto markets. Includes price impact, timing, and evidence.',
keywords: [
'Trump crypto market impact',
'Trump Truth Social Bitcoin',
'crypto market moving events',
'Trump BTC trade case study',
'KOL divergence example',
'Bitcoin macro bottom case study',
],
ogTitle: 'Case Studies | Trump Alpha',
ogDescription:
'Historical cases that show why the Trump, BTC, and KOL engines exist: posts, wallet behavior, price reaction, and evidence.',
heroTitle: 'Case Studies',
heroSubtitle: 'Real posts, real positioning, and real market reactions worth studying',
intro:
'This is not a performance-claims page. It is an evidence page. Each case is here to answer three questions: what happened, how the market reacted, and why that event supports the existence of a specific signal engine.',
statAsset: 'Asset',
statImpact: 'Price impact',
statWindow: 'Window',
evidenceLabel: 'Evidence',
footer: 'These cases illustrate the historical basis of the signal stack. They are not forward-looking return promises.',
footerMethodology: 'Methodology',
footerGlossary: 'Glossary',
cases: [
{
id: 'strategic-reserve-2025',
date: 'March 2, 2025',
source: 'Trump Truth Social',
title: 'Strategic Crypto Reserve announcement',
summary: 'Trump confirmed a U.S. Strategic Crypto Reserve including BTC, ETH, SOL, XRP, and ADA.',
signal: 'LONG',
asset: 'BTC / ETH',
priceImpact: 'BTC +8.2%, ETH +10%+',
impactWindow: '24 hours',
detail:
'This case mattered because the post moved from vague political tone into explicit asset-level policy language. A signal engine should classify that as a high-conviction LONG event, because it names specific assets and ties them to a state-level commitment.',
evidence:
'CNBC and Al Jazeera both documented the market response, and exchange plus on-chain data showed clear momentum-driven inflows after the post.',
externalUrl:
'https://www.cnbc.com/2025/03/02/trump-announces-strategic-crypto-reserve-including-bitcoin-solana-xrp-and-more.html',
},
{
id: 'whale-6m-perp',
date: 'March 2025',
source: 'On-chain / Truth Social',
title: '$6.8M pre-positioning profit around the reserve post',
summary:
'An anonymous address built a large leveraged BTC/ETH position around the reserve announcement and reportedly closed it the same day for roughly $6.8M profit.',
signal: 'LONG',
asset: 'BTC',
priceImpact: '+$6.8M',
impactWindow: 'Same day',
detail:
'This case highlights two facts at once. First, Trump-linked posts can create enough directional force to matter. Second, speed itself is edge in event-driven trading. Whether this was advance positioning or ultra-fast automation, it validates the post-to-trade-to-PnL chain.',
evidence:
'The trade was documented by Raw Story / NewsBreak, and TIME later referenced the political and regulatory scrutiny around the episode.',
externalUrl:
'https://www.newsbreak.com/raw-story-2096750/4286876592634-that-s-the-maga-playbook-crypto-trade-made-moments-before-trump-post-raises-eyebrows',
},
{
id: 'tariff-china-2025',
date: 'April 2025',
source: 'Trump Truth Social',
title: 'Tariff escalation post triggered a risk-off move',
summary: 'A tariff-escalation post created a short-term macro risk-off setup rather than a bullish crypto reaction.',
signal: 'SHORT',
asset: 'BTC',
priceImpact: 'BTC -4.1%',
impactWindow: '4 hours',
detail:
'Not every Trump post is bullish for crypto. Posts framed around trade conflict, tariff escalation, tighter regulation, or macro uncertainty can compress risk appetite quickly. This case supports the need for a real SHORT branch in the signal engine.',
evidence:
'CoinDesk has documented multiple instances of Trump statements moving BTC. This post fits that broader historical pattern of immediate sentiment repricing.',
externalUrl:
'https://www.coindesk.com/markets/2026/04/20/five-times-president-trump-made-a-statement-that-moved-bitcoin-and-why-it-might-happen-again-this-week',
},
{
id: 'kol-divergence-example',
date: 'Illustrative composite',
source: 'KOL post + on-chain wallet',
title: 'Publicly bullish on ETH, privately reducing ETH',
summary:
'A tracked KOL published a bullish ETH thesis, then reduced roughly $180k of ETH exposure within five days. That is classic talks-vs-trades divergence.',
signal: 'DIVERGENCE',
asset: 'ETH',
priceImpact: 'N/A',
impactWindow: '±7 days',
detail:
'This example is not about a single post moving price. It is about the information gap between public narrative and real positioning. For research-heavy users, that gap is often more valuable than a simple bullish or bearish statement.',
evidence:
'The divergence classification comes from the platforms cross-signal logic, which is documented in full on the Methodology page.',
},
{
id: 'btc-bottom-nov-2022',
date: 'November 2022',
source: 'Historical BTC macro-bottom reference',
title: 'The $15.5k FTX washout zone',
summary:
'After the FTX collapse, BTC entered the $15.5k region and later recovered toward $69k within roughly 18 months. This is the kind of regime the BTC macro-bottom engine is built to identify.',
signal: 'LONG',
asset: 'BTC',
priceImpact: '+345%',
impactWindow: '18 months',
detail:
'The current live BTC engine is not trying to replay an old premium-data model. It is trying to locate the same market structure with AHR999, the 200-week moving average, and Pi Cycle Bottom: deep value, long-cycle support, and emotional washout lining up together.',
evidence:
'Public price archives and long-range market charts consistently mark the FTX washout zone as the core bottom region of that bear market.',
},
],
}
}
export function generateMetadata({
params: { locale },
}: {
params: { locale: string }
}): Metadata {
const copy = getCopy(locale)
return {
title: copy.title,
description: copy.description,
keywords: copy.keywords,
openGraph: {
title: copy.ogTitle,
description: copy.ogDescription,
},
alternates: {
canonical: `${siteUrl}/${locale}/case-studies`,
languages: {
en: `${siteUrl}/en/case-studies`,
'x-default': `${siteUrl}/en/case-studies`,
},
},
}
}
const SIGNAL_COLOR: Record<string, string> = {
LONG: '#22c55e',
SHORT: '#ef4444',
DIVERGENCE: '#f5a524',
}
export default function CaseStudiesPage({ params: { locale } }: { params: { locale: string } }) {
const copy = getCopy(locale)
const isZh = false // i18n shelved — Chinese branches kept as dead code for future revival; see messages/zh.json
return (
<div className="page" style={{ maxWidth: 780 }}>
<div className="page-head">
<div>
<h1 className="page-title">{copy.heroTitle}</h1>
<p className="page-sub">{copy.heroSubtitle}</p>
</div>
</div>
<p style={{
fontSize: 13, color: 'var(--ink-3)', lineHeight: 1.7,
marginBottom: 24, fontStyle: 'italic',
}}>
{copy.intro}
</p>
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
{copy.cases.map((c) => (
<article
key={c.id}
className="card"
style={{ padding: '24px 28px' }}
itemScope
itemType="https://schema.org/Article"
>
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>
<span style={{
fontSize: 10, fontWeight: 700, letterSpacing: '0.07em',
textTransform: 'uppercase', fontFamily: 'monospace',
padding: '4px 10px', borderRadius: 4, flexShrink: 0,
background: `color-mix(in srgb, ${SIGNAL_COLOR[c.signal]} 14%, transparent)`,
color: SIGNAL_COLOR[c.signal],
border: `1px solid color-mix(in srgb, ${SIGNAL_COLOR[c.signal]} 30%, transparent)`,
}}>
{c.signal}
</span>
<span style={{ fontSize: 12, color: 'var(--ink-4)', fontFamily: 'monospace', flexShrink: 0 }}>
{c.date}
</span>
<span style={{
fontSize: 11, color: 'var(--ink-4)', padding: '4px 8px',
background: 'var(--bg-sunk)', borderRadius: 4, flexShrink: 0,
}}>
{c.source}
</span>
</div>
<h2
itemProp="headline"
style={{ fontSize: 17, fontWeight: 700, color: 'var(--ink)', margin: '0 0 8px', lineHeight: 1.3 }}
>
{c.title}
</h2>
<p style={{ fontSize: 14, color: 'var(--ink-2)', lineHeight: 1.6, margin: '0 0 16px' }}>
{c.summary}
</p>
<div style={{
display: 'flex', gap: 0, marginBottom: 16, flexWrap: 'wrap',
border: '1px solid var(--line)', borderRadius: 8, overflow: 'hidden',
}}>
{[
{ k: copy.statAsset, v: c.asset },
{ k: copy.statImpact, v: c.priceImpact },
{ k: copy.statWindow, v: c.impactWindow },
].map(({ k, v }, i) => (
<div key={k} style={{
flex: '1 1 120px', padding: '10px 16px',
borderRight: i < 2 ? '1px solid var(--line)' : 'none',
background: 'var(--bg-sunk)',
}}>
<div style={{ fontSize: 10, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em', fontFamily: 'monospace', marginBottom: 4 }}>{k}</div>
<div style={{ fontSize: 14, fontWeight: 700, color: 'var(--ink)', fontFamily: 'monospace' }}>{v}</div>
</div>
))}
</div>
<p itemProp="description" style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.7, margin: '0 0 12px' }}>
{c.detail}
</p>
<p style={{
fontSize: 12, color: 'var(--ink-3)', lineHeight: 1.65,
margin: 0, paddingLeft: 12,
borderLeft: '2px solid var(--line-2)',
}}>
<strong>{copy.evidenceLabel}:</strong> {c.evidence}
{c.externalUrl && (
<> {' '}
<a
href={c.externalUrl}
target="_blank"
rel="noopener noreferrer"
style={{ color: 'var(--amber)', textDecoration: 'none' }}
>
{isZh ? '来源 ↗' : 'Source ↗'}
</a>
</>
)}
</p>
</article>
))}
</div>
<div className="card" style={{ padding: '20px 24px', marginTop: 12 }}>
<p style={{ fontSize: 13, color: 'var(--ink-4)', lineHeight: 1.6, margin: 0 }}>
{copy.footer}{' '}
{isZh ? '另见:' : 'See also:'}{' '}
<Link href={`/${locale}/methodology`} style={{ color: 'var(--amber)' }}>{copy.footerMethodology}</Link>
{' '}·{' '}
<Link href={`/${locale}/glossary`} style={{ color: 'var(--amber)' }}>{copy.footerGlossary}</Link>.
</p>
</div>
</div>
)
}