Commit d57d2acb by jaymehta
2 parents b350ec31 f85792b0
import Image from "next/image";
import { Formik } from "formik";
import { Fragment } from "react";
import { ErrorMessage, FieldArray, Formik } from "formik";
import { Fragment, useState } from "react";
import { Button, Form } from "react-bootstrap";
import * as Yup from "yup";
import { FaTimes, FaTrash } from "react-icons/fa";
const ActivityDetails = () => {
const activityDetailsValidationSchema = Yup.object().shape({
category: Yup.string()
.required("Category is Required"),
subcategory: Yup.string()
.required("SubCategory is Required"),
activity_name: Yup.string()
.required("Activity Name is Required"),
activity_description: Yup.string()
.required("Activity Description is Required"),
location: Yup.string()
.required("Location is Required"),
address: Yup.string()
.required("Address is Required"),
price_per_person: Yup.string()
.required("Price Per Person is Required"),
gifting_to_someone: Yup.string()
.required("Gifting to someone is Required"),
place: Yup.string()
.required("Place is Required"),
contact_person_for_activity: Yup.string()
.required("City is Required"),
min_group_size: Yup.string()
.required("Address Line 1 is Required"),
max_group_size: Yup.string()
.required("Address Line 2 is Required"),
month: Yup.string()
.required("Month is Required"),
min_duration: Yup.string()
.required("Month is Required"),
max_duration: Yup.string()
.required("Month is Required"),
const [expandedIndex, setExpandedIndex] = useState(0); // Initially set the first item as expanded
const toggleAccordion = (index) => {
setExpandedIndex((prevIndex) => (prevIndex === index ? null : index));
};
link_of_booking: Yup.string()
.required("Link of Booking is Required"),
activity_images: Yup.array(),
contact_person_for_booking: Yup.string(),
contact_number_for_booking: Yup.string(),
cancellation_policy_file: Yup.string(),
terms_conditions_file: Yup.string(),
const activityDetailsValidationSchema = Yup.object().shape({
activities: Yup.array().of(
Yup.object().shape({
category: Yup.string().required("Category is Required"),
subCategory: Yup.string().required("SubCategory is Required"),
activityName: Yup.string().required("Activity Name is Required"),
activityDescription: Yup.string().required("Activity Description is Required"),
location: Yup.string().required("Location is Required"),
addressLine1: Yup.string().required("Address is Required"),
addressLine2: Yup.string().required("Address is Required"),
pricePerPerson: Yup.string().required("Price Per Person is Required"),
giftingToSomeone: Yup.string().required("Gifting to someone is Required"),
place: Yup.string().required("Place is Required"),
contactPersonForActivity: Yup.string().required("Contact Person Name is Required"),
minGroupSize: Yup.string().required("Min Group Size is Required"),
maxGroupSize: Yup.string().required("Max Group Size is Required"),
months: Yup.string().required("Month is Required"),
minDuration: Yup.string().required("Min Duration is Required"),
maxDuration: Yup.string().required("Max Duration is Required"),
durationUnit: Yup.string().required("Duration Unit is Required"),
ageGroup: Yup.string().required("Age Group is Required"),
linkOfBooking: Yup.string().required("Link of Booking is Required"),
activityImages: Yup.array(),
contactPersonForBooking: Yup.string(),
countryCode: Yup.string(),
contactNumberForBooking: Yup.string(),
cancellationPolicyFile: Yup.string(),
termsConditionsFile: Yup.string(),
})
)
});
return (
......@@ -52,41 +50,38 @@ const ActivityDetails = () => {
<div className="row">
<div className="col-12 col-lg-8">
<div className="content-div business-details">
<div className="d-flex align-items-center justify-content-between">
<h4 className="mb-0">Activity Details</h4>
<Button type="button" variant="" className="btnAdd m-0">
<span className="image-container me-2">
<Image alt="" layout="fill" src="/images/vendor/icon-plus.svg" className="image" />
</span>
<span>Add Activity</span>
</Button>
</div>
<hr />
<div className="form-container">
<Formik
initialValues={{
activities: [
{
category: "",
subcategory: "",
activity_name: "",
activity_description: "",
subCategory: "",
activityName: "",
activityDescription: "",
location: "",
address: "",
price_per_person: "",
gifting_to_someone: "",
addressLine1: "",
addressLine2: "",
pricePerPerson: "",
giftingToSomeone: "",
place: "",
contact_person_for_activity: "",
min_group_size: "",
max_group_size: "",
month: "",
min_duration: "",
max_duration: "",
link_of_booking: "",
activity_images: [],
contact_person_for_booking: "",
contact_number_for_booking: "",
cancellation_policy_file: "",
terms_conditions_file: "",
contactPersonForActivity: "",
minGroupSize: "",
maxGroupSize: "",
months: "",
minDuration: "",
maxDuration: "",
durationUnit: "",
ageGroup: "",
linkOfBooking: "",
activityImages: [],
contactPersonForBooking: "",
countryCode: "",
contactNumberForBooking: "",
cancellationPolicyFile: "",
termsConditionsFile: "",
}
]
}}
validationSchema={activityDetailsValidationSchema}
// enableReinitialize={true}
......@@ -94,23 +89,81 @@ const ActivityDetails = () => {
console.log("activity details values", values)
}}
>
{({ values, errors, touched, handleChange, handleBlur, handleSubmit }) => (
{({ values, errors, touched, handleChange, handleBlur, handleSubmit, setFieldValue }) => (
<Form
onSubmit={e => {
e.preventDefault();
handleSubmit();
}}
>
<p className="textH">Activity Name 1</p>
<FieldArray name="activities">
{({ push, remove }) => (
<div className="activityDetails">
<div className="d-flex justify-content-between mb-3">
<h4 className="mb-0">Activity Details</h4>
<Button type="button" variant="" className="btnAdd m-0"
onClick={() => {
push({
category: "",
subCategory: "",
activityName: "",
activityDescription: "",
location: "",
addressLine1: "",
addressLine2: "",
pricePerPerson: "",
giftingToSomeone: "",
place: "",
contactPersonForActivity: "",
minGroupSize: "",
maxGroupSize: "",
months: "",
minDuration: "",
maxDuration: "",
durationUnit: "",
ageGroup: "",
linkOfBooking: "",
activityImages: [],
contactPersonForBooking: "",
countryCode: "",
contactNumberForBooking: "",
cancellationPolicyFile: "",
termsConditionsFile: "",
});
setExpandedIndex(values.activities.length);
}}
>
<span className="image-container me-2">
<Image alt="" layout="fill" src="/images/vendor/icon-plus.svg" className="image" />
</span>
<span>Add Activity</span>
</Button>
</div>
{values.activities.map((_, index) => (
<div key={index} className="accordionItem">
<AccordionItem
index={index}
expanded={expandedIndex === index}
toggleAccordion={() => toggleAccordion(index)}
remove={() => remove(index)}
>
<div>
<div className="mt-4">
{/* <p className="textH">Basic Details</p> */}
<div className="d-flex justify-content-between">
<p className="textH">Basic Details</p>
{index > 0 && (
<div style={{ cursor: "pointer" }} onClick={remove}><FaTrash style={{ marginTop: "-5px" }} /> Remove</div>
)}
</div>
<div className="row">
<div className="col-12 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Category</label>
<select
id="category"
name="category"
id={`activities.${index}.category`}
name={`activities.${index}.category`}
onChange={handleChange}
onBlur={handleBlur}
>
......@@ -118,15 +171,15 @@ const ActivityDetails = () => {
<option value="Category 1">Category 1</option>
<option value="Category 2">Category 2</option>
</select>
{errors.category && touched.category && (<span className="form-error">{errors.category}</span>)}
<ErrorMessage name={`activities.${index}.category`} component="div" className="form-error" />
</div>
</div>
<div className="col-12 offset-lg-1 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>SubCategory</label>
<select
id="subcategory"
name="subcategory"
id={`activities.${index}.subCategory`}
name={`activities.${index}.subCategory`}
onChange={handleChange}
onBlur={handleBlur}
>
......@@ -134,45 +187,45 @@ const ActivityDetails = () => {
<option value="Sub Category 1">Sub Category 1</option>
<option value="Sub Category 2">Sub Category 2</option>
</select>
{errors.subcategory && touched.subcategory && (<span className="form-error">{errors.subcategory}</span>)}
<ErrorMessage name={`activities.${index}.category`} component="div" className="form-error" />
</div>
</div>
</div>
<div className="row">
<div className="col-12 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Activity Name</label>
<input
type="text"
name="activity_name"
name={`activities.${index}.activityName`}
onChange={handleChange}
onBlur={handleBlur}
value={values.activity_name}
value={values.activities[index].activityName}
/>
{errors.activity_name && touched.activity_name && (<span className="form-error">{errors.activity_name}</span>)}
<ErrorMessage name={`activities.${index}.activityName`} component="div" className="form-error" />
</div>
</div>
<div className="col-12 offset-lg-1 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Activity Description</label>
<input
type="text"
name="activity_description"
<textarea
rows="4"
name={`activities.${index}.activityDescription`}
onChange={handleChange}
onBlur={handleBlur}
value={values.activity_description}
value={values.activities[index].activityDescription}
/>
{errors.activity_description && touched.activity_description && (<span className="form-error">{errors.activity_description}</span>)}
<ErrorMessage name={`activities.${index}.activityDescription`} component="div" className="form-error" />
</div>
</div>
</div>
<div className="row">
<div className="col-12 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Location</label>
<select
id="location"
name="location"
id={`activities.${index}.location`}
name={`activities.${index}.location`}
onChange={handleChange}
onBlur={handleBlur}
>
......@@ -180,161 +233,172 @@ const ActivityDetails = () => {
<option value="Location 1">Location 1</option>
<option value="Location 2">Location 2</option>
</select>
{errors.location && touched.location && (<span className="form-error">{errors.location}</span>)}
<ErrorMessage name={`activities.${index}.location`} component="div" className="form-error" />
</div>
</div>
<div className="col-12 offset-lg-1 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Address</label>
<label>Price (per person)</label>
<input
type="text"
name="address"
name={`activities.${index}.pricePerPerson`}
onChange={handleChange}
onBlur={handleBlur}
value={values.address}
value={values.activities[index].pricePerPerson}
/>
{errors.address && touched.address && (<span className="form-error">{errors.address}</span>)}
<ErrorMessage name={`activities.${index}.pricePerPerson`} component="div" className="form-error" />
</div>
</div>
</div>
<div className="row">
<div className="col-12 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Price (per person)</label>
<label>Address Line 1</label>
<input
type="text"
name="price_per_person"
name={`activities.${index}.addressLine1`}
onChange={handleChange}
onBlur={handleBlur}
value={values.price_per_person}
value={values.activities[index].addressLine1}
/>
{errors.price_per_person && touched.price_per_person && (<span className="form-error">{errors.price_per_person}</span>)}
<ErrorMessage name={`activities.${index}.addressLine1`} component="div" className="form-error" />
</div>
</div>
<div className="col-12 offset-lg-1 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Address Line 2</label>
<input
type="text"
name={`activities.${index}.addressLine2`}
onChange={handleChange}
onBlur={handleBlur}
value={values.activities[index].addressLine2}
/>
<ErrorMessage name={`activities.${index}.addressLine2`} component="div" className="form-error" />
</div>
</div>
</div>
<div className="row">
<div className="col-12 col-lg-6">
<div className="input-group mb-2">
<label>Gifting to Someone</label>
<div className="row">
<div className="col-6 col-lg-6">
<label htmlFor="gifting_allowed">
<label className="radioContainer" htmlFor={`gifting_allowed.${index}`}>
<input
type="radio"
id="gifting_allowed"
name="gifting_to_someone"
id={`gifting_allowed.${index}`}
name={`activities.${index}.giftingToSomeone`}
onChange={handleChange}
onBlur={handleBlur}
value="gifting_allowed"
/> Allowed
<span className="checkmark"></span>
</label>
</div>
<div className="col-6 col-lg-6">
<label htmlFor="gifting_disallowed">
<label className="radioContainer" htmlFor={`gifting_disallowed.${index}`}>
<input
type="radio"
id="gifting_disallowed"
name="gifting_to_someone"
id={`gifting_disallowed.${index}`}
name={`activities.${index}.giftingToSomeone`}
onChange={handleChange}
onBlur={handleBlur}
value="gifting_disallowed"
/> Disallowed
<span className="checkmark"></span>
</label>
</div>
</div>
{errors.gifting_to_someone && touched.gifting_to_someone && (<span className="form-error">{errors.gifting_to_someone}</span>)}
</div>
<ErrorMessage name={`activities.${index}.giftingToSomeone`} component="div" className="form-error" />
</div>
</div>
<div className="row">
<div className="col-12 col-lg-5">
<div className="input-group">
<div className="col-12 col-lg-6">
<div className="input-group mb-2">
<label>Place</label>
<div className="row">
<div className="col-4 col-lg-4">
<label htmlFor="indoor">
<label className="radioContainer" htmlFor={`indoor.${index}`}>
<input
type="radio"
id="indoor"
name="place"
id={`indoor.${index}`}
name={`activities.${index}.place`}
onChange={handleChange}
onBlur={handleBlur}
value="indoor"
/> Indoor
<span className="checkmark"></span>
</label>
</div>
<div className="col-4 col-lg-4">
<label htmlFor="outdoor">
<div className="col-5 col-lg-5">
<label className="radioContainer" htmlFor={`outdoor.${index}`}>
<input
type="radio"
id="outdoor"
name="place"
id={`outdoor.${index}`}
name={`activities.${index}.place`}
onChange={handleChange}
onBlur={handleBlur}
value="outdoor"
/> Outdoor
<span className="checkmark"></span>
</label>
</div>
<div className="col-4 col-lg-4">
<label htmlFor="both">
<div className="col-3 col-lg-3">
<label className="radioContainer" htmlFor={`both.${index}`}>
<input
type="radio"
id="both"
name="place"
id={`both.${index}`}
name={`activities.${index}.place`}
onChange={handleChange}
onBlur={handleBlur}
value="both"
/> Both
<span className="checkmark"></span>
</label>
</div>
</div>
{errors.place && touched.place && (<span className="form-error">{errors.place}</span>)}
<ErrorMessage name={`activities.${index}.place`} component="div" className="form-error" />
</div>
</div>
</div>
</div>
<hr />
<div>
<p>Group Information</p>
<div className="mt-4">
<p className="textH">Group Information</p>
<div className="row">
<div className="col-12 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Contact Person for the Activity</label>
<input
type="text"
name="contact_person_for_activity"
name={`activities.${index}.contactPersonForActivity`}
onChange={handleChange}
onBlur={handleBlur}
value={values.contact_person_for_activity}
value={values.activities[index].contactPersonForActivity}
/>
{errors.contact_person_for_activity && touched.contact_person_for_activity && (<span className="form-error">{errors.contact_person_for_activity}</span>)}
<ErrorMessage name={`activities.${index}.contactPersonForActivity`} component="div" className="form-error" />
</div>
</div>
<div className="col-12 offset-lg-1 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Size of the Group</label>
<div className="row">
<div className="col-6 col-lg-6">
<div className="input-group mb-0">
<div className="col-6 col-lg-5">
<input
type="text"
name="min_group_size"
placeholder="Min."
name={`activities.${index}.minGroupSize`}
onChange={handleChange}
onBlur={handleBlur}
value={values.min_group_size}
value={values.activities[index].minGroupSize}
/>
{errors.min_group_size && touched.min_group_size && (<span className="form-error">{errors.min_group_size}</span>)}
</div>
<ErrorMessage name={`activities.${index}.minGroupSize`} component="div" className="form-error" />
</div>
<div className="col-6 col-lg-6">
<div className="input-group mb-0">
<div className="col-6 col-lg-5">
<input
type="text"
name="max_group_size"
placeholder="Max."
name={`activities.${index}.maxGroupSize`}
onChange={handleChange}
onBlur={handleBlur}
value={values.max_group_size}
value={values.activities[index].maxGroupSize}
/>
{errors.max_group_size && touched.max_group_size && (<span className="form-error">{errors.max_group_size}</span>)}
</div>
<ErrorMessage name={`activities.${index}.maxGroupSize`} component="div" className="form-error" />
</div>
</div>
</div>
......@@ -342,15 +406,15 @@ const ActivityDetails = () => {
</div>
</div>
<hr />
<div>
<p>Availability</p>
<div className="mt-4">
<p className="textH">Availability</p>
<div className="row">
<div className="col-12 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Months</label>
<select
id="month"
name="month"
id={`activities.${index}.months`}
name={`activities.${index}.months`}
onChange={handleChange}
onBlur={handleBlur}
>
......@@ -358,47 +422,221 @@ const ActivityDetails = () => {
<option value="Location 1">Location 1</option>
<option value="Location 2">Location 2</option>
</select>
{errors.contact_person_for_activity && touched.contact_person_for_activity && (<span className="form-error">{errors.contact_person_for_activity}</span>)}
<ErrorMessage name={`activities.${index}.months`} component="div" className="form-error" />
</div>
</div>
<div className="col-12 offset-lg-1 col-lg-5">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Size of the Group</label>
<label>Day & Time</label>
<select
id={`activities.${index}.dayTime`}
name={`activities.${index}.dayTime`}
onChange={handleChange}
onBlur={handleBlur}
>
<option value="">Select</option>
<option value="Location 1">Location 1</option>
<option value="Location 2">Location 2</option>
</select>
<ErrorMessage name={`activities.${index}.dayTime`} component="div" className="form-error" />
</div>
</div>
</div>
<div className="row">
<div className="col-6 col-lg-6">
<div className="input-group mb-0">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Duration</label>
<div className="row">
<div className="col-5 col-lg-4">
<select
id="minDuration"
name="minDuration"
onChange={handleChange}
onBlur={handleBlur}
>
<option value="">Min</option>
</select>
{errors.minDuration && touched.minDuration && (<span className="form-error">{errors.minDuration}</span>)}
</div>
<div className="col-5 col-lg-4">
<select
id="maxDuration"
name="maxDuration"
onChange={handleChange}
onBlur={handleBlur}
style={{ width: "100%" }}
>
<option value="">Max</option>
</select>
{errors.maxDuration && touched.maxDuration && (<span className="form-error">{errors.maxDuration}</span>)}
</div>
<div className="col-2 col-lg-4">
<select
id="durationUnit"
name="durationUnit"
onChange={handleChange}
onBlur={handleBlur}
>
<option value="Hrs">Hrs</option>
<option value="Mins">Mins</option>
</select>
{errors.durationUnit && touched.durationUnit && (<span className="form-error">{errors.durationUnit}</span>)}
</div>
</div>
</div>
</div>
</div>
</div>
<hr />
<div className="mt-4">
<p className="textH">Booking & Activity Information</p>
<div className="row">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Link of Booking</label>
<input
type="text"
name="min_group_size"
name={`activities.${index}.linkOfBooking`}
onChange={handleChange}
onBlur={handleBlur}
value={values.min_group_size}
value={values.activities[index].linkOfBooking}
/>
{errors.min_group_size && touched.min_group_size && (<span className="form-error">{errors.min_group_size}</span>)}
<ErrorMessage name={`activities.${index}.linkOfBooking`} component="div" className="form-error" />
</div>
</div>
<div className="col-6 col-lg-6">
<div className="input-group mb-0">
</div>
<div className="row">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Contact Person Name</label>
<input
type="text"
name="max_group_size"
name={`activities.${index}.contactPersonForBooking`}
onChange={handleChange}
onBlur={handleBlur}
value={values.max_group_size}
value={values.activities[index].contactPersonForBooking}
/>
{errors.max_group_size && touched.max_group_size && (<span className="form-error">{errors.max_group_size}</span>)}
<ErrorMessage name={`activities.${index}.contactPersonForBooking`} component="div" className="form-error" />
</div>
</div>
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Contact Person Number</label>
<div className="contact-number">
<select
id={`activities.${index}.countryCode`}
name={`activities.${index}.countryCode`}
onChange={handleChange}
onBlur={handleBlur}
style={{ width: "80px" }}
>
<option value="+91">+91</option>
<option value="+44">+44</option>
</select>
<input
type="text"
name={`activities.${index}.contactNumberForBooking`}
onChange={handleChange}
onBlur={handleBlur}
value={values.activities[index].contactNumberForBooking}
/>
</div>
<ErrorMessage name={`activities.${index}.contactNumberForBooking`} component="div" className="form-error" />
</div>
</div>
</div>
</div>
<div className="row mb-5">
<hr />
<div className="mt-4">
<p className="textH">Policy & Terms</p>
<div className="row">
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Cancellation Policy</label>
<div className="custom-file">
<input
type="file"
className="custom-file-input"
id={`activities.${index}.cancellationPolicyFile`}
name={`activities.${index}.cancellationPolicyFile`}
onChange={(event) => {
if (event) {
const file = event.currentTarget.files[0]
setFieldValue(`activities.${index}.cancellationPolicyFile`, file)
}
}}
onBlur={handleBlur}
onClick={event => {
const { target = {} } = event || {};
target.value = "";
}}
/>
<label className="custom-file-label" htmlFor={`activities.${index}.cancellationPolicyFile`}>
Upload
</label>
</div>
<ErrorMessage name={`activities.${index}.cancellationPolicyFile`} component="div" className="form-error" />
{values.activities[index].cancellationPolicyFile && (
<div className="d-flex align-items-center justify-content-between p-1" style={{ width: "100%" }}>
<p className="textS m-0">{values.activities[index].cancellationPolicyFile.name}</p>
<FaTimes style={{ cursor: "pointer" }} onClick={() => {
setFieldValue(`activities.${index}.cancellationPolicyFile`, "")
}} />
</div>
)}
</div>
</div>
<div className="col-12 col-lg-6">
<div className="input-group">
<label>Terms & Conditions</label>
<div className="custom-file">
<input
type="file"
className="custom-file-input"
id={`activities.${index}.termsConditionsFile`}
name={`activities.${index}.termsConditionsFile`}
onChange={(event) => {
if (event) {
const file = event.currentTarget.files[0]
setFieldValue(`activities.${index}.termsConditionsFile`, file)
}
}}
onBlur={handleBlur}
onClick={event => {
const { target = {} } = event || {};
target.value = "";
}}
/>
<label className="custom-file-label" htmlFor={`activities.${index}.termsConditionsFile`}>
Upload
</label>
</div>
<ErrorMessage name={`activities.${index}.termsConditionsFile`} component="div" className="form-error" />
{values.activities[index].termsConditionsFile && (
<div className="d-flex align-items-center justify-content-between p-1" style={{ width: "100%" }}>
<p className="textS m-0">{values.activities[index].termsConditionsFile.name}</p>
<FaTimes style={{ cursor: "pointer" }} onClick={() => {
setFieldValue(`activities.${index}.termsConditionsFile`, "")
}} />
</div>
)}
</div>
</div>
</div>
</div>
</div>
</AccordionItem>
</div>
))}
</div>
)}
</FieldArray>
<div className="row">
<div className="col-12 col-lg-5">
<div className="input-group">
<Button type="submit" className="btn btn-primary btn-submit">
Send for Approval
<Button type="submit" className="btn btn-primary btn-submit" disabled>
Submit
</Button>
</div>
</div>
......@@ -438,8 +676,23 @@ const ActivityDetails = () => {
</div>
</div>
</div>
</Fragment >
</Fragment>
)
}
const AccordionItem = ({ index, expanded, toggleAccordion, remove, children }) => {
return (
<div>
<div className="d-flex align-items-center justify-content-between" onClick={toggleAccordion} style={{ cursor: "pointer" }}>
<p className="textH mb-0">Activity Name {index + 1}</p>
<div>
{expanded ? <Image alt="" width="24" height="24" src="/images/vendor/minus.svg" /> : <Image alt="" width="24" height="24" src="/images/vendor/plus.svg" />}
</div>
</div>
<div style={{ display: expanded ? 'block' : 'none' }}>{children}</div>
</div>
);
};
export default ActivityDetails;
\ No newline at end of file
// AccordionForm.js
import React, { useState } from 'react';
import { Formik, FieldArray, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const validationSchema = Yup.object().shape({
items: Yup.array().of(
Yup.object().shape({
title: Yup.string().required('Title is required'),
content: Yup.string().required('Content is required'),
})
),
});
const initialValues = {
items: [{ title: '', content: '' }],
};
import { Formik, Form, Field, FieldArray } from 'formik';
const AccordionForm = () => {
const [expandedIndex, setExpandedIndex] = useState(null);
const [expandedIndex, setExpandedIndex] = useState(0); // Initially set the first item as expanded
const handleToggleAccordion = (index) => {
const toggleAccordion = (index) => {
setExpandedIndex((prevIndex) => (prevIndex === index ? null : index));
};
return (
<div>
<h1>Accordion Form</h1>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
initialValues={{
items: [{ title: '', content: '' }]
}}
onSubmit={(values) => {
console.log(values);
}}
>
{({ values }) => (
<form>
<Form>
<FieldArray name="items">
{({ push, remove }) => (
<>
<div>
{values.items.map((_, index) => (
<div key={index}>
<div
style={{
border: '1px solid #ccc',
padding: '10px',
marginBottom: '10px',
}}
<AccordionItem
index={index}
expanded={expandedIndex === index}
toggleAccordion={() => toggleAccordion(index)}
remove={() => remove(index)}
>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
onClick={() => handleToggleAccordion(index)}
>
<h3>Accordion {index + 1}</h3>
<button type="button" onClick={() => remove(index)}>
Remove
</button>
</div>
{expandedIndex === index && (
<div>
<div>
<label htmlFor={`items.${index}.title`}>Title</label>
<Field name={`items.${index}.title`} />
<ErrorMessage name={`items.${index}.title`} component="div" />
</div>
<div>
<label htmlFor={`items.${index}.content`}>Content</label>
<Field name={`items.${index}.content`} />
<ErrorMessage name={`items.${index}.content`} component="div" />
</div>
</div>
)}
<Field name={`items.${index}.title`} placeholder="Title" />
<Field name={`items.${index}.content`} placeholder="Content" />
</div>
</AccordionItem>
</div>
))}
<button type="button" onClick={() => push({ title: '', content: '' })}>
Add Accordion
<button
type="button"
onClick={() => {
push({ title: '', content: '' });
setExpandedIndex(values.items.length);
}}
>
Add Item
</button>
</>
</div>
)}
</FieldArray>
<button type="submit">Submit</button>
</form>
</Form>
)}
</Formik>
</div>
);
};
const AccordionItem = ({ index, expanded, toggleAccordion, remove, children }) => {
return (
<div>
<button type="button" onClick={toggleAccordion}>
{expanded ? '-' : '+'}
</button>
<button type="button" onClick={remove}>Remove</button>
<div style={{ display: expanded ? 'block' : 'none' }}>{children}</div>
</div>
);
};
export default AccordionForm;
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 11H5V13H19V11Z" fill="black"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z" fill="black"/>
</svg>
......@@ -574,7 +574,7 @@ p {
line-height: normal;
}
span.form-error {
span.form-error, .form-error {
color: red;
font-size: 0.8rem;
font-family: "Sofia Pro Light";
......@@ -647,10 +647,11 @@ span.form-error {
font-size: 15px;
line-height: normal;
margin-bottom: 10px;
width: 100%;
}
.form-container input,
.form-container select {
.form-container select, .form-container textarea {
width: 100%;
border-radius: 10px !important;
border: 0.814px solid #000;
......@@ -665,7 +666,7 @@ span.form-error {
}
.form-container input:focus,
.form-container select:focus {
.form-container select:focus, .form-container textarea {
box-shadow: none;
outline: unset;
}
......@@ -675,6 +676,11 @@ span.form-error {
background-color: transparent;
}
.form-container textarea {
resize: none;
height: auto;
}
.contact-number {
width: 100%;
display: flex;
......@@ -1133,11 +1139,12 @@ span.form-error {
/*----- vendor business details -------*/
.content-div {
padding: 2rem 3rem 1rem;
padding: 2rem 2rem 1rem;
background: #ffffff;
border-radius: 8px;
box-shadow: 0px 4px 20px 0px #73737340;
position: relative;
min-height: 600px;
}
.content-div h2 {
......@@ -1376,7 +1383,7 @@ span.form-error {
.btnAdd {
background-color: #0070BD !important;
/* border: 1px solid #0070BD; */
padding: 1rem 2rem !important;
padding: 0.75rem 2rem !important;
border-radius: 10px !important;
font-family: "Sofia Pro Bold";
font-size: 16px !important;
......@@ -1389,15 +1396,104 @@ span.form-error {
justify-content: center;
margin: 1rem auto;
}
.btnAdd:disabled {
background-color: #A4AFB7 !important;
color: #FFFFFF;
border: none;
}
.btnAdd:hover, .btnAdd:focus, .btnAdd:active {
.btnAdd:hover,
.btnAdd:focus,
.btnAdd:active {
border: 1px solid #0070BD;
}
.activityDetails .accordionItem {
padding: 1rem;
border-bottom: 1px solid #ECECEC;
}
.activityDetails .accordionItem:last-child {
border-bottom: none;
}
/* The radioContainer */
.radioContainer {
display: block;
position: relative;
cursor: pointer;
padding-left: 25px;
font-family: "Sofia Pro Regular";
font-size: 15px;
line-height: 15px;
letter-spacing: 0em;
text-align: left;
color: #000;
margin-top: 5px;
}
/* Hide the browser's default radio button */
.radioContainer input {
position: absolute;
opacity: 0;
cursor: pointer;
}
.form-container .radioContainer input {
height: 0;
width: 0;
}
/* Create a custom radio button */
.checkmark {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-55%);
height: 20px;
width: 20px;
background-color: #FFF;
border-radius: 50%;
border: 1px solid #75777B;
}
/* On mouse-over, add a grey background color */
.radioContainer:hover input~.checkmark {
background-color: #FFF;
}
/* When the radio button is checked, add a blue background */
.radioContainer input:checked~.checkmark {
color: #0070BD;
}
/* Create the indicator (the dot/circle - hidden when not checked) */
.checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the indicator (dot/circle) when checked */
.radioContainer input:checked~.checkmark:after {
display: block;
}
/* Style the indicator (dot/circle) */
.radioContainer .checkmark:after {
top: 50%;
left: 50%;
width: 12px;
height: 12px;
border-radius: 50%;
background: #0070BD;
transform: translate(-50%, -50%);
}
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!