diff --git a/src/components/frontend/DateTimePicker.jsx b/src/components/frontend/DateTimePicker.jsx index f0128a9..c4542e3 100644 --- a/src/components/frontend/DateTimePicker.jsx +++ b/src/components/frontend/DateTimePicker.jsx @@ -36,9 +36,11 @@ const DateTimePicker = ({ // Only check slots for the selected date const selectedDateStr = moment(selectedDate).format("YYYY-MM-DD"); return bookedSlots.some((booking) => { - // booking should have start and end in ISO or parseable format - const bookingStart = moment(booking.start); - const bookingEnd = moment(booking.end); + // booking should have booking_start_time and booking_end_time in ISO or parseable format + const bookingStart = moment( + booking.booking_start_time || booking.start_time + ); + const bookingEnd = moment(booking.booking_end_time || booking.end_time); // Only check if booking is on the same day if (bookingStart.format("YYYY-MM-DD") !== selectedDateStr) return false; // If slotTime is within booking range diff --git a/src/components/frontend/StaticSearchBar.jsx b/src/components/frontend/StaticSearchBar.jsx index a2e3adb..54ec6a1 100644 --- a/src/components/frontend/StaticSearchBar.jsx +++ b/src/components/frontend/StaticSearchBar.jsx @@ -6,6 +6,7 @@ import SearchIcon from "./icons/SearchIcon"; import ReactTestUtils from "react-dom/test-utils"; import { isNotInViewport, sleep } from "@/utils/utils"; import { useForm } from "react-hook-form"; +import CustomLocationAutoCompleteV2 from "../CustomLocationAutoCompleteV2"; import CustomComboBox from "../CustomComboBox"; import { GlobalContext } from "@/globalContext"; import { MagnifyingGlassIcon } from "@heroicons/react/24/solid"; diff --git a/src/pages/Common/Booking/PropertyPage.jsx b/src/pages/Common/Booking/PropertyPage.jsx index 7f04a84..9c363c1 100644 --- a/src/pages/Common/Booking/PropertyPage.jsx +++ b/src/pages/Common/Booking/PropertyPage.jsx @@ -1,6 +1,12 @@ import React, { useContext, useEffect } from "react"; import { useState } from "react"; -import { Link, Navigate, useLocation, useNavigate, useParams } from "react-router-dom"; +import { + Link, + Navigate, + useLocation, + useNavigate, + useParams, +} from "react-router-dom"; import FaqAccordion from "@/components/frontend/FaqAccordion"; import ReviewCard from "@/components/frontend/ReviewCard"; @@ -15,7 +21,15 @@ import { GlobalContext } from "@/globalContext"; import FavoriteButton from "@/components/frontend/FavoriteButton"; import Counter from "@/components/frontend/Counter"; import { Tooltip } from "react-tooltip"; -import { usePropertyAddons, usePropertySpace, usePropertySpaceImages, usePublicUserData, usePropertySpaceAmenities, usePropertySpaceFaqs, usePropertySpaceReviews } from "@/hooks/api"; +import { + usePropertyAddons, + usePropertySpace, + usePropertySpaceImages, + usePublicUserData, + usePropertySpaceAmenities, + usePropertySpaceFaqs, + usePropertySpaceReviews, +} from "@/hooks/api"; import PropertyImageSlider from "@/components/frontend/PropertyImageSlider"; import PropertySpaceMapImage from "@/components/frontend/PropertySpaceMapImage"; import AllReviewsModal from "@/components/frontend/AllReviewsModal"; @@ -25,7 +39,8 @@ import CircleCheckIcon from "@/components/frontend/icons/CircleCheckIcon"; let sdk = new MkdSDK(); const PropertyPage = () => { - const { dispatch: globalDispatch, state: globalState } = useContext(GlobalContext); + const { dispatch: globalDispatch, state: globalState } = + useContext(GlobalContext); const { state: authState, dispatch: authDispatch } = useContext(AuthContext); const { state: spaceData } = useLocation(); const { bookingData, dispatch } = useBookingContext(); @@ -34,7 +49,10 @@ const PropertyPage = () => { const [fetching, setFetching] = useState(true); const navigate = useNavigate(); const { id } = useParams(); - const bookingDetails = bookingData?.from === "" ? bookingData : JSON.parse(localStorage.getItem("booking_details")); + const bookingDetails = + bookingData?.from === "" + ? bookingData + : JSON.parse(localStorage.getItem("booking_details")); const [reviewDirection, setReviewDirection] = useState("DESC"); const [bookedSlots, setBookedSlots] = useState([]); const [scheduleTemplate, setScheduleTemplate] = useState({}); @@ -47,7 +65,11 @@ const PropertyPage = () => { const { propertySpace, notFound } = usePropertySpace(id, render); const hostData = usePublicUserData(propertySpace.host_id); - const spaceImages = usePropertySpaceImages(propertySpace.id, true, setFetching); + const spaceImages = usePropertySpaceImages( + propertySpace.id, + true, + setFetching + ); const spaceAddons = usePropertyAddons(propertySpace.property_id); const spaceAmenities = usePropertySpaceAmenities(propertySpace.id); const faqs = usePropertySpaceFaqs(propertySpace.id); @@ -56,12 +78,19 @@ const PropertyPage = () => { const { pathname } = useLocation(); if (!fetching && spaceImages.length === 0) { - navigate("*") + navigate("*"); } async function fetchBookedSlots(id) { try { - const result = await callCustomAPI("customer/schedule", "post", { property_spaces_id: id }, "", null, "v3"); + const result = await callCustomAPI( + "customer/schedule", + "post", + { property_spaces_id: id }, + "", + null, + "v3" + ); if (Array.isArray(result.list)) { setBookedSlots(result.list); } @@ -86,11 +115,10 @@ const PropertyPage = () => { limit: 1, where: [`property_spaces_id = ${id}`], }, - "PAGINATE", + "PAGINATE" ); if (Array.isArray(result.list) && result.list.length > 0) { setScheduleTemplate({ custom_slots: result.list[0].custom_slots }); - } if (result.list[0]?.schedule_template_id) { const templateResult = await callCustomAPI( @@ -101,9 +129,12 @@ const PropertyPage = () => { limit: 1, where: [`id = ${result.list[0].schedule_template_id}`], }, - "PAGINATE", + "PAGINATE" ); - if (Array.isArray(templateResult.list) && (templateResult.list[0] ?? {})) { + if ( + Array.isArray(templateResult.list) && + (templateResult.list[0] ?? {}) + ) { setScheduleTemplate((prev) => { let updated = { ...prev, ...templateResult.list[0] }; return updated; @@ -140,15 +171,24 @@ const PropertyPage = () => { } if (authState.user == propertySpace.host_id) { - globalDispatch({ type: "SHOW_ERROR", payload: { heading: "error", message: "Owners can't book their own spaces" } }) - return + globalDispatch({ + type: "SHOW_ERROR", + payload: { + heading: "error", + message: "Owners can't book their own spaces", + }, + }); + return; } if (globalState.user.verificationStatus != 1) { globalDispatch({ type: "OPEN_NOT_VERIFIED_MODAL" }); return; } - dispatch({ type: "SET_BOOKING_DETAILS", payload: { ...data, ...propertySpace } }); + dispatch({ + type: "SET_BOOKING_DETAILS", + payload: { ...data, ...propertySpace }, + }); navigate("booking-preview"); }; @@ -169,99 +209,119 @@ const PropertyPage = () => { return new Date(a.post_date) - new Date(b.post_date); }; - if (notFound || isNaN(id)) return ; + if (notFound || isNaN(id)) return ; return (
{ setShowCalendar(false); }} > -
-
-

{propertySpace.name ?? spaceData?.name}

+
+
+

+ {propertySpace.name ?? spaceData?.name} +

-
-

+

+

- - {(Number(propertySpace.average_space_rating ?? spaceData?.average_space_rating) || 0).toFixed(1)} - ({propertySpace.space_rating_count ?? spaceData?.space_rating_count}) + + {( + Number( + propertySpace.average_space_rating ?? + spaceData?.average_space_rating + ) || 0 + ).toFixed(1)} + + ( + {propertySpace.space_rating_count ?? + spaceData?.space_rating_count} + ) +

-
+
Save
-
- {spaceImages[0]?.photo_url && +
+ {spaceImages[0]?.photo_url && ( - } - {spaceImages[1]?.photo_url && + )} + {spaceImages[1]?.photo_url && ( - } -
- {spaceImages[2]?.photo_url && + )} +
+ {spaceImages[2]?.photo_url && ( - } - {spaceImages[3]?.photo_url && + )} + {spaceImages[3]?.photo_url && ( - } + )}
- {spaceImages[4]?.photo_url && + {spaceImages[4]?.photo_url && ( - } + )}
-
-
-

Description

-

{propertySpace.description ?? spaceData?.description}

-
-

Amenities

-
    +
    +
    +

    Description

    +

    + {propertySpace.description ?? spaceData?.description} +

    +
    +

    Amenities

    +
      {spaceAmenities.map((am, idx) => (
    • @@ -269,72 +329,80 @@ const PropertyPage = () => {
    • ))}
    -
    -

    Add ons

    -
      +
      +

      Add ons

      +
        {spaceAddons.map((addon) => (
      • - + {" "} -
        +
        {addon.add_on_name}
        {" "} {" "} - ${addon.cost}/h + ${addon.cost}/h
      • ))}
      -
      -
      -

      About the host

      - {(authState.role == "customer" && propertySpace?.id) && ( +
      +
      +

      + About the host +

      + {authState.role == "customer" && propertySpace?.id && ( Contact the host )}
      -
      -
      - +
      +
      +
      -
      -

      {propertySpace.first_name}

      -

      {propertySpace.about ?? spaceData?.about}

      +
      +

      + {propertySpace.first_name} +

      +

      + {propertySpace.about ?? spaceData?.about} +

      - {(authState.role == "customer" && propertySpace?.id) && ( + {authState.role == "customer" && propertySpace?.id && ( Contact the host )}
      -

      {propertySpace.about ?? spaceData?.about}

      +

      + {propertySpace.about ?? spaceData?.about} +

      -
      -
      -

      Reviews

      +
      +
      +

      Reviews

      @@ -344,15 +412,12 @@ const PropertyPage = () => { .sort(sortByPostDate) .slice(0, 10) .map((rw) => ( - + ))} -
      +
      {reviews.length > 10 ? (
    -
    -

    FAQs

    +
    +

    FAQs

    {faqs.map((faq) => ( - + ))} -
    -

    Property rules

    -

    {propertySpace.rule ?? spaceData?.rule}

    +
    +

    Property rules

    +

    {propertySpace.rule ?? spaceData?.rule}

-
-
-

Price and availability

-
- Max capacity +
+
+

+ Price and availability +

+
+ Max capacity {" "} - {propertySpace.max_capacity ?? spaceData?.max_capacity} people + + {propertySpace.max_capacity ?? spaceData?.max_capacity} + {" "} + people
-
- Pricing from +
+ Pricing from - from: ${propertySpace.rate ?? spaceData?.rate}/h + from:{" "} + + ${propertySpace.rate ?? spaceData?.rate} + + /h
-
-
- Number of guests + +
+ Number of guests
-
-
+
+
{ setShowCalendar={setShowCalendar} fromDefault={bookingDetails.from} toDefault={bookingDetails.to} - bookedSlots={bookedSlots.map((slot) => ({ fromTime: new Date(slot.start_time), toTime: new Date(slot.end_time) }))} + bookedSlots={bookedSlots} scheduleTemplate={scheduleTemplate} defaultDate={bookingDetails.selectedDate || undefined} />
{authState.role != "customer" && authState.isAuthenticated ? ( ) : ( )}
-
-

Price and availability

-
- Max capacity +
+

+ Price and availability +

+
+ Max capacity {" "} - {propertySpace.max_capacity ?? spaceData?.max_capacity} people + + {propertySpace.max_capacity ?? spaceData?.max_capacity} + {" "} + people
-
- Pricing from +
+ Pricing from - from: ${propertySpace.rate ?? spaceData?.rate}/h + from:{" "} + + ${propertySpace.rate ?? spaceData?.rate} + + /h
-
-
- Number of guests + +
+ Number of guests
-
-
+
+
{ setShowCalendar={setShowCalendar} fromDefault={bookingDetails.from} toDefault={bookingDetails.to} - bookedSlots={bookedSlots.map((slot) => ({ fromTime: new Date(slot.start_time), toTime: new Date(slot.end_time) }))} + bookedSlots={bookedSlots} scheduleTemplate={scheduleTemplate} />
{authState.role != "customer" && authState.isAuthenticated ? ( ) : ( -

Edit Booking

-
-
-
+

Edit Booking

+
+
+
-
-

{booking.property_name}

-

{booking.address_line_1}

-

{booking.city + ", " + booking.address_line_2}

+
+

+ {booking.property_name} +

+

+ {booking.address_line_1} +

+

+ {booking.city + ", " + booking.address_line_2} +

-
-
+
+
-

Date & time

+

Date & time

-
+

Date

-

+

{" "} - {(bookingStartDate instanceof Date ? fullMonthsMapping[bookingStartDate.getMonth()] : "") + " " + bookingStartDate.getDate() + "/" + bookingStartDate.getFullYear()} + {(bookingStartDate instanceof Date + ? fullMonthsMapping[bookingStartDate.getMonth()] + : "") + + " " + + bookingStartDate.getDate() + + "/" + + bookingStartDate.getFullYear()}

-
+

Time

-

+

{formValues.from} - {formValues.to}

-
+

Duration

-

{getDuration(formValues.from, formValues.to)} hour(s)

+

+ {getDuration(formValues.from, formValues.to)} hour(s) +

-
+
-

Add Ons

+

Add Ons

{addons.map((addon) => { return ( @@ -217,41 +267,50 @@ export default function EditBookingPage() { key={addon.id} data={addon} register={register} - name="selectedAddons" + name='selectedAddons' /> ); })}
-
-

Price and availability

-
- Max capacity +
+

+ Price and availability +

+
+ Max capacity {" "} - {booking.max_capacity} people + + {booking.max_capacity} + {" "} + people
-
- Pricing from +
+ Pricing from - from: ${booking.rate}/h + from: ${booking.rate}/h
-
-
- Number of guests +
+
+ Number of guests
-
-
+
+
({ fromTime: new Date(slot.start_time), toTime: new Date(slot.end_time) }))} + bookedSlots={bookedSlots} scheduleTemplate={scheduleTemplate} defaultDate={bookingStartDate} />
-
-
-

Charges

+
+
+

Charges

-
-
+
+

Rate

-

${booking.rate.toFixed(2)}/h

+

+ ${booking.rate.toFixed(2)}/h +

-
+

Price

-

${(booking.rate * getDuration(formValues.from, formValues.to)).toFixed(2)}

+

+ {" "} + $ + {( + booking.rate * getDuration(formValues.from, formValues.to) + ).toFixed(2)} +

{formValues.selectedAddons.map((addon_name, idx) => { - let price = addons.find((addon) => addon.add_on_name == addon_name)?.cost; + let price = addons.find( + (addon) => addon.add_on_name == addon_name + )?.cost; if (!price) return null; return ( -
+

{addon_name}

-

${Number(price).toFixed(2)}

+

+ {" "} + ${Number(price).toFixed(2)} +

); })} -
+

Tax

-

${Number((booking.rate * getDuration(formValues.from, formValues.to) * tax) / 100).toFixed(2)}

+

+ {" "} + $ + {Number( + (booking.rate * + getDuration(formValues.from, formValues.to) * + tax) / + 100 + ).toFixed(2)} +

-
+

Total

-

+

{" "} $ {( Number( addons.reduce((acc, curr) => { - if (!formValues.selectedAddons.includes(curr.add_on_name)) return acc; + if ( + !formValues.selectedAddons.includes(curr.add_on_name) + ) + return acc; return Number(acc) + (Number(curr.cost) ?? 0); - }, 0), + }, 0) ) + - Number((booking.rate * getDuration(formValues.from, formValues.to) * tax) / 100) + - Number(booking.rate * getDuration(formValues.from, formValues.to)) + Number( + (booking.rate * + getDuration(formValues.from, formValues.to) * + tax) / + 100 + ) + + Number( + booking.rate * getDuration(formValues.from, formValues.to) + ) ).toFixed(2)}

Save -

(Note: this will affect the rates)

+

+ (Note: this will affect the rates) +

Cancellation Policy diff --git a/src/pages/Host/Spaces/MySpaceDetailsPage.jsx b/src/pages/Host/Spaces/MySpaceDetailsPage.jsx index 1fb9d12..61e3b57 100644 --- a/src/pages/Host/Spaces/MySpaceDetailsPage.jsx +++ b/src/pages/Host/Spaces/MySpaceDetailsPage.jsx @@ -1,6 +1,11 @@ import React, { Fragment, useEffect } from "react"; import { useState } from "react"; -import { Navigate, useLocation, useNavigate, useParams } from "react-router-dom"; +import { + Navigate, + useLocation, + useNavigate, + useParams, +} from "react-router-dom"; import FaqAccordion from "@/components/frontend/FaqAccordion"; import ReviewCard from "@/components/frontend/ReviewCard"; import StarIcon from "@/components/frontend/icons/StarIcon"; @@ -13,12 +18,24 @@ import ThreeDotsMenu from "@/components/frontend/ThreeDotsMenu"; import MySpaceBookingHistoryPage from "./MySpaceBookingHistoryPage"; import CustomSelect from "@/components/frontend/CustomSelect"; import DraftProgress from "@/components/frontend/DraftProgress"; -import { DRAFT_STATUS, IMAGE_STATUS, SPACE_VISIBILITY } from "@/utils/constants"; +import { + DRAFT_STATUS, + IMAGE_STATUS, + SPACE_VISIBILITY, +} from "@/utils/constants"; import { useContext } from "react"; import { GlobalContext } from "@/globalContext"; import FavoriteButton from "@/components/frontend/FavoriteButton"; import PropertyImageSlider from "@/components/frontend/PropertyImageSlider"; -import { usePropertyAddons, usePropertySpace, usePropertySpaceAmenities, usePropertySpaceFaqs, usePropertySpaceImages, usePropertySpaceReviews, usePublicUserData } from "@/hooks/api"; +import { + usePropertyAddons, + usePropertySpace, + usePropertySpaceAmenities, + usePropertySpaceFaqs, + usePropertySpaceImages, + usePropertySpaceReviews, + usePublicUserData, +} from "@/hooks/api"; import PropertySpaceMapImage from "@/components/frontend/PropertySpaceMapImage"; import { Tab } from "@headlessui/react"; import AllReviewsModal from "@/components/frontend/AllReviewsModal"; @@ -32,7 +49,11 @@ let sdk = new MkdSDK(); let ctrl = new AbortController(); const statusMapping = ["Under Review", "Active", "Rejected"]; -const statusColorMapping = ["text-[#DC6803]", "my-text-gradient", "text-[#D92D20]"]; +const statusColorMapping = [ + "text-[#DC6803]", + "my-text-gradient", + "text-[#D92D20]", +]; const MySpaceDetailsPage = () => { const { state: spaceData } = useLocation(); @@ -55,10 +76,9 @@ const MySpaceDetailsPage = () => { const [fetching, setFetching] = useState(true); - const { propertySpace, notFound } = usePropertySpace(id, render); const hostData = usePublicUserData(propertySpace.host_id); - const spaceImages = usePropertySpaceImagesV2(propertySpace.id, false,); + const spaceImages = usePropertySpaceImagesV2(propertySpace.id, false); const spaceAddons = usePropertyAddons(propertySpace.property_id); const spaceAmenities = usePropertySpaceAmenities(propertySpace.id); @@ -66,10 +86,16 @@ const MySpaceDetailsPage = () => { const reviews = usePropertySpaceReviews(propertySpace.id); const [deleteSpace, setDeleteSpace] = useState(false); - async function fetchBookedSlots(id) { try { - const result = await callCustomAPI("customer/schedule", "post", { property_spaces_id: id }, "", null, "v3"); + const result = await callCustomAPI( + "customer/schedule", + "post", + { property_spaces_id: id }, + "", + null, + "v3" + ); if (Array.isArray(result.list)) { setBookedSlots(result.list); } @@ -94,11 +120,14 @@ const MySpaceDetailsPage = () => { limit: 1, where: [`property_spaces_id = ${id}`], }, - "PAGINATE", + "PAGINATE" ); if (Array.isArray(result.list) && result.list.length > 0) { - setScheduleTemplate({ custom_slots: result.list[0].custom_slots, schedule_id: result.list[0].id }); + setScheduleTemplate({ + custom_slots: result.list[0].custom_slots, + schedule_id: result.list[0].id, + }); } if (result.list[0]?.schedule_template_id) { const templateResult = await callCustomAPI( @@ -109,9 +138,12 @@ const MySpaceDetailsPage = () => { limit: 1, where: [`id = ${result.list[0].schedule_template_id}`], }, - "PAGINATE", + "PAGINATE" ); - if (Array.isArray(templateResult.list) && (templateResult.list[0] ?? {})) { + if ( + Array.isArray(templateResult.list) && + (templateResult.list[0] ?? {}) + ) { setScheduleTemplate((prev) => { let updated = { ...prev, ...templateResult.list[0] }; return updated; @@ -131,9 +163,16 @@ const MySpaceDetailsPage = () => { async function fetchMySpaceBookings() { const user_id = localStorage.getItem("user"); - var where = [`ergo_booking.host_id = ${user_id} AND ergo_booking.property_space_id = ${id} AND ergo_booking.deleted_at IS NULL`]; + var where = [ + `ergo_booking.host_id = ${user_id} AND ergo_booking.property_space_id = ${id} AND ergo_booking.deleted_at IS NULL`, + ]; try { - const result = await sdk.callRawAPI("/v2/api/custom/ergo/booking/PAGINATE", { page: 1, limit: 10000, where }, "POST", ctrl.signal); + const result = await sdk.callRawAPI( + "/v2/api/custom/ergo/booking/PAGINATE", + { page: 1, limit: 10000, where }, + "POST", + ctrl.signal + ); if (Array.isArray(result.list)) { setMyBookings(result.list); } @@ -153,7 +192,12 @@ const MySpaceDetailsPage = () => { async function hidePropertySpace(id) { globalDispatch({ type: "START_LOADING" }); try { - await sdk.callRawAPI("/rest/property_spaces/PUT", { id, availability: SPACE_VISIBILITY.HIDDEN }, "POST", ctrl.signal); + await sdk.callRawAPI( + "/rest/property_spaces/PUT", + { id, availability: SPACE_VISIBILITY.HIDDEN }, + "POST", + ctrl.signal + ); forceRender(new Date()); } catch (err) { tokenExpireError(dispatch, err.message); @@ -175,7 +219,12 @@ const MySpaceDetailsPage = () => { async function showPropertySpace(id) { globalDispatch({ type: "START_LOADING" }); try { - await sdk.callRawAPI("/rest/property_spaces/PUT", { id, availability: SPACE_VISIBILITY.VISIBLE }, "POST", ctrl.signal); + await sdk.callRawAPI( + "/rest/property_spaces/PUT", + { id, availability: SPACE_VISIBILITY.VISIBLE }, + "POST", + ctrl.signal + ); forceRender(new Date()); } catch (err) { tokenExpireError(dispatch, err.message); @@ -215,54 +264,90 @@ const MySpaceDetailsPage = () => { return (
{ setShowCalendar(false); }} >
-
-

Space Details

-
- +
+

+ Space Details +

+
+ {" "} - {(propertySpace.draft_status ?? spaceData?.draft_status) < DRAFT_STATUS.COMPLETED ? "DRAFT" : statusMapping[propertySpace.space_status ?? spaceData?.space_status ?? 0]} + {(propertySpace.draft_status ?? spaceData?.draft_status) < + DRAFT_STATUS.COMPLETED + ? "DRAFT" + : statusMapping[ + propertySpace.space_status ?? spaceData?.space_status ?? 0 + ]} - +
- + - + {" "} - + {" "} -
+
@@ -307,126 +399,163 @@ const MySpaceDetailsPage = () => { {propertySpace.id ?? spaceData?.id ? ( <> {" "} - {(propertySpace.draft_status ?? spaceData?.draft_status) < DRAFT_STATUS.COMPLETED ? ( + {(propertySpace.draft_status ?? spaceData?.draft_status) < + DRAFT_STATUS.COMPLETED ? ( <> -

Finish creating your space

+

Finish creating your space

) : ( -
-
+
+

Space ID

-

{id}

+

{id}

-
+

Total Revenue

-

+

${" "} {myBookings .reduce((acc, curr) => { - return acc + (curr.total ?? 0) + (curr.addon_cost ?? 0); + return ( + acc + (curr.total ?? 0) + (curr.addon_cost ?? 0) + ); }, 0) .toFixed(2)}

-
+

Total Bookings

-

{myBookings.length}

+

{myBookings.length}

)} ) : null} -
-
-

{propertySpace.name ?? spaceData?.name}

-

{propertySpace.address_line_1 ?? spaceData?.address_line_1}

+
+
+

+ {propertySpace.name ?? spaceData?.name} +

+

+ {propertySpace.address_line_1 ?? spaceData?.address_line_1} +

-
-

+

+

- - {(Number(propertySpace.average_space_rating ?? spaceData?.average_space_rating) || 0).toFixed(1)} - ({propertySpace.space_rating_count ?? spaceData?.space_rating_count}) + + {( + Number( + propertySpace.average_space_rating ?? + spaceData?.average_space_rating + ) || 0 + ).toFixed(1)} + + ( + {propertySpace.space_rating_count ?? + spaceData?.space_rating_count} + ) +

-
+
Save
-
- - {spaceImages[0]?.photo_url && +
+ {spaceImages[0]?.photo_url && ( - } - {spaceImages[1]?.photo_url && + )} + {spaceImages[1]?.photo_url && ( - } -
- {spaceImages[2]?.photo_url && + )} +
+ {spaceImages[2]?.photo_url && ( - } - {spaceImages[3]?.photo_url && + )} + {spaceImages[3]?.photo_url && ( - } + )}
- {spaceImages[4]?.photo_url && + {spaceImages[4]?.photo_url && ( - } + )}
-
-
-

Description

-

{propertySpace.description ?? spaceData?.description}

-
-

Amenities

-
    +
    +
    +

    + Description +

    +

    + {propertySpace.description ?? spaceData?.description} +

    +
    +

    + Amenities +

    +
      {spaceAmenities.map((am, idx) => (
    • @@ -434,58 +563,66 @@ const MySpaceDetailsPage = () => {
    • ))}
    -
    -

    Add ons

    -
      +
      +

      Add ons

      +
        {spaceAddons.map((addon) => (
      • - + {" "} -
        +
        {addon.add_on_name}
        {" "} {" "} - ${addon.cost}/h + + ${addon.cost}/h +
      • ))}
      -
      -
      -

      About the host

      +
      +
      +

      + About the host +

      -
      -
      - +
      +
      +
      -
      -
      -

      {hostData.first_name}

      -

      {hostData.last_name}

      +
      +
      +

      {hostData.first_name}

      +

      {hostData.last_name}

      -

      {propertySpace.about ?? spaceData?.about}

      +

      + {propertySpace.about ?? spaceData?.about} +

      - -

      {propertySpace.about ?? spaceData?.about}

      -
      -
      -

      Reviews

      + +

      + {propertySpace.about ?? spaceData?.about} +

      +
      +
      +

      Reviews

      @@ -495,15 +632,12 @@ const MySpaceDetailsPage = () => { .sort(sortByPostDate) .slice(0, 10) .map((rw) => ( - + ))} -
      +
      {reviews.length > 10 ? (
    -
    -

    FAQs

    +
    +

    FAQs

    {faqs.map((faq) => ( - + ))} -
    -

    Property rules

    -

    {propertySpace.rule ?? spaceData?.rule}

    +
    +

    + Property rules +

    +

    + {propertySpace.rule ?? spaceData?.rule} +

-
-
-

Price and availability

-
- Max capacity +
+
+

+ Price and availability +

+
+ Max capacity {" "} - {propertySpace.max_capacity ?? spaceData?.max_capacity} people + + {propertySpace.max_capacity ?? + spaceData?.max_capacity} + {" "} + people
-
- Pricing from +
+ Pricing from - from: ${propertySpace.rate ?? spaceData?.rate}/h + from:{" "} + + ${propertySpace.rate ?? spaceData?.rate} + + /h
- {propertySpace.additional_guest_rate && propertySpace.max_capacity > 1 ? ( -
- Additional guest + {propertySpace.additional_guest_rate && + propertySpace.max_capacity > 1 ? ( +
+ Additional guest - from: ${propertySpace.additional_guest_rate}/h + from:{" "} + + ${propertySpace.additional_guest_rate} + + /h
) : null} -
+
-
+
{ setShowCalendar={setShowCalendar} fromDefault={""} toDefault={""} - bookedSlots={bookedSlots.map((slot) => ({ fromTime: new Date(slot.start_time), toTime: new Date(slot.end_time) }))} + bookedSlots={bookedSlots} scheduleTemplate={scheduleTemplate} - defaultMessage="Check Availability" + defaultMessage='Check Availability' />
@@ -601,8 +753,15 @@ const MySpaceDetailsPage = () => { setShowMap(false)}