fix(chart): keep zero-year chara and ephemeris dates apart

A zero-year Chara period is shown as 0 years instead of failing the whole chart. Switching ephemeris dates drops the previous day immediately and can be retried. Missing birth data links to chart settings.
This commit is contained in:
jesse-ux
2026-09-25 02:10:48 +08:00
parent 82c8aeb06a
commit 19ea0f06c1
25 changed files with 744 additions and 60 deletions
@@ -1,6 +1,6 @@
import { chartLayerFailureCopy } from "@/lib/chart-view-failure";
import type { ChartViewFailureStatus, ChartViewOk } from "@/lib/chart-view-contract";
import { CHART_VIEW_COPY } from "@/lib/chart-view-labels";
import { CHARA_ZERO_YEAR_LABEL, CHARA_ZERO_YEAR_NOTE, CHART_VIEW_COPY } from "@/lib/chart-view-labels";
function Track({
title,
@@ -28,9 +28,11 @@ function Track({
>
<p>
<strong>{period.label}</strong>
<span>{period.start} – {period.end}</span>
<span>{period.zeroYear ? CHARA_ZERO_YEAR_LABEL : `${period.start} – ${period.end}`}</span>
</p>
{period.antardashas.length > 0 ? (
{period.zeroYear ? (
<p className="chart-page-note">{CHARA_ZERO_YEAR_NOTE}</p>
) : period.antardashas.length > 0 ? (
<ul>
{period.antardashas.map((antar) => (
<li key={`${antar.lord}-${antar.start}`} className={antar.current ? "is-current" : undefined}>
@@ -12,6 +12,7 @@ import {
} from "@/lib/chart-view-contract";
import type { ChartViewLayer } from "@/lib/chart-view-engine";
import { CHART_VIEW_COPY } from "@/lib/chart-view-labels";
import { CHART_SETTINGS_HREF } from "@/lib/settings-url";
import { chartLayerFailureCopy } from "@/lib/chart-view-failure";
import { ChartPageSkeleton } from "./chart-page-skeleton";
import { ChartBasicsTab } from "./chart-basics-tab";
@@ -36,6 +37,19 @@ function WaitingNote({ copy }: { copy: string }) {
return <p className="chart-page-note">{copy}</p>;
}
const PROFILE_ENTRY_REASONS = new Set([
"profile_incomplete",
"profile_query_error",
"adopted_calculation_incomplete",
"timezone_resolver_failure",
]);
function showsProfileEntry(view: ChartViewResponse): boolean {
if (view.status === "ok") return false;
if (view.status === "birth_profile_incomplete") return true;
return view.reason != null && PROFILE_ENTRY_REASONS.has(view.reason);
}
export function ChartPageView({
view,
pendingLayers,
@@ -75,7 +89,11 @@ export function ChartPageView({
>
{view != null && view.status !== "ok" ? (
<section className="chart-page-message">
{view.status === "birth_profile_incomplete" ? <h2>{CHART_VIEW_COPY.profileEntryTitle}</h2> : null}
<p>{view.message}</p>
{showsProfileEntry(view) ? (
<a className="button-primary" href={CHART_SETTINGS_HREF}>{CHART_VIEW_COPY.profileEntryAction}</a>
) : null}
</section>
) : (
<div className="chart-page-body">