1 Commits

Author SHA1 Message Date
61fb17f984 fix(deps): update dependency recharts to v3
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
Lint / Lint and Typecheck (push) Failing after 24s
Lint / Lint and Typecheck (pull_request) Failing after 24s
2025-11-15 16:03:07 +00:00
7 changed files with 476 additions and 453 deletions

View File

@@ -13,7 +13,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4

View File

@@ -23,39 +23,40 @@
"@t3-oss/env-nextjs": "^0.13.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.554.0",
"lucide-react": "^0.553.0",
"next": "16.0.3",
"next-plausible": "^3.12.4",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-hook-form": "^7.56.1",
"recharts": "^2.15.3",
"recharts": "^3.0.0",
"tailwind-merge": "^3.2.0",
"zod": "^4.0.0"
},
"devDependencies": {
"@tailwindcss/postcss": "4.1.17",
"@types/node": "24.10.1",
"@types/react": "19.2.6",
"@types/react": "19.2.5",
"@types/react-dom": "19.2.3",
"eslint": "9.39.1",
"eslint-config-next": "16.0.3",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-react-hooks": "5.2.0",
"postcss": "8.5.6",
"prettier": "3.6.2",
"prettier-plugin-tailwindcss": "0.7.1",
"tailwindcss": "4.1.17",
"tw-animate-css": "1.4.0",
"typescript": "5.9.3",
"typescript-eslint": "8.47.0"
"typescript-eslint": "8.46.4"
},
"ct3aMetadata": {
"initVersion": "7.39.3"
},
"packageManager": "pnpm@10.23.0",
"packageManager": "pnpm@10.22.0",
"pnpm": {
"overrides": {
"@types/react": "19.2.6",
"@types/react": "19.2.5",
"@types/react-dom": "19.2.3"
}
}

832
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
"use client";
import { useState, useEffect } from "react";
import type React from "react";
import {
type LucideIcon,
HandCoins,
@@ -113,15 +112,14 @@ export default function MultiIconPattern({ opacity = 0.2, spacing = 160 }) {
Target,
];
const [icons, setIcons] = useState<React.ReactElement[]>([]);
useEffect(() => {
if (rows === 0 || columns === 0) {
setIcons([]);
return;
}
const iconElements: React.ReactElement[] = [];
const renderIcons = ({
rows,
columns,
}: {
rows: number;
columns: number;
}) => {
const icons = [];
for (let y = 0; y < rows; y++) {
for (let x = 0; x < columns; x++) {
// Pick a random icon component from the array
@@ -132,30 +130,28 @@ export default function MultiIconPattern({ opacity = 0.2, spacing = 160 }) {
const size = 28 + Math.floor(Math.random() * 8);
const xOffset = Math.floor(Math.random() * (spacing / 1.618));
const yOffset = Math.floor(Math.random() * (spacing / 1.618));
const rotation = Math.round((Math.random() - 0.5) * 30);
iconElements.push(
icons.push(
<IconComponent
key={`icon-${String(x)}-${String(y)}`}
key={`icon-${x}-${y}`}
size={size}
className="text-primary fixed"
style={{
left: `${String(x * spacing + xOffset)}px`,
top: `${String(y * spacing + yOffset)}px`,
left: `${x * spacing + xOffset}px`,
top: `${y * spacing + yOffset}px`,
opacity: opacity,
transform: `rotate(${String(rotation)}deg)`,
transform: `rotate(${Math.round((Math.random() - 0.5) * 30)}deg)`,
}}
/>,
);
}
}
setIcons(iconElements);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rows, columns, spacing, opacity]);
return icons;
};
return (
<div className="absolute h-full w-full">
{width > 0 && icons}
{width > 0 && renderIcons({ rows, columns })}
</div>
);
}

View File

@@ -216,7 +216,7 @@ export default function FireCalculatorForm() {
return [0, 0];
})();
if (retirementIndex === -1) {
if (retirementIndex === -1 || !retirementData) {
setResult({
fireNumber: null,
fireNumber4percent: null,
@@ -246,13 +246,7 @@ export default function FireCalculatorForm() {
</CardHeader>
<CardContent>
<Form {...form}>
<form
onSubmit={(e) => {
e.preventDefault();
void form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
<FormField
control={form.control}
@@ -271,8 +265,7 @@ export default function FireCalculatorForm() {
? undefined
: Number(e.target.value),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
@@ -300,8 +293,7 @@ export default function FireCalculatorForm() {
? undefined
: Number(e.target.value),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
@@ -329,8 +321,7 @@ export default function FireCalculatorForm() {
? undefined
: Number(e.target.value),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
@@ -358,8 +349,7 @@ export default function FireCalculatorForm() {
? undefined
: Number(e.target.value),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
@@ -388,8 +378,7 @@ export default function FireCalculatorForm() {
? undefined
: Number(e.target.value),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
@@ -418,8 +407,7 @@ export default function FireCalculatorForm() {
? undefined
: Number(e.target.value),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
@@ -449,8 +437,7 @@ export default function FireCalculatorForm() {
? undefined
: Number(e.target.value),
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
@@ -480,8 +467,7 @@ export default function FireCalculatorForm() {
step={1}
onValueChange={(value: number[]) => {
field.onChange(value[0]);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.handleSubmit(onSubmit)();
void form.handleSubmit(onSubmit)();
}}
className="py-4"
/>

View File

@@ -135,12 +135,12 @@ function ChartTooltipContent({
return null;
}
const item = payload[0];
const key = labelKey ?? String(item.dataKey ?? item.name ?? "value");
const [item] = payload;
const key = `${labelKey ?? item?.dataKey ?? item?.name ?? "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const value =
!labelKey && typeof label === "string"
? (label in config && config[label].label ? config[label].label : undefined) ?? label
? (config[label]?.label ?? label)
: itemConfig?.label;
if (labelFormatter) {
@@ -182,7 +182,7 @@ function ChartTooltipContent({
{!nestLabel ? tooltipLabel : null}
<div className="grid gap-1.5">
{payload.map((item, index) => {
const key = nameKey ?? String(item.name ?? item.dataKey ?? "value");
const key = `${nameKey ?? item.name ?? item.dataKey ?? "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const indicatorColor: string | undefined =
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -196,7 +196,7 @@ function ChartTooltipContent({
indicator === "dot" && "items-center",
)}
>
{formatter && item.value !== undefined && item.name ? (
{formatter && item?.value !== undefined && item.name ? (
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
formatter(item.value, item.name, item, index, item.payload)
) : (

View File

@@ -134,7 +134,7 @@ function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
const { error, formMessageId } = useFormField();
const body = error ? (error.message ?? "") : props.children;
const body = error ? String(error?.message ?? "") : props.children;
if (!body) {
return null;