Fix Finance page: remove Recharts Tooltips, defensive string coercion
CI / build-and-push (push) Successful in 37s
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:
@@ -1,8 +1,8 @@
|
|||||||
import { useGameStore } from '@/store';
|
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 type { FundingRoundType } from '@ai-tycoon/shared';
|
||||||
import { TrendingUp, TrendingDown, DollarSign, PiggyBank, BarChart3, Rocket } from 'lucide-react';
|
import { TrendingUp, DollarSign, PiggyBank, BarChart3, Rocket } from 'lucide-react';
|
||||||
import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, LineChart, Line } from 'recharts';
|
import { AreaChart, Area, XAxis, YAxis, ResponsiveContainer, LineChart, Line } from 'recharts';
|
||||||
import { canRaiseFunding } from '@ai-tycoon/game-engine';
|
import { canRaiseFunding } from '@ai-tycoon/game-engine';
|
||||||
import type { GameState } from '@ai-tycoon/shared';
|
import type { GameState } from '@ai-tycoon/shared';
|
||||||
|
|
||||||
@@ -10,21 +10,20 @@ export function FinancePage() {
|
|||||||
const money = useGameStore((s) => s.economy.money);
|
const money = useGameStore((s) => s.economy.money);
|
||||||
const revenuePerTick = useGameStore((s) => s.economy.revenuePerTick);
|
const revenuePerTick = useGameStore((s) => s.economy.revenuePerTick);
|
||||||
const expensesPerTick = useGameStore((s) => s.economy.expensesPerTick);
|
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 funding = useGameStore((s) => s.economy.funding);
|
||||||
const history = useGameStore((s) => s.economy.financialHistory);
|
const history = useGameStore((s) => s.economy.financialHistory);
|
||||||
const infrastructure = useGameStore((s) => s.infrastructure);
|
const infrastructure = useGameStore((s) => s.infrastructure);
|
||||||
const talent = useGameStore((s) => s.talent);
|
const talent = useGameStore((s) => s.talent);
|
||||||
const raiseFunding = useGameStore((s) => s.raiseFunding);
|
const raiseFunding = useGameStore((s) => s.raiseFunding);
|
||||||
|
|
||||||
const gameStateForFunding: GameState = useGameStore((s) => ({
|
const state = useGameStore.getState();
|
||||||
meta: s.meta, economy: s.economy, infrastructure: s.infrastructure,
|
const gameStateForFunding: GameState = {
|
||||||
compute: s.compute, research: s.research, models: s.models,
|
meta: state.meta, economy: state.economy, infrastructure: state.infrastructure,
|
||||||
market: s.market, competitors: s.competitors, talent: s.talent,
|
compute: state.compute, research: state.research, models: state.models,
|
||||||
data: s.data, reputation: s.reputation, events: s.events,
|
market: state.market, competitors: state.competitors, talent: state.talent,
|
||||||
achievements: s.achievements,
|
data: state.data, reputation: state.reputation, events: state.events,
|
||||||
}));
|
achievements: state.achievements,
|
||||||
|
};
|
||||||
const fundingStatus = canRaiseFunding(gameStateForFunding);
|
const fundingStatus = canRaiseFunding(gameStateForFunding);
|
||||||
|
|
||||||
const netIncome = revenuePerTick - expensesPerTick;
|
const netIncome = revenuePerTick - expensesPerTick;
|
||||||
@@ -71,10 +70,6 @@ export function FinancePage() {
|
|||||||
</defs>
|
</defs>
|
||||||
<XAxis dataKey="tick" hide />
|
<XAxis dataKey="tick" hide />
|
||||||
<YAxis 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)" />
|
<Area type="monotone" dataKey="money" stroke="#6366f1" fill="url(#cashGrad)" />
|
||||||
</AreaChart>
|
</AreaChart>
|
||||||
</ResponsiveContainer>
|
</ResponsiveContainer>
|
||||||
@@ -92,10 +87,6 @@ export function FinancePage() {
|
|||||||
<LineChart data={history}>
|
<LineChart data={history}>
|
||||||
<XAxis dataKey="tick" hide />
|
<XAxis dataKey="tick" hide />
|
||||||
<YAxis 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="revenue" stroke="#22c55e" dot={false} strokeWidth={2} />
|
||||||
<Line type="monotone" dataKey="expenses" stroke="#ef4444" dot={false} strokeWidth={2} />
|
<Line type="monotone" dataKey="expenses" stroke="#ef4444" dot={false} strokeWidth={2} />
|
||||||
</LineChart>
|
</LineChart>
|
||||||
@@ -167,7 +158,7 @@ export function FinancePage() {
|
|||||||
Raise {formatMoney(FUNDING_ROUNDS[fundingStatus.nextRound! as FundingRoundType].amount)}
|
Raise {formatMoney(FUNDING_ROUNDS[fundingStatus.nextRound! as FundingRoundType].amount)}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-xs text-warning">{fundingStatus.reason}</span>
|
<span className="text-xs text-warning">{String(fundingStatus.reason ?? '')}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user