Fix Finance page: remove Recharts Tooltips, defensive string coercion
CI / build-and-push (push) Successful in 37s

Remove chart Tooltip components and wrap fundingStatus.reason in
String() to eliminate possible object-as-React-child errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-24 19:04:44 -04:00
parent 6659941632
commit 1af9408c87
+12 -21
View File
@@ -1,8 +1,8 @@
import { useGameStore } from '@/store';
import { formatMoney, formatPercent, formatNumber, FUNDING_ROUNDS } from '@ai-tycoon/shared';
import { formatMoney, formatPercent, FUNDING_ROUNDS } from '@ai-tycoon/shared';
import type { FundingRoundType } from '@ai-tycoon/shared';
import { TrendingUp, TrendingDown, DollarSign, PiggyBank, BarChart3, Rocket } from 'lucide-react';
import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, LineChart, Line } from 'recharts';
import { TrendingUp, DollarSign, PiggyBank, BarChart3, Rocket } from 'lucide-react';
import { AreaChart, Area, XAxis, YAxis, ResponsiveContainer, LineChart, Line } from 'recharts';
import { canRaiseFunding } from '@ai-tycoon/game-engine';
import type { GameState } from '@ai-tycoon/shared';
@@ -10,21 +10,20 @@ export function FinancePage() {
const money = useGameStore((s) => s.economy.money);
const revenuePerTick = useGameStore((s) => s.economy.revenuePerTick);
const expensesPerTick = useGameStore((s) => s.economy.expensesPerTick);
const totalRevenue = useGameStore((s) => s.economy.totalRevenue);
const totalExpenses = useGameStore((s) => s.economy.totalExpenses);
const funding = useGameStore((s) => s.economy.funding);
const history = useGameStore((s) => s.economy.financialHistory);
const infrastructure = useGameStore((s) => s.infrastructure);
const talent = useGameStore((s) => s.talent);
const raiseFunding = useGameStore((s) => s.raiseFunding);
const gameStateForFunding: GameState = useGameStore((s) => ({
meta: s.meta, economy: s.economy, infrastructure: s.infrastructure,
compute: s.compute, research: s.research, models: s.models,
market: s.market, competitors: s.competitors, talent: s.talent,
data: s.data, reputation: s.reputation, events: s.events,
achievements: s.achievements,
}));
const state = useGameStore.getState();
const gameStateForFunding: GameState = {
meta: state.meta, economy: state.economy, infrastructure: state.infrastructure,
compute: state.compute, research: state.research, models: state.models,
market: state.market, competitors: state.competitors, talent: state.talent,
data: state.data, reputation: state.reputation, events: state.events,
achievements: state.achievements,
};
const fundingStatus = canRaiseFunding(gameStateForFunding);
const netIncome = revenuePerTick - expensesPerTick;
@@ -71,10 +70,6 @@ export function FinancePage() {
</defs>
<XAxis dataKey="tick" hide />
<YAxis hide />
<Tooltip
contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: '8px' }}
formatter={(v: number) => formatMoney(v)}
/>
<Area type="monotone" dataKey="money" stroke="#6366f1" fill="url(#cashGrad)" />
</AreaChart>
</ResponsiveContainer>
@@ -92,10 +87,6 @@ export function FinancePage() {
<LineChart data={history}>
<XAxis dataKey="tick" hide />
<YAxis hide />
<Tooltip
contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: '8px' }}
formatter={(v: number) => formatMoney(v)}
/>
<Line type="monotone" dataKey="revenue" stroke="#22c55e" dot={false} strokeWidth={2} />
<Line type="monotone" dataKey="expenses" stroke="#ef4444" dot={false} strokeWidth={2} />
</LineChart>
@@ -167,7 +158,7 @@ export function FinancePage() {
Raise {formatMoney(FUNDING_ROUNDS[fundingStatus.nextRound! as FundingRoundType].amount)}
</button>
) : (
<span className="text-xs text-warning">{fundingStatus.reason}</span>
<span className="text-xs text-warning">{String(fundingStatus.reason ?? '')}</span>
)}
</div>
</div>