Skip to content

Commit

Permalink
Merge pull request #15 from niscy-eudiw/feat/confirmation-page
Browse files Browse the repository at this point in the history
confirmation-page, custom-error connection, added car contract
  • Loading branch information
SmirlakisParis authored Sep 23, 2024
2 parents 49facaa + aa5e1f5 commit 69068d1
Show file tree
Hide file tree
Showing 17 changed files with 488 additions and 378 deletions.
Binary file added public/Car-Rental-Contract.pdf
Binary file not shown.
Binary file added public/images/car.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions src/client/components/atoms/CarImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { SvgIcon, SvgIconProps } from "@mui/material";
import React from "react";

interface IconProps extends SvgIconProps {
className?: string;
}

const CarImage: React.FC<IconProps> = ({ className, ...props }) => {
return (
<SvgIcon
{...props}
className={className}
viewBox="0 0 24 24"
sx={{
fontSize: 24, // Default size (equivalent to Tailwind size-6)
...(props.sx || {}), // Allow custom `sx` prop to override styles
}}
></SvgIcon>
);
};

export default CarImage;
37 changes: 37 additions & 0 deletions src/client/components/atoms/RightBoxArrowIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { SvgIcon, SvgIconProps } from "@mui/material";
import React from "react";

interface IconProps extends SvgIconProps {
className?: string;
}

