76 lines
2.9 KiB
TypeScript
76 lines
2.9 KiB
TypeScript
/* ============================================================
|
||
ConstellationTab.tsx — обёртка вкладки «Группировка» с реальными данными.
|
||
Грузит состав/геометрию/расписание из API (realData.ts) и монтирует
|
||
прототипный ConstellationDashboard уже с готовыми env/domain/sched — поэтому
|
||
его mount-once замыкания (RAF/canvas) видят стабильные данные с первого рендера.
|
||
============================================================ */
|
||
import { useEffect, useState, type ComponentType } from "react";
|
||
import ConstellationDashboardImpl from "./ConstellationDashboard.jsx";
|
||
import { loadConstellationEnv, type ConstellationConfig } from "./realData";
|
||
import "./dashboard.css";
|
||
|
||
// ConstellationDashboard — JS-модуль прототипа; типизируем точку монтирования.
|
||
const ConstellationDashboard = ConstellationDashboardImpl as ComponentType<ConstellationConfig>;
|
||
|
||
type LoadState =
|
||
| { kind: "loading" }
|
||
| { kind: "error"; message: string }
|
||
| { kind: "ready"; cfg: ConstellationConfig };
|
||
|
||
export function ConstellationTab() {
|
||
const [state, setState] = useState<LoadState>({ kind: "loading" });
|
||
|
||
useEffect(() => {
|
||
let cancelled = false;
|
||
setState({ kind: "loading" });
|
||
loadConstellationEnv()
|
||
.then((cfg) => {
|
||
if (!cancelled) setState({ kind: "ready", cfg });
|
||
})
|
||
.catch((error: unknown) => {
|
||
if (!cancelled) {
|
||
setState({ kind: "error", message: error instanceof Error ? error.message : "Не удалось загрузить данные группировки." });
|
||
}
|
||
});
|
||
return () => {
|
||
cancelled = true;
|
||
};
|
||
}, []);
|
||
|
||
if (state.kind === "loading") {
|
||
return <ConstellationNotice text="Загрузка состояния группировки…" />;
|
||
}
|
||
if (state.kind === "error") {
|
||
return <ConstellationNotice text={`Ошибка загрузки: ${state.message}`} tone="error" />;
|
||
}
|
||
if (state.cfg.env.sats.length === 0) {
|
||
return <ConstellationNotice text="Нет эксплуатируемых КА с доступной трассой на горизонте планирования." />;
|
||
}
|
||
return <ConstellationDashboard env={state.cfg.env} domain={state.cfg.domain} sched={state.cfg.sched} />;
|
||
}
|
||
|
||
function ConstellationNotice({ text, tone }: { text: string; tone?: "error" }) {
|
||
return (
|
||
<div
|
||
className="cdash"
|
||
style={{
|
||
height: "100%",
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
background: "#0a0c0b",
|
||
color: tone === "error" ? "#d9685f" : "#95a19d",
|
||
fontFamily: "'IBM Plex Mono', monospace",
|
||
fontSize: 13,
|
||
letterSpacing: ".04em",
|
||
padding: 24,
|
||
textAlign: "center"
|
||
}}
|
||
>
|
||
{text}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default ConstellationTab;
|