From 16e1414bcd376f04dcfc0bb8f2f5982867271f92 Mon Sep 17 00:00:00 2001 From: elgharbi Date: Mon, 18 Dec 2023 04:55:43 +0100 Subject: [PATCH] update profile page --- api/package.json | 4 +- frontend/package.json | 1 + frontend/src/assets/css/minicalender.css | 5 + .../src/components/calender/MniCalender.tsx | 4 +- frontend/src/pages/profile/Profile.page.tsx | 146 ++++++++++-------- .../pages/profile/partials/RentDetails.tsx | 94 ++++++----- .../src/pages/profile/partials/RentalCard.tsx | 83 ++++++++++ frontend/src/pages/profile/rental.tsx | 65 -------- yarn.lock | 27 ++-- 9 files changed, 244 insertions(+), 185 deletions(-) create mode 100644 frontend/src/pages/profile/partials/RentalCard.tsx delete mode 100644 frontend/src/pages/profile/rental.tsx diff --git a/api/package.json b/api/package.json index 9a9d04f..f1b47d7 100644 --- a/api/package.json +++ b/api/package.json @@ -73,9 +73,9 @@ "supertest": "^6.1.3", "ts-jest": "^26.5.2", "ts-loader": "^8.0.17", - "ts-node": "^9.1.1", + "ts-node": "^10.9.1", "tsconfig-paths": "^3.9.0", - "typescript": "^5.0.2" + "typescript": "^5.2.2" }, "jest": { "moduleFileExtensions": [ diff --git a/frontend/package.json b/frontend/package.json index de4e750..3fb61d7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,7 @@ "axios": "^1.6.2", "formik": "^2.4.5", "framer-motion": "^10.16.5", + "moment": "^2.29.4", "react": "^18.2.0", "react-calendar": "^4.7.0", "react-dom": "^18.2.0", diff --git a/frontend/src/assets/css/minicalender.css b/frontend/src/assets/css/minicalender.css index 40346e7..b08c14c 100644 --- a/frontend/src/assets/css/minicalender.css +++ b/frontend/src/assets/css/minicalender.css @@ -3,6 +3,11 @@ background-color: transparent; font-family: "DM Sans", sans-serif; } +@media screen and (max-width: 767px) { + .react-calendar { + width: 100% !important; + } +} .react-calendar__navigation__prev2-button { display: none; } diff --git a/frontend/src/components/calender/MniCalender.tsx b/frontend/src/components/calender/MniCalender.tsx index e4cb93b..02aaa83 100644 --- a/frontend/src/components/calender/MniCalender.tsx +++ b/frontend/src/components/calender/MniCalender.tsx @@ -23,8 +23,8 @@ export default function MiniCalendar(props: { flexDirection="column" borderRadius={"xl"} shadow={"xl"} - w="80%" - maxW="max-content" + w="full" + // maxW="full" p="20px 15px" h="max-content" {...rest} diff --git a/frontend/src/pages/profile/Profile.page.tsx b/frontend/src/pages/profile/Profile.page.tsx index 8b12c8e..848317e 100644 --- a/frontend/src/pages/profile/Profile.page.tsx +++ b/frontend/src/pages/profile/Profile.page.tsx @@ -3,30 +3,58 @@ import { Box, Flex, Heading, + Spinner, // Icon, Text, } from "@chakra-ui/react"; -import bikeImg from "../../assets/images/bikes/bike1.jpg"; import MiniCalendar from "../../components/calender/MniCalender"; import RentDetails from "./partials/RentDetails"; import { useEffect, useState } from "react"; import axios from "../../apis/axios"; +import { useAuth } from "../../hooks/useAuth"; +import Rental from "./partials/RentalCard"; export type Rental = { id: number; price: number; status: string; - bike: { + start_time: string; + end_time: string; + qrcode: string; + created_at: string; + updated_at: string; + User: { + id: number; name: string; + email: string; + image: string; + phone: string; + birthday: string; + }; + Bike: { + model: string; + image: string; + status: string; location: string; + Park: { + id: number; + name: string; + location: string; + image: string; + }; }; }; const Profile = () => { const [rentals, setrentals] = useState([]); + const [currRental, setcurrRental] = useState(null); // rentals[0] + const [isLoaded, setIsLoaded] = useState(true); + const { user } = useAuth(); useEffect(() => { axios - .get(`/rentals/user/8`) + .get(`/rentals/user/9`, { + withCredentials: true, + }) .then((response) => { setrentals(response.data); }) @@ -34,10 +62,21 @@ const Profile = () => { console.error("Error fetching rentals:", error); }); }, []); + useEffect(() => { + setcurrRental(rentals[0]); + setIsLoaded(false); + }, [rentals]); + + const handleRentalClick = (rental: Rental) => { + setcurrRental(rental); + }; return ( - - - + + + { borderRadius={"md"} > - ayoub El Gharbi + {user?.name} { - + + - + - + + { Rentals
- {rentals.length > 0 ? ( - rentals.map((rental) => ( - - - - - {rental.bike?.name} - - - {rental.bike?.location} - - - - ${rental?.price} - {/* */} - - - 3h - ago - + + {isLoaded ? ( + + + + ) : rentals.length > 0 ? ( + rentals.map((rental) => ( + + )) + ) : ( + + + No history yet + - )) - ) : ( - - - No history yet - - - )} + )} +
diff --git a/frontend/src/pages/profile/partials/RentDetails.tsx b/frontend/src/pages/profile/partials/RentDetails.tsx index 22d76ff..0648b3b 100644 --- a/frontend/src/pages/profile/partials/RentDetails.tsx +++ b/frontend/src/pages/profile/partials/RentDetails.tsx @@ -10,14 +10,17 @@ import { import bikeImg from "../../../assets/images/bikes/bike1.jpg"; import qrCode from "../../../assets/images/bikes/qr-code.png"; import { Rental } from "../Profile.page"; - +import moment from "moment"; enum Status { completed = "green", ongoing = "blue", lost = "red", } -const RentDetails = ({ rent }: { rent: Rental }) => { +const RentDetails = ({ rent }: { rent: Rental | null }) => { + const handleDate = (date: string | undefined) => { + return moment(date).format("MMM Do YY, h:mm a"); + }; return (
@@ -29,7 +32,7 @@ const RentDetails = ({ rent }: { rent: Rental }) => { pl={2} mb={6} > - Current Rent + Current Rental { variant="solid" colorScheme={Status[rent?.status as keyof typeof Status]} > - ongoing + {rent?.status}
- + { shadow={"md"} > { { > User Information - - - Full Name: - Ayoub El Gharbi + + + Full Name: + + {rent?.User?.name} + - - Age: - 26 + + Age: + 26 - - - Email: - ayoub@test.com + + + Email: + + {rent?.User?.email} + - - Phone Number: - - {/* ${bike.price}/hour */} - 6-666-665-666 + + Phone Number: + + {rent?.User?.phone} @@ -123,28 +129,32 @@ const RentDetails = ({ rent }: { rent: Rental }) => { > Rent Information - - - Bike Model: - Cross + + + Bike Model: + + {rent?.Bike?.model} + - - Location: - Msalah, Tanger + + Location: + + {rent?.Bike?.location} + - - - Pick-up Time: - - 2021-05-05 07:00 + + + Pick-up Time: + + {handleDate(rent?.start_time)} - - Return Time: - - {/* ${bike.price}/hour */} + + Return Time: + + {handleDate(rent?.end_time)} diff --git a/frontend/src/pages/profile/partials/RentalCard.tsx b/frontend/src/pages/profile/partials/RentalCard.tsx new file mode 100644 index 0000000..7c21913 --- /dev/null +++ b/frontend/src/pages/profile/partials/RentalCard.tsx @@ -0,0 +1,83 @@ +import { Avatar, Box, Heading, Text } from "@chakra-ui/react"; +import { Rental } from "../Profile.page"; +import bikeImg from "../../../assets/images/bikes/bike1.jpg"; +import moment from "moment"; +import { useEffect } from "react"; + +const RentalCard = ({ + rental, + onclickRent, +}: { + key: number; + rental: Rental; + onclickRent: (rental: Rental) => void; +}) => { + useEffect(() => { + moment.locale("en", { + relativeTime: { + future: "in %s", + past: "%s ago", + s: "1s", + ss: "%ss", + m: "1m", + mm: "%dm", + h: "1h", + hh: "%dh", + d: "1d", + dd: "%dd", + M: "1M", + MM: "%dM", + y: "1Y", + yy: "%dY", + }, + }); + }, []); + + return ( + onclickRent(rental)} + > + + + + {rental.Bike?.model} + + + {rental.Bike?.Park?.name} + + + + ${rental?.price} + {/* */} + + + {moment(rental.updated_at).fromNow()} + {/* 3h */} + {/* ago */} + + + ); +}; + +export default RentalCard; diff --git a/frontend/src/pages/profile/rental.tsx b/frontend/src/pages/profile/rental.tsx deleted file mode 100644 index 84c77a0..0000000 --- a/frontend/src/pages/profile/rental.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react"; -import { Center, VStack, Heading, Box, Text, Button, Divider } from "@chakra-ui/react"; - -const ProfilePage: React.FC = () => { - // You can fetch the user's rental history from the server using API calls or use mock data for demonstration purposes - const rentalHistory = [ - { - id: 1, - bikeName: "Bike 1", - startTime: "2023-11-01T10:00:00Z", - endTime: "2023-11-01T12:00:00Z", - status: "Completed", - price: 10.0 - }, - { - id: 2, - bikeName: "Bike 2", - startTime: "2023-11-02T14:00:00Z", - endTime: "2023-11-02T16:00:00Z", - status: "Completed", - price: 15.0 - }, - // Add more rental history items here - ]; - - const handleSettingsChange = () => { - // Implement the logic to handle user settings change here - }; - - return ( -
- - Profile - - - Rental History - - - {rentalHistory.map((rental) => ( - - - Bike: {rental.bikeName} | Duration: {rental.startTime} - {rental.endTime} - - Status: {rental.status} - Price: ${rental.price} - - ))} - - - - Settings - - - {/* Add your user settings form or any other settings components here */} - {/* Example: */} - - - -
- ); -}; - -export default ProfilePage; diff --git a/yarn.lock b/yarn.lock index a8edd63..6e3f802 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3575,16 +3575,16 @@ defer-to-connect "^2.0.0" "@tanstack/react-table@^8.7.9": - version "8.10.7" - resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.10.7.tgz#733f4bee8cf5aa19582f944dd0fd3224b21e8c94" - integrity sha512-bXhjA7xsTcsW8JPTTYlUg/FuBpn8MNjiEPhkNhIGCUR6iRQM2+WEco4OBpvDeVcR9SE+bmWLzdfiY7bCbCSVuA== + version "8.11.0" + resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.11.0.tgz#14fe04434b34d6d2f22ccde1f5df63a9b2fcae78" + integrity sha512-47wdYFlsbJlR6qt4F38nTGo93E6wNkXlN8t1TUI5SpSGiewx+KzBayMjfud3LgqbPLYYcpHby/tGkIF3tR8Upg== dependencies: - "@tanstack/table-core" "8.10.7" + "@tanstack/table-core" "8.11.0" -"@tanstack/table-core@8.10.7": - version "8.10.7" - resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.10.7.tgz#577e8a635048875de4c9d6d6a3c21d26ff9f9d08" - integrity sha512-KQk5OMg5OH6rmbHZxuNROvdI+hKDIUxANaHlV+dPlNN7ED3qYQ/WkpY2qlXww1SIdeMlkIhpN/2L00rof0fXFw== +"@tanstack/table-core@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.11.0.tgz#70e15c706ccf5c5980c52d341ced5d38d0909a6a" + integrity sha512-7SC8/v6cXbUriOs2UISN8Jho3ttnA8cRZgusLn15b8meb28prHnWg4t4oNSHIR3rYn0g7iiIg+pax2CtBnyffg== "@testing-library/dom@^8.5.0": version "8.20.1" @@ -10208,9 +10208,9 @@ levn@~0.3.0: type-check "~0.3.2" libphonenumber-js@^1.9.43: - version "1.10.51" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.51.tgz#a3b8c15db2721c3e5f7fe6759e2a524712b578e6" - integrity sha512-vY2I+rQwrDQzoPds0JeTEpeWzbUJgqoV0O4v31PauHBb/e+1KCXKylHcDnBMgJZ9fH9mErsEbROJY3Z3JtqEmg== + version "1.10.52" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.52.tgz#786d7743e75aba1996824057b60003bb539f8daa" + integrity sha512-6vCuCHgem+OW1/VCAKgkasfegItCea8zIT7s9/CG/QxdCMIM7GfzbEBG5d7lGO3rzipjt5woOQL3DiHa8Fy78Q== lilconfig@^2.0.3, lilconfig@^2.1.0: version "2.1.0" @@ -10663,6 +10663,11 @@ mkdirp@^0.5.4, mkdirp@~0.5.1: dependencies: minimist "^1.2.6" +moment@^2.29.4: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"