ISSUE 3: add image uploader and include add FAQ logic
This commit is contained in:
@@ -13,7 +13,12 @@ import MkdSDK from "@/utils/MkdSDK";
|
||||
import useDelayUnmount from "@/hooks/useDelayUnmount";
|
||||
import { useContext } from "react";
|
||||
import { GlobalContext, showToast } from "@/globalContext";
|
||||
import { DRAFT_STATUS, IMAGE_STATUS, SPACE_STATUS, SPACE_VISIBILITY } from "@/utils/constants";
|
||||
import {
|
||||
DRAFT_STATUS,
|
||||
IMAGE_STATUS,
|
||||
SPACE_STATUS,
|
||||
SPACE_VISIBILITY,
|
||||
} from "@/utils/constants";
|
||||
import { Link } from "react-router-dom";
|
||||
import CustomSelectV2 from "@/components/CustomSelectV2";
|
||||
import useCancellation from "@/hooks/api/useCancellation";
|
||||
@@ -110,14 +115,30 @@ const SpaceDetailsTwo = () => {
|
||||
|
||||
for (let i = 0; i < pictures.length; i++) {
|
||||
const file = pictures[i];
|
||||
const allowedTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/svg+xml'];
|
||||
const allowedTypes = [
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
"image/svg+xml",
|
||||
];
|
||||
if (file?.type && !allowedTypes.includes(file?.type)) {
|
||||
showToast(globalDispatch, 'Invalid file type. Only JPEG, PNG, WEBP, and SVG are allowed.', 4000, "ERROR");
|
||||
showToast(
|
||||
globalDispatch,
|
||||
"Invalid file type. Only JPEG, PNG, WEBP, and SVG are allowed.",
|
||||
4000,
|
||||
"ERROR"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (file?.size && file?.size > 5 * 1024 * 1024) { // 5 MB limit
|
||||
showToast(globalDispatch, 'One of the image is too large. Max size is 5 MB.', 4000, "ERROR");
|
||||
if (file?.size && file?.size > 5 * 1024 * 1024) {
|
||||
// 5 MB limit
|
||||
showToast(
|
||||
globalDispatch,
|
||||
"One or more of the image is too large. Max size is 5 MB.",
|
||||
4000,
|
||||
"ERROR"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -128,7 +149,16 @@ const SpaceDetailsTwo = () => {
|
||||
dispatch({ type: "SET_THUMBNAIL", payload: upload.id });
|
||||
}
|
||||
}
|
||||
dispatch({ type: "SET_DETAILS_TWO", payload: { faqs: data.faqs, amenities: data.amenities, addons: data.addons, pictures: uploadedImages, pictureIds: uploadedIds } });
|
||||
dispatch({
|
||||
type: "SET_DETAILS_TWO",
|
||||
payload: {
|
||||
faqs: data.faqs,
|
||||
amenities: data.amenities,
|
||||
addons: data.addons,
|
||||
pictures: uploadedImages,
|
||||
pictureIds: uploadedIds,
|
||||
},
|
||||
});
|
||||
globalDispatch({ type: "STOP_LOADING" });
|
||||
|
||||
navigate("/spaces/add/3");
|
||||
@@ -156,7 +186,7 @@ const SpaceDetailsTwo = () => {
|
||||
name: spaceData.name,
|
||||
rule: spaceData.rule,
|
||||
},
|
||||
"POST",
|
||||
"POST"
|
||||
);
|
||||
dispatch({ type: "SET_PROPERTY_ID", payload: propertyResult.message });
|
||||
}
|
||||
@@ -177,7 +207,7 @@ const SpaceDetailsTwo = () => {
|
||||
additional_guest_rate: spaceData.additional_guest_rate || undefined,
|
||||
size: spaceData.size || undefined,
|
||||
},
|
||||
"POST",
|
||||
"POST"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -190,7 +220,7 @@ const SpaceDetailsTwo = () => {
|
||||
property_id: propertyResult?.message ?? spaceData.property_id,
|
||||
add_on_id: addon_id,
|
||||
},
|
||||
"POST",
|
||||
"POST"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -208,7 +238,7 @@ const SpaceDetailsTwo = () => {
|
||||
photo_id: upload.id,
|
||||
is_approved: IMAGE_STATUS.IN_REVIEW,
|
||||
},
|
||||
"POST",
|
||||
"POST"
|
||||
);
|
||||
}
|
||||
if (file?.name == formValues.thumbnail) {
|
||||
@@ -219,7 +249,7 @@ const SpaceDetailsTwo = () => {
|
||||
default_image_id: upload.id,
|
||||
// is_approved: IMAGE_STATUS.APPROVED,
|
||||
},
|
||||
"PUT",
|
||||
"PUT"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -234,7 +264,7 @@ const SpaceDetailsTwo = () => {
|
||||
question: faq.question,
|
||||
answer: faq.answer,
|
||||
},
|
||||
"POST",
|
||||
"POST"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,7 +277,7 @@ const SpaceDetailsTwo = () => {
|
||||
property_spaces_id: propertySpaceResult.message,
|
||||
amenity_id,
|
||||
},
|
||||
"POST",
|
||||
"POST"
|
||||
);
|
||||
}
|
||||
navigate("/account/my-spaces");
|
||||
@@ -278,138 +308,228 @@ const SpaceDetailsTwo = () => {
|
||||
setPictures((prev) => {
|
||||
var copy = [...prev];
|
||||
copy[i] = picFile;
|
||||
return copy;
|
||||
return copy.filter(Boolean);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
function isCatOthers(){
|
||||
const cat = spaceCategories.find((cat) => Number(cat.id) == Number(spaceData.category))
|
||||
function isCatOthers() {
|
||||
const cat = spaceCategories.find(
|
||||
(cat) => Number(cat.id) == Number(spaceData.category)
|
||||
);
|
||||
if (cat?.category === "Others") {
|
||||
return true
|
||||
} else return false
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen pb-40 md:max-w-[656px]">
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
autoComplete="off"
|
||||
>
|
||||
<h1 className="mb-8 text-3xl font-bold md:text-4xl">Space Details</h1>
|
||||
<div className="text-sm md:px-[20px] md:py-[32px]">
|
||||
<h3 className="text-xl font-semibold md:text-2xl">* Photographs of the space</h3>
|
||||
<p className="mb-8">file type (jpeg/png/svg), max size (5MB), suggest resolution (640*480)</p>
|
||||
<div className="eighteen-step-image mb-8 flex flex-wrap justify-center gap-x-2 gap-y-4 md:gap-5">
|
||||
<div className='min-h-screen pb-40 md:max-w-[656px]'>
|
||||
<form onSubmit={handleSubmit(onSubmit)} autoComplete='off'>
|
||||
<h1 className='mb-8 text-3xl font-bold md:text-4xl'>Space Details</h1>
|
||||
<div className='text-sm md:px-[20px] md:py-[32px]'>
|
||||
<h3 className='text-xl font-semibold md:text-2xl'>
|
||||
* Photographs of the space
|
||||
</h3>
|
||||
<p className='mb-8'>
|
||||
file type (jpeg/png/svg), max size (5MB), suggest resolution
|
||||
(640*480)
|
||||
</p>
|
||||
<div className='mb-8 flex flex-col justify-center gap-x-2 gap-y-4 md:gap-5'>
|
||||
{/* FileUploader for images */}
|
||||
<FileUploader
|
||||
multiple
|
||||
handleChange={(files) => {
|
||||
const fileArray =
|
||||
files instanceof FileList ? Array.from(files) : [files];
|
||||
|
||||
// Enforce max 6 images
|
||||
if (pictures.length + fileArray.length > 6) {
|
||||
showToast(
|
||||
globalDispatch,
|
||||
"You can only upload up to 6 images.",
|
||||
4000,
|
||||
"ERROR"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Enforce 1MB per image
|
||||
for (let file of fileArray) {
|
||||
if (file.size > 1024 * 1024) {
|
||||
showToast(
|
||||
globalDispatch,
|
||||
"Each image must not exceed 1MB.",
|
||||
4000,
|
||||
"ERROR"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setPictures((prev) => [...prev, ...fileArray]);
|
||||
}}
|
||||
name='images'
|
||||
types={["JPG", "PNG", "JPEG", "SVG", "WEBP"]}
|
||||
maxSize={1}
|
||||
/>
|
||||
{/* Show previews */}
|
||||
<div className='eighteen-step-image flex flex-wrap gap-2'>
|
||||
{pictures.map((file, idx) => {
|
||||
// add FileUploader logic here
|
||||
const imageUrl =
|
||||
file instanceof File ? URL.createObjectURL(file) : file;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={idx}
|
||||
className='relative flex flex-col items-center'
|
||||
>
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={`preview-${idx + 1}`}
|
||||
className='mb-2 h-24 w-24 rounded border object-cover'
|
||||
/>
|
||||
<button
|
||||
type='button'
|
||||
className='text-xs text-red-500 underline'
|
||||
onClick={() =>
|
||||
setPictures((prev) => prev.filter((_, i) => i !== idx))
|
||||
}
|
||||
>
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<h3 className="mb-4 text-xl font-bold">* Select thumbnail image</h3>
|
||||
</div>
|
||||
<h3 className='mb-4 text-xl font-bold'>* Select thumbnail image</h3>
|
||||
<CustomSelectV2
|
||||
items={pictures.filter((pic) => pic?.name)}
|
||||
labelField="name"
|
||||
valueField="name"
|
||||
containerClassName="mb-12"
|
||||
className="w-full border py-2 px-3 focus:outline-primary"
|
||||
openClassName="ring-primary ring-2"
|
||||
labelField='name'
|
||||
valueField='name'
|
||||
containerClassName='mb-12'
|
||||
className='w-full border px-3 py-2 focus:outline-primary'
|
||||
openClassName='ring-primary ring-2'
|
||||
placeholder={"Select thumbnail"}
|
||||
control={control}
|
||||
name="thumbnail"
|
||||
name='thumbnail'
|
||||
/>
|
||||
<h3 className="mb-4 text-xl font-bold">
|
||||
What do you offer with the space <span className="text-sm font-normal italic text-gray-500">(optional)</span>
|
||||
<h3 className='mb-4 text-xl font-bold'>
|
||||
What do you offer with the space{" "}
|
||||
<span className='text-sm font-normal italic text-gray-500'>
|
||||
(optional)
|
||||
</span>
|
||||
</h3>
|
||||
<div className="flex gap-3 items-center">
|
||||
<div className='flex items-center gap-3'>
|
||||
<button
|
||||
type="button"
|
||||
className="mb-2 font-bold text-[#1570EF]"
|
||||
type='button'
|
||||
className='mb-2 font-bold text-[#1570EF]'
|
||||
onClick={() => setAddAmenitiesPopup(true)}
|
||||
>
|
||||
+ Select items
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div className="addons-grid mb-12">
|
||||
<div className='addons-grid mb-12'>
|
||||
{amenities
|
||||
?.filter((am) => {
|
||||
if (Array.isArray(selectedAmenities)) {
|
||||
return selectedAmenities?.includes(String(am.id));
|
||||
}
|
||||
return false;
|
||||
}).sort((a, b) => (a.space_id === null ? -1 : 1) - (b.space_id === null ? -1 : 1))
|
||||
})
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.space_id === null ? -1 : 1) -
|
||||
(b.space_id === null ? -1 : 1)
|
||||
)
|
||||
.map((am) => (
|
||||
<li
|
||||
className="flex w-fit items-center gap-2 mb-4 sm:mb-0"
|
||||
key={am.id}>
|
||||
className='mb-4 flex w-fit items-center gap-2 sm:mb-0'
|
||||
key={am.id}
|
||||
>
|
||||
<CircleCheckIcon />
|
||||
{am.name}
|
||||
</li>
|
||||
))}
|
||||
</div>
|
||||
<h3 className="mb-4 text-xl font-bold">
|
||||
Add-ons <span className="text-sm font-normal italic text-gray-500">(optional)</span>
|
||||
<h3 className='mb-4 text-xl font-bold'>
|
||||
Add-ons{" "}
|
||||
<span className='text-sm font-normal italic text-gray-500'>
|
||||
(optional)
|
||||
</span>
|
||||
</h3>
|
||||
<div className="flex gap-3 items-center">
|
||||
<div className='flex items-center gap-3'>
|
||||
<button
|
||||
type="button"
|
||||
className="mb-2 font-bold text-[#1570EF]"
|
||||
type='button'
|
||||
className='mb-2 font-bold text-[#1570EF]'
|
||||
onClick={() => setAddAddonsPopup(true)}
|
||||
>
|
||||
+ Select items
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="addons-grid mb-12">
|
||||
<div className='addons-grid mb-12'>
|
||||
{addons
|
||||
?.filter((addon) => {
|
||||
if (Array.isArray(selectedAddons)) {
|
||||
return selectedAddons?.includes(String(addon.id));
|
||||
}
|
||||
return false;
|
||||
}).sort((a, b) => (a.space_id === null ? -1 : 1) - (b.space_id === null ? -1 : 1))
|
||||
})
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.space_id === null ? -1 : 1) -
|
||||
(b.space_id === null ? -1 : 1)
|
||||
)
|
||||
.map((addon) => (
|
||||
<li
|
||||
className="flex w-fit items-center gap-2 mb-4 sm:mb-0"
|
||||
key={addon.id}>
|
||||
className='mb-4 flex w-fit items-center gap-2 sm:mb-0'
|
||||
key={addon.id}
|
||||
>
|
||||
<CircleCheckIcon />
|
||||
{addon.name}</li>
|
||||
{addon.name}
|
||||
</li>
|
||||
))}
|
||||
</div>
|
||||
<h3 className="mb-2 text-xl font-bold">
|
||||
Frequently asked question <span className="text-sm font-normal italic text-gray-500">(optional)</span>
|
||||
<h3 className='mb-2 text-xl font-bold'>
|
||||
Frequently asked question{" "}
|
||||
<span className='text-sm font-normal italic text-gray-500'>
|
||||
(optional)
|
||||
</span>
|
||||
</h3>
|
||||
<p>These FAQs will show as part of your space listing.</p>
|
||||
<div>
|
||||
{fields.map((field, index) => (
|
||||
<div
|
||||
className="p-[20px]"
|
||||
key={field.id}
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<label className="mb-1 font-semibold">* Question #{index + 1}</label>
|
||||
<div className='p-[20px]' key={field.id}>
|
||||
<div className='flex justify-between'>
|
||||
<label className='mb-1 font-semibold'>
|
||||
* Question #{index + 1}
|
||||
</label>
|
||||
<button
|
||||
className="text-sm font-semibold text-[#667085]"
|
||||
className='text-sm font-semibold text-[#667085]'
|
||||
onClick={() => remove(index)}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
placeholder=""
|
||||
autoComplete="off"
|
||||
placeholder=''
|
||||
autoComplete='off'
|
||||
{...register(`faqs.${index}.question`)}
|
||||
className={`mb-4 w-full rounded border py-2 px-3 leading-tight text-gray-700 focus:outline-primary`}
|
||||
className={`mb-4 w-full rounded border px-3 py-2 leading-tight text-gray-700 focus:outline-primary`}
|
||||
/>
|
||||
<br />
|
||||
<label className="mb-2 font-semibold">* Answer #{index + 1}</label>
|
||||
<label className='mb-2 font-semibold'>
|
||||
* Answer #{index + 1}
|
||||
</label>
|
||||
<SunEditor
|
||||
width="100%"
|
||||
height="107px"
|
||||
onChange={(content) => setValue(`faqs.${index}.answer`, content)}
|
||||
placeholder=""
|
||||
width='100%'
|
||||
height='107px'
|
||||
onChange={(content) =>
|
||||
setValue(`faqs.${index}.answer`, content)
|
||||
}
|
||||
placeholder=''
|
||||
hideToolbar={true}
|
||||
setOptions={{ resizingBar: false }}
|
||||
defaultValue={getValues().faqs[index].answer}
|
||||
@@ -418,62 +538,76 @@ const SpaceDetailsTwo = () => {
|
||||
))}
|
||||
|
||||
<button
|
||||
className="mb-12 font-bold text-[#1570EF]"
|
||||
type="button"
|
||||
id="append_faq_btn"
|
||||
// add logic to handle appending new FAQs field
|
||||
className='mb-12 font-bold text-[#1570EF]'
|
||||
type='button'
|
||||
id='append_faq_btn'
|
||||
onClick={() => append({ question: "", answer: "" })}
|
||||
>
|
||||
+ Add question
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr className="my-[20px]" />
|
||||
<p className="px-4 text-sm md:px-0" dangerouslySetInnerHTML={{ __html: sanitizeAndTruncate(cancellationPolicy, 400) }}>
|
||||
</p>
|
||||
<div className="flex justify-end">
|
||||
<Link to={"/help/cancellation-policy"}
|
||||
className="mt-4 text-end text-sm font-semibold underline"
|
||||
<hr className='my-[20px]' />
|
||||
<p
|
||||
className='px-4 text-sm md:px-0'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: sanitizeAndTruncate(cancellationPolicy, 400),
|
||||
}}
|
||||
></p>
|
||||
<div className='flex justify-end'>
|
||||
<Link
|
||||
to={"/help/cancellation-policy"}
|
||||
className='mt-4 text-end text-sm font-semibold underline'
|
||||
target={"_blank"}
|
||||
>
|
||||
View More
|
||||
</Link>
|
||||
</div>
|
||||
<hr className="my-[30px]" />
|
||||
<hr className='my-[30px]' />
|
||||
<button
|
||||
type="submit"
|
||||
className="login-btn-gradient rounded py-2 px-4 tracking-wide text-white outline-none focus:outline-none"
|
||||
type='submit'
|
||||
className='login-btn-gradient rounded px-4 py-2 tracking-wide text-white outline-none focus:outline-none'
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
<br />
|
||||
<div
|
||||
className={`${showAddAmenitiesPopup ? "flex" : "hidden"} popup-container items-center justify-center normal-case`}
|
||||
className={`${
|
||||
showAddAmenitiesPopup ? "flex" : "hidden"
|
||||
} popup-container items-center justify-center normal-case`}
|
||||
onClick={() => setAddAmenitiesPopup(false)}
|
||||
>
|
||||
<div
|
||||
className={`${addAmenitiesPopup ? "pop-in" : "pop-out"} w-[510px] max-w-[80%] rounded-lg bg-white p-5 px-3 md:px-5`}
|
||||
className={`${
|
||||
addAmenitiesPopup ? "pop-in" : "pop-out"
|
||||
} w-[510px] max-w-[80%] rounded-lg bg-white p-5 px-3 md:px-5`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="mb-[18px] flex items-center justify-between">
|
||||
<h3 className="mb-[8px] text-2xl font-semibold">Select Amenities</h3>
|
||||
<div className='mb-[18px] flex items-center justify-between'>
|
||||
<h3 className='mb-[8px] text-2xl font-semibold'>
|
||||
Select Amenities
|
||||
</h3>
|
||||
<button
|
||||
type="button"
|
||||
type='button'
|
||||
onClick={() => setAddAmenitiesPopup(false)}
|
||||
className="rounded-full border p-1 px-3 text-2xl font-normal duration-100 hover:bg-gray-200 active:bg-gray-300"
|
||||
className='rounded-full border p-1 px-3 text-2xl font-normal duration-100 hover:bg-gray-200 active:bg-gray-300'
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
<div className="review-scroll max-h-[400px] overflow-y-auto">
|
||||
{isCatOthers() ?
|
||||
amenities.sort((a, b) => (a.creator_id !== 1 ? -1 : 1) - (b.creator_id !== 1 ? -1 : 1)).map((am) => (
|
||||
<div
|
||||
key={am.id}
|
||||
className="checkbox-container mb-4"
|
||||
>
|
||||
<div className='review-scroll max-h-[400px] overflow-y-auto'>
|
||||
{isCatOthers()
|
||||
? amenities
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.creator_id !== 1 ? -1 : 1) -
|
||||
(b.creator_id !== 1 ? -1 : 1)
|
||||
)
|
||||
.map((am) => (
|
||||
<div key={am.id} className='checkbox-container mb-4'>
|
||||
<input
|
||||
type="checkbox"
|
||||
className=""
|
||||
type='checkbox'
|
||||
className=''
|
||||
{...register("amenities")}
|
||||
id={"amenity" + am.id}
|
||||
value={am.id}
|
||||
@@ -481,94 +615,113 @@ const SpaceDetailsTwo = () => {
|
||||
<label htmlFor={"amenity" + am.id}>{am.name}</label>
|
||||
</div>
|
||||
))
|
||||
:
|
||||
amenities.filter((am) => (am.space_id === Number(spaceData.category)) || am.creator_id === Number(localStorage.getItem("user"))).sort((a, b) => (a.creator_id !== 1 ? -1 : 1) - (b.creator_id !== 1 ? -1 : 1)).map((am) => (
|
||||
<div
|
||||
key={am.id}
|
||||
className="checkbox-container mb-4"
|
||||
>
|
||||
: amenities
|
||||
.filter(
|
||||
(am) =>
|
||||
am.space_id === Number(spaceData.category) ||
|
||||
am.creator_id === Number(localStorage.getItem("user"))
|
||||
)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.creator_id !== 1 ? -1 : 1) -
|
||||
(b.creator_id !== 1 ? -1 : 1)
|
||||
)
|
||||
.map((am) => (
|
||||
<div key={am.id} className='checkbox-container mb-4'>
|
||||
<input
|
||||
type="checkbox"
|
||||
className=""
|
||||
type='checkbox'
|
||||
className=''
|
||||
{...register("amenities")}
|
||||
id={"amenity" + am.id}
|
||||
value={am.id}
|
||||
/>
|
||||
<label htmlFor={"amenity" + am.id}>{am.name}</label>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`${showAddAddonsPopup ? "flex" : "hidden"} popup-container items-center justify-center normal-case`}
|
||||
className={`${
|
||||
showAddAddonsPopup ? "flex" : "hidden"
|
||||
} popup-container items-center justify-center normal-case`}
|
||||
onClick={() => setAddAddonsPopup(false)}
|
||||
>
|
||||
<div
|
||||
className={`${addAddonsPopup ? "pop-in" : "pop-out"} w-[510px] max-w-[80%] rounded-lg bg-white p-5 px-3 md:px-5`}
|
||||
className={`${
|
||||
addAddonsPopup ? "pop-in" : "pop-out"
|
||||
} w-[510px] max-w-[80%] rounded-lg bg-white p-5 px-3 md:px-5`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="mb-[18px] flex items-center justify-between">
|
||||
<h3 className="mb-[8px] text-2xl font-semibold">Select Addons</h3>
|
||||
<div className='mb-[18px] flex items-center justify-between'>
|
||||
<h3 className='mb-[8px] text-2xl font-semibold'>Select Addons</h3>
|
||||
<button
|
||||
type="button"
|
||||
type='button'
|
||||
onClick={() => setAddAddonsPopup(false)}
|
||||
className="rounded-full border p-1 px-3 text-2xl font-normal duration-100 hover:bg-gray-200 active:bg-gray-300"
|
||||
className='rounded-full border p-1 px-3 text-2xl font-normal duration-100 hover:bg-gray-200 active:bg-gray-300'
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
<div className="review-scroll max-h-[400px] overflow-y-auto">
|
||||
{isCatOthers() ?
|
||||
addons.sort((a, b) => (a.creator_id !== 1 ? -1 : 1) - (b.creator_id !== 1 ? -1 : 1)).map((addon) => (
|
||||
<div
|
||||
key={addon.id}
|
||||
className="checkbox-container mb-4"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
{...register("addons")}
|
||||
id={"addon" + addon.id}
|
||||
value={addon.id}
|
||||
/>
|
||||
<label htmlFor={"addon" + addon.id}>{addon.name}{" "}${addon.cost}</label>
|
||||
</div>
|
||||
))
|
||||
:
|
||||
addons.sort((a, b) => (a.creator_id !== 1 ? -1 : 1) - (b.creator_id !== 1 ? -1 : 1)).filter((ad) => ad.space_id === Number(spaceData.category) || ad.creator_id === Number(localStorage.getItem("user")))
|
||||
<div className='review-scroll max-h-[400px] overflow-y-auto'>
|
||||
{isCatOthers()
|
||||
? addons
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.creator_id !== 1 ? -1 : 1) -
|
||||
(b.creator_id !== 1 ? -1 : 1)
|
||||
)
|
||||
.map((addon) => (
|
||||
<div
|
||||
key={addon.id}
|
||||
className="checkbox-container mb-4"
|
||||
>
|
||||
<div key={addon.id} className='checkbox-container mb-4'>
|
||||
<input
|
||||
type="checkbox"
|
||||
type='checkbox'
|
||||
{...register("addons")}
|
||||
id={"addon" + addon.id}
|
||||
value={addon.id}
|
||||
/>
|
||||
<label htmlFor={"addon" + addon.id}>{addon.name}{" "}${addon.cost}</label>
|
||||
<label htmlFor={"addon" + addon.id}>
|
||||
{addon.name} ${addon.cost}
|
||||
</label>
|
||||
</div>
|
||||
))
|
||||
|
||||
}
|
||||
: addons
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.creator_id !== 1 ? -1 : 1) -
|
||||
(b.creator_id !== 1 ? -1 : 1)
|
||||
)
|
||||
.filter(
|
||||
(ad) =>
|
||||
ad.space_id === Number(spaceData.category) ||
|
||||
ad.creator_id === Number(localStorage.getItem("user"))
|
||||
)
|
||||
.map((addon) => (
|
||||
<div key={addon.id} className='checkbox-container mb-4'>
|
||||
<input
|
||||
type='checkbox'
|
||||
{...register("addons")}
|
||||
id={"addon" + addon.id}
|
||||
value={addon.id}
|
||||
/>
|
||||
<label htmlFor={"addon" + addon.id}>
|
||||
{addon.name} ${addon.cost}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
id="save-as-draft"
|
||||
className="mt-[24px] rounded border-2 border-[#98A2B3] py-2 px-4 tracking-wide outline-none focus:outline-none"
|
||||
type='button'
|
||||
id='save-as-draft'
|
||||
className='mt-[24px] rounded border-2 border-[#98A2B3] px-4 py-2 tracking-wide outline-none focus:outline-none'
|
||||
onClick={() => onSaveDraft()}
|
||||
>
|
||||
Save draft and exit
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{addOnModal &&
|
||||
<HostAddAddonsModal setAddOnModal={setAddOnModal}/>
|
||||
}
|
||||
{addOnModal && <HostAddAddonsModal setAddOnModal={setAddOnModal} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user