🐙

【NextJs14】NextJs14 と 便利なライブラリ【#15Shadcn-ui Form 】

2023/12/29に公開

【#15Shadcn Form 】

YouTube: https://youtu.be/bBjST4vvAKE

https://youtu.be/bBjST4vvAKE

今回は前回作成した設定をshadcn-uiのformコンポーネントに反映していきます。

components/forms/user-email-form.tsx
"use client";

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

import { Button } from "@/components/ui/button";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";

const formSchema = z.object({
  email: z.string().email({ message: "Please enter email" }),
});

interface UserEmailFormProps {
  email?: string;
}

export const UserEmailForm = ({ email }: UserEmailFormProps) => {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      email: email,
    },
  });

  const onSubmit = (values: z.infer<typeof formSchema>) => {
    alert(values.email);
  };

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input placeholder="Enter Email" {...field} />
              </FormControl>
              <FormDescription>Enter your email address.</FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">Submit</Button>
      </form>
    </Form>
  );
};
app/(main)/protected/page.tsx
import Image from "next/image";
import { currentUser, UserProfile } from "@clerk/nextjs";
import { dark } from "@clerk/themes";
import { UserProfileModal } from "@/components/modals/user-profile-modal";
import { UserEmailForm } from "@/components/forms/user-email-form";

const ProtectedPage = async () => {
  const user = await currentUser();

  return (
    <div className="flex flex-col p-10">
      <ul className="flex flex-col p-6">
        <li>
          User Name: {user?.lastName} {user?.firstName}
        </li>
        <li>User Email: {user?.emailAddresses?.[0].emailAddress}</li>
        <li className="flex gap-x-2">
          User Image:{" "}
          <Image src={user?.imageUrl!} width={30} height={30} alt="User" />
        </li>
      </ul>

      <UserEmailForm email={user?.emailAddresses?.[0].emailAddress || ""} />

      <UserProfile
        appearance={{
          baseTheme: dark,
          elements: {
            card: {
              // boxShadow: "none",
            },
          },
        }}
      />
    </div>
  );
};

export default ProtectedPage;

Discussion