74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
import { content } from "@deadhead/content";
|
|
import { realToGame } from "@deadhead/sim";
|
|
import { useClock } from "../clock/clock";
|
|
import { formatGameTime } from "../clock/GameClock";
|
|
import { Countdown } from "../components/Countdown";
|
|
import { GoalsCard } from "../components/GoalsCard";
|
|
import { LoanCard } from "../components/LoanCard";
|
|
import { formatCredits, locationName } from "../format";
|
|
import { useLoadedPlayer } from "../state/actions";
|
|
|
|
export function HQ() {
|
|
const state = useLoadedPlayer();
|
|
const now = useClock((s) => s.now);
|
|
const idle = state.ships.filter((s) => s.status === "idle").length;
|
|
const flying = state.ships.filter((s) => s.status === "in-flight").length;
|
|
const runsBeforeDeal = content.config.tutorialRunsBeforeDeal;
|
|
const next = [...state.activeDispatches].sort((a, b) => a.arrivalAt - b.arrivalAt)[0];
|
|
|
|
return (
|
|
<section className="space-y-4 p-4">
|
|
<h1 className="text-xl font-semibold">HQ</h1>
|
|
|
|
<div className="grid grid-cols-2 gap-3">
|
|
<Stat label="Credits" value={formatCredits(state.company.credits)} />
|
|
<Stat label="Game date" value={formatGameTime(realToGame(now, content.config))} />
|
|
<Stat label="Ships idle" value={String(idle)} />
|
|
<Stat label="Ships in flight" value={String(flying)} />
|
|
</div>
|
|
|
|
<div className="rounded-lg border border-slate-800 p-3">
|
|
<h2 className="text-sm font-semibold text-slate-300">Next arrival</h2>
|
|
{next ? (
|
|
<p className="mt-1">
|
|
{locationName(next.originId)} → {locationName(next.destinationId)} in{" "}
|
|
<Countdown to={next.arrivalAt} />
|
|
</p>
|
|
) : (
|
|
<p className="mt-1 text-sm text-slate-400">Nothing in flight.</p>
|
|
)}
|
|
</div>
|
|
|
|
{!state.tutorial && state.ships.length === 0 && (
|
|
<p className="text-sm text-slate-400">No ships yet — buy one in the Market.</p>
|
|
)}
|
|
|
|
{state.tutorial && (
|
|
<div className="rounded-lg border border-amber-500/40 bg-amber-500/10 p-3">
|
|
<h2 className="font-semibold text-amber-300">Flying for Halvorsen Lunar Freight</h2>
|
|
<p aria-label="Company runs" className="mt-1 text-sm text-slate-300">
|
|
Company runs: {Math.min(state.tutorial.runsCompleted, runsBeforeDeal)} of{" "}
|
|
{runsBeforeDeal}
|
|
</p>
|
|
<p className="mt-1 text-xs text-slate-400">
|
|
Keep flying — the old man has an offer for you.
|
|
</p>
|
|
</div>
|
|
)}
|
|
|
|
{!state.tutorial && <GoalsCard />}
|
|
|
|
{!state.tutorial && state.company.loanBalance > 0 && <LoanCard />}
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function Stat({ label, value }: { label: string; value: string }) {
|
|
return (
|
|
<div className="rounded-lg border border-slate-800 p-3">
|
|
<div className="text-xs text-slate-400">{label}</div>
|
|
<div className="mt-1 font-semibold tabular-nums">{value}</div>
|
|
</div>
|
|
);
|
|
}
|