👏

【NextJs14】NextJs14 と 便利なライブラリ【#25 Images Upload Form】

2024/01/29に公開

【#25 Images Upload Form】

YouTube: https://youtu.be/QG0gScJYi4M

https://youtu.be/QG0gScJYi4M

今回は前回作成した画像のアップロードボタンを
Shadcn-uiのフォームに組み込みます。

app/(main)/images/page.tsx
import { ImagesForm } from "./_components/images-form";

const ImagesPage = () => {
  return (
    <div className="p-6">
      <div className="flex flex-col w-full h-full">
        <div>
          <ImagesForm />
        </div>
      </div>
    </div>
  );
};
export default ImagesPage;
app/(main)/images/_components/images-form.tsx
"use client";

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

import { UploadImagesForm } from "@/components/forms/upload-images-form";
import { Button } from "@/components/ui/button";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
} from "@/components/ui/form";

const formSchema = z.object({
  images: z.object({ url: z.string() }).array(),
});

export const ImagesForm = () => {
  const [isLoading, setIsLoading] = useState(false);
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      images: [],
    },
  });

  const onSubmit = () => {
    setIsLoading(true);
    const { images } = form.getValues();
    alert(JSON.stringify(images, null, 2));
    setIsLoading(false);
  };

  return (
    <Form {...form}>
      <form
        onSubmit={form.handleSubmit(onSubmit)}
        className="flex flex-col space-y-4"
      >
        <FormField
          control={form.control}
          name="images"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Images upload button</FormLabel>
              <FormControl>
                <UploadImagesForm />
              </FormControl>
            </FormItem>
          )}
        />
        <Button type="submit" variant="primary" disabled={isLoading}>
          Submit
        </Button>
      </form>
    </Form>
  );
};

Discussion