"use client";
import ButtonPrimary from "@/shared/ButtonPrimary";
import ButtonSecondary from "@/shared/ButtonSecondary";
import React, { FC, useState } from "react";
import { Controller, useFieldArray } from "react-hook-form";
import Image from "next/image";
import Checkbox from "@/shared/Checkbox";
import FormItem from "./FormItem";
import Input from "@/shared/Input";
export interface PageAddListing7Props {
formData: any[];
errors: any;
control: any;
register: any;
handleSubmit: any;
prevPageHandler: any;
nextPageHandler: any;
setFormData: any;
watch: any;
setError: any;
coverImgee: any;
setCoverImage: any;
image1: any;
image2: any;
image3: any;
image4: any;
setImage1: any;
setImage2: any;
setImage3: any;
setImage4: any;
data2: any;
}
const PageAddListing7: FC<PageAddListing7Props> = ({
formData,
errors,
control,
register,
handleSubmit,
prevPageHandler,
nextPageHandler,
setFormData,
watch,
setError,
coverImgee,
setCoverImage,
image1,
image2,
image3,
image4,
setImage4,
setImage1,
setImage2,
setImage3,
data2,
}) => {
const [multipleCategory, setMultipleCategory] = useState(false);
const { fields, append, remove } = useFieldArray({
control,
name: "entries",
});
console.log("fields")
return (
<>
<div className="w-14 border-b border-neutral-200 dark:border-neutral-700"></div>
{/* FORM */}
<form
className="space-y-8"
onSubmit={handleSubmit((data: any) => {
setFormData({ ...formData, ...data });
nextPageHandler();
})}
>
{multipleCategory ? null : (
<div>
<div>
<h2 className="text-2xl font-semibold">Pictures of the hall</h2>
<span className="block mt-2 text-neutral-500 dark:text-neutral-400">
A few beautiful photos will help customers have more sympathy
for your hall.
</span>
</div>
<div>
<span className="text-lg font-semibold">Cover image</span>
<div className="mt-5 ">
<div className="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-neutral-300 dark:border-neutral-6000 border-dashed rounded-md">
<div className="space-y-1 text-center">
{coverImgee ? (
<Image
src={URL.createObjectURL(coverImgee)}
alt="image"
className="object-cover"
width={200}
height={200}
/>
) : (
<svg
className="mx-auto h-12 w-12 text-neutral-400"
stroke="currentColor"
fill="none"
viewBox="0 0 48 48"
aria-hidden="true"
>
<path
d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
></path>
</svg>
)}
<div className="flex text-sm text-neutral-6000 dark:text-neutral-300">
<label
htmlFor="file-upload"
className="relative cursor-pointer rounded-md font-medium text-primary-6000 hover:text-primary-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-primary-500"
>
<Controller
name="image_0"
control={control}
rules={{ required: "Please select a cover image." }}
render={({ field }) => (
<label
htmlFor="fileInput"
className="cursor-pointer bg-transparent border-none outline-none focus:outline-none"
>
<span className="">Upload a file</span>
<input
type="file"
id="fileInput"
onChange={(e: any) => {
const selectedFile = e.target.files[0];
if (selectedFile && selectedFile.size > 0) {
data2.append("image[0]", selectedFile);
console.log("settt");
} else {
// Handle the case when no file is selected or the file is empty
setError(
"image_0",
"Please select a valid file."
);
}
field.onChange(selectedFile);
setCoverImage(e.target.files[0]);
}}
className="w-full absolute h-full opacity-0 cursor-pointer"
/>
</label>
)}
/>
</label>
<p className="pl-1">or drag and drop</p>
</div>
<p className="text-xs text-neutral-500 dark:text-neutral-400">
PNG, JPG, GIF up to 10MB
</p>
</div>
</div>
</div>
<span className="text-red-500 text-sm mt-2">
{errors["image_0"] && errors["image_0"].message}
</span>
</div>
<div>
<span className="text-lg font-semibold">Picture one</span>
<div className="mt-5 ">
<div className="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-neutral-300 dark:border-neutral-6000 border-dashed rounded-md">
<div className="space-y-1 text-center">
{image1 ? (
<Image
src={URL.createObjectURL(image1)}
alt="image"
className="object-cover"
width={200}
height={200}
/>
) : (
<svg
className="mx-auto h-12 w-12 text-neutral-400"
stroke="currentColor"
fill="none"
viewBox="0 0 48 48"
aria-hidden="true"
>
<path
d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
></path>
</svg>
)}
<div className="flex text-sm text-neutral-6000 dark:text-neutral-300">
<label
htmlFor="file-upload"
className="relative cursor-pointer rounded-md font-medium text-primary-6000 hover:text-primary-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-primary-500"
>
<Controller
name="image_1"
control={control}
rules={{ required: "Please select an image." }}
render={({ field }) => (
<label
htmlFor="image_1"
className="cursor-pointer bg-transparent border-none outline-none focus:outline-none"
>
<span className="">Upload a file</span>
<input
type="file"
id="image_1"
onChange={(e: any) => {
const selectedFile = e.target.files[0];
field.onChange(selectedFile);
setImage1(e.target.files[0]);
}}
className="w-full absolute h-full opacity-0 cursor-pointer"
/>
</label>
)}
/>
</label>
<p className="pl-1">or drag and drop</p>
</div>
<p className="text-xs text-neutral-500 dark:text-neutral-400">
PNG, JPG, GIF up to 10MB
</p>
</div>
</div>
</div>
<span className="text-red-500 text-sm mt-2">
{errors["image_1"] && errors["image_1"].message}
</span>
</div>
<div>
<span className="text-lg font-semibold">Picture two</span>
<div className="mt-5 ">
<div className="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-neutral-300 dark:border-neutral-6000 border-dashed rounded-md">
<div className="space-y-1 text-center">
{image2 ? (
<Image
src={URL.createObjectURL(image2)}
alt="image"
className="object-cover"
width={200}
height={200}
/>
) : (
<svg
className="mx-auto h-12 w-12 text-neutral-400"
stroke="currentColor"
fill="none"
viewBox="0 0 48 48"
aria-hidden="true"
>
<path
d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
></path>
</svg>
)}
<div className="flex text-sm text-neutral-6000 dark:text-neutral-300">
<label
htmlFor="image_2"
className="relative cursor-pointer rounded-md font-medium text-primary-6000 hover:text-primary-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-primary-500"
>
<Controller
name="image_2"
control={control}
rules={{ required: "Please select an image." }}
render={({ field }) => (
<label
htmlFor="image_2"
className="cursor-pointer bg-transparent border-none outline-none focus:outline-none"
>
<span className="">Upload a file</span>
<input
type="file"
id="image_2"
onChange={(e: any) => {
const selectedFile = e.target.files[0];
field.onChange(selectedFile);
setImage2(e.target.files[0]);
}}
className="w-full absolute h-full opacity-0 cursor-pointer"
/>
</label>
)}
/>
</label>
<p className="pl-1">or drag and drop</p>
</div>
<p className="text-xs text-neutral-500 dark:text-neutral-400">
PNG, JPG, GIF up to 10MB
</p>
</div>
</div>
</div>
<span className="text-red-500 text-sm mt-2">
{errors["image_2"] && errors["image_2"].message}
</span>
</div>
<div>
<span className="text-lg font-semibold">Picture three</span>
<div className="mt-5 ">
<div className="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-neutral-300 dark:border-neutral-6000 border-dashed rounded-md">
<div className="space-y-1 text-center">
{image3 ? (
<Image
src={URL.createObjectURL(image3)}
alt="image"
className="object-cover"
width={200}
height={200}
/>
) : (
<svg
className="mx-auto h-12 w-12 text-neutral-400"
stroke="currentColor"
fill="none"
viewBox="0 0 48 48"
aria-hidden="true"
>
<path
d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
></path>
</svg>
)}
<div className="flex text-sm text-neutral-6000 dark:text-neutral-300">
<label
htmlFor="image_2"
className="relative cursor-pointer rounded-md font-medium text-primary-6000 hover:text-primary-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-primary-500"
>
<Controller
name="image_3"
control={control}
rules={{ required: "Please select an image." }}
render={({ field }) => (
<label
htmlFor="image_3"
className="cursor-pointer bg-transparent border-none outline-none focus:outline-none"
>
<span className="">Upload a file</span>
<input
type="file"
id="image_3"
onChange={(e: any) => {
const selectedFile = e.target.files[0];
field.onChange(selectedFile);
setImage3(e.target.files[0]);
}}
className="w-full absolute h-full opacity-0 cursor-pointer"
/>
</label>
)}
/>
</label>
<p className="pl-1">or drag and drop</p>
</div>
<p className="text-xs text-neutral-500 dark:text-neutral-400">
PNG, JPG, GIF up to 10MB
</p>
</div>
</div>
</div>
<span className="text-red-500 text-sm mt-2">
{errors["image_3"] && errors["image_3"].message}
</span>
</div>
<div>
<span className="text-lg font-semibold">Picture four</span>
<div className="mt-5 ">
<div className="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-neutral-300 dark:border-neutral-6000 border-dashed rounded-md">
<div className="space-y-1 text-center">
{image4 ? (
<Image
src={URL.createObjectURL(image4)}
alt="image"
className="object-cover"
width={200}
height={200}
/>
) : (
<svg
className="mx-auto h-12 w-12 text-neutral-400"
stroke="currentColor"
fill="none"
viewBox="0 0 48 48"
aria-hidden="true"
>
<path
d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
></path>
</svg>
)}
<div className="flex text-sm text-neutral-6000 dark:text-neutral-300">
<label
htmlFor="image_4"
className="relative cursor-pointer rounded-md font-medium text-primary-6000 hover:text-primary-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-primary-500"
>
<Controller
name="image_4"
control={control}
rules={{ required: "Please select an image." }}
render={({ field }) => (
<label
htmlFor="image_4"
className="cursor-pointer bg-transparent border-none outline-none focus:outline-none"
>
<span className="">Upload a file</span>
<input
type="file"
id="image_4"
onChange={(e: any) => {
const selectedFile = e.target.files[0];
field.onChange(selectedFile);
setImage4(e.target.files[0]);
}}
className="w-full absolute h-full opacity-0 cursor-pointer"
/>
</label>
)}
/>
</label>
<p className="pl-1">or drag and drop</p>
</div>
<p className="text-xs text-neutral-500 dark:text-neutral-400">
PNG, JPG, GIF up to 10MB
</p>
</div>
</div>
</div>
<span className="text-red-500 text-sm mt-2">
{errors["image_4"] && errors["image_4"].message}
</span>
</div>
</div>
)}
{/* ----------------- */}
<div className="mt-6 flex flex">
<Checkbox
label="Check if you have more than one category for this hall"
name="mutiple-halls"
onChange={() => setMultipleCategory((prevState) => !prevState)}
defaultChecked={false}
/>
</div>
/* this display on my browser*/
<p>{multipleCategory}</p>
{multipleCategory ? (
<div className="space-y-8 border rounded p-4">
{/* ITEM */}
<FormItem label="Size (Acreage (m2))" desc="How large the hall is">
<Input
placeholder="..."
type="number"
{...register("size", {
required: {
value: true,
message: "size is required", // Set your custom error message
},
})}
/>
{errors?.size && (
<p className="text-red-500 text-sm mt-1">
{`${errors?.size?.message}`}
</p>
)}
</FormItem>
<FormItem
label="Seat capacity"
desc="The number of seats the hall has"
>
<Input
placeholder="100"
type="number"
{...register("seat_capacity", {
required: {
value: true,
message: "size is required", // Set your custom error message
},
})}
/>
{errors?.seat_capacity && (
<p className="text-red-500 text-sm mt-1">
{`${errors?.seat_capacity?.message}`}
</p>
)}
</FormItem>
<FormItem label="Amount " desc="What the cost of the hall is">
<Input
placeholder="..."
type="number"
{...register("amount", {
required: {
value: true,
message: "amount is required", // Set your custom error message
},
})}
/>
{errors?.size && (
<p className="text-red-500 text-sm mt-1">
{`${errors?.size?.message}`}
</p>
)}
</FormItem>
<div className="flex justify-end space-x-5">
<ButtonPrimary type="submit">{"Add Row"}</ButtonPrimary>
</div>
</div>
) : null}
/* this does not display on my browser*/
{multipleCategory?
fields.map((item, index) => (
<div key={item.id}>
{/* Your form fields for each entry */}
<FormItem
label={`Size (Acreage (m2)) for Entry ${index + 1}`}
desc="How large the hall is"
>
<Input
placeholder="..."
type="number"
{...control.fields[index].size}
/>
</FormItem>
<FormItem
label={`Seat capacity for Entry ${index + 1}`}
desc="The number of seats the hall has"
>
<Input
placeholder="100"
type="number"
{...control.fields[index].seat_capacity}
/>
</FormItem>
<FormItem
label={`Amount for Entry ${index + 1}`}
desc="What the cost of the hall is"
>
<Input
placeholder="..."
type="number"
{...control.fields[index].amount}
/>
</FormItem>
<div className="flex justify-end space-x-5">
{index === fields.length - 1 && (
<ButtonPrimary type="button" onClick={() => append({})}>
Add Row
</ButtonPrimary>
)}
{index > 0 && (
<ButtonSecondary type="button" onClick={() => remove(index)}>
Remove Row
</ButtonSecondary>
)}
</div>
</div>
)): null}
{/* ----------------- */}
<div className="flex justify-end space-x-5">
<ButtonSecondary type="button" onClick={prevPageHandler}>
Go back
</ButtonSecondary>
<ButtonPrimary type="submit">{"Continue"}</ButtonPrimary>
</div>
</form>
</>
);
};
export default PageAddListing7;
我想要实现的是,当我单击添加行时,它应该克隆表单以允许用户输入多个条目,第一部分是我不使用 useFieldArray 的表单的第一部分显示在我的 nexjs 应用程序上,但是为了改进它,我决定使用 useFieldArray 来允许用户添加行并创建更多条目。代码块不会显示在浏览器中。有人在使用 nextjs 时遇到过类似的问题吗?
我需要帮助,但我没有收到任何错误。
从最初的外观来看,您的代码似乎是正确的,但它可能与复选框组件有关:
您可以尝试最初将 multipleCategories 设置为 true 进行调试吗?如果仍然不起作用,请尝试添加使用效果并观察 fields 属性、控制台日志以确保其工作;下一步是删除 multipleCategory 检查并确保它不会导致错误。