const RightBoxArrowIcon: React.FC<IconProps> = ({ className, ...props }) => {
return (
<SvgIcon
{...props}
className={className}
viewBox="0 0 24 24"
sx={{
fontSize: 24, // Default size equivalent to "size-6" in Tailwind
...(props.sx || {}), // Allow custom sx prop to override styles
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="size-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"
/>
</svg>
</SvgIcon>
);
};

export default RightBoxArrowIcon;
24 changes: 7 additions & 17 deletions src/client/components/atoms/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
import React from "react";
import { Box } from "@mui/material";
import Image from "next/image";
import React from "react";

const Sidebar: React.FC = () => {
return (
<Box
component="aside"
sx={{
w: "100%",
p: 2,
display: "flex",
flexDirection: "column",
ml: { md: 5, xs: 0 },
mt: { xs: 10, md: 0 },
width: { xs: "100%", md: "auto" },
flexWrap: "wrap",
alignItems: { sm: "center", md: "end" },
justifyContent: { sm: "center", md: "end" },
}}
>
<Image
loading="lazy"
src="/images/sidebar.png"
alt="reviews"
width={259}
height={454} // Aspect ratio of 0.57 (259px width * 0.57 = 147px height)
style={{
width: "100%",
height: "auto",
minWidth:'280px'
}}
/>
<Image src="/images/sidebar.png" alt="reviews" width={259} height={454} />
</Box>
);
};
Expand Down
56 changes: 56 additions & 0 deletions src/client/components/molecules/CarInformation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Box, Button, Typography } from "@mui/material";
import Image from "next/image";
import RightBoxArrowIcon from "../atoms/RightBoxArrowIcon";

export default function CarInformation() {
const downloadContract = () => {
// Create a link element, set its href to the PDF file, and trigger the download
const link = document.createElement("a");
link.href = "/Car-Rental-Contract.pdf"; // The file path within the public folder
link.download = "Car-Rental-Contract.pdf"; // The file name for download
link.click();
};

return (
<Box
sx={{
display: "flex",
flexDirection: "column",
}}
>
<Typography fontWeight={"bold"}>Car rental information</Typography>
{/* Car Image and Information */}

<Image src="/images/car.png" alt="car" width={217} height={145} />
<Typography variant="body2" sx={{ fontWeight: "bold" }}>
To continue booking your car rental, you must{" "}
<Typography
component="a"
color="primary"
sx={{ textDecoration: "underline", cursor: "pointer" }}
>
sign your contract
</Typography>{" "}
with the rental service electronically.
</Typography>

{/* Car Rental Button */}
<Box
sx={{
color: "white",
mt: 4,
}}
>
<Button
color="primary"
variant="contained"
onClick={downloadContract}
startIcon={<RightBoxArrowIcon />}
sx={{ p: 2, fontWeight: "bold" }}
>
Sign your car rental contract
</Button>
</Box>
</Box>
);
}
52 changes: 24 additions & 28 deletions src/client/components/molecules/HotelDescription.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,32 @@
import { Box, Typography } from "@mui/material";
import React from "react";
import { Box, Button, Typography, CircularProgress } from "@mui/material";


import { Hotel } from "@/shared";

const HotelDescription: React.FC = () => {

return (

<Box sx={{ textAlign: 'left', fontSize: '0.875rem' }}>
<Typography color="textPrimary">
{Hotel.name} Hotel has a garden, terrace, a restaurant, and bar in
Brussels. With free WiFi, this 4-star hotel offers room service and a
24-hour front desk. There is a spa and wellness centre with an outdoor
swimming pool, indoor pool, and fitness centre, as well as a sauna.
<br />
<br />
The hotel will provide guests with air-conditioned rooms offering a
desk, a kettle, a fridge, a safety deposit box, a flat-screen TV, and a
private bathroom with a shower. Some rooms include a kitchenette with
a dishwasher, an oven, and a microwave. At {Hotel.name} Hotel, rooms
come with bed linen and towels.
<br />
<br />
The accommodation offers a buffet or continental breakfast. The
wellness area at {Hotel.name} Hotel includes a hot tub and a hammam.
<br />
<br />
</Typography>
</Box>


<Box sx={{ textAlign: "left", fontSize: "0.875rem" }}>
<Typography color="textPrimary">
{Hotel.name} Hotel has a garden, terrace, a restaurant, and bar in
Brussels. With free WiFi, this 4-star hotel offers room service and a
24-hour front desk. There is a spa and wellness centre with an outdoor
swimming pool, indoor pool, and fitness centre, as well as a sauna.
<br />
<br />
The hotel will provide guests with air-conditioned rooms offering a
desk, a kettle, a fridge, a safety deposit box, a flat-screen TV, and a
private bathroom with a shower. Some rooms include a kitchenette with a
dishwasher, an oven, and a microwave. At {Hotel.name} Hotel, rooms come
with bed linen and towels.
<br />
<br />
The accommodation offers a buffet or continental breakfast. The wellness
area at {Hotel.name} Hotel includes a hot tub and a hammam.
<br />
<br />
</Typography>
</Box>
);
};

export default HotelDescription;
export default HotelDescription;
17 changes: 7 additions & 10 deletions src/client/components/molecules/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import React from "react";
import { Box, Button, Typography, Modal as MuiModal } from "@mui/material";
import QRCode from "react-qr-code";
import { ModalStatus, useAppStore } from "@/client/store";
import { useBookingVerify } from "../../hooks/useBookingVerify";
import { Box, Button, Modal as MuiModal, Typography } from "@mui/material";
import React from "react";

interface ModalProps {
title: string; // Accept title as a prop
content: React.ReactNode; // Accept content as a prop
handleClose: () => void; // Close function prop
title: string; // Accept title as a prop
content: React.ReactNode; // Accept content as a prop
handleClose: () => void; // Close function prop
}

const Modal: React.FC<ModalProps> = ({ title, content, handleClose }) => {
const { modal } = useAppStore();


if (modal === ModalStatus.CLOSE) return null;

Expand All @@ -35,11 +32,11 @@ const Modal: React.FC<ModalProps> = ({ title, content, handleClose }) => {
}}
>
<Typography id="modal-title" variant="h5" fontWeight="bold" mb={2}>
{title} {/* Display the title prop */}
{title} {/* Display the title prop */}
</Typography>

<Box id="modal-description" sx={{ textAlign: "center", mb: 4 }}>
{content} {/* Display the content prop */}
{content} {/* Display the content prop */}
</Box>

<Box sx={{ display: "flex", justifyContent: "flex-end" }}>
Expand Down
124 changes: 124 additions & 0 deletions src/client/components/molecules/ReservationConfirmation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { useBookingStore } from "@/client/store";
import { BookingDetailsDto } from "@/shared";
import {
Box,
Button,
CircularProgress,
IconButton,
Typography,
} from "@mui/material";
import Image from "next/image";
import { toast } from "react-toastify";
import CopyIcon from "../atoms/CopyIcon";

type Props = { details: BookingDetailsDto; id: string; deviceType: string };

export default function ReservationConfirmation({
details,
id,
deviceType,
}: Props) {
const {
checkIn,
checkOut,
numberOfRooms,
numberOfGuests,
reservationDate,
hotel,
} = details;
const { isLoading, issueConfirmationAsync } = useBookingStore();

const copyToClipboard = () => {
navigator.clipboard.writeText(id);
toast.info("successfully copied to clipboard");
};
const issueConfirmation = async () => {
if (deviceType === "mobile") {
// window.location.href = bookingCreateRes?.url; // Navigate to the confirmation page
} else {
await issueConfirmationAsync(id);
}
};
return (
<Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography fontWeight={"bold"}>
Here is your resenvation confirmation
</Typography>
{/* Hotel Details */}
<Box sx={{ mt: 2 }}>
<Typography fontWeight="bold" color="green">
{hotel}
</Typography>

<Box sx={{ display: "flex" }}>
<Box sx={{ mr: 5 }}>
<Typography color="black">Check-in</Typography>
<Typography color="primary">{checkIn}</Typography>
</Box>
<Box>
<Typography color="black">Check-out</Typography>
<Typography color="primary">{checkOut}</Typography>
</Box>
</Box>
<Typography sx={{ mt: 1 }} color="black">
Rooms and guests
</Typography>
<Typography color="primary">
{`${numberOfRooms} Room, ${numberOfGuests} Guests`}
</Typography>
</Box>
{/* Reservation ID */}
<Box sx={{ mt: 4 }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Typography fontWeight="bold">YOUR RESERVATION ID:</Typography>
<Box
sx={{
display: "flex",
alignItems: "center",
ml: 1,
fontWeight: "bold",
}}
>
<Typography fontWeight="bold" color="primary">
{id}
</Typography>

<IconButton onClick={copyToClipboard}>
<CopyIcon color="primary" />
</IconButton>
</Box>
</Box>
<Box sx={{ mt: 2 }}>
<Typography variant="body2" color="textPrimary">
Reservation date
</Typography>
<Typography color="primary">{reservationDate}</Typography>
</Box>
</Box>

{/* Issue confirmation to EUDI wallet */}
<Box sx={{ mt: 4 }}>
<Button
color="primary"
variant="contained"
sx={{ p: 2, fontWeight: "bold" }}
startIcon={
isLoading ? (
<CircularProgress size={20} sx={{ color: "white", mr: 1 }} />
) : (
<Image
src="/images/eudiwallet.svg"
alt="reviews"
width={40}
height={40}
/>
)
}
onClick={issueConfirmation}
>
Issue your reservation confirmation to EUDI Wallet
</Button>
</Box>
</Box>
);
}
Loading

0 comments on commit 69068d1

Please sign in to comment.