steelforesight/src/pages/Home/sections/LatestReportsSection.tsx

252 lines
6.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from 'react'
import { Link } from 'react-router-dom'
import { SectionBanner } from '@/components/ui/SectionBanner'
import { reports, type Report } from '@/data/reports'
const displayReports = reports.filter(r => !r.featured).slice(0, 6)
const typeLabel: Record<string, string> = {
quarterly: 'گزارش فصلی',
flash: 'فوری',
risk: 'ریسک',
free: 'رایگان',
special: 'ویژه',
}
const dotColor: Record<string, string> = {
quarterly: 'var(--ink)',
flash: 'var(--red)',
risk: 'var(--red)',
free: 'var(--green-ink)',
special: 'var(--amber)',
}
function formatPrice(n: number) {
return n.toLocaleString('fa-IR')
}
interface ReportCardProps {
report: Report
colIndex: number
rowIndex: number
totalRows: number
}
function ReportCard({ report, colIndex, rowIndex, totalRows }: ReportCardProps) {
const [hovered, setHovered] = useState(false)
const isLastRow = rowIndex === totalRows - 1
const isRightCol = colIndex === 0 // RTL: right col is index 0
return (
<div
style={{
padding: '40px',
borderBottom: isLastRow ? 'none' : '1px solid var(--rule-thin)',
borderLeft: isRightCol ? '1px solid var(--rule-thin)' : 'none',
cursor: 'pointer',
transition: 'background-color 150ms',
backgroundColor: hovered ? 'var(--paper-2)' : 'transparent',
}}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{/* Type badge */}
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
marginBottom: '16px',
}}
>
<div
style={{
width: '4px',
height: '4px',
borderRadius: '50%',
backgroundColor: dotColor[report.type] ?? 'var(--ink)',
flexShrink: 0,
}}
/>
<span
style={{
fontSize: '9px',
textTransform: 'uppercase',
letterSpacing: '2px',
color: 'var(--ink-5)',
fontWeight: 700,
}}
>
{typeLabel[report.type] ?? report.type} · {report.category}
</span>
</div>
{/* Title */}
<Link to={`/reports/${report.id}`} style={{ textDecoration: 'none' }}>
<h3
style={{
fontSize: 'clamp(18px, 2vw, 20px)',
fontWeight: 800,
lineHeight: 1.35,
letterSpacing: '-0.3px',
color: hovered ? 'var(--red)' : 'var(--ink)',
marginBottom: '12px',
transition: 'color 150ms',
cursor: 'pointer',
}}
>
{report.title}
</h3>
</Link>
{/* Deck */}
<p
style={{
fontSize: '13px',
fontWeight: 300,
color: 'var(--ink-3)',
lineHeight: 1.8,
marginBottom: '20px',
}}
>
{report.summary.slice(0, 140)}
{report.summary.length > 140 ? '…' : ''}
</p>
{/* Divider */}
<div
style={{
height: '1px',
backgroundColor: 'var(--rule-thin)',
marginBottom: '16px',
}}
/>
{/* Footer row */}
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'flex-end',
gap: '12px',
}}
>
{/* Price block */}
<div>
{report.isFree ? (
<span
style={{
fontSize: '16px',
fontWeight: 900,
color: 'var(--green-ink)',
}}
>
دانلود رایگان
</span>
) : (
<span
style={{
fontSize: '16px',
fontWeight: 900,
color: 'var(--ink)',
}}
>
{formatPrice(report.price)}
<span
style={{
fontSize: '11px',
fontWeight: 400,
color: 'var(--ink-4)',
marginRight: '4px',
}}
>
تومان
</span>
</span>
)}
<div
style={{
fontSize: '10px',
color: 'var(--ink-5)',
marginTop: '3px',
}}
>
{report.pages} صفحه · {report.publishDate}
</div>
</div>
{/* Buy link */}
<Link
to={`/reports/${report.id}`}
style={{
fontSize: '10px',
fontWeight: 700,
textTransform: 'uppercase',
letterSpacing: '2px',
color: 'var(--red)',
textDecoration: 'none',
cursor: 'pointer',
transition: 'text-decoration 150ms',
whiteSpace: 'nowrap',
}}
onMouseEnter={e =>
(e.currentTarget.style.textDecoration = 'underline')
}
onMouseLeave={e => (e.currentTarget.style.textDecoration = 'none')}
>
{report.isFree ? 'دانلود' : 'خرید گزارش'}
</Link>
</div>
</div>
)
}
export default function LatestReportsSection() {
const rows = Math.ceil(displayReports.length / 2)
return (
<section
style={{
padding: '96px 48px',
borderBottom: '2px solid var(--ink)',
direction: 'rtl',
}}
className="max-md:px-6 max-md:py-16"
>
{/* Section header */}
<div style={{ marginBottom: '40px' }}>
<SectionBanner
label="آخرین گزارش‌ها"
link={{ text: 'مشاهده آرشیو کامل ←', to: '/reports' }}
/>
</div>
{/* 2-col grid */}
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
border: '1px solid var(--rule-thin)',
borderBottom: 'none',
borderLeft: 'none',
}}
className="max-md:grid-cols-1"
>
{displayReports.map((report, idx) => {
const colIndex = idx % 2
const rowIndex = Math.floor(idx / 2)
return (
<ReportCard
key={report.id}
report={report}
colIndex={colIndex}
rowIndex={rowIndex}
totalRows={rows}
/>
)
})}
</div>
</section>
)
}