Files
trumpsignal-frontend/components/wallet/MobileWalletSheet.tsx
T
k 4c3c8c6f87 KOL count: 29 → 25 across marketing/SEO copy
Backend KOL_FEEDS trimmed from 29 to 25 (dead feeds removed).
Sync all hardcoded count mentions:
- layout.tsx JSON-LD, page.tsx (metric + comparison + copy)
- kol/page.tsx, KolPageClient.tsx ("and 26 more" → "and 22 more")
- glossary/page.tsx, opengraph-image.tsx
- public/llms.txt, llms-full.txt
- drop removed KOLs (Dragonfly Capital, Nic Carter) from named lists

Bundles other in-flight frontend work already in the working tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 22:55:27 +08:00

190 lines
6.0 KiB
TypeScript

'use client'
/**
* MobileWalletSheet — bottom-drawer shown on mobile when no injected wallet
* is detected. Offers deep links to common mobile wallets so the user can
* open MetaMask (or Trust / Coinbase / OKX) and land directly on this dApp.
*
* Rendered as a fixed overlay + slide-up panel. Backdrop tap dismisses it.
* The CSS animation class `mobile-sheet-enter` is defined in globals.css.
*
* Usage:
* <MobileWalletSheet open={open} onClose={() => setOpen(false)} />
*/
import { useEffect, useState } from 'react'
import { getWalletLinks } from '@/lib/mobileWallet'
import type { WalletLink } from '@/lib/mobileWallet'
interface Props {
open: boolean
onClose: () => void
}
export default function MobileWalletSheet({ open, onClose }: Props) {
const [links, setLinks] = useState<WalletLink[]>([])
// Build deep links client-side only (needs window.location.href).
useEffect(() => {
if (open) {
setLinks(getWalletLinks(window.location.href))
}
}, [open])
// Lock body scroll while sheet is open.
useEffect(() => {
if (open) {
document.body.style.overflow = 'hidden'
return () => { document.body.style.overflow = '' }
}
}, [open])
// Escape key closes.
useEffect(() => {
if (!open) return
function onKey(e: KeyboardEvent) { if (e.key === 'Escape') onClose() }
window.addEventListener('keydown', onKey)
return () => window.removeEventListener('keydown', onKey)
}, [open, onClose])
if (!open) return null
return (
/* Backdrop */
<div
style={{
position: 'fixed', inset: 0, zIndex: 9000,
background: 'rgba(0,0,0,0.55)',
display: 'flex', alignItems: 'flex-end',
backdropFilter: 'blur(4px)',
WebkitBackdropFilter: 'blur(4px)',
}}
onClick={onClose}
aria-modal="true"
role="dialog"
aria-label="Connect a wallet"
>
{/* Sheet */}
<div
className="mobile-sheet-enter"
style={{
width: '100%',
background: 'var(--bg-elev)',
borderRadius: '20px 20px 0 0',
padding: '20px 20px 32px',
boxShadow: '0 -8px 40px rgba(0,0,0,0.18)',
maxHeight: '80vh',
overflowY: 'auto',
}}
onClick={e => e.stopPropagation()}
>
{/* Handle bar */}
<div style={{
width: 40, height: 4,
background: 'var(--line-2)',
borderRadius: 99,
margin: '0 auto 20px',
}} />
{/* Header */}
<div style={{ marginBottom: 20 }}>
<div style={{ fontSize: 18, fontWeight: 700, letterSpacing: '-0.01em', marginBottom: 4 }}>
Connect a wallet
</div>
<div style={{ fontSize: 13, color: 'var(--ink-3)', lineHeight: 1.5 }}>
Open the dApp inside your wallet's built-in browser to connect.
</div>
</div>
{/* Wallet list */}
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
{links.map(link => (
<a
key={link.name}
href={link.href}
target="_blank"
rel="noopener noreferrer"
style={{
display: 'flex',
alignItems: 'center',
gap: 14,
padding: '14px 16px',
borderRadius: 'var(--r-md)',
border: '1px solid var(--line)',
background: 'var(--surface)',
textDecoration: 'none',
color: 'inherit',
transition: 'background 120ms, border-color 120ms',
}}
onTouchStart={e => {
(e.currentTarget as HTMLAnchorElement).style.background = 'var(--bg-sunk)'
}}
onTouchEnd={e => {
(e.currentTarget as HTMLAnchorElement).style.background = 'var(--surface)'
}}
>
{/* Icon */}
<div style={{
width: 44, height: 44,
borderRadius: 12,
background: link.color,
display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: link.abbr.length > 2 ? 12 : 20,
fontWeight: 700,
color: '#fff',
flexShrink: 0,
letterSpacing: '-0.01em',
}}>
{link.abbr}
</div>
{/* Text */}
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ fontSize: 15, fontWeight: 600, marginBottom: 2 }}>{link.name}</div>
<div style={{ fontSize: 12, color: 'var(--ink-3)' }}>{link.hint}</div>
</div>
{/* Arrow */}
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" style={{ color: 'var(--ink-3)', flexShrink: 0 }}>
<path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
</a>
))}
</div>
{/* WalletConnect note */}
<div style={{
marginTop: 18,
padding: '12px 14px',
borderRadius: 'var(--r-sm)',
background: 'var(--bg-sunk)',
fontSize: 12,
color: 'var(--ink-3)',
lineHeight: 1.55,
}}>
<strong style={{ color: 'var(--ink-2)' }}>Already in your wallet's browser?</strong>
{' '}Tap Cancel to dismiss, then use the built-in browser navigation to reload the page MetaMask should auto-detect the dApp.
</div>
{/* Close */}
<button
onClick={onClose}
style={{
marginTop: 14,
width: '100%',
padding: '14px',
borderRadius: 'var(--r-md)',
background: 'var(--bg-sunk)',
border: '1px solid var(--line)',
fontSize: 14,
fontWeight: 500,
color: 'var(--ink-2)',
}}
>
Cancel
</button>
</div>
</div>
)
}