Compare commits

..

1 Commits

Author SHA1 Message Date
e1cf5c05b5 fix(deps): update dependency zod to v4
Some checks failed
Lint / Lint and Typecheck (push) Failing after 46s
Lint / Lint and Typecheck (pull_request) Failing after 47s
2025-07-13 00:42:20 +02:00
7 changed files with 7690 additions and 5156 deletions

View File

@@ -4,7 +4,7 @@ on:
pull_request:
push:
branches:
- "**" # matches every branch
- '**' # matches every branch
jobs:
lint_and_typecheck:
@@ -15,17 +15,14 @@ jobs:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: "pnpm"
cache: 'npm'
- name: Install dependencies
run: pnpm install
run: npm ci
- name: Run check
run: pnpm run check
run: npm run check

View File

@@ -29,6 +29,7 @@ The projects code is structured using React/Next.js with TypeScript, focusing
The calculator models your FIRE journey in two phases:
1. **Accumulation:**
- Your starting capital is grown by your expected CAGR (~7% by default).
- Monthly savings are added for each year until retirement.
- Every variable can be adjusted live (capital, savings, age, growth, inflation, spending, target retirement).
@@ -57,11 +58,11 @@ To run locally:
```
2. **Install dependencies**
```bash
pnpm install
npm install
```
3. **Run the app**
```bash
pnpm run dev
npm run dev
```
4. Visit [http://localhost:3000](http://localhost:3000) and unleash the fire.

7649
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
"scripts": {
"build": "next build",
"check": "next lint && tsc --noEmit",
"dev": "next dev --turbopack",
"dev": "next dev --turbo",
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
"format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
"lint:fix": "next lint --fix",
@@ -24,7 +24,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.525.0",
"next": "^15.4.1",
"next": "^15.2.3",
"next-plausible": "^3.12.4",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@@ -40,8 +40,7 @@
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"eslint": "9.31.0",
"eslint-config-next": "15.4.1",
"eslint-plugin-react-hooks": "5.2.0",
"eslint-config-next": "15.3.5",
"postcss": "8.5.6",
"prettier": "3.6.2",
"prettier-plugin-tailwindcss": "0.6.14",
@@ -53,5 +52,5 @@
"ct3aMetadata": {
"initVersion": "7.39.3"
},
"packageManager": "pnpm@10.13.1"
"packageManager": "npm@11.4.2"
}

5055
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +0,0 @@
ignoredBuiltDependencies:
- unrs-resolver
onlyBuiltDependencies:
- '@tailwindcss/oxide'
- sharp

View File

@@ -120,7 +120,7 @@ export default function FireCalculatorForm() {
const [showing4percent, setShowing4percent] = useState(false);
// Initialize form with default values
const form = useForm<z.input<typeof formSchema>, undefined, FormValues>({
const form = useForm<FormValues>({
resolver: zodResolver(formSchema),
defaultValues: {
startingCapital: 50000,
@@ -258,18 +258,11 @@ export default function FireCalculatorForm() {
<Input
placeholder="e.g., 10000"
type="number"
value={field.value as number | string | undefined}
onChange={(e) => {
field.onChange(
e.target.value === ""
? undefined
: Number(e.target.value),
);
{...field}
onChange={(value) => {
field.onChange(value);
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
@@ -286,18 +279,11 @@ export default function FireCalculatorForm() {
<Input
placeholder="e.g., 500"
type="number"
value={field.value as number | string | undefined}
onChange={(e) => {
field.onChange(
e.target.value === ""
? undefined
: Number(e.target.value),
);
{...field}
onChange={(value) => {
field.onChange(value);
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
@@ -314,18 +300,11 @@ export default function FireCalculatorForm() {
<Input
placeholder="e.g., 30"
type="number"
value={field.value as number | string | undefined}
onChange={(e) => {
field.onChange(
e.target.value === ""
? undefined
: Number(e.target.value),
);
{...field}
onChange={(value) => {
field.onChange(value);
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
@@ -342,18 +321,11 @@ export default function FireCalculatorForm() {
<Input
placeholder="e.g., 90"
type="number"
value={field.value as number | string | undefined}
onChange={(e) => {
field.onChange(
e.target.value === ""
? undefined
: Number(e.target.value),
);
{...field}
onChange={(value) => {
field.onChange(value);
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
@@ -371,18 +343,11 @@ export default function FireCalculatorForm() {
placeholder="e.g., 7"
type="number"
step="0.1"
value={field.value as number | string | undefined}
onChange={(e) => {
field.onChange(
e.target.value === ""
? undefined
: Number(e.target.value),
);
{...field}
onChange={(value) => {
field.onChange(value);
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
@@ -400,18 +365,11 @@ export default function FireCalculatorForm() {
placeholder="e.g., 2"
type="number"
step="0.1"
value={field.value as number | string | undefined}
onChange={(e) => {
field.onChange(
e.target.value === ""
? undefined
: Number(e.target.value),
);
{...field}
onChange={(value) => {
field.onChange(value);
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
@@ -430,18 +388,11 @@ export default function FireCalculatorForm() {
<Input
placeholder="e.g., 2000"
type="number"
value={field.value as number | string | undefined}
onChange={(e) => {
field.onChange(
e.target.value === ""
? undefined
: Number(e.target.value),
);
{...field}
onChange={(value) => {
field.onChange(value);
void form.handleSubmit(onSubmit)();
}}
onBlur={field.onBlur}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormMessage />
@@ -455,13 +406,11 @@ export default function FireCalculatorForm() {
name="retirementAge"
render={({ field }) => (
<FormItem>
<FormLabel>
Retirement Age: {field.value as number}
</FormLabel>
<FormLabel>Retirement Age: {field.value}</FormLabel>
<FormControl>
<Slider
name="retirementAge"
value={[field.value as number]}
value={[field.value]}
min={25}
max={75}
step={1}
@@ -614,8 +563,8 @@ export default function FireCalculatorForm() {
<ReferenceLine
x={
irlYear +
(Number(form.getValues("retirementAge")) -
Number(form.getValues("currentAge")))
(form.getValues("retirementAge") -
form.getValues("currentAge"))
}
stroke="var(--primary)"
strokeWidth={2}
@@ -630,7 +579,7 @@ export default function FireCalculatorForm() {
x={
irlYear +
(result.retirementAge4percent -
Number(form.getValues("currentAge")))
form.getValues("currentAge"))
}
stroke="var(--secondary)"
strokeWidth={1}
@@ -693,8 +642,8 @@ export default function FireCalculatorForm() {
</CardHeader>
<CardContent>
<p className="text-3xl font-bold">
{Number(form.getValues("lifeExpectancy")) -
Number(form.getValues("retirementAge"))}
{form.getValues("lifeExpectancy") -
form.getValues("retirementAge")}
</p>
</CardContent>
</Card>
@@ -725,7 +674,7 @@ export default function FireCalculatorForm() {
</CardHeader>
<CardContent>
<p className="text-3xl font-bold">
{Number(form.getValues("lifeExpectancy")) -
{form.getValues("lifeExpectancy") -
(result.retirementAge4percent ?? 0)}
</p>
</CardContent>