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

Commit

Permalink
[Client] A.5 Booking Management (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cassianky authored Oct 30, 2023
1 parent ba38144 commit 2e842de
Show file tree
Hide file tree
Showing 12 changed files with 1,626 additions and 20 deletions.
20 changes: 20 additions & 0 deletions client-frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import ShopPage from "./containers/Client/ShopPage";
import HomePage from "./containers/HomePage";
import LoginPage from "./containers/LoginPage";
import SocketConnection from "./utils/SocketConnection";
import MyBookings from "./containers/Client/Booking/MyBookings";
import BookingsDetails from "./containers/Client/Booking/BookingsDetails";

import VendorProtectedRoute from "./components/Routes/VendorProtectedRoute";
import VendorDetails from "./containers/Client/Activity/VendorDetails";
Expand Down Expand Up @@ -157,6 +159,24 @@ function App() {
</ClientProtectedRoute>
}
/>
<Route
exact
path="/bookings"
element={
<ClientProtectedRoute>
<MyBookings />
</ClientProtectedRoute>
}
/>
<Route
exact
path="/booking/:bookingId"
element={
<ClientProtectedRoute>
<BookingsDetails />
</ClientProtectedRoute>
}
/>
<Route
path="/login"
element={
Expand Down
117 changes: 117 additions & 0 deletions client-frontend/src/components/CancelField.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import React, { useState } from "react";
import { useTheme } from "@emotion/react";
import useSnackbarStore from "../zustand/SnackbarStore";
import useBookingStore from "../zustand/BookingStore";
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
Button,
TextField,
Typography,
} from "@mui/material";

const CancelField = ({ bookingData }) => {
const theme = useTheme();
const [dialogOpen, setDialogOpen] = useState(false);
const [reason, setReason] = useState("");
const { openSnackbar } = useSnackbarStore();
const { cancelBookingForClient, getAllBookingsForClient } = useBookingStore();

const handleDialogOpen = (event) => {
event.stopPropagation();
setDialogOpen(true);
};

const handleDialogClose = () => {
setDialogOpen(false);
};

const handleConfirmCancel = async (bookingId) => {
try {
const message = await cancelBookingForClient(bookingId, reason);
getAllBookingsForClient();
openSnackbar(message);
setDialogOpen(false);
} catch (error) {
openSnackbar(error.message, "error");
}
};

const confirmationDisplayDetails = [
{ label: "Client Company", value: bookingData.clientId.companyName },
{ label: "Vendor", value: bookingData.vendorName },
{ label: "Activity", value: bookingData.activityTitle },
{
label: "Date",
value: new Date(bookingData.startDateTime).toLocaleDateString(),
},
{
label: "Timeslot",
value: `${new Date(
bookingData.startDateTime
).toLocaleTimeString()} - ${new Date(
bookingData.endDateTime
).toLocaleTimeString()}`,
},
{ label: "Total Cost", value: `$${bookingData.totalCost}` },
];

return (
<div>
<Button variant="contained" color="error" onClick={handleDialogOpen}>
Cancel
</Button>

<Dialog fullWidth open={dialogOpen} onClose={handleDialogClose}>
<DialogTitle>Confirm Cancellation</DialogTitle>
<DialogContent>
{confirmationDisplayDetails.map((detail, index) => (
<div key={index}>
<Typography>
<span
style={{
fontWeight: "bold",
color: theme.palette.dark_purple.main,
}}
>
{detail.label}:{" "}
</span>
{detail.value}
</Typography>
</div>
))}
<DialogContentText sx={{ pt: 2 }}>
Please provide a reason for cancelling this booking:
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="reason"
label="Reason"
fullWidth
variant="standard"
value={reason}
onChange={(e) => setReason(e.target.value)}
/>
</DialogContent>
<DialogActions>
<Button onClick={handleDialogClose} color="primary">
Back
</Button>
<Button
onClick={async () => await handleConfirmCancel(bookingData._id)}
color="primary"
disabled={!reason.trim()}
>
Confirm
</Button>
</DialogActions>
</Dialog>
</div>
);
};

export default CancelField;
12 changes: 12 additions & 0 deletions client-frontend/src/components/NavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import useVendorStore from "../zustand/VendorStore.js";
import useShopStore from "../zustand/ShopStore.js";
import useSnackbarStore from "../zustand/SnackbarStore.js";
import useCartStore from "../zustand/CartStore.js";
import EventOutlinedIcon from "@mui/icons-material/EventOutlined";
import {
BookmarkBorderOutlined,
LogoutOutlined,
Expand Down Expand Up @@ -362,6 +363,17 @@ function NavBar(props) {
</ListItemIcon>
<ListItemText>Bookmarks</ListItemText>
</MenuItem>
<MenuItem
sx={{ px: "32px" }}
onClick={() => {
navigate("/bookings");
}}
>
<ListItemIcon>
<EventOutlinedIcon />
</ListItemIcon>
<ListItemText>My Bookings</ListItemText>
</MenuItem>
<MenuItem sx={{ px: "32px" }} onClick={logout}>
<ListItemIcon>
<LogoutOutlined />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,20 +210,17 @@ const ActivityDetailsPage = () => {

const weekendAddOn = calculateWeekendAddOn(
selectedDate,
currentActivity.weekendPricing,
totalBasePrice
currentActivity.weekendPricing
);

const offlineAddOn = calculateOfflineAddOn(
location,
currentActivity.offlinePricing,
totalBasePrice
currentActivity.offlinePricing
);

const onlineAddOn = calculateOnlineAddOn(
location,
currentActivity.onlinePricing,
totalBasePrice
currentActivity.onlinePricing
);

const totalPriceCalculated =
Expand All @@ -243,18 +240,15 @@ const ActivityDetailsPage = () => {
let totalBasePrice = calculateBasePrice(pax);
const weekendAddOn = calculateWeekendAddOn(
selectedDate,
currentActivity.weekendPricing,
totalBasePrice
currentActivity.weekendPricing
);
const offlineAddOn = calculateOfflineAddOn(
location,
currentActivity.offlinePricing,
totalBasePrice
currentActivity.offlinePricing
);
const onlineAddOn = calculateOnlineAddOn(
location,
currentActivity.onlinePricing,
totalBasePrice
currentActivity.onlinePricing
);
let activityPricingRule;
for (const pricingRule of currentActivity?.activityPricingRules) {
Expand Down Expand Up @@ -630,8 +624,7 @@ const ActivityDetailsPage = () => {
{""}
{currentActivity?.offlinePricing?.amount?.toFixed(
2
)}{" "}
%
)}
</Typography>
</Box>
</Box>
Expand Down
Loading

0 comments on commit 2e842de

Please sign in to comment.