Commit fd80d47d by jaymehta

.

1 parent 6398a988
import React, { Fragment } from "react";
import React, { Fragment, useEffect } from "react";
import DetailGallery from "./DetailGallery";
import DetailInfo from "./DetailInfo";
import { Breadcrumb } from "react-bootstrap";
......@@ -6,8 +6,22 @@ import GuestReviews from "./GuestReviews";
import SimilarExperiences from "./SimilarExperiences";
import Faqs from "./Faqs";
import SignUpToExperienceOurPlatform from "../home/SignUpToExperienceOurPlatform";
import { useDispatch, useSelector } from "react-redux";
import { getActivitiesByFilters } from "../../redux/actions/activityAction";
import { useRouter } from "next/router";
const Detail = () => {
const router = useRouter();
const dispatch = useDispatch();
const { allActivitiesData } = useSelector(state => state.allActivitiesData);
const { activityById } = useSelector(state => state.activityById);
useEffect(() => {
// console.log("router", activityById.data.attributes.category?.data?.attributes.name);
dispatch(getActivitiesByFilters({ category: activityById.data.attributes.category?.data?.id }));
}, [activityById]);
console.log("activityById", activityById);
// console.log("allActivitiesData", allActivitiesData);
return (
<Fragment>
<main>
......@@ -15,7 +29,7 @@ const Detail = () => {
<div className="container mt-5">
<div className="row hide-on-mobile">
<div className="col-12">
<div className="breadcrumb-container">
<div className="breadcrum$eq: categoryb-container">
<Breadcrumb>
<Breadcrumb.Item href="#">Home</Breadcrumb.Item>
<Breadcrumb.Item href="#">New York</Breadcrumb.Item>
......@@ -27,16 +41,16 @@ const Detail = () => {
</div>
<div className="row mb-5">
<div className="col-xl-5">
<DetailGallery></DetailGallery>
<DetailGallery activityById={activityById}></DetailGallery>
</div>
<div className="col-xl-7 listing-wrapper">
<DetailInfo></DetailInfo>
<DetailInfo activityById={activityById}></DetailInfo>
</div>
</div>
</div>
</section>
<GuestReviews />
<SimilarExperiences />
<GuestReviews activityById={activityById} />
<SimilarExperiences allActivitiesData={allActivitiesData} />
<Faqs />
<SignUpToExperienceOurPlatform />
</main>
......
......@@ -2,7 +2,7 @@ import React, { useState } from "react";
import ImageGallery from "react-image-gallery";
import Image from "next/image";
const DetailGallery = () => {
const DetailGallery = ({ activityById }) => {
const [showInfo, setShowInfo] = useState(false);
const handleMouseEnter = () => {
......@@ -38,6 +38,32 @@ const DetailGallery = () => {
thumbnail: "/images/product-gallery/01.png"
}
];
const returnAvilablleDaysArray = ({ data }) => {
let array = [];
if (data.attributes.availableOnMonday) {
array = [...array, { name: "Monday", value: "monday" }];
}
if (data.attributes.availableOnTuesday) {
array = [...array, { name: "Tuesday", value: "tuesday" }];
}
if (data.attributes.availableOnWednesday) {
array = [...array, { name: "Wednesday", value: "wednesday" }];
}
if (data.attributes.availableOnThursday) {
array = [...array, { name: "Thursday", value: "thursday" }];
}
if (data.attributes.availableOnFriday) {
array = [...array, { name: "Friday", value: "friday" }];
}
if (data.attributes.availableOnSaturday) {
array = [...array, { name: "Saturday", value: "saturday" }];
}
if (data.attributes.availableOnSunday) {
array = [...array, { name: "Sunday", value: "sunday" }];
}
return array;
};
return (
<>
<div className="product-info hide-on-desktop">
......@@ -75,37 +101,42 @@ const DetailGallery = () => {
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/availability/month.svg" />
</span>
Month: All
From: {activityById.data.attributes.fromDate} To: {activityById.data.attributes.toDate}
</li>
<li>
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/availability/time.svg" />
</span>
Time: 9:45 AM - 10:00 AM
Time: {activityById.data.attributes.fromTime} - {activityById.data.attributes.toTime}
</li>
<li>
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/availability/duration.svg" />
</span>
Duration: 2-3 Hours
Duration: {activityById.data.attributes.minimumDuration}-{activityById.data.attributes.maximumDuration} Hours
</li>
<li>
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/availability/contact.svg" />
</span>
Contact: 1(332) 204-8500
Contact: {activityById.data.attributes.phoneNumber}
</li>
<li>
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/availability/date.svg" />
</span>
Date: All
Active on:{" "}
{returnAvilablleDaysArray({ data: activityById.data })
.map(item => {
return item.name;
})
.join(", ")}
</li>
<li>
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/availability/age.svg" />
</span>
Age: 13+
Age: {activityById.data.attributes.ageLowerLimit}+
<div className="info-div">
<a className="image-container info" onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/info.svg" />
......
......@@ -4,7 +4,7 @@ import { Button } from "react-bootstrap";
import { fadeIn, zoomIn, slideFromLeft, slideFromRight } from "../animationvariants.js";
import { motion } from "framer-motion";
const DetailInfo = () => {
const DetailInfo = ({ activityById }) => {
const [showInfo, setShowInfo] = useState(false);
const [isToggled, setIsToggled] = useState(false);
......@@ -41,11 +41,11 @@ const DetailInfo = () => {
</div>
</div>
<motion.div variants={slideFromRight(0.4)} initial={"hidden"} whileInView={"show"} viewport={{ once: false, amount: 0.2 }}>
<div className="product-name">Edge City Climb</div>
<div className="product-name">{activityById.data.attributes.name}</div>
</motion.div>
</div>
<div className="product-reviews">
<span className="rating">8.8</span>
<span className="rating">{activityById.data.attributes.rating}</span>
<span className="review">1,365 Reviews</span>
<span className="star">
<a href="">
......@@ -77,18 +77,16 @@ const DetailInfo = () => {
</div>
<div className="mb-2">Per Person</div>
<div className="price">
$185 <span>20% Off</span>
${activityById.data.attributes.pricePerPerson} {activityById.data.attributes.offers && <span>{activityById.data.attributes.offers}% Off</span>}
</div>
<div className="mb-4">
The worlds highest building ascent, City Climb allows participants to scale the outside of a skyscraper more than 1,200 feet (366 meters) above the ground, then
lean out and look down from the highest outdoor platform in the city. Following that, experience The Edge, the highest outdoor sky deck in the Western
Hemisphere. Height: 4.9ft - 6.7ft; Maximum Weight: 310lbs; Cannot be under the influence of alcohol.
{activityById.data.attributes.description}
</div>
<div className="location">
Location & Address <span>(Outdoor)</span>
Location & Address <span>{activityById.data.attributes.activityType}</span>
</div>
<div className="mb-2">Chelsea </div>
<div className="">30 Hudson Yards, New York, NY 10001</div>
<div className="">{activityById.data.attributes.address}</div>
<div className="btn-row">
<Button variant="primary me-3">Book Now</Button>
<Button variant="secondary">
......@@ -108,7 +106,7 @@ const DetailInfo = () => {
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/availability/month.svg" />
</span>
Month: All
From: {activityById.data.attributes.fromDate} To: {activityById.data.attributes.toDate}
</li>
<li>
<span className="image-container">
......
import Image from "next/image";
import React from "react";
const GuestReviews = () => {
const GuestReviews = ({activityById}) => {
const guestReviewsData = [
{
name: "Andrea",
......
......@@ -12,9 +12,10 @@ import "swiper/css";
import "swiper/css/pagination";
import "swiper/css/navigation";
import { cleanImage } from "../../services/imageHandling.js";
import { useRouter } from "next/router.js";
const BrowseExperiences = ({allActivitiesData}) => {
const router = useRouter()
return (
<>
......@@ -63,7 +64,7 @@ const BrowseExperiences = ({allActivitiesData}) => {
modules={[Navigation, Autoplay]}
className="mySwiper01 mySwiper02"
>
{allActivitiesData.data &&
{allActivitiesData &&
allActivitiesData.data.map(data => {
return (
<SwiperSlide key={data?.id}>
......@@ -108,7 +109,9 @@ const BrowseExperiences = ({allActivitiesData}) => {
<div className="">Includes taxes & Fees</div>
</div>
<div className="explore-now">
<Button href="/detail" variant="primary">Explore Now</Button>
<Button onClick={()=> {
router.push(`/activities/${data.id}`)
}} variant="primary">Explore Now</Button>
</div>
</div>
</div>
......
import React, { useEffect, useRef, useState } from "react";
import { Button, Dropdown, Input, Space, Table } from "antd";
import { Button, Dropdown, Input, Space, Table, Tag } from "antd";
import { useDispatch, useSelector } from "react-redux";
import Highlighter from "react-highlight-words";
import { DeleteTwoTone, DownCircleOutlined, EditTwoTone, SearchOutlined } from "@ant-design/icons";
......@@ -13,7 +13,7 @@ const onChange = (pagination, filters, sorter, extra) => {
console.log("params", pagination, filters, sorter, extra);
};
export const ActivityListingRBAC = ({setactivityDetailInfo, setShowActivityDetailsModal}) => {
export const ActivityListingRBAC = ({ setactivityDetailInfo, setShowActivityDetailsModal }) => {
const router = useRouter();
const dispatch = useDispatch();
// let columns = []
......@@ -160,12 +160,13 @@ export const ActivityListingRBAC = ({setactivityDetailInfo, setShowActivityDetai
return {
key: item.id,
name: item.attributes.name,
category: item.attributes.subCategory?.data.attributes.category.data.attributes.name,
category: item.attributes.category?.data.attributes.name,
subCategory: item.attributes.subCategory?.data.attributes.name,
location: item.attributes.masterPincode.data.attributes.name,
price: item.attributes.pricePerPerson,
place: item.attributes.activityType,
gift: item.attributes.giftSomeone ? "Yes" : "No"
gift: item.attributes.giftSomeone ? "Yes" : "No",
status: item.attributes.approved
};
});
......@@ -176,73 +177,6 @@ export const ActivityListingRBAC = ({setactivityDetailInfo, setShowActivityDetai
return { text: item.attributes.name, value: item.attributes.name };
});
setdata(initialData);
if (loadedUser && !loadedUser.role.type == "admin") {
setcolumns([
{
title: "Category",
dataIndex: "category",
filters: categoryFilterArray,
filterMode: "tree",
filterSearch: true,
onFilter: (value, record) => record.category.startsWith(value),
width: "15%"
},
{
title: "Sub-category",
dataIndex: "subCategory",
filters: subCategoryFilterArray,
filterSearch: true,
onFilter: (value, record) => record.subCategory.startsWith(value),
width: "15%"
},
{
title: "Name",
dataIndex: "name",
key: "name",
...getColumnSearchProps("name"),
width: "15%"
},
{
title: "Location",
dataIndex: "location",
width: "15%"
},
{
title: "Price",
dataIndex: "price",
width: "15%"
},
{
title: "Place",
dataIndex: "place",
width: "15%"
},
{
title: "Edit record",
render: (_, record) => (
<Space size="middle">
{/* <a>Invite {record.name}</a> */}
<EditTwoTone
style={{ fontSize: "22px" }}
onClick={() => {
router.push(`/vendor/activities/${record.key}`);
console.log(record);
}}
/>
{/* <DeleteTwoTone
twoToneColor="#FF0000"
style={{ fontSize: "22px" }}
onClick={() => {
console.log(record);
}}
/> */}
</Space>
),
width: "10%"
}
]);
}
if (loadedUser && loadedUser.role.type == "admin") {
setcolumns([
{
......@@ -299,7 +233,7 @@ export const ActivityListingRBAC = ({setactivityDetailInfo, setShowActivityDetai
<a
rel="noopener noreferrer"
onClick={() => {
adminActions({type:"view", activityId: record.key})
adminActions({ type: "view", activityId: record.key });
// console.log(record);
}}
>
......@@ -349,6 +283,90 @@ export const ActivityListingRBAC = ({setactivityDetailInfo, setShowActivityDetai
width: "10%"
}
]);
} else {
setcolumns([
{
title: "Category",
dataIndex: "category",
filters: categoryFilterArray,
filterMode: "tree",
filterSearch: true,
onFilter: (value, record) => record.category.startsWith(value),
width: "15%"
},
{
title: "Sub-category",
dataIndex: "subCategory",
filters: subCategoryFilterArray,
filterSearch: true,
onFilter: (value, record) => record.subCategory.startsWith(value),
width: "15%"
},
{
title: "Name",
dataIndex: "name",
key: "name",
...getColumnSearchProps("name"),
width: "15%"
},
{
title: "Location",
dataIndex: "location",
width: "15%"
},
{
title: "Price",
dataIndex: "price",
width: "15%"
},
{
title: "Place",
dataIndex: "place",
width: "12%"
},
{
title: "Approved",
key: "status",
dataIndex: "status",
render: (_, { status }) => (
<>
{status ? (
<Tag color={"green"} key={1}>
Approved
</Tag>
) : (
<Tag color={"red"} key={1}>
Rejected
</Tag>
)}
</>
)
},
{
title: "Edit record",
render: (_, record) => (
<Space size="middle">
{/* <a>Invite {record.name}</a> */}
<EditTwoTone
style={{ fontSize: "22px" }}
onClick={() => {
router.push(`/vendor/activities/${record.key}`);
console.log(record);
}}
/>
{/* <DeleteTwoTone
twoToneColor="#FF0000"
style={{ fontSize: "22px" }}
onClick={() => {
console.log(record);
}}
/> */}
</Space>
),
width: "10%"
}
]);
}
}, [allActivitiesData, loadedUser]);
......@@ -400,9 +418,9 @@ export const ActivityListingRBAC = ({setactivityDetailInfo, setShowActivityDetai
setrejectPopUp(true);
}
if (type == "view") {
let data = allActivitiesData.data.filter(item => item.id == activityId)
setactivityDetailInfo(data)
setShowActivityDetailsModal(true)
let data = allActivitiesData.data.filter(item => item.id == activityId);
setactivityDetailInfo(data);
setShowActivityDetailsModal(true);
}
};
return (
......@@ -440,7 +458,7 @@ export const ActivityListingRBAC = ({setactivityDetailInfo, setShowActivityDetai
await updateActivityStatusAdmin({ status: false, activityId: rejectionId, rejectionReason: rejectionReasonText });
setrejectionId(null);
setrejectPopUp(false);
toast.success("Activity rejected.")
toast.success("Activity rejected.");
}}
>
Submit
......
......@@ -14,7 +14,7 @@ import { useRouter } from "next/router";
const BusinessDetails = () => {
const [session, setSession] = useState(null);
const dispatch = useDispatch();
const router = useRouter()
const router = useRouter();
const { loggedInVendor } = useSelector(state => state.loggedInVendor);
const { vendorDetails } = useSelector(state => state.vendorDetails);
const { loadedUser, error } = useSelector(state => state.loadedUser);
......@@ -172,7 +172,7 @@ const BusinessDetails = () => {
const updateBusinessDetails = await dispatch(updateVendorBusinessDetails({ businessDetails, vendorId: response.id }));
await updateUserApprovalStatus({ status: "pending" });
await dispatch(loadUser());
router.push("/vendor/dashboard")
router.push("/vendor/dashboard");
// console.log("updateBusinessDetails", updateBusinessDetails);
}}
>
......@@ -381,6 +381,15 @@ const BusinessDetails = () => {
</Button>
</div>
</div>
<div className="col-12 col-lg-5">
<div className="input-group">
<Button disabled={false} onClick={()=> {
router.push("/vendor/dashboard")
}} className="btn btn-primary btn-submit">
Go to dashboard
</Button>
</div>
</div>
</div>
</Form>
)}
......
import React from "react";
import Detail from "../../components/detail/Detail";
import Layout from "../../components/layout/Layout";
import { getActivitiesByFilters, getActivityById } from "../../redux/actions/activityAction";
import { wrapper } from "../../redux/store";
const ActivityDetailPage = () => {
return (
<Layout>
<Detail />
</Layout>
);
};
export default ActivityDetailPage;
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
await store.dispatch(getActivityById(query.id))
// await store.dispatch(getActivitiesByFilters({category: query.category}))
return {
props: {}
};
});
import React from "react";
import { wrapper } from "../../redux/store";
const ActivitiesListingPage = () => {
return <div>
</div>;
};
export default ActivitiesListingPage;
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
// Get the menu data.
// get the locations data.
// await store.dispatch(loadUser())
return {
props: {}
};
});
......@@ -15,6 +15,7 @@ export default function ActivityListingPage() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(getActivitiesByVendor());
dispatch(loadUser())
}, []);
return (
......
......@@ -10,21 +10,37 @@ import { wrapper } from "../../../redux/store";
import { useRouter } from "next/router";
const VendorDashboard = () => {
const { user, error } = useSelector(state => state.loadedUser);
const { loadedUser, error } = useSelector(state => state.loadedUser);
const router = useRouter();
console.log("user", user);
console.log("user", loadedUser);
const ApprovalStatus = () => {
if (user) {
switch (user.approved) {
if (loadedUser) {
switch (loadedUser.approved) {
case "approved":
return <></>;
return (
<>
<div className="col-12 offset-lg-2 col-lg-8 ">
<div className="alert alert-success alert-dismissible fade show text-center" role="alert">
<div className="text-center">
<p className="p1 text-center">Profile is approved!</p>
<p className="p2 text-center">You can add activities.</p>
</div>
</div>
</div>
</>
);
case "rejected":
return (
<>
<div class="alert alert-danger" role="alert">
Your profile has been rejected! Please contact the admin for more details!
<div className="col-12 offset-lg-2 col-lg-8 ">
<div className="alert alert-danger alert-dismissible fade show text-center" role="alert">
<div className="text-center">
<p className="p1 text-center">Your profile has been rejected!</p>
<p className="p2 text-center"> Please contact the admin for more details!</p>
</div>
</div>
</div>
</>
);
......@@ -33,29 +49,12 @@ const VendorDashboard = () => {
return (
<>
<div className="col-12 offset-lg-2 col-lg-8 ">
<div className="alert alert-danger alert-dismissible fade show text-center" role="alert">
{/* <div className="bgCircleBlue">
<Image alt="" src="/images/vendor/icon-tick.svg" width="15" height="10" />
</div> */}
<div className="alert alert-warning alert-dismissible fade show text-center" role="alert">
<div className="text-center">
<p className="p1 text-center">Business information sent successfully.</p>
<p className="p2 text-center">Kindly wait until we verify the details. You can start adding activities once your account is verified.</p>
</div>
{/* <button type="button" className="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> */}
</div>
{/* <div className="infoSent">
<div className="bgCircleBlue">
<Image alt="" src="/images/vendor/icon-tick.svg" width="15" height="10" />
</div>
<div className="px-3">
<p className="p1">Business information sent successfully.</p>
<p className="p2">Kindly wait until we verify the details. You can start adding activities once your account is verified.</p>
</div>
<div>
<Image alt="" src="/images/vendor/icon-close.svg" width="14" height="14" />
</div>
</div> */}
</div>
</>
);
......@@ -90,7 +89,7 @@ const VendorDashboard = () => {
type="button"
variant=""
className="btnAdd"
disabled={user?.approved != "approved"}
disabled={loadedUser?.approved != "approved"}
>
<span className="image-container me-2">
<Image alt="" layout="fill" src="/images/vendor/icon-plus.svg" width="14" height="14" className="image" />
......
......@@ -108,9 +108,8 @@ export const getActivitiesByVendor = () => async dispatch => {
}
}
},
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor", "image"]
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor", "image", "category"]
};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
......@@ -119,9 +118,9 @@ export const getActivitiesByVendor = () => async dispatch => {
// ...data
// }
// };
console.log(query);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/experiences?${queryString}`, config);
// console.log("Response", response.data);
console.log("Response", response.data);
dispatch({
type: GET_ACTIVITIES_SUCCESS,
payload: response.data
......@@ -148,7 +147,7 @@ export const getActivityById = id => async dispatch => {
};
const query = {
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor"]
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor", "category"]
};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
......@@ -239,7 +238,7 @@ export const getActivitiesForAdmin =
}
}
},
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor", "image"]
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor", "image", "category"]
};
const queryString = qs.stringify(query, {
......@@ -266,10 +265,7 @@ export const getActivitiesForAdmin =
}
};
export const getActivitiesForEndUser =
() =>
async dispatch => {
export const getActivitiesForEndUser = () => async dispatch => {
try {
dispatch({
type: GET_ACTIVITIES_REQUEST,
......@@ -317,3 +313,49 @@ async dispatch => {
});
}
};
export const getActivitiesByFilters =
({ category, subCategory, price, ageLimit, duration, fromDate, toDate, minGroupSize, maxGroupSize, minDuration, maxDuration, activityType }) =>
async dispatch => {
try {
dispatch({
type: GET_ACTIVITIES_REQUEST,
loading: true
});
const config = {
headers: {
"Content-Type": "application/json"
}
};
let query = {
filters: {
approved: { $eq: true }
},
populate: ["masterMonths", "subCategory", "subCategory.category", "timeSlots", "masterPincode", "vendor", "image", "category"]
};
console.log("query:", category);
if (category) {
query.filters["category"] = { id: { $eq: category } };
}
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/experiences?${queryString}`, config);
dispatch({
type: GET_ACTIVITIES_SUCCESS,
payload: response.data
});
return response.data;
} catch (error) {
dispatch({
type: GET_ACTIVITIES_FAIL,
payload: error.response.data
});
}
};
......@@ -14,4 +14,8 @@ export const UPDATE_ACTIVITY_BY_ID_REQUEST = "UPDATE_ACTIVITY_BY_ID_REQUEST"
export const UPDATE_ACTIVITY_BY_ID_SUCCESS = "UPDATE_ACTIVITY_BY_ID_SUCCESS"
export const UPDATE_ACTIVITY_BY_ID_FAIL = "UPDATE_ACTIVITY_BY_ID_FAIL"
// export const GET_ACTIVITY_BY_ID_REQUEST = "GET_ACTIVITY_BY_ID_REQUEST"
// export const GET_ACTIVITY_BY_ID_SUCCESS = "GET_ACTIVITY_BY_ID_SUCCESS"
// export const GET_ACTIVITY_BY_ID_FAIL = "GET_ACTIVITY_BY_ID_FAIL"
export const CLEAR_ERRORS = "CLEAR_ERRORS";
\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!