steelforesight/src/content/radarCategories.ts

277 lines
13 KiB
TypeScript

/* ─────────────────────────────────────────────────────────────
Radar category-detail pages content layer.
Each of the 5 "رادار آینده" categories gets its own detail page
at /radar/:slug with the SAME layout, only the content differs.
Kept separate from the component so it can be served from the
panel/API later (replace these objects with a fetch).
───────────────────────────────────────────────────────────── */
import type { RadarCategory } from './radar'
export type RadarSlug =
| 'foresight' // آینده‌پژوهی و رصد هوشمند
| 'market' // بازار و زنجیره فولاد
| 'sustainability' // پایداری و فولاد سبز
| 'geopolitics' // ژئوپلیتیک و اقتصاد جهانی
| 'technology' // فناوری و نوآوری
export type RadarCard = {
id: string
img: string
fa: { title: string; excerpt: string; date: string }
en: { title: string; excerpt: string; date: string }
}
export type RadarCategoryPage = {
slug: RadarSlug
/** which RadarCategory(ies) from radar.ts this page draws its card pool from */
sourceCategories: RadarCategory[]
fa: {
label: string // breadcrumb + headings
latestHeading: string // "تازه‌ترین‌های …"
featured: { title: string; date: string; img: string }
banner: { kicker: string; title: string; desc: string }
}
en: {
label: string
latestHeading: string
featured: { title: string; date: string; img: string }
banner: { kicker: string; title: string; desc: string }
}
}
const BOOK_IMG = '/Horizontal_Book_Mockup_6 1.webp'
/* ── the 5 pages ─────────────────────────────────────────────── */
export const RADAR_CATEGORY_PAGES: Record<RadarSlug, RadarCategoryPage> = {
foresight: {
slug: 'foresight',
sourceCategories: ['market', 'tech', 'commodity', 'geo', 'energy'],
fa: {
label: 'آینده‌پژوهی و رصد هوشمند',
latestHeading: 'تازه‌ترین‌های آینده‌پژوهی',
featured: {
title: 'طلوع هوشمندی: چگونه هوش مصنوعی، زنجیره ارزش فولاد را بازتعریف می‌کند؟',
date: 'اردیبهشت ۱۴۰۵',
img: '/news/photo-1611974789855-9c2a0a7236a3.jpg',
},
banner: {
kicker: 'تحلیل ویژه',
title: 'نقشه راه آینده‌پژوهی صنعت فولاد',
desc: 'جامع‌ترین گزارش تحلیلی سال پیرامون سناریوهای محتمل برای آینده صنعت فولاد، روندهای نوظهور فناورانه و سیگنال‌های راهبردی برای تصمیم‌سازان.',
},
},
en: {
label: 'Foresight & Smart Monitoring',
latestHeading: 'Latest in Foresight',
featured: {
title: 'The Dawn of Intelligence: How AI Is Redefining the Steel Value Chain',
date: 'May 2026',
img: '/news/photo-1611974789855-9c2a0a7236a3.jpg',
},
banner: {
kicker: 'Special Analysis',
title: 'A Foresight Roadmap for the Steel Industry',
desc: 'The most comprehensive analytical report of the year on plausible scenarios for the future of steel, emerging tech trends and strategic signals for decision-makers.',
},
},
},
market: {
slug: 'market',
sourceCategories: ['market', 'commodity'],
fa: {
label: 'بازار و زنجیره فولاد',
latestHeading: 'تازه‌ترین‌های بازار و زنجیره فولاد',
featured: {
title: 'طلوع هوشمندی: چگونه هوش مصنوعی، زنجیره ارزش فولاد را بازتعریف می‌کند؟',
date: 'اردیبهشت ۱۴۰۵',
img: '/news/photo-1611974789855-9c2a0a7236a3.jpg',
},
banner: {
kicker: 'تحلیل ویژه',
title: 'معماری نوین زنجیره تأمین',
desc: 'جامع‌ترین گزارش تحلیلی سال پیرامون مسیر تجارت جهانی سنگ‌آهن، تأثیرات قطعی استانداردهای کربنی اروپا (CBAM) و سناریوهای تاب‌آوری برای فولادسازان خاورمیانه.',
},
},
en: {
label: 'Market & Steel Chain',
latestHeading: 'Latest in Market & Chain',
featured: {
title: 'The Dawn of Intelligence: How AI Is Redefining the Steel Value Chain',
date: 'May 2026',
img: '/news/photo-1611974789855-9c2a0a7236a3.jpg',
},
banner: {
kicker: 'Special Analysis',
title: 'A New Supply-Chain Architecture',
desc: "The most comprehensive analytical report of the year on global iron-ore trade routes, the decisive impact of Europe's carbon standards (CBAM) and resilience scenarios for Middle-Eastern steelmakers.",
},
},
},
sustainability: {
slug: 'sustainability',
sourceCategories: ['energy', 'commodity'],
fa: {
label: 'پایداری و فولاد سبز',
latestHeading: 'تازه‌ترین‌های پایداری و فولاد سبز',
featured: {
title: 'هیدروژن سبز؛ سوخت کربن‌زدایی صنعت فولاد در افق ۲۰۵۰',
date: 'اردیبهشت ۱۴۰۵',
img: '/news/photo-1466611653911-95081537e5b7.jpg',
},
banner: {
kicker: 'تحلیل ویژه',
title: 'مسیر کربن‌زدایی صنعت فولاد',
desc: 'جامع‌ترین گزارش تحلیلی سال پیرامون فناوری‌های احیای مستقیم بر پایه هیدروژن، برق تجدیدپذیر و سناریوهای دستیابی به فولاد بدون کربن تا افق ۲۰۵۰.',
},
},
en: {
label: 'Sustainability & Green Steel',
latestHeading: 'Latest in Sustainability',
featured: {
title: 'Green Hydrogen: The Decarbonization Fuel of Steel Toward 2050',
date: 'May 2026',
img: '/news/photo-1466611653911-95081537e5b7.jpg',
},
banner: {
kicker: 'Special Analysis',
title: 'The Steel Decarbonization Pathway',
desc: 'The most comprehensive analytical report of the year on hydrogen-based direct reduction, renewable power and scenarios for reaching carbon-free steel by 2050.',
},
},
},
geopolitics: {
slug: 'geopolitics',
sourceCategories: ['geo', 'market'],
fa: {
label: 'ژئوپلیتیک و اقتصاد جهانی',
latestHeading: 'تازه‌ترین‌های ژئوپلیتیک و اقتصاد جهانی',
featured: {
title: 'هندسه نوین قدرت؛ ژئوپلیتیک فولاد در جهانی چندقطبی',
date: 'اردیبهشت ۱۴۰۵',
img: '/news/photo-1518770660439-4636190af475.jpg',
},
banner: {
kicker: 'تحلیل ویژه',
title: 'ژئوپلیتیک تجارت فولاد',
desc: 'جامع‌ترین گزارش تحلیلی سال پیرامون تنش‌های تجاری، تعرفه‌ها و بازآرایی مسیرهای صادراتی فولاد و پیامد آن بر رقابت‌پذیری ایران در بازارهای منطقه‌ای.',
},
},
en: {
label: 'Geopolitics & Global Economy',
latestHeading: 'Latest in Geopolitics',
featured: {
title: 'A New Power Geometry: Steel Geopolitics in a Multipolar World',
date: 'May 2026',
img: '/news/photo-1518770660439-4636190af475.jpg',
},
banner: {
kicker: 'Special Analysis',
title: 'The Geopolitics of Steel Trade',
desc: "The most comprehensive analytical report of the year on trade tensions, tariffs and the realignment of steel export routes, and their fallout for Iran's regional competitiveness.",
},
},
},
technology: {
slug: 'technology',
sourceCategories: ['tech'],
fa: {
label: 'فناوری و نوآوری',
latestHeading: 'تازه‌ترین‌های فناوری و نوآوری',
featured: {
title: 'کارخانه هوشمند؛ تحول دیجیتال در خطوط تولید فولاد',
date: 'اردیبهشت ۱۴۰۵',
img: '/news/photo-1581092160607-ee22731c9b4e.jpg',
},
banner: {
kicker: 'تحلیل ویژه',
title: 'انقلاب دیجیتال در صنعت فولاد',
desc: 'جامع‌ترین گزارش تحلیلی سال پیرامون هوش مصنوعی، دوقلوی دیجیتال، اینترنت اشیا صنعتی و اثر اتوماسیون هوشمند بر بهره‌وری و کیفیت تولید فولاد.',
},
},
en: {
label: 'Technology & Innovation',
latestHeading: 'Latest in Technology',
featured: {
title: 'The Smart Factory: Digital Transformation in Steel Production Lines',
date: 'May 2026',
img: '/news/photo-1581092160607-ee22731c9b4e.jpg',
},
banner: {
kicker: 'Special Analysis',
title: 'The Digital Revolution in Steel',
desc: 'The most comprehensive analytical report of the year on AI, digital twins, industrial IoT and the impact of smart automation on steel productivity and quality.',
},
},
},
}
export const RADAR_SLUGS = Object.keys(RADAR_CATEGORY_PAGES) as RadarSlug[]
export { BOOK_IMG }
/* ── CMS wiring ─────────────────────────────────────────────────
Overwrites RADAR_CATEGORY_PAGES from the panel at startup.
Falls back to the static objects above when the panel is offline.
──────────────────────────────────────────────────────────────── */
const PANEL_API =
(import.meta as ImportMeta & { env?: Record<string, string> }).env?.VITE_PANEL_API ||
'http://localhost:3001'
const VALID_SLUGS = new Set(RADAR_SLUGS)
const VALID_CATS: RadarCategory[] = ['market', 'tech', 'commodity', 'geo', 'energy']
const asCats = (v: unknown): RadarCategory[] =>
Array.isArray(v) ? v.filter((c): c is RadarCategory => VALID_CATS.includes(c as RadarCategory)) : []
export async function bootstrapRadarPages(): Promise<void> {
try {
const res = await fetch(`${PANEL_API}/api/radar-pages`)
if (!res.ok) return
const rows = await res.json()
if (!Array.isArray(rows) || rows.length === 0) return
for (const r of rows as Record<string, unknown>[]) {
const slug = String(r.slug) as RadarSlug
if (!VALID_SLUGS.has(slug)) continue
const cats = asCats(r.sourceCategories)
RADAR_CATEGORY_PAGES[slug] = {
slug,
sourceCategories: cats.length ? cats : RADAR_CATEGORY_PAGES[slug].sourceCategories,
fa: {
label: String(r.labelFa ?? RADAR_CATEGORY_PAGES[slug].fa.label),
latestHeading: String(r.latestHeadingFa ?? RADAR_CATEGORY_PAGES[slug].fa.latestHeading),
featured: {
title: String(r.featuredTitleFa ?? RADAR_CATEGORY_PAGES[slug].fa.featured.title),
date: String(r.featuredDateFa ?? RADAR_CATEGORY_PAGES[slug].fa.featured.date),
img: String(r.featuredImg ?? RADAR_CATEGORY_PAGES[slug].fa.featured.img),
},
banner: {
kicker: String(r.bannerKickerFa ?? RADAR_CATEGORY_PAGES[slug].fa.banner.kicker),
title: String(r.bannerTitleFa ?? RADAR_CATEGORY_PAGES[slug].fa.banner.title),
desc: String(r.bannerDescFa ?? RADAR_CATEGORY_PAGES[slug].fa.banner.desc),
},
},
en: {
label: String(r.labelEn ?? RADAR_CATEGORY_PAGES[slug].en.label),
latestHeading: String(r.latestHeadingEn ?? RADAR_CATEGORY_PAGES[slug].en.latestHeading),
featured: {
title: String(r.featuredTitleEn ?? RADAR_CATEGORY_PAGES[slug].en.featured.title),
date: String(r.featuredDateEn ?? RADAR_CATEGORY_PAGES[slug].en.featured.date),
img: String(r.featuredImg ?? RADAR_CATEGORY_PAGES[slug].en.featured.img),
},
banner: {
kicker: String(r.bannerKickerEn ?? RADAR_CATEGORY_PAGES[slug].en.banner.kicker),
title: String(r.bannerTitleEn ?? RADAR_CATEGORY_PAGES[slug].en.banner.title),
desc: String(r.bannerDescEn ?? RADAR_CATEGORY_PAGES[slug].en.banner.desc),
},
},
}
}
} catch {
/* panel offline → keep static fallback */
}
}