diff --git a/client/src/components/composite/BookingForm/BookingForm.tsx b/client/src/components/composite/Bookings/BookingForm.tsx
similarity index 100%
rename from client/src/components/composite/BookingForm/BookingForm.tsx
rename to client/src/components/composite/Bookings/BookingForm.tsx
diff --git a/client/src/components/composite/ProfileBookingHistory/ProfileBookingHistory.tsx b/client/src/components/composite/Bookings/ProfileBookingHistory/ProfileBookingHistory.tsx
similarity index 100%
rename from client/src/components/composite/ProfileBookingHistory/ProfileBookingHistory.tsx
rename to client/src/components/composite/Bookings/ProfileBookingHistory/ProfileBookingHistory.tsx
diff --git a/client/src/components/composite/ProfileCurrentBookings/ProfileCurrentBookings.tsx b/client/src/components/composite/Bookings/ProfileCurrentBookings/ProfileCurrentBookings.tsx
similarity index 100%
rename from client/src/components/composite/ProfileCurrentBookings/ProfileCurrentBookings.tsx
rename to client/src/components/composite/Bookings/ProfileCurrentBookings/ProfileCurrentBookings.tsx
diff --git a/client/src/components/composite/Profile/ProfileCalendarCard/ProfileCalendarCard.tsx b/client/src/components/composite/Profile/ProfileCalendarCard/ProfileCalendarCard.tsx
new file mode 100644
index 000000000..340161d23
--- /dev/null
+++ b/client/src/components/composite/Profile/ProfileCalendarCard/ProfileCalendarCard.tsx
@@ -0,0 +1,31 @@
+import { Card, Typography, CardContent, Stack, Box } from "@mui/material"
+
+function ProfileCalendarCard() {
+ return (
+
+
+
+
+
+ Calendar
+
+
+
+
+
+
+ )
+}
+
+export default ProfileCalendarCard
diff --git a/client/src/components/composite/Profile/UserInformation/UserInformationDisplay.tsx b/client/src/components/composite/Profile/UserInformation/UserInformationDisplay.tsx
new file mode 100644
index 000000000..18aba86dc
--- /dev/null
+++ b/client/src/components/composite/Profile/UserInformation/UserInformationDisplay.tsx
@@ -0,0 +1,40 @@
+import Button from "components/generic/FigmaButtons/FigmaButton"
+import { UserAdditionalInfo } from "models/User"
+
+interface IUserInformationDisplay {
+ userData?: UserAdditionalInfo
+ editHandler?: () => void
+}
+
+const UserInformationDisplay = ({
+ userData,
+ editHandler
+}: IUserInformationDisplay) => {
+ if (userData) {
+ const { date_of_birth, ...displayableFields } = userData
+ return (
+ <>
+
+
+ {/* TODO: Properly style and name fields */}
+ {Object.keys(displayableFields).map((key) => {
+ const _key = key as keyof typeof displayableFields
+ return (
+ <>
+
+ {_key}: {displayableFields[_key]}
+
+ >
+ )
+ })}
+ {new Date(date_of_birth.seconds * 1000).toDateString()}
+
+ >
+ )
+ }
+ return <>No Data found>
+}
+
+export default UserInformationDisplay
diff --git a/client/src/components/composite/Profile/UserInformation/UserInformationEdit.tsx b/client/src/components/composite/Profile/UserInformation/UserInformationEdit.tsx
new file mode 100644
index 000000000..1e7f0ac9d
--- /dev/null
+++ b/client/src/components/composite/Profile/UserInformation/UserInformationEdit.tsx
@@ -0,0 +1,40 @@
+import Button from "components/generic/FigmaButtons/FigmaButton"
+import TextInput from "components/generic/TextInputComponent/TextInput"
+import { UserAdditionalInfo } from "models/User"
+
+interface IUserInformationEdit {
+ userData?: UserAdditionalInfo
+ saveHandler?: () => void
+}
+
+const UserInformationEdit = ({
+ userData,
+ saveHandler
+}: IUserInformationEdit) => {
+ if (userData) {
+ const { date_of_birth, ...displayableFields } = userData
+ return (
+ <>
+
+
+ {/* TODO: Properly style and name fields */}
+ {Object.keys(displayableFields).map((key) => {
+ const _key = key as keyof typeof displayableFields
+ return (
+ <>
+
{_key}
+
+ >
+ )
+ })}
+ {new Date(date_of_birth.seconds * 1000).toDateString()}
+
+ >
+ )
+ }
+ return <>No Data found>
+}
+
+export default UserInformationEdit
diff --git a/client/src/components/composite/Profile/UserInformation/UserInformationSection.tsx b/client/src/components/composite/Profile/UserInformation/UserInformationSection.tsx
new file mode 100644
index 000000000..68dcbee7a
--- /dev/null
+++ b/client/src/components/composite/Profile/UserInformation/UserInformationSection.tsx
@@ -0,0 +1,32 @@
+import { useState } from "react"
+import { useSearchParams } from "react-router-dom"
+import UserInformationEdit from "./UserInformationEdit"
+import UserInformationDisplay from "./UserInformationDisplay"
+import { UserAdditionalInfo } from "models/User"
+
+interface IUserInformationSection {
+ userData?: UserAdditionalInfo
+}
+
+const UserInformationSection = ({ userData }: IUserInformationSection) => {
+ const [searchParams] = useSearchParams()
+ const [isEdit, setIsEdit] = useState(!!searchParams.get("edit"))
+
+ return (
+ <>
+ {isEdit ? (
+ setIsEdit(false)}
+ userData={userData}
+ />
+ ) : (
+ setIsEdit(true)}
+ userData={userData}
+ />
+ )}
+ >
+ )
+}
+
+export default UserInformationSection
diff --git a/client/src/components/composite/ProfileCalendarCard/ProfileCalendarCard.tsx b/client/src/components/composite/ProfileCalendarCard/ProfileCalendarCard.tsx
deleted file mode 100644
index 00a29ae6b..000000000
--- a/client/src/components/composite/ProfileCalendarCard/ProfileCalendarCard.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import { Card, Typography, CardContent, Stack, Box } from "@mui/material"
-import React from "react"
-import { DateCalendar, PickersDay } from "@mui/x-date-pickers"
-import { styled } from "@mui/material/styles"
-
-const StyledCalendarDay = styled(PickersDay, {
- shouldForwardProp: (prop) => prop !== "isBookedDate"
-})(
- /**
- * @param {{isBookedDate: boolean}}
- */
- ({ theme, isBookedDate }: any) => ({
- ...(isBookedDate && {
- backgroundColor: theme.palette.primary[theme.palette.mode],
- "&:hover, &:focus": {
- backgroundColor: theme.palette.primary[theme.palette.mode]
- },
- borderTopLeftRadius: "50%",
- borderBottomLeftRadius: "50%",
- borderTopRightRadius: "50%",
- borderBottomRightRadius: "50%"
- })
- })
-)
-
-function CalendarDay(props: any) {
- const { bookings, ...others } = props
-
- const isBookedDate = bookings.some((booking: any) => {
- const start = booking.data().check_in.toDate()
- const end = booking.data().check_out.toDate()
-
- const calendarDate = others.day.toDate()
-
- return start <= calendarDate && end >= calendarDate
- })
-
- return
-}
-
-/**
- * @param {{bookings: Array}}
- */
-function ProfileCalendarCard({ bookings }: any) {
- // construct all the dates
-
- return (
-
-
-
-
-
- Calendar
-
-
- ({
- bookings
- })
- }}
- />
-
-
-
-
-
- )
-}
-
-export default ProfileCalendarCard
diff --git a/client/src/components/composite/ProfileCard/ProfileCard.tsx b/client/src/components/composite/ProfileCard/ProfileCard.tsx
deleted file mode 100644
index a487d63b9..000000000
--- a/client/src/components/composite/ProfileCard/ProfileCard.tsx
+++ /dev/null
@@ -1,222 +0,0 @@
-import {
- Card,
- Typography,
- Avatar,
- CardContent,
- Stack,
- Button
-} from "@mui/material"
-import React, { useEffect, useState } from "react"
-
-import { useAuthenticatedUser } from "hooks/useAuthenticatedUser"
-
-const textType = "body1"
-
-function ProfileCard() {
- const [user, userMetadata] = useAuthenticatedUser()
- const [userData, setUserData] = useState(undefined)
- const [expanded, setExpanded] = useState(false)
-
- // Expanding the more details on the user page
- const expandDetails = () => {
- setExpanded(!expanded)
- }
-
- useEffect(() => {
- if (userMetadata) {
- // @ts-ignore
- setUserData(userMetadata)
- }
- }, [user, userMetadata])
-
- return (
-
-
-
-
-
-
-
-
- {userData
- ? userData.firstName + " " + userData.lastName
- : "John Doe"}
-
-
-
-
- {/* @ts-ignore */}
-
-
-
- Phone
-
-
- {userData ? userData.phoneNumber : "N/A"}
-
-
-
-
- Email
-
-
- {userData ? userData.email : "N/A"}
-
-
-
-
- Membership
-
-
- {userMetadata
- ? // @ts-ignore
- userMetadata.membership === undefined
- ? "Member"
- : // @ts-ignore
- userMetadata.membership
- : "N/A"}
-
-
-
-
- {expanded ? (
- // @ts-ignore
-
-
-
- Emergency Contact Name
-
-
- Jane Doe
-
-
-
-
- Emergency Contact Number
-
-
- +64 2400 420 422
-
-
-
-
- Emergency Contact Relation
-
-
- Mother
-
-
-
- ) : (
-
- )}
-
- {expanded ? "Hide Details" : "More Details"}
-
-
-
-
-
-
- )
-}
-
-export default ProfileCard
diff --git a/client/src/components/generic/ProfileInformationPanel/ProfileInformationPanel.tsx b/client/src/components/generic/ProfileInformationPanel/ProfileInformationPanel.tsx
index 61fc7d4b2..717813fac 100644
--- a/client/src/components/generic/ProfileInformationPanel/ProfileInformationPanel.tsx
+++ b/client/src/components/generic/ProfileInformationPanel/ProfileInformationPanel.tsx
@@ -12,7 +12,7 @@ const ProfileInformationPanel = ({
onEdit
}: IProfileInformationPanel) => {
return (
-
+
{title}
{onEdit && (
diff --git a/client/src/components/generic/ResponsiveBackgroundImage/ResponsiveBackground.story.tsx b/client/src/components/generic/ResponsiveBackgroundImage/ResponsiveBackground.story.tsx
new file mode 100644
index 000000000..b4c25d428
--- /dev/null
+++ b/client/src/components/generic/ResponsiveBackgroundImage/ResponsiveBackground.story.tsx
@@ -0,0 +1,14 @@
+import type { Meta, StoryObj } from "@storybook/react"
+
+import ResponsiveBackgroundImage from "./ResponsiveBackground"
+
+const meta: Meta
= {
+ component: ResponsiveBackgroundImage
+}
+
+export default meta
+type Story = StoryObj
+
+export const DefaultExample: Story = {
+ args: {}
+}
diff --git a/client/src/components/generic/ResponsiveBackgroundImage/ResponsiveBackground.tsx b/client/src/components/generic/ResponsiveBackgroundImage/ResponsiveBackground.tsx
new file mode 100644
index 000000000..21d868ae8
--- /dev/null
+++ b/client/src/components/generic/ResponsiveBackgroundImage/ResponsiveBackground.tsx
@@ -0,0 +1,19 @@
+interface IResponsiveBackgroundImage {
+ children: React.ReactNode
+}
+/**
+ * to find/change the bg you need to check the
+ * `backgroundImage` property in `tailwind.config.ts`
+ */
+const ResponsiveBackgroundImage = ({
+ children
+}: IResponsiveBackgroundImage) => (
+
+)
+
+export default ResponsiveBackgroundImage
diff --git a/client/src/pages/Booking.tsx b/client/src/pages/Booking.tsx
index 3cf96f488..e23596fe0 100644
--- a/client/src/pages/Booking.tsx
+++ b/client/src/pages/Booking.tsx
@@ -1,12 +1,28 @@
-import { Route, Routes } from "react-router-dom"
-import BookingSuccess from "pages/BookingSuccess"
+import BookingForm from "components/composite/Bookings/BookingForm"
+import { Typography, Stack } from "@mui/material"
const Booking = () => {
return (
-
-
- } />
-
+
+
+
+ Bookings
+
+
+
)
}
diff --git a/client/src/pages/Profile.tsx b/client/src/pages/Profile.tsx
deleted file mode 100644
index 919e1ed84..000000000
--- a/client/src/pages/Profile.tsx
+++ /dev/null
@@ -1,98 +0,0 @@
-import { db } from "../firebase"
-import React, { useEffect, useState } from "react"
-import {
- getDocs,
- where,
- query,
- collection,
- doc,
- QueryDocumentSnapshot,
- DocumentData
-} from "firebase/firestore"
-import { Stack, Typography } from "@mui/material"
-import ProfileCard from "components/composite/ProfileCard/ProfileCard"
-import ProfileCalendarCard from "components/composite/ProfileCalendarCard/ProfileCalendarCard"
-import ProfileCurrentBookings from "components/composite/ProfileCurrentBookings/ProfileCurrentBookings"
-import ProfileBookingHistory from "components/composite/ProfileBookingHistory/ProfileBookingHistory"
-import { useAuthenticatedUser } from "../hooks/useAuthenticatedUser"
-
-/**
- * Reference to a booking from the Firestore.
- * @typedef {{ data(): { user_id: string, check_in: require("firebase/firestore").Timestamp, check_out: require("firebase/firestore").Timestamp } }} Booking
- */
-
-export default function Profile() {
- const [user, userMetadata] = useAuthenticatedUser()
- /**
- * @type {[Array
, React.Dispatch>]}
- */
- const [bookings, setBookings] = useState<
- QueryDocumentSnapshot[] | undefined
- >(undefined)
-
- /**
- * Retrieves the current user bookings from firestore.
- * @param {string} userId
- */
- const getBookings = (userId: any) => {
- getDocs(
- query(
- collection(db, "bookings"),
- where("user_id", "==", doc(db, "users", userId))
- )
- )
- .then((storeBookings) => {
- setBookings(storeBookings.docs)
- })
- .catch((err) =>
- console.error(
- `Failed to retrieve bookings for authenticated user: ${err}`
- )
- )
- }
-
- useEffect(() => {
- if (user) {
- getBookings(user.uid)
- }
- }, [user, userMetadata])
-
- return (
-
-
-
- Profile
-
-
-
-
-
- My Bookings
-
-
-
-
-
-
-
-
- )
-}
diff --git a/client/src/pages/Profile/Profile.story.tsx b/client/src/pages/Profile/Profile.story.tsx
new file mode 100644
index 000000000..c527de032
--- /dev/null
+++ b/client/src/pages/Profile/Profile.story.tsx
@@ -0,0 +1,21 @@
+import type { Meta, StoryObj } from "@storybook/react"
+
+import Profile from "./Profile"
+import { MemoryRouter } from "react-router-dom"
+
+const meta: Meta = {
+ component: Profile
+}
+
+export default meta
+type Story = StoryObj
+
+export const DefaultProfilePage: Story = {
+ decorators: [
+ (Story) => (
+
+
+
+ )
+ ]
+}
diff --git a/client/src/pages/Profile/Profile.tsx b/client/src/pages/Profile/Profile.tsx
new file mode 100644
index 000000000..826d45ab8
--- /dev/null
+++ b/client/src/pages/Profile/Profile.tsx
@@ -0,0 +1,145 @@
+import { useAppData } from "store/Store"
+import { useNavigate } from "react-router-dom"
+
+import ProfileInformationPanel from "components/generic/ProfileInformationPanel/ProfileInformationPanel"
+import { Footer } from "components/generic/Footer/Footer"
+import ResponsiveBackgroundImage from "components/generic/ResponsiveBackgroundImage/ResponsiveBackground"
+
+const SignOutButton = () => {
+ const navigate = useNavigate()
+ const handleOnclick = () => {
+ navigate("/login")
+ }
+ return (
+
+
+
+ )
+}
+
+const Field = ({
+ subtitle,
+ description
+}: {
+ subtitle: string
+ description?: string
+}) => {
+ return (
+ <>
+
+
+ {subtitle}
+
+
+ {description}
+
+
+ >
+ )
+}
+export default function Profile() {
+ const [{ currentUserData }] = useAppData()
+ const [{ currentUser }] = useAppData()
+
+ function toDateTime(secs?: number) {
+ const t = new Date() // Epoch
+ t.setSeconds(secs!)
+ const f = t.toDateString()
+ return f
+ }
+
+ return (
+
+
+
+
+
+
{`${currentUserData?.first_name} ${currentUserData?.last_name}`}
+
+
+
+
+
+
+
{}}
+ >
+
+
+
+
{}}>
+
+
+
+
{}}
+ >
+
+
+
+
+
+ Calender component waiting to be implemented
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/client/src/routes/routes.tsx b/client/src/routes/routes.tsx
index 82d154728..b1b3f2317 100644
--- a/client/src/routes/routes.tsx
+++ b/client/src/routes/routes.tsx
@@ -7,7 +7,7 @@ import Contact from "pages/Contact"
import Events from "pages/Events"
import Home from "pages/Home/Home"
import Login from "pages/Login/Login"
-import Profile from "pages/Profile"
+import Profile from "pages/Profile/Profile"
import Register from "pages/Register/Register"
import Thanks from "pages/Thanks"
import { Route, Routes } from "react-router-dom"