steelforesight/src/pages/Risks/Risks.tsx

334 lines
12 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 { 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>
);
}