Risk slider: mobile 1-card + RiskCard component + padding tweaks
This commit is contained in:
parent
3c40a655de
commit
54c4aa698b
|
|
@ -161,6 +161,65 @@ const T = {
|
|||
},
|
||||
}
|
||||
|
||||
/* ─── Shared card ───────────────────────────────────────── */
|
||||
function RiskCard({
|
||||
item, cfg, lang, idx, mobile,
|
||||
}: {
|
||||
item: RiskItem
|
||||
cfg: { dot: string; label: string; bg: string }
|
||||
lang: 'fa' | 'en'
|
||||
idx: number
|
||||
mobile?: boolean
|
||||
}) {
|
||||
const text = lang === 'en' && item.quoteEn ? item.quoteEn : item.quote
|
||||
const name = lang === 'en' && item.nameEn ? item.nameEn : item.name
|
||||
const date = lang === 'en' && item.dateEn ? item.dateEn : item.date
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background: 'var(--paper)',
|
||||
border: '1px solid var(--rule-thin)',
|
||||
borderTop: `3px solid ${cfg.dot}`,
|
||||
padding: mobile ? '20px 18px 16px' : '24px 24px 20px',
|
||||
direction: 'rtl',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
animation: `riskCardIn 320ms ${idx * 60}ms ease both`,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 10 }}>
|
||||
<div style={{ width: 7, height: 7, borderRadius: '50%', background: cfg.dot, flexShrink: 0 }} />
|
||||
<span style={{ fontSize: 9, fontWeight: 700, letterSpacing: '2px', textTransform: 'uppercase', color: cfg.dot }}>
|
||||
{cfg.label}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p style={{
|
||||
fontSize: mobile ? 13 : 13,
|
||||
lineHeight: 1.8,
|
||||
color: 'var(--ink-2)',
|
||||
marginBottom: 14,
|
||||
flex: 1,
|
||||
/* on mobile truncate to ~4 lines */
|
||||
...(mobile ? { WebkitLineClamp: 4, WebkitBoxOrient: 'vertical', overflow: 'hidden', display: '-webkit-box' } : {}),
|
||||
}}>
|
||||
{text}
|
||||
</p>
|
||||
|
||||
<div style={{ paddingTop: 12, borderTop: '1px solid var(--rule-thin)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, color: 'var(--ink)' }}>{name}</div>
|
||||
<div style={{ fontSize: 10, color: 'var(--ink-5)' }}>{date}</div>
|
||||
</div>
|
||||
<div style={{ fontSize: 9, fontWeight: 700, letterSpacing: '1px', textTransform: 'uppercase', color: cfg.dot, background: cfg.bg, padding: '4px 10px' }}>
|
||||
{cfg.label}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/* ─── Section ────────────────────────────────────────────── */
|
||||
export default function RiskSection() {
|
||||
const { lang } = useLang()
|
||||
|
|
@ -252,7 +311,7 @@ export default function RiskSection() {
|
|||
{/* ── Slider ── */}
|
||||
<div
|
||||
className="max-w-7xl mx-auto px-12 max-md:px-5"
|
||||
style={{ padding: '28px 48px 48px', position: 'relative' }}
|
||||
style={{ paddingTop: 28, paddingBottom: 48, position: 'relative' }}
|
||||
onMouseEnter={() => setPaused(true)}
|
||||
onMouseLeave={() => setPaused(false)}
|
||||
onTouchStart={e => { touchStartX.current = e.touches[0].clientX }}
|
||||
|
|
@ -261,81 +320,50 @@ export default function RiskSection() {
|
|||
if (Math.abs(dx) > 50) go(dx > 0 ? 'next' : 'prev')
|
||||
}}
|
||||
>
|
||||
{/* Cards row */}
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(3, 1fr)',
|
||||
gap: 16,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
className="max-md:grid-cols-1"
|
||||
>
|
||||
{visibleItems.map((item, idx) => {
|
||||
const cfg = levelCfg[item.level]
|
||||
return (
|
||||
<div
|
||||
key={`${current}-${idx}`}
|
||||
className={idx > 0 ? 'max-md:hidden' : ''}
|
||||
style={{
|
||||
background: 'var(--paper)',
|
||||
border: '1px solid var(--rule-thin)',
|
||||
borderTop: `3px solid ${cfg.dot}`,
|
||||
padding: '24px 24px 20px',
|
||||
direction: 'rtl',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
animation: `riskCardIn 320ms ease both`,
|
||||
animationDelay: `${idx * 60}ms`,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 12 }}>
|
||||
<div style={{ width: 7, height: 7, borderRadius: '50%', background: cfg.dot, flexShrink: 0 }} />
|
||||
<span style={{ fontSize: 9, fontWeight: 700, letterSpacing: '2px', textTransform: 'uppercase', color: cfg.dot }}>
|
||||
{cfg.label}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p style={{ fontSize: 13, lineHeight: 1.85, color: 'var(--ink-2)', fontWeight: 400, marginBottom: 16, flex: 1 }}>
|
||||
{lang === 'en' && item.quoteEn ? item.quoteEn : item.quote}
|
||||
</p>
|
||||
|
||||
<div style={{ paddingTop: 12, borderTop: '1px solid var(--rule-thin)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, color: 'var(--ink)' }}>{lang === 'en' && item.nameEn ? item.nameEn : item.name}</div>
|
||||
<div style={{ fontSize: 10, color: 'var(--ink-5)' }}>{lang === 'en' && item.dateEn ? item.dateEn : item.date}</div>
|
||||
</div>
|
||||
<div style={{ fontSize: 9, fontWeight: 700, letterSpacing: '1px', textTransform: 'uppercase', color: cfg.dot, background: cfg.bg, padding: '4px 10px' }}>
|
||||
{cfg.label}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{/* Desktop: 3 cards */}
|
||||
<div className="hidden md:grid md:grid-cols-3 gap-4">
|
||||
{visibleItems.map((item, idx) => (
|
||||
<RiskCard key={`${current}-${idx}`} item={item} cfg={levelCfg[item.level]} lang={lang} idx={idx} />
|
||||
))}
|
||||
</div>
|
||||
{/* Mobile: 1 card */}
|
||||
<div className="md:hidden">
|
||||
{/* Mobile: single card with slide animation */}
|
||||
<div key={current} style={{ animation: 'riskCardIn 320ms ease both' }}>
|
||||
<RiskCard item={riskItems[current]} cfg={levelCfg[riskItems[current].level]} lang={lang} idx={0} mobile />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Controls */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 24 }}>
|
||||
{/* Dots */}
|
||||
<div style={{ display: 'flex', gap: 6 }}>
|
||||
{/* Progress bar (mobile) + dots (desktop) + arrows */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 20, gap: 12 }}>
|
||||
{/* Progress bar on mobile, dots on desktop */}
|
||||
<div className="md:hidden" style={{ flex: 1, height: 3, background: 'var(--rule-thin)', borderRadius: 2 }}>
|
||||
<div style={{
|
||||
height: '100%', borderRadius: 2,
|
||||
background: 'var(--ink)',
|
||||
width: `${((current + 1) / total) * 100}%`,
|
||||
transition: 'width 300ms ease',
|
||||
}} />
|
||||
</div>
|
||||
<div className="hidden md:flex" style={{ display: 'none', gap: 6 }}>
|
||||
{riskItems.map((_, i) => (
|
||||
<button
|
||||
key={i}
|
||||
onClick={() => { setAnimDir('next'); setCurrent(i) }}
|
||||
style={{
|
||||
width: i === current ? 24 : 8, height: 8,
|
||||
borderRadius: 4, border: 'none', cursor: 'pointer',
|
||||
background: i === current ? 'var(--ink)' : 'var(--rule-thin)',
|
||||
transition: 'all 300ms ease', padding: 0,
|
||||
}}
|
||||
/>
|
||||
<button key={i} onClick={() => setCurrent(i)} style={{
|
||||
width: i === current ? 24 : 8, height: 8, borderRadius: 4,
|
||||
border: 'none', cursor: 'pointer', padding: 0,
|
||||
background: i === current ? 'var(--ink)' : 'var(--rule-thin)',
|
||||
transition: 'all 300ms ease',
|
||||
}} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Counter on mobile */}
|
||||
<span className="md:hidden" style={{ fontSize: 12, color: 'var(--ink-4)', flexShrink: 0 }}>
|
||||
{(current + 1).toLocaleString('fa-IR')} / {total.toLocaleString('fa-IR')}
|
||||
</span>
|
||||
|
||||
{/* Arrows */}
|
||||
<div style={{ display: 'flex', gap: 8 }}>
|
||||
<button
|
||||
onClick={() => go('prev')}
|
||||
<div style={{ display: 'flex', gap: 8, flexShrink: 0 }}>
|
||||
<button onClick={() => go('prev')}
|
||||
style={{ width: 36, height: 36, border: '1px solid var(--rule-thin)', background: 'transparent', cursor: 'pointer', fontSize: 16, display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'background 150ms' }}
|
||||
onMouseEnter={e => (e.currentTarget.style.background = 'var(--paper-2)')}
|
||||
onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export default function SnapshotBar() {
|
|||
<div
|
||||
key={price.id}
|
||||
style={{
|
||||
padding: '24px 0',
|
||||
padding: '28px 0',
|
||||
borderRight: isLast ? 'none' : '1px solid var(--rule-thin)',
|
||||
paddingLeft: idx === 0 ? '0' : '28px',
|
||||
paddingRight: idx === prices.length - 1 ? '0' : '28px',
|
||||
|
|
|
|||
Loading…
Reference in New Issue