import React, { useState } from "react"; import type { DomainType } from "./engine/shared/types"; import { AppHeader, InputBanner, ScenarioLayout } from "./ui"; import { SCENARIO_REGISTRY, DEFAULT_SCENARIO_ID, getScenarioById, } from "./scenarios/registry"; import { MACRO_ROADMAP_ITEMS, NOTEBOOKLM_MACRO_ID, } from "./scenarios/macro"; import { rationingScenario, type RationingParams, } from "./scenarios/micro/consumer/rationing"; import { priceCeilingScenario, type PriceCeilingParams, } from "./scenarios/micro/consumer/price_ceiling"; import { cornerSolutionScenario, type CornerSolutionParams, } from "./scenarios/micro/consumer/corner_solution"; import { inkindVsCashScenario, type InKindVsCashParams, } from "./scenarios/micro/consumer/inkind_vs_cash"; export default function App(): React.JSX.Element { const [currentDomain, setCurrentDomain] = useState<"all" | DomainType>("all"); const [currentScenarioId, setCurrentScenarioId] = useState(DEFAULT_SCENARIO_ID); // Lưu trữ state params độc lập cho từng module const [rationingParams, setRationingParams] = useState({ quotaX: 6, }); const [ceilingParams, setCeilingParams] = useState({ pFixed: 5, xCap: 6, }); const [cornerParams, setCornerParams] = useState({ exampleCase: 1, yogurtPrice: 2.0, iceCreamTaste: 0.85, trustFund: 80, trustAlpha: 0.3, foodStamp: 70, stampAlpha: 0.25, }); const [inkindParams, setInkindParams] = useState({ alpha: 0.3, transfer: 80, }); const activeScenario = getScenarioById(currentScenarioId) ?? rationingScenario; const handleSelectDomain = (domain: "all" | DomainType) => { setCurrentDomain(domain); if (domain === "micro") { if (activeScenario.meta.domain !== "micro") { setCurrentScenarioId("micro.consumer.rationing"); } } else if (domain === "bridge") { setCurrentScenarioId("micro.consumer.corner_solution"); setCornerParams((prev) => ({ ...prev, exampleCase: 2 })); } }; const handleNavigateScenario = (scenarioId: string) => { const target = getScenarioById(scenarioId); if (target) { setCurrentScenarioId(scenarioId); if (currentDomain !== "all" && currentDomain !== target.meta.domain) { setCurrentDomain(target.meta.domain); } } }; return (
setCurrentScenarioId(id)} />
{currentDomain === "macro" ? ( /* Khung giới thiệu lộ trình Kinh tế học Vĩ mô Giai đoạn 2 */
Lộ trình Giai đoạn 2 • FSPPM MPP28 Macroeconomics

Hệ thống Mô phỏng Mô hình Kinh tế học Vĩ mô

Khung phân tích thực nghiệm các chính sách kinh tế vĩ mô: tài khóa, tiền tệ, tỷ giá hối đoái và tăng trưởng dài hạn. Đồng bộ dữ liệu học thuật cùng NotebookLM Vĩ mô FSPPM.

Mã NotebookLM:{" "} {NOTEBOOKLM_MACRO_ID}
Giáo trình tham chiếu:{" "} N. Gregory Mankiw (Ấn bản 10) & Olivier Blanchard (Ấn bản 8)
{MACRO_ROADMAP_ITEMS.map((item) => { const isUpcoming = item.status === "upcoming"; return (
{item.chapter} {isUpcoming ? "Sắp ra mắt" : "Kế hoạch"}

{item.title}

{item.subtitle}

{item.description}

{item.tags.map((tag, tIdx) => ( {tag} ))}
); })}
) : ( /* Khung mô phỏng tương tác 2 cột của module đang hoạt động */ <> {activeScenario.meta.id === "micro.consumer.rationing" && ( setRationingParams((prev) => ({ ...prev, [k]: v })) } onChangeParams={(newParams) => setRationingParams(newParams)} onResetParams={() => setRationingParams({ quotaX: rationingScenario.params.quotaX.default, }) } onSelectPreset={(p) => setRationingParams(p.params)} onNavigateScenario={handleNavigateScenario} /> )} {activeScenario.meta.id === "micro.consumer.price_ceiling" && ( setCeilingParams((prev) => ({ ...prev, [k]: v })) } onChangeParams={(newParams) => setCeilingParams(newParams)} onResetParams={() => setCeilingParams({ pFixed: priceCeilingScenario.params.pFixed.default, xCap: priceCeilingScenario.params.xCap.default, }) } onSelectPreset={(p) => setCeilingParams(p.params)} onNavigateScenario={handleNavigateScenario} /> )} {activeScenario.meta.id === "micro.consumer.corner_solution" && ( setCornerParams((prev) => ({ ...prev, [k]: v })) } onChangeParams={(newParams) => setCornerParams(newParams)} onResetParams={() => setCornerParams({ exampleCase: 1, yogurtPrice: cornerSolutionScenario.params.yogurtPrice.default, iceCreamTaste: cornerSolutionScenario.params.iceCreamTaste.default, trustFund: cornerSolutionScenario.params.trustFund.default, trustAlpha: cornerSolutionScenario.params.trustAlpha.default, foodStamp: cornerSolutionScenario.params.foodStamp.default, stampAlpha: cornerSolutionScenario.params.stampAlpha.default, }) } onSelectPreset={(p) => setCornerParams((prev) => ({ ...prev, ...p.params })) } onNavigateScenario={handleNavigateScenario} /> )} {activeScenario.meta.id === "micro.consumer.inkind_vs_cash" && ( setInkindParams((prev) => ({ ...prev, [k]: v })) } onChangeParams={(newParams) => setInkindParams(newParams)} onResetParams={() => setInkindParams({ alpha: inkindVsCashScenario.params.alpha.default, transfer: inkindVsCashScenario.params.transfer.default, }) } onSelectPreset={(p) => setInkindParams(p.params)} onNavigateScenario={handleNavigateScenario} /> )} )}
); }