334 lines
12 KiB
TypeScript
334 lines
12 KiB
TypeScript
import { Link } from 'react-router-dom';
|
||
import { reports } from '@/data/reports';
|
||
|
||
const riskMatrix = [
|
||
{ id: 1, title: 'تشدید تحریمهای صادراتی', category: 'ژئوپلیتیک', probability: 'بالا', impact: 'بسیار بالا', level: 'critical' },
|
||
{ id: 2, title: 'سقوط قیمت جهانی فولاد', category: 'بازار', probability: 'متوسط', impact: 'بالا', level: 'high' },
|
||
{ id: 3, title: 'کمبود انرژی صنعتی', category: 'زیرساخت', probability: 'بالا', impact: 'متوسط', level: 'high' },
|
||
{ id: 4, title: 'اجرای CBAM اروپا', category: 'مقررات', probability: 'قطعی', impact: 'متوسط', level: 'medium' },
|
||
{ id: 5, title: 'رقابت صادرات چین', category: 'بازار', probability: 'قطعی', impact: 'بالا', level: 'high' },
|
||
{ id: 6, title: 'نوسانات نرخ ارز', category: 'مالی', probability: 'بالا', impact: 'متوسط', level: 'medium' },
|
||
] as const;
|
||
|
||
type RiskLevel = 'critical' | 'high' | 'medium' | 'low';
|
||
|
||
const levelConfig: Record<RiskLevel, { color: string; label: string }> = {
|
||
critical: { color: '#7f1d1d', label: 'بحرانی' },
|
||
high: { color: 'var(--red)', label: 'بالا' },
|
||
medium: { color: 'var(--amber)', label: 'متوسط' },
|
||
low: { color: 'var(--green-ink)', label: 'پایین' },
|
||
};
|
||
|
||
function formatPrice(price: number): string {
|
||
if (price === 0) return 'رایگان';
|
||
return price.toLocaleString('fa-IR') + ' تومان';
|
||
}
|
||
|
||
export default function Risks() {
|
||
const riskReports = reports.filter((r) => r.type === 'risk');
|
||
|
||
return (
|
||
<div
|
||
dir="rtl"
|
||
style={{
|
||
fontFamily: 'Vazir, sans-serif',
|
||
background: 'var(--paper)',
|
||
color: 'var(--ink)',
|
||
minHeight: '100vh',
|
||
}}
|
||
>
|
||
{/* Page Header */}
|
||
<div
|
||
style={{
|
||
borderBottom: '4px double var(--ink)',
|
||
padding: 'clamp(20px, 4vw, 40px) clamp(16px, 4vw, 48px) clamp(16px, 3vw, 32px)',
|
||
background: 'var(--paper)',
|
||
}}
|
||
>
|
||
<div style={{ maxWidth: '1200px', margin: '0 auto' }}>
|
||
<div
|
||
style={{
|
||
fontSize: '11px',
|
||
letterSpacing: '0.12em',
|
||
color: 'var(--ink-5)',
|
||
fontWeight: 600,
|
||
marginBottom: '12px',
|
||
}}
|
||
>
|
||
اندیشکده فولاد آینده — پایش ریسک
|
||
</div>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: '16px' }}>
|
||
<h1
|
||
style={{
|
||
fontSize: '36px',
|
||
fontWeight: 900,
|
||
margin: 0,
|
||
lineHeight: 1.3,
|
||
}}
|
||
>
|
||
پایش ریسکهای صنعت فولاد
|
||
</h1>
|
||
<span
|
||
style={{
|
||
fontSize: '12px',
|
||
color: 'var(--ink-4)',
|
||
border: '1px solid var(--rule-thin)',
|
||
padding: '4px 12px',
|
||
background: 'var(--paper-2)',
|
||
}}
|
||
>
|
||
بهروز شده: بهمن ۱۴۰۳
|
||
</span>
|
||
</div>
|
||
|
||
{/* Legend */}
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
gap: '24px',
|
||
marginTop: '24px',
|
||
flexWrap: 'wrap',
|
||
}}
|
||
>
|
||
{(Object.keys(levelConfig) as RiskLevel[]).map((level) => (
|
||
<div key={level} style={{ display: 'flex', alignItems: 'center', gap: '7px' }}>
|
||
<div
|
||
style={{
|
||
width: '10px',
|
||
height: '10px',
|
||
borderRadius: '50%',
|
||
background: levelConfig[level].color,
|
||
flexShrink: 0,
|
||
}}
|
||
/>
|
||
<span style={{ fontSize: '13px', color: 'var(--ink-3)' }}>{levelConfig[level].label}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style={{ maxWidth: '1200px', margin: '0 auto', padding: 'clamp(20px,4vw,40px) clamp(16px,4vw,48px) clamp(32px,6vw,64px)' }}>
|
||
{/* Risk Matrix Table */}
|
||
<div style={{ marginBottom: '56px' }}>
|
||
<h2
|
||
style={{
|
||
fontSize: '18px',
|
||
fontWeight: 800,
|
||
margin: '0 0 20px',
|
||
color: 'var(--ink)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '10px',
|
||
}}
|
||
>
|
||
<span style={{ display: 'inline-block', width: '4px', height: '20px', background: 'var(--red)' }} />
|
||
ماتریس ریسکهای کلیدی
|
||
</h2>
|
||
|
||
<div className="overflow-x-auto border border-[var(--ink)]">
|
||
<div style={{ minWidth: 768 }}>
|
||
{/* Table Header */}
|
||
<div
|
||
style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: '48px 1fr 100px 100px 120px 130px',
|
||
background: 'var(--ink)',
|
||
color: 'var(--paper)',
|
||
padding: '12px 16px',
|
||
gap: '0',
|
||
}}
|
||
>
|
||
{['#', 'عنوان ریسک', 'دسته', 'احتمال', 'شدت تأثیر', 'سطح ریسک'].map((col, i) => (
|
||
<div
|
||
key={i}
|
||
style={{
|
||
fontSize: '12px',
|
||
fontWeight: 700,
|
||
letterSpacing: '0.05em',
|
||
padding: '0 8px',
|
||
borderRight: i > 0 ? '1px solid rgba(255,255,255,0.12)' : 'none',
|
||
}}
|
||
>
|
||
{col}
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Table Rows */}
|
||
{riskMatrix.map((risk, idx) => {
|
||
const cfg = levelConfig[risk.level as RiskLevel];
|
||
return (
|
||
<div
|
||
key={risk.id}
|
||
style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: '48px 1fr 100px 100px 120px 130px',
|
||
background: idx % 2 === 0 ? 'var(--paper)' : 'var(--paper-2)',
|
||
borderTop: '1px solid var(--rule-thin)',
|
||
padding: '14px 16px',
|
||
alignItems: 'center',
|
||
}}
|
||
>
|
||
{/* # */}
|
||
<div style={{ fontSize: '13px', color: 'var(--ink-5)', fontWeight: 600, padding: '0 8px' }}>
|
||
{risk.id}
|
||
</div>
|
||
{/* Title */}
|
||
<div style={{ fontSize: '14px', fontWeight: 600, color: 'var(--ink)', padding: '0 8px', borderRight: '1px solid var(--rule-thin)' }}>
|
||
{risk.title}
|
||
</div>
|
||
{/* Category */}
|
||
<div style={{ fontSize: '12px', color: 'var(--ink-4)', padding: '0 8px', borderRight: '1px solid var(--rule-thin)' }}>
|
||
{risk.category}
|
||
</div>
|
||
{/* Probability */}
|
||
<div style={{ fontSize: '12px', color: 'var(--ink-3)', padding: '0 8px', borderRight: '1px solid var(--rule-thin)' }}>
|
||
{risk.probability}
|
||
</div>
|
||
{/* Impact */}
|
||
<div style={{ fontSize: '12px', color: 'var(--ink-3)', padding: '0 8px', borderRight: '1px solid var(--rule-thin)' }}>
|
||
{risk.impact}
|
||
</div>
|
||
{/* Level */}
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '8px',
|
||
padding: '0 8px',
|
||
borderRight: '1px solid var(--rule-thin)',
|
||
}}
|
||
>
|
||
<div
|
||
style={{
|
||
width: '9px',
|
||
height: '9px',
|
||
borderRadius: '50%',
|
||
background: cfg.color,
|
||
flexShrink: 0,
|
||
}}
|
||
/>
|
||
<span style={{ fontSize: '12px', fontWeight: 700, color: cfg.color }}>
|
||
{cfg.label}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Risk Reports Section */}
|
||
<div>
|
||
<div
|
||
style={{
|
||
borderTop: '3px solid var(--ink)',
|
||
borderBottom: '1px solid var(--rule-thin)',
|
||
padding: '18px 0',
|
||
marginBottom: '24px',
|
||
display: 'flex',
|
||
alignItems: 'baseline',
|
||
gap: '16px',
|
||
}}
|
||
>
|
||
<h2 style={{ fontSize: '20px', fontWeight: 800, margin: 0 }}>
|
||
گزارشهای ریسک اندیشکده
|
||
</h2>
|
||
<span style={{ fontSize: '13px', color: 'var(--ink-5)' }}>
|
||
{riskReports.length} گزارش تحلیلی
|
||
</span>
|
||
</div>
|
||
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0' }}>
|
||
{riskReports.map((report, idx) => (
|
||
<Link
|
||
key={report.id}
|
||
to={`/reports/${report.id}`}
|
||
className="grid grid-cols-[90px_1fr_120px_140px_140px] max-md:grid-cols-1 max-md:p-5 max-md:gap-3 p-4 items-center"
|
||
style={{
|
||
borderBottom: '1px solid var(--rule-thin)',
|
||
background: idx % 2 === 0 ? 'var(--paper)' : 'var(--paper-2)',
|
||
textDecoration: 'none',
|
||
color: 'inherit',
|
||
}}
|
||
>
|
||
{/* Type badge */}
|
||
<div style={{ padding: '0 0 0 12px' }} className="max-md:p-0">
|
||
<span
|
||
style={{
|
||
fontSize: '10px',
|
||
fontWeight: 700,
|
||
color: 'var(--paper)',
|
||
background: '#7f1d1d',
|
||
padding: '3px 8px',
|
||
}}
|
||
>
|
||
ریسک
|
||
</span>
|
||
</div>
|
||
{/* Title */}
|
||
<div
|
||
style={{
|
||
fontSize: '14px',
|
||
fontWeight: 600,
|
||
color: 'var(--ink)',
|
||
}}
|
||
className="border-r border-[var(--rule-thin)] px-4 max-md:border-r-0 max-md:p-0"
|
||
>
|
||
{report.title}
|
||
</div>
|
||
{/* Date */}
|
||
<div
|
||
style={{
|
||
fontSize: '12px',
|
||
color: 'var(--ink-5)',
|
||
}}
|
||
className="border-r border-[var(--rule-thin)] px-4 max-md:border-r-0 max-md:p-0"
|
||
>
|
||
{report.publishDate}
|
||
</div>
|
||
{/* Pages */}
|
||
<div
|
||
style={{
|
||
fontSize: '12px',
|
||
color: 'var(--ink-5)',
|
||
}}
|
||
className="border-r border-[var(--rule-thin)] px-4 max-md:border-r-0 max-md:p-0"
|
||
>
|
||
{report.pages} صفحه
|
||
</div>
|
||
{/* Price + link */}
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'flex-end',
|
||
gap: '12px',
|
||
}}
|
||
className="border-r border-[var(--rule-thin)] px-4 max-md:border-r-0 max-md:p-0 max-md:justify-start"
|
||
>
|
||
<span style={{ fontSize: '13px', fontWeight: 700, color: 'var(--ink)' }}>
|
||
{formatPrice(report.price)}
|
||
</span>
|
||
<span
|
||
style={{
|
||
fontSize: '12px',
|
||
color: 'var(--red)',
|
||
fontWeight: 600,
|
||
textDecoration: 'underline',
|
||
}}
|
||
>
|
||
مشاهده ←
|
||
</span>
|
||
</div>
|
||
</Link>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|