Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 21 additions & 50 deletions src/app/RegistrationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"use client";
import { useFormState } from "react-dom";
import { useRef } from "react";

import { Button } from "@/components/ui/button";
import { useEffect, useRef } from "react";
import { Input } from "@/components/ui/input";
import {
Form,
Expand All @@ -16,33 +14,38 @@ import {

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { number, z } from "zod";

import { schema } from "./registrationSchema";
import SubmitButton from "./sumbit-button";
import { Button } from "@/components/ui/button";

export const RegistrationForm = ({
onDataAction,
onFormAction,
}: {
onDataAction: (data: z.infer<typeof schema>) => Promise<{
message: string;
user?: z.infer<typeof schema>;
issues?: string[];
}>;
onFormAction: (
additional: {
userId: number;
},
prevState: {
message: string;
success: boolean;
user?: z.infer<typeof schema>;
issues?: string[];
},
data: FormData
) => Promise<{
message: string;
success: boolean;
user?: z.infer<typeof schema>;
issues?: string[];
}>;
}) => {
const [state, formAction] = useFormState(onFormAction, {
const withId = onFormAction.bind(null, {
userId: 1
})
const [state, formAction] = useFormState(withId, {
success: false,
message: "",
});
const form = useForm<z.infer<typeof schema>>({
Expand All @@ -53,51 +56,19 @@ export const RegistrationForm = ({
email: "",
zipcode: "",
},
mode: 'all'
});

const onSubmit = async (data: z.infer<typeof schema>) => {
console.log(data);
fetch("/api/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((data) => console.log(data));
// const formData = new FormData();
// formData.append("first", data.first);
// formData.append("last", data.last);
// formData.append("email", data.email);
// fetch("/api/registerForm", {
// method: "POST",
// body: formData,
// })
// .then((response) => response.json())
// .then((data) => console.log(data));
// console.log(await onDataAction(data));
// const formData = new FormData();
// formData.append("first", data.first);
// formData.append("last", data.last);
// formData.append("email", data.email);
// console.log(await onDataAction(data));
};

const formRef = useRef<HTMLFormElement>(null);

return (
return (<>
<Button onClick={() => {
formRef.current?.requestSubmit()
}}>test Programmatic form submission </Button>
<Form {...form}>
<div>{state?.message}</div>
<form
ref={formRef}
action={formAction}
onSubmit={(evt) => {
evt.preventDefault();
form.handleSubmit(() => {
formAction(new FormData(formRef.current!));
})(evt);
}}
className="space-y-8"
>
<div className="flex gap-2">
Expand Down Expand Up @@ -158,8 +129,8 @@ export const RegistrationForm = ({
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
<SubmitButton text="Submit"></SubmitButton>
</form>
</Form>
</Form></>
);
};
29 changes: 11 additions & 18 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,40 @@ import { z } from "zod";
import { schema } from "./registrationSchema";

export default function Home() {
const onDataAction = async (data: z.infer<typeof schema>) => {
"use server";
const parsed = schema.safeParse(data);

if (parsed.success) {
console.log("User registered");
return { message: "User registered", user: parsed.data };
} else {
return {
message: "Invalid data",
issues: parsed.error.issues.map((issue) => issue.message),
};
}
};
const onFormAction = async (
additional: {
userId: number;
},
prevState: {
message: string;
success: boolean;
user?: z.infer<typeof schema>;
issues?: string[];
},
formData: FormData
) => {
"use server";
console.log(additional, formData)
const data = Object.fromEntries(formData);
const parsed = await schema.safeParseAsync(data);

if (parsed.success) {
console.log("User registered");
return { message: "User registered", user: parsed.data };
return { success: true, message: "User registered", user: parsed.data };
} else {
return {
const obj = {
success: false,
message: "Invalid data",
issues: parsed.error.issues.map((issue) => issue.message),
};
}
console.log(JSON.stringify(obj))
return obj;
}
};

return (
<div className="mx-auto max-w-xl">
<RegistrationForm
onDataAction={onDataAction}
onFormAction={onFormAction}
/>
</div>
Expand Down
17 changes: 17 additions & 0 deletions src/app/sumbit-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

import { useFormStatus } from 'react-dom';
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils";

interface SubmitButtonProps {
text: string;
className?: string;
}

export default function SubmitButton(props: SubmitButtonProps) {
const { pending, data, method, action } = useFormStatus();
return <Button
className={cn("gap-1", props.className)}
aria-disabled={pending}
disabled={pending}>{props.text}</Button>
}