Skip to content
This repository has been archived by the owner on Dec 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #43 from Cassianky/vendor-yt-view-details-of-booking
Browse files Browse the repository at this point in the history
[Vendor] Add cancel to view all bookings
  • Loading branch information
e056 authored Oct 28, 2023
2 parents 1e74f67 + 8cada3a commit f8f347d
Show file tree
Hide file tree
Showing 14 changed files with 685 additions and 231 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,44 @@
import { Grid, TextField, Typography, useTheme } from "@mui/material";
import CancelIcon from "@mui/icons-material/Cancel";
import EventAvailableIcon from "@mui/icons-material/EventAvailable";
import EventBusyIcon from "@mui/icons-material/EventBusy";
import PaidIcon from "@mui/icons-material/Paid";
import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt";
import {
Grid,
List,
ListItem,
ListItemIcon,
ListItemText,
TextField,
Typography,
useTheme,
} from "@mui/material";
import { LocalizationProvider, TimePicker } from "@mui/x-date-pickers";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DateField } from "@mui/x-date-pickers/DateField";
import dayjs from "dayjs";
import { appointmentDataShape } from "../../../utils/ComponentPropTypes";
import {
convertISOtoShortDate,
convertISOtoTime,
} from "../../../utils/TimeFormatter";

const BookingDetailsForm = ({ appointmentData }) => {
const theme = useTheme();
const statusIcons = {
CONFIRMED: <ThumbUpAltIcon color="primary" />,
REJECTED: <CancelIcon color="primary" />,
CANCELLED: <EventBusyIcon color="primary" />,
PENDING_PAYMENT: <PaidIcon color="primary" />,
PAID: <EventAvailableIcon color="primary" />,
};
const statusActions = {
CONFIRMED: "Confirmed",
REJECTED: "Rejected",
CANCELLED: "Cancelled",
PENDING_PAYMENT: "Updated to Pending Payment",
PAID: "Updated to Paid",
};
return (
<Grid
container
Expand Down Expand Up @@ -101,6 +133,45 @@ const BookingDetailsForm = ({ appointmentData }) => {
fullWidth
/>
</Grid>
<Grid item xs={12}>
<Typography fontSize={"1.5rem"} color={theme.palette.primary.main}>
Status Changelog
</Typography>
</Grid>
<Grid item xs={12}>
<List>
{appointmentData?.actionHistory.length === 0 && (
<ListItem>
<ListItemText>No status changes</ListItemText>
</ListItem>
)}
{appointmentData?.actionHistory.map((details, index) => (
<ListItem key={index}>
<ListItemIcon>{statusIcons[details.newStatus]}</ListItemIcon>
<ListItemText
primary={
<>
{statusActions[details.newStatus]} by{" "}
<span
style={{
fontWeight: "bold",
color: theme.palette.primary.main,
}}
>
{details.actionByUserType} {details.actionByUserName}
</span>{" "}
on {convertISOtoShortDate(details.actionTimestamp)} at{" "}
{convertISOtoTime(details.actionTimestamp)}
</>
}
secondary={
details.actionRemarks && "Reason: " + details.actionRemarks
}
/>
</ListItem>
))}
</List>
</Grid>
</Grid>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const BookingRejectModal = ({
borderRadius: "10px",
boxShadow: "none",
},
"& .MuiBackdrop-root": {
backgroundColor: "rgb(0 0 0 / 0.2)",
},
}}
>
<DialogTitle sx={{ paddingBottom: 0 }}>
Expand Down Expand Up @@ -66,7 +69,7 @@ const BookingRejectModal = ({
<DialogActions>
<Button onClick={onClose}>Cancel</Button>
<Button
onClick={async () => handleRejectButton()}
onClick={async () => handleRejectButton(bookingToReject._id)}
variant="contained"
color="error"
disabled={!rejectionReason || rejectionReason === ""}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ import {
} from "../../../utils/ComponentPropTypes";
import BookingDetailsForm from "./BookingDetailsForm";
import BookingRejectModal from "./BookingRejectModal";
import {
convertISOtoDate,
convertISOtoTime,
} from "../../../utils/TimeFormatter";

const PREFIX = "Demo";

Expand Down Expand Up @@ -92,13 +96,13 @@ const BookingsMonthView = ({
startDate: startDateTime,
endDate: endDateTime,
...restProps,
}),
})
)
.filter((booking) =>
filterCriteria[newStatus].value === "ALL"
? booking.status === filterCriteria.pending.value ||
booking.status === filterCriteria.confirmed.value
: booking.status === filterCriteria[newStatus].value,
: booking.status === filterCriteria[newStatus].value
);
setBookings(newBookings);
};
Expand Down Expand Up @@ -176,30 +180,6 @@ const BookingsMonthView = ({
</StyledToolbarFlexibleSpace>
);

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 convertISOtoTime = (value) => {
const date = new Date(value);
const formattedTime = date
.toLocaleTimeString("en-SG", {
hour: "numeric",
minute: "numeric",
hour12: true,
})
.toUpperCase();
return formattedTime;
};

const ToolTipContent = ({ appointmentData }) => {
return (
<Grid
Expand Down Expand Up @@ -350,13 +330,13 @@ const BookingsMonthView = ({
startDate: startDateTime,
endDate: endDateTime,
...restProps,
}),
})
)
.filter((booking) =>
filterCriteria[currentStatus].value === "ALL"
? booking.status === filterCriteria.pending.value ||
booking.status === filterCriteria.confirmed.value
: booking.status === filterCriteria[currentStatus].value,
: booking.status === filterCriteria[currentStatus].value
);
};

