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

331 lines
14 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 { Link } from 'react-router-dom'
import { Carousel, Card } from '@/components/ui/apple-cards-carousel'
import type { CardData } from '@/components/ui/apple-cards-carousel'
import { reports } from '@/data/reports'
import type { Report } from '@/data/reports'
/* ─── Per-report images (industrial, steel-relevant) ─ */
const reportImage: Record<string, string> = {
'iran-steel-global-trade-scenarios-1404':
'/news/photo-1578662996442-48f60103fc96.jpg',
'steel-energy-consumption-efficiency-1403':
'/news/photo-1473341304170-971dccb5ac1e.jpg',
'global-steel-market-q3-1403':
'/news/photo-1504328345606-18bbc8c9d7d1.jpg',
'iran-steel-export-sanctions-impact-1403':
'/news/photo-1494412519320-aa613dfb7738.jpg',
'flash-iron-ore-price-surge-1403':
'/news/photo-1611974789855-9c2a0a7236a3.jpg',
'domestic-production-dri-outlook-1403':
'/news/photo-1567789884554-0b844b597180.jpg',
'esg-carbon-emissions-steel-iran-1403':
'/news/photo-1466611653911-95081537e5b7.jpg',
'policy-steel-pricing-reform-1403':
'/news/photo-1551288049-bebda4e38f71.jpg',
'flash-china-steel-overcapacity-1403':
'/news/photo-1570168007204-dfb528c6958f.jpg',
}
const fallbackImage =
'/news/photo-1558618666-fcd25c85cd64.jpg'
const typeLabel: Record<string, string> = {
quarterly: 'گزارش فصلی',
flash: 'گزارش فوری',
risk: 'گزارش ریسک',
free: 'رایگان',
special: 'گزارش ویژه',
}
const typeColor: Record<string, string> = {
flash: 'var(--red)',
risk: '#92400e',
free: '#166534',
quarterly: 'var(--ink-4)',
special: 'var(--ink)',
}
/* ─── Key findings per category (mock but plausible) ─ */
const keyFindings: Record<string, string[]> = {
'بازار جهانی': [
'کاهش ۱۲٪ تقاضای چین در نیمه دوم ۲۰۲۴ فشار قیمتی جهانی ایجاد کرده',
'هند با رشد ۱۸٪ ظرفیت تولید، رقیب اصلی ایران در بازارهای منطقه شده',
'پیش‌بینی بازگشت تقاضا در Q2 2025 با ریکاوری بخش ساختمان آمریکا',
],
'انرژی و ESG': [
'شکاف مصرف انرژی واحدهای ایرانی ۲۵٪ بیشتر از میانگین جهانی است',
'اجرای CBAM از ۲۰۲۶ می‌تواند ۱۵٪ رقابت‌پذیری صادرات را کاهش دهد',
'مسیر هیدروژن سبز برای ایران تا ۱۴۱۰ اقتصادی نخواهد بود',
],
'صادرات': [
'عراق، افغانستان و پاکستان ۶۵٪ صادرات فولاد ایران را تشکیل می‌دهند',
'مسیرهای جایگزین آفریقای شرقی پتانسیل ۲ میلیون تن اضافی دارد',
'تحریم‌های جدید ۳ مسیر اصلی پرداخت را مسدود کرده است',
],
'تولید داخلی': [
'ایران با ۳۰ میلیون تن DRI رتبه اول جهانی را حفظ کرده است',
'کمبود گاز زمستانی می‌تواند تا ۲۰٪ ظرفیت تولید را کاهش دهد',
'۸ پروژه در دست احداث تا ۱۴۰۵ به ظرفیت می‌رسند',
],
'سیاست‌گذاری': [
'قیمت‌گذاری دستوری هزینه ۱.۲ میلیارد دلار در سال به صنعت تحمیل می‌کند',
'تجربه ترکیه نشان می‌دهد آزادسازی تدریجی قیمت بهترین مسیر است',
'اصلاح تعرفه‌های سنگ‌آهن می‌تواند ۸٪ به حاشیه سود اضافه کند',
],
'ریسک و بحران': [
'احتمال تشدید تحریم‌ها در ۶ ماه آینده ۶۵٪ برآورد می‌شود',
'ریسک کمبود ارز برای واردات مواد اولیه در سطح بالا قرار دارد',
'شکست مذاکرات هسته‌ای می‌تواند ۳۰٪ صادرات را تحت تأثیر قرار دهد',
],
}
/* ─── Report contents (TOC-style) ───────────────────── */
const reportContents: Record<string, string[]> = {
quarterly: ['مروری بر بازار فصل', 'تحلیل قیمت‌ها و حجم معاملات', 'رویدادهای کلیدی', 'پیش‌بینی فصل آینده', 'داده‌های خام ضمیمه'],
flash: ['خلاصه اجرایی', 'رویداد و محرک', 'تأثیر بر بازار داخلی', 'توصیه‌های فوری'],
risk: ['ارزیابی ریسک', 'تحلیل سناریو', 'احتمال‌سنجی', 'راهکارهای پوشش ریسک', 'پیوست داده'],
free: ['خلاصه یافته‌ها', 'روش‌شناسی', 'مقایسه بین‌المللی', 'توصیه‌های سیاستی'],
special: ['تحلیل جامع', 'سناریوسازی کمی', 'مقایسه تطبیقی', 'توصیه‌های راهبردی', 'مدل Excel پیوست'],
}
/* ─── Expanded card body ─────────────────────────────── */
function ReportCardContent({ report }: { report: Report }) {
const findings = keyFindings[report.category] ?? []
const contents = reportContents[report.type] ?? []
return (
<div style={{ direction: 'rtl', fontFamily: 'Vazir, sans-serif' }}>
{/* Tags */}
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 20 }}>
{report.tags.map(tag => (
<span key={tag} style={{
fontSize: 10, fontWeight: 600,
padding: '3px 10px', borderRadius: 999,
background: '#f1f5f9', color: '#475569',
}}>
{tag}
</span>
))}
</div>
{/* Summary */}
<p style={{
fontSize: 14, lineHeight: 1.9, fontWeight: 300,
color: '#374151', marginBottom: 24,
paddingBottom: 24, borderBottom: '1px solid #f1f5f9',
}}>
{report.summary}
</p>
{/* Key findings */}
{findings.length > 0 && (
<div style={{ marginBottom: 24 }}>
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '2px', textTransform: 'uppercase', color: '#9b1c1c', marginBottom: 12 }}>
یافتههای کلیدی
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
{findings.map((f, i) => (
<div key={i} style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
<div style={{ width: 5, height: 5, borderRadius: '50%', background: '#9b1c1c', flexShrink: 0, marginTop: 6 }} />
<span style={{ fontSize: 13, lineHeight: 1.7, color: '#374151', fontWeight: 300 }}>{f}</span>
</div>
))}
</div>
</div>
)}
{/* Report contents */}
{contents.length > 0 && (
<div style={{ marginBottom: 24, padding: '16px 20px', background: '#f8fafc', borderRadius: 12 }}>
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '2px', textTransform: 'uppercase', color: '#64748b', marginBottom: 10 }}>
محتوای این گزارش
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
{contents.map((item, i) => (
<div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
<span style={{ fontSize: 10, color: '#94a3b8', fontWeight: 700, minWidth: 18 }}>
{(i + 1).toLocaleString('fa-IR')}
</span>
<span style={{ fontSize: 12, color: '#475569', lineHeight: 1.5 }}>{item}</span>
</div>
))}
</div>
</div>
)}
{/* Meta grid */}
<div className="mq-stack" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10, marginBottom: 20 }}>
{[
{ label: 'نویسنده', value: report.author },
{ label: 'صفحات', value: `${report.pages} صفحه` },
{ label: 'تاریخ انتشار', value: report.publishDate },
].map(item => (
<div key={item.label} style={{ background: '#f8fafc', borderRadius: 10, padding: '10px 14px', textAlign: 'center' }}>
<div style={{ fontSize: 9, color: '#94a3b8', marginBottom: 4, fontWeight: 700, letterSpacing: '1px', textTransform: 'uppercase' }}>
{item.label}
</div>
<div style={{ fontSize: 12, fontWeight: 700, color: '#1e293b' }}>{item.value}</div>
</div>
))}
</div>
{/* Author */}
<div style={{
display: 'flex', alignItems: 'center', gap: 12,
padding: '14px 18px', background: '#f8fafc', borderRadius: 12, marginBottom: 20,
}}>
<div style={{
width: 40, height: 40, background: '#1a1712', color: '#f4efe7',
borderRadius: 999, display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: 16, fontWeight: 900, flexShrink: 0,
}}>
{report.authorInitial}
</div>
<div>
<div style={{ fontSize: 13, fontWeight: 700, color: '#1e293b' }}>{report.author}</div>
<div style={{ fontSize: 11, color: '#64748b' }}>{report.authorRole}</div>
</div>
</div>
{/* CTA */}
<div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
{report.isFree ? (
<Link to={`/reports/${report.id}`} style={{
background: '#166534', color: 'white',
padding: '13px 28px', fontSize: 13, fontWeight: 700,
fontFamily: 'Vazir, sans-serif', borderRadius: 999,
textDecoration: 'none', display: 'inline-block',
}}>
دانلود رایگان
</Link>
) : (
<>
<button style={{
background: '#1a1712', color: '#f4efe7', border: 'none',
padding: '13px 28px', fontSize: 13, fontWeight: 700,
fontFamily: 'Vazir, sans-serif', cursor: 'pointer', borderRadius: 999,
}}>
خرید {report.price.toLocaleString('fa-IR')} تومان
</button>
<Link to={`/reports/${report.id}`} style={{
color: '#9b1c1c', fontSize: 12, fontWeight: 700, textDecoration: 'none',
}}>
مشاهده جزئیات
</Link>
</>
)}
</div>
</div>
)
}
/* ─── Section ────────────────────────────────────────── */
export default function ReportsCarouselSection() {
const carouselReports = reports.filter(r => !r.featured)
const cards: CardData[] = carouselReports.map(report => ({
src: reportImage[report.id] ?? fallbackImage,
title: report.title,
category: typeLabel[report.type] ?? report.type,
summary: report.summary,
author: report.author,
date: report.publishDate,
pages: report.pages,
content: <ReportCardContent report={report} />,
}))
const cardElements = cards.map((card, index) => (
<Card key={card.src + index} card={card} index={index} layout />
))
return (
<section style={{ background: 'var(--paper-2)', paddingBottom: 96 }}>
{/* ── Editorial header ── */}
<div className="max-w-7xl mx-auto px-12 pt-24 max-md:px-5 max-md:pt-16">
<div
style={{
display: 'grid',
gridTemplateColumns: '1fr auto',
alignItems: 'end',
gap: 32,
paddingBottom: 28,
borderBottom: '1px solid var(--rule-thin)',
marginBottom: 32,
}}
className="mq-stack max-md:grid-cols-1 max-md:gap-4"
>
<div>
<div style={{
display: 'flex',
alignItems: 'center',
gap: 12,
marginBottom: 18,
}}>
<div style={{ width: 32, height: 2, background: 'var(--red)' }} />
<span style={{
fontSize: 11,
fontWeight: 700,
letterSpacing: '3px',
textTransform: 'uppercase',
color: 'var(--ink-4)',
}}>
آرشیو پژوهش · ۱۴۰۳
</span>
</div>
<h2 style={{
fontSize: 'clamp(28px, 3.6vw, 48px)',
fontWeight: 900,
letterSpacing: '-1.2px',
color: 'var(--ink)',
lineHeight: 1.1,
marginBottom: 12,
}}>
تحلیلهای اخیر
</h2>
<p style={{
fontSize: 14,
lineHeight: 1.7,
color: 'var(--ink-4)',
maxWidth: 560,
}}>
مجموعهای از گزارشهای راهبردی، تحلیلهای فصلی و توصیههای سیاستی
منتشرشده در ماههای اخیر.
</p>
</div>
<Link
to="/archive"
style={{
fontSize: 11,
fontWeight: 700,
letterSpacing: '1.5px',
textTransform: 'uppercase',
color: 'var(--red)',
textDecoration: 'none',
whiteSpace: 'nowrap',
paddingBottom: 4,
}}
>
همه گزارشها
</Link>
</div>
{/* Legend row */}
<div style={{ display: 'flex', gap: 20, flexWrap: 'wrap' }}>
{Object.entries(typeLabel).map(([key, label]) => (
<div key={key} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<div style={{ width: 7, height: 7, borderRadius: '50%', background: typeColor[key] }} />
<span style={{ fontSize: 11, color: 'var(--ink-4)', fontWeight: 600 }}>{label}</span>
</div>
))}
</div>
</div>
<div className="max-w-7xl mx-auto w-full px-12 max-md:px-5 mt-10">
<Carousel items={cardElements} />
</div>
</section>
)
}