+
Form example
+
+
+ {(field) => (
+
+ )}
+
+
+ {/*
+ Good candidate to use with `withFieldGroup`:
+ https://tanstack.com/form/latest/docs/framework/solid/guides/form-composition#reusing-groups-of-fields-in-multiple-forms
+ */}
+
+
+ {(field) => (
+
+ )}
+
+
+ {(field) => (
+
+ )}
+
+
+ {(field) => (
+
+ )}
+
+
+ getFieldErrors(state, [
+ "postalCode",
+ "houseNumber",
+ "houseNumberAdd",
+ ])
+ }
+ >
+ {(errors) =>
+ errors.length > 0 ? (
+
+ {errors}
+
+ ) : null
+ }
+
+
+
+
+ {(field) => (
+
+ )}
+
+
+
+ {(field) => (
+
+ )}
+
+
+
+
+
+ {!mutation.isSuccess && (
+
+ DEV: to successfully submit, update the call to{" "}
+ fakeSubmit in
+ the mutation.
+
+ )}
+ {mutation.isSuccess && (
+
Success!
+ )}
+
+ );
+}
diff --git a/src/routes/_auth/login.tsx b/src/routes/_auth/login.tsx
index ed45106..aa5348e 100644
--- a/src/routes/_auth/login.tsx
+++ b/src/routes/_auth/login.tsx
@@ -1,3 +1,5 @@
+import { revalidateLogic } from "@tanstack/react-form";
+import { useMutation } from "@tanstack/react-query";
import {
createFileRoute,
Link,
@@ -5,15 +7,18 @@ import {
} from "@tanstack/react-router";
import clsx from "clsx";
import { ErrorText } from "components/error-text/error-text";
-import { Button, Form, Input } from "components/form";
+import { Button, Form } from "components/form";
import { H1 } from "components/heading/heading";
+import { useAppForm } from "lib/forms";
import {
- postApiAuthLogin,
- type ValidationError,
-} from "lib/heyapi";
+ mutateAndValidate,
+ normalizeFieldErrors,
+} from "lib/forms/validation-helpers";
+import type { LoginRequest } from "lib/heyapi";
+import { postApiAuthLoginMutation } from "lib/heyapi/@tanstack/react-query.gen";
+import { zLoginRequest } from "lib/heyapi/zod.gen";
import * as m from "lib/paraglide/messages";
import { makePageTitle } from "lib/title";
-import { useState } from "react";
import z from "zod";
import style from "./login.module.scss";
@@ -34,30 +39,25 @@ export const Route = createFileRoute("/_auth/login")({
function LoginPage() {
const { redirect } = Route.useSearch();
const navigate = useNavigate();
- const [email, setEmail] = useState("");
- const [password, setPassword] = useState("");
- const [error, setError] = useState