Expand Down
160 changes: 149 additions & 11 deletions client-frontend/src/containers/Vendor/Booking/BookingsPage.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import styled from "@emotion/styled";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
import CloseIcon from "@mui/icons-material/Close";
import DoneIcon from "@mui/icons-material/Done";
import EventAvailableIcon from "@mui/icons-material/EventAvailable";
import NewReleasesIcon from "@mui/icons-material/NewReleases";
import ConfirmField from "./ConfirmField";
import CancelField from "./CancelField";
import { Badge, Box, Tab, Tabs, Typography, useTheme } from "@mui/material";
import { useEffect, useState } from "react";
import useBookingStore from "../../../zustand/BookingStore";
import BookingsMonthView from "./BookingsMonthView";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
import NewReleasesIcon from "@mui/icons-material/NewReleases";
import PendingBookingsTable from "./PendingBookingsTable";
import useSnackbarStore from "../../../zustand/SnackbarStore";
import BookingsMonthView from "./BookingsMonthView";
import BookingsTable from "./BookingsTable";
import DetailsField from "./DetailsField";
import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt";

const StyledPage = styled("div")(({ theme }) => ({
backgroundColor: theme.palette.grey[50],
Expand All @@ -19,7 +26,6 @@ const StyledBadge = styled(Badge)(({ theme }) => ({
border: `2px solid ${theme.palette.background.paper}`,
padding: "0 4px",
color: "white",
backgroundColor: theme.palette.success.pastel,
},
}));

Expand All @@ -31,7 +37,15 @@ const BookingsPage = () => {
const { openSnackbar } = useSnackbarStore();

const pendingBookingBadgeNumber = bookings.filter(
(booking) => booking.status === "PENDING_CONFIRMATION",
(booking) => booking.status === "PENDING_CONFIRMATION"
).length;

const completedAndPaidBadgeNumber = bookings.filter((booking) =>
["PAID", "PENDING_PAYMENT"].includes(booking.status)
).length;

const confirmedBadgeNumber = bookings.filter(
(booking) => booking.status === "CONFIRMED"
).length;

useEffect(() => {
Expand All @@ -45,6 +59,84 @@ const BookingsPage = () => {
const handleChange = (event, newVal) => {
setCurrentTab(newVal);
};

const pendingConfirmationAdditionalColumns = [
{
field: "approve",
type: "actions",
flex: 1,
renderHeader: (params) => {
return (
<Typography
fontSize={"1rem"}
sx={{ color: theme.palette.secondary.main }}
>
Approve?
</Typography>
);
},
renderCell: (params) => {
return <ConfirmField bookingData={params.row} />;
},
},
];
const completedAndPaidAdditionalColumns = [
{
field: "status",
flex: 1,
renderHeader: (params) => {
return (
<Typography
fontSize={"1rem"}
sx={{ color: theme.palette.secondary.main }}
>
Paid?
</Typography>
);
},
renderCell: (params) => {
return params.row.status === "PAID" ? <DoneIcon /> : <CloseIcon />;
},
},
];
const confirmedAdditionalColumns = [
{
field: "details",
flex: 1,
renderHeader: () => {
return (
<Typography
fontSize={"1rem"}
sx={{ color: theme.palette.secondary.main }}
>
Confirmation Details
</Typography>
);
},
sortable: false,
renderCell: (params) => {
return <DetailsField params={params.row} />;
},
},
{
field: "cancelAction",
align: "center",
renderHeader: () => {
return (
<Typography
fontSize={"1rem"}
sx={{ color: theme.palette.secondary.main }}
></Typography>
);
},
flex: 1,
sortable: false,
renderCell: (params) => {
return <CancelField bookingData={params.row} />;
},
},
];

return (
<StyledPage>
<Typography
Expand All @@ -71,11 +163,44 @@ const BookingsPage = () => {
value="bookingsList"
label=" New Bookings"
icon={
<StyledBadge badgeContent={pendingBookingBadgeNumber}>
<StyledBadge
badgeContent={pendingBookingBadgeNumber}
color="light_green"
>
<NewReleasesIcon />
</StyledBadge>
}
/>
<Tab
icon={
<StyledBadge
color={
currentTab === "completedAndPaid"
? "pale_purple"
: "unselected"
}
badgeContent={completedAndPaidBadgeNumber}
>
<EventAvailableIcon />
</StyledBadge>
}
value="completedAndPaid"
label="Completed"
/>
<Tab
icon={
<StyledBadge
color={
currentTab === "confirmed" ? "pale_purple" : "unselected"
}
badgeContent={confirmedBadgeNumber}
>
<ThumbUpAltIcon />
</StyledBadge>
}
value="confirmed"
label="Confirmed"
/>
</Tabs>
</Box>
<Box sx={{ paddingLeft: 2, paddingRight: 2 }}>
Expand All @@ -88,11 +213,24 @@ const BookingsPage = () => {
/>
)}
{currentTab === "bookingsList" && (
<PendingBookingsTable
<BookingsTable
allBookings={bookings}
approveBooking={approveBooking}
rejectBooking={rejectBooking}
openSnackbar={openSnackbar}
status={["PENDING_CONFIRMATION"]}
additionalColumns={pendingConfirmationAdditionalColumns}
/>
)}
{currentTab === "completedAndPaid" && (
<BookingsTable
allBookings={bookings}
status={["PAID", "PENDING_PAYMENT"]}
additionalColumns={completedAndPaidAdditionalColumns}
/>
)}
{currentTab === "confirmed" && (
<BookingsTable
allBookings={bookings}
status={["CONFIRMED"]}
additionalColumns={confirmedAdditionalColumns}
/>
)}
</Box>
Expand Down
Loading

0 comments on commit f8f347d

Please sign in to comment.