import { useParams, Link, useNavigate } from 'react-router-dom' import { motion } from 'framer-motion' import { Calendar, Tag, MessageCircle, ArrowLeft, MoreHorizontal, Heart, Reply, Plus, UserPlus, LogIn, Send, Share2, Globe, Mail } from 'lucide-react' import { useLang } from '@/context/LangContext' import { useAuth } from '@/context/AuthContext' import { getPost, type Post } from '@/content/posts' import { MagicTextGroup } from '@/components/ui/magic-text' const NAVY = '#032340' const GOLD = '#CD9E53' const BLUE = '#1f8fff' const PAPER = '#faf7f4' const EASE = [0.22, 1, 0.36, 1] as const /* ════════ Pareto chart (bars desc + cumulative line + 80% rule) ════════ */ function ParetoChart() { const bars = [46, 30, 22, 14, 10, 7, 5, 3] const total = bars.reduce((a, b) => a + b, 0) let acc = 0 const cum = bars.map((b) => { acc += b; return (acc / total) * 100 }) const W = 560, H = 240, padL = 36, padR = 40, padB = 44, padT = 14 const cw = W - padL - padR, ch = H - padB - padT const maxBar = 60 const bw = cw / bars.length const x = (i: number) => padL + i * bw + bw / 2 const yBar = (v: number) => padT + ch - (v / maxBar) * ch const yCum = (v: number) => padT + ch - (v / 100) * ch const labels = ['Defect Type A','Defect Type B','Defect Type C','Defect Type D','Defect Type E','Defect Type F','Defect Type G','Defect Type H'] const linePts = cum.map((v, i) => `${x(i)},${yCum(v)}`).join(' ') return (
{/* y grid + left axis labels */} {[0, 15, 30, 45, 60].map((v) => ( {v} ))} {/* right axis (cumulative %) */} {[0, 25, 50, 75, 100].map((v) => ( {v} ))} {/* 80% dashed rule */} {/* bars */} {bars.map((v, i) => ( ))} {/* cumulative line + dots */} {cum.map((v, i) => )} {/* x labels */} {labels.map((l, i) => ( {l} ))} {/* legend */}
80% Line Cumulative % Frequency
{/* caption box */}
Pareto Analysis (80/20 Rule)
Top 20% categories:
2 of 8
Contribute:
68.8% of total
) } /* ════════ Grouped monthly bar chart (expenses / profit / revenue) ════════ */ function BarsChart() { const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] const data = [ [3000, 2000, 4500], [3200, 1800, 5200], [2800, 2400, 4800], [3500, 2600, 6000], [3100, 2200, 5500], [3400, 2800, 6200], [3000, 2500, 5800], [3600, 3000, 6800], [3300, 2700, 6400], [3800, 3200, 7600], [3500, 2900, 8200], [3200, 3400, 9000], ] const W = 560, H = 250, padL = 40, padR = 12, padB = 36, padT = 14 const cw = W - padL - padR, ch = H - padB - padT const maxV = 10000 const gw = cw / months.length const colors = [NAVY, GOLD, BLUE] const y = (v: number) => padT + ch - (v / maxV) * ch return (
{[0, 2500, 5000, 7500, 10000].map((v) => ( {v} ))} {data.map((grp, i) => { const x0 = padL + i * gw const innerBw = (gw * 0.7) / 3 return grp.map((v, j) => ( )) })} {months.map((m, i) => ( {m} ))}
{[['expenses', NAVY], ['profit', GOLD], ['revenue', BLUE]].map(([l, c]) => ( {l} ))}
) } /* ════════ floating related sidebar (sticky → follows scroll) ════════ */ function RelatedSidebar({ related, lang }: { related: Post['related']; lang: 'fa' | 'en' }) { return ( ) } /* ════════ a single comment ════════ */ function CommentCard({ c, lang }: { c: Post['comments'][number]; lang: 'fa' | 'en' }) { const isFa = lang === 'fa' return (
{/* identity */}
{c.name.trim().charAt(0)}
{c.name}
{isFa ? c.roleFa : c.roleEn}
{/* actions */}
{c.date}
{/* tag pills */}
{c.tags.map((tg, i) => ( {isFa ? tg.fa : tg.en} ))}

{c[lang]}

) } /* ════════ membership gate (shown to logged-out readers) ════════ */ function MembershipGate({ lang, onPreviewLogin }: { lang: 'fa' | 'en'; onPreviewLogin: () => void }) { const isFa = lang === 'fa' const copy = isFa ? 'تحلیل‌های راهبردی، آمارهای تخصصی و گزارش‌های اختصاصی اندیشکده فولاد آینده تنها در اختیار اعضای شبکه قرار می‌گیرد. برای دسترسی به این محتوا، وارد حساب کاربری خود شوید یا به جمع اعضای اندیشکده بپیوندید.' : 'At the Future Steel Institute we craft our strategic outputs for members of our expert network. Membership unlocks full reports, foresight scenarios and high-level analysis — and a seat in the conversation with industry pioneers.' return (

{copy}

{/* socials */}
{[Send, Share2, Globe, Mail].map((Icon, i) => ( ))}
{/* actions */}
{isFa ? 'ثبت نام' : 'Sign up'}
) } export default function PostDetail() { const { lang } = useLang() const { id } = useParams<{ id: string }>() const post = getPost(id || 'p1')! const t = post[lang] const isFa = lang === 'fa' const { member } = useAuth() const navigate = useNavigate() const loggedIn = member !== null return (
{/* ── COVER — full-screen, full-bleed (rounded mask corners) ── */}
{t.title}
{/* ── BODY GRID: article (main) + floating related ── */}
{/* MAIN */}
{/* date badge */}
{t.date}
{/* title */}

{t.title}

{/* category */}
{post.category[lang]}
{/* body — full when logged in, gated preview (blurred + gate) when logged out */} {loggedIn ? ( <> {/* body blocks — consecutive paragraphs grouped so they reveal sequentially */} {(() => { const out: React.ReactNode[] = [] let paraRun: string[] = [] const flush = (key: string) => { if (!paraRun.length) return out.push( , ) paraRun = [] } post.body.forEach((b, i) => { if (b.type === 'p') { paraRun.push(b[lang]); return } flush(`g${i}`) if (b.type === 'h') { out.push(

{b[lang]}

) } else if (b.type === 'chart') { out.push( {b.chart === 'pareto' ? : } , ) } else if (b.type === 'figure') { out.push(
{b[lang]}
{b[lang]}
, ) } }) flush('g-end') return out })()} {/* ── COMMENTS (دیدگاه) ── */}

{isFa ? 'دیدگاه' : 'Comments'}

{post.comments.map((c) => )}
) : ( (() => { const paras: string[] = [] post.body.forEach((b) => { if (b.type === 'p') paras.push(b[lang]) }) const teaser = paras.join(' ') return ( <> {/* logged-out: at most 5 lines, faded out at the bottom, then the gate */} {teaser && (

{teaser}

)} navigate('/login')} /> ) })() )}
{/* FLOATING RELATED */}
) }