diff --git a/client-frontend/src/containers/Client/Booking/BookingsDetails.jsx b/client-frontend/src/containers/Client/Booking/BookingsDetails.jsx index 9020e4b..86619fb 100644 --- a/client-frontend/src/containers/Client/Booking/BookingsDetails.jsx +++ b/client-frontend/src/containers/Client/Booking/BookingsDetails.jsx @@ -1,22 +1,20 @@ +import ArticleIcon from "@mui/icons-material/Article"; import { Box, - Tab, + Button, Chip, - Tabs, - Typography, - Badge, Divider, Grid, - Button, + Typography } from "@mui/material"; -import React, { useEffect, useState } from "react"; -import { useParams } from "react-router-dom"; -import useBookingStore from "../../../zustand/BookingStore"; +import { useTheme } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; -import { lighten, useTheme } from "@mui/material/styles"; +import React, { useEffect } from "react"; +import { Link, useParams } from "react-router-dom"; import notFound from "../../../assets/not_found.png"; +import MainBodyContainer from "../../../components/Common/MainBodyContainer"; import VendorProfileItem from "../../../components/Vendor/VendorProfileItem"; -import { Link } from "react-router-dom"; +import useBookingStore from "../../../zustand/BookingStore"; const BookingsDetails = () => { const { bookingId } = useParams(); @@ -55,314 +53,365 @@ const BookingsDetails = () => { getBookingForClient(bookingId); }, [bookingId]); + const isSurveyClosed = () => { + console.log(currentBooking?.isSurveySubmitted); + console.log(currentBooking?.status); + return ( + currentBooking?.isSurveySubmitted === true || + currentBooking?.status !== "CONFIRMED" || + currentBooking?.status !== "PAID" + ); + }; + const isMediumScreen = useMediaQuery((theme) => theme.breakpoints.down("md")); const activityPath = `/shop/activity/${currentBooking?.activityId._id}`; return ( - - - Booking Overview - - - - - BOOKING ID: {currentBooking?._id} - + + + Booking Overview + + + + + BOOKING ID: {currentBooking?._id} + + + + {!isMediumScreen && ( + + + + )} + {isMediumScreen && ( + + + + )} + + + + Order placed on{" "} + {new Date(currentBooking?.creationDateTime).toLocaleTimeString()} + {", "} + {new Date(currentBooking?.creationDateTime).toLocaleDateString()} + + + + {!isMediumScreen && ( + + + + )} + {isMediumScreen && ( + + + + )} + + + + - - {!isMediumScreen && ( - - - - )} - {isMediumScreen && ( - - + + Billing information + + + + + + + + Billing Party Name + + + {currentBooking?.billingPartyName} + + + + + Billing Email + + + {currentBooking?.billingEmail} + + + + + Billing Postal Code + + + {currentBooking?.billingOfficePostalCode} + + + + + Billing Postal Code + + + {currentBooking?.billingOfficePostalCode} + + + - )} - - - - Order placed on{" "} - {new Date(currentBooking?.creationDateTime).toLocaleTimeString()} - {", "} - {new Date(currentBooking?.creationDateTime).toLocaleDateString()} - + - - {!isMediumScreen && ( - - - - )} - {isMediumScreen && ( - - - + + Booking Details + + + {currentBooking?.vendorId && ( + )} - - + - - - - - Billing information - - - - - - - Billing Party Name - - - {currentBooking?.billingPartyName} - - - - - Billing Email - - - {currentBooking?.billingEmail} - - - - - Billing Postal Code - - - {currentBooking?.billingOfficePostalCode} - - - - - Billing Postal Code - - - {currentBooking?.billingOfficePostalCode} - - - - - - - - Booking Details - - - {currentBooking?.vendorId && ( - - )} - - - - - {currentBooking?.activityId?.preSignedImages && - currentBooking?.activityId?.preSignedImages?.length > 0 && ( + + {currentBooking?.activityId?.preSignedImages && + currentBooking?.activityId?.preSignedImages?.length > 0 && ( + {currentBooking?.activityTitle} + )} + {!currentBooking?.activityId?.preSignedImages?.length > 0 && ( {currentBooking?.activityTitle} )} - {!currentBooking?.activityId?.preSignedImages?.length > 0 && ( - {currentBooking?.activityTitle} - )} - - - - {currentBooking?.activityTitle} + + + + {currentBooking?.activityTitle} + + + + Date: + {new Date(currentBooking?.startDateTime).toLocaleDateString()} - - - Date: - {new Date(currentBooking?.startDateTime).toLocaleDateString()} - - - Start Time: - {new Date(currentBooking?.startDateTime).toLocaleTimeString()} - - - End Time: - {new Date(currentBooking?.endDateTime).toLocaleTimeString()} - - - Event Location Type: - {currentBooking?.eventLocationType} - - {currentBooking?.additionalComments && ( - Comments: - {currentBooking?.additionalComments} + Start Time: + {new Date(currentBooking?.startDateTime).toLocaleTimeString()} - )} + + End Time: + {new Date(currentBooking?.endDateTime).toLocaleTimeString()} + + + Event Location Type: + {currentBooking?.eventLocationType} + + {currentBooking?.additionalComments && ( + + Comments: + {currentBooking?.additionalComments} + + )} + + + + + Adult: {currentBooking?.totalPax} pax + - - - Adult: {currentBooking?.totalPax} pax - + + - - - - - - - Base Price - - - S$ {currentBooking?.basePricePerPax?.toFixed(2)} x{" "} - {currentBooking?.totalPax} Pax - - - {currentBooking?.weekendAddOnCost !== 0 && ( - Weekend Discounts/Add-ons + Base Price - S$ {currentBooking?.weekendAddOnCost?.toFixed(2)} + S$ {currentBooking?.basePricePerPax?.toFixed(2)} x{" "} + {currentBooking?.totalPax} Pax - )} - {currentBooking?.onlineAddOnCost !== 0 && ( + {currentBooking?.weekendAddOnCost !== 0 && ( + + + Weekend Discounts/Add-ons + + + S$ {currentBooking?.weekendAddOnCost?.toFixed(2)} + + + )} + {currentBooking?.onlineAddOnCost !== 0 && ( + + + Online Discounts/Add-ons + + + S$ {currentBooking?.onlineAddOnCost?.toFixed(2)} + + + )} + {currentBooking?.offlineAddOnCost !== 0 && ( + + + Offline Discounts/Add-ons + + + S$ {currentBooking?.offlineAddOnCost?.toFixed(2)} + + + )} - - Online Discounts/Add-ons + + Total - - S$ {currentBooking?.onlineAddOnCost?.toFixed(2)} + + S$ {currentBooking?.totalCost?.toFixed(2)} - )} - {currentBooking?.offlineAddOnCost !== 0 && ( - + + + + {currentBooking?.isSurveySubmitted ? ( + + ) : currentBooking?.status === "CONFIRMED" || + currentBooking?.status === "PAID" ? ( + + ) : ( + + )} - )} - - - Total - - - S$ {currentBooking?.totalCost?.toFixed(2)} - - - - - - - - + ); }; export default BookingsDetails; diff --git a/client-frontend/src/containers/Client/Booking/CancelBookingsTable.jsx b/client-frontend/src/containers/Client/Booking/CancelBookingsTable.jsx index 3cb72b7..bb311c6 100644 --- a/client-frontend/src/containers/Client/Booking/CancelBookingsTable.jsx +++ b/client-frontend/src/containers/Client/Booking/CancelBookingsTable.jsx @@ -1,66 +1,40 @@ import AccessTimeIcon from "@mui/icons-material/AccessTime"; import notFound from "../../../assets/not_found.png"; import { Box, Chip, Typography, useTheme, Alert } from "@mui/material"; -import { useNavigate } from "react-router-dom"; +import { useNavigate, useSearchParams } from "react-router-dom"; import { DataGrid, GridToolbarFilterButton } from "@mui/x-data-grid"; import PropTypes from "prop-types"; import { useEffect, useState } from "react"; import CancelField from "../../../components/CancelField"; +import { + convertISOtoDate, + convertISOtoTime, + convertISOtoShortDate, +} from "../../../utils/TimeFormatter"; const CancelBookingsTable = ({ allBookings, filter, hasCancel }) => { const navigate = useNavigate(); const [bookings, setBookings] = useState([]); const theme = useTheme(); const secondary = theme.palette.secondary.main; + let [searchParams, setSearchParams] = useSearchParams(); let containerStyle = { minHeight: "10rem", // Default for extra-large screens - width: "100%", + width: "10rem", objectFit: "cover", borderTopLeftRadius: "4px", borderTopRightRadius: "4px", borderBottomRightRadius: "4px", borderBottomLeftRadius: "4px", + borderRadius: "4px", }; useEffect(() => { const formattedBookings = filter(allBookings); setBookings(formattedBookings); + const tab = searchParams.get("tab"); }, [allBookings]); - const convertISOtoDate = (value) => { - const date = new Date(value); - const options = { - weekday: "long", - year: "numeric", - month: "long", - day: "numeric", - }; - const formattedDate = date.toLocaleDateString("en-SG", options); - return formattedDate; - }; - const convertISOtoShortDate = (value) => { - const date = new Date(value); - const options = { - year: "2-digit", - month: "2-digit", - day: "2-digit", - }; - const formattedDate = date.toLocaleDateString("en-SG", options); - return formattedDate; - }; - - const convertISOtoTime = (value) => { - const date = new Date(value); - const formattedTime = date - .toLocaleTimeString("en-SG", { - hour: "numeric", - minute: "numeric", - hour12: true, - }) - .toUpperCase(); - return formattedTime; - }; - const handleRowClick = ({ _id }) => { navigate(`/booking/${_id.toString()}`); }; @@ -83,7 +57,7 @@ const CancelBookingsTable = ({ allBookings, filter, hasCancel }) => { const title = params.value; const preSignedImages = params.row.activityId.preSignedImages; return ( - + { > {title} - + {/* Apply styling to the image */} {preSignedImages && preSignedImages.length > 0 && ( { ]; return ( -
+
{hasCancel && ( diff --git a/client-frontend/src/containers/Client/Bookmark/MyBookmarks.jsx b/client-frontend/src/containers/Client/Bookmark/MyBookmarks.jsx index 8484781..e5e3f9d 100644 --- a/client-frontend/src/containers/Client/Bookmark/MyBookmarks.jsx +++ b/client-frontend/src/containers/Client/Bookmark/MyBookmarks.jsx @@ -62,7 +62,11 @@ function MyBookmarks() { useEffect(() => { const fetchBookmarks = async () => { - await getBookmarks(); + try { + await getBookmarks(); + } catch (error) { + openSnackbar("An error occurred.", "error"); + } }; fetchBookmarks(); diff --git a/client-frontend/src/containers/Client/Survey/PendingSurveys.jsx b/client-frontend/src/containers/Client/Survey/PendingSurveys.jsx index bc82a60..89b768d 100644 --- a/client-frontend/src/containers/Client/Survey/PendingSurveys.jsx +++ b/client-frontend/src/containers/Client/Survey/PendingSurveys.jsx @@ -5,6 +5,7 @@ import { useParams } from "react-router-dom"; import useBookingStore from "../../../zustand/BookingStore"; import PendingSurveysTable from "./PendingSurveysTable"; import MainBodyContainer from "../../../components/Common/MainBodyContainer"; +import useSnackbarStore from "../../../zustand/SnackbarStore"; const StyledPaper = styled(Paper)` padding: 20px; @@ -16,13 +17,17 @@ const StyledPaper = styled(Paper)` function PendingSurveys() { const { bookings, getBookingsWithPendingSurvey, isLoading } = useBookingStore(); - + const { openSnackbar } = useSnackbarStore(); useEffect(() => { - const get = async () => { - await getBookingsWithPendingSurvey(); - }; + try { + const get = async () => { + await getBookingsWithPendingSurvey(); + }; - get(); + get(); + } catch (error) { + openSnackbar("An error occurred.", "error"); + } }, []); return (