diff --git a/.eslintrc.json b/.eslintrc.json index 51f38ce..f782284 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,35 +1,35 @@ { - "env": { - "browser": true, - "es6": true, - "jest": true + "env": { + "browser": true, + "es6": true, + "jest": true + }, + "parser": "@babel/eslint-parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true }, - "parser": "@babel/eslint-parser", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 2018, - "sourceType": "module" - }, - "extends": ["plugin:react/recommended", "plugin:react-hooks/recommended"], - "plugins": ["react"], - "rules": { - "react/jsx-filename-extension": ["warn", { "extensions": [".js", ".jsx"] }], - "react/react-in-jsx-scope": "off", - "import/no-unresolved": "off", - "no-shadow": "off" - }, - "overrides": [ - { - // feel free to replace with your preferred file pattern - eg. 'src/**/*Slice.js' or 'redux/**/*Slice.js' - "files": ["src/**/*Slice.js"], - // avoid state param assignment - "rules": { "no-param-reassign": ["error", { "props": false }] } - } - ], - "ignorePatterns": [ - "dist/", - "build/" - ] - } \ No newline at end of file + "ecmaVersion": 2018, + "sourceType": "module" + }, + "extends": ["airbnb", "plugin:react/recommended", "plugin:react-hooks/recommended"], + "plugins": ["react"], + "rules": { + "react/jsx-filename-extension": ["warn", { "extensions": [".js", ".jsx"] }], + "react/react-in-jsx-scope": "off", + "import/no-unresolved": "off", + "no-shadow": "off" + }, + "overrides": [ + { + // feel free to replace with your preferred file pattern - eg. 'src/**/*Slice.js' or 'redux/**/*Slice.js' + "files": ["src/**/*Slice.js"], + // avoid state param assignment + "rules": { "no-param-reassign": ["error", { "props": false }] } + } + ], + "ignorePatterns": [ + "dist/", + "build/" + ] +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 0ff45ea..5e15ab5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,7 @@ import './styles/App.css'; -import React, {useEffect} from 'react'; -import Router from './routes/routes'; +import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; +import Router from './routes/routes'; import { fetchCarReservations, fetchCars } from './redux/thunk'; function App() { diff --git a/src/components/Card/DisplayCartCard.js b/src/components/Card/DisplayCartCard.js index 1fadf12..12e489c 100644 --- a/src/components/Card/DisplayCartCard.js +++ b/src/components/Card/DisplayCartCard.js @@ -4,7 +4,9 @@ import styled from '@emotion/styled'; import { FaFacebook, FaTwitter, FaInstagram } from 'react-icons/fa'; import { Link } from 'react-router-dom'; -const DisplayCartCard = ({ id, imgSrc, name, shortNote }) => ( +const DisplayCartCard = ({ + id, imgSrc, name, shortNote, +}) => ( {name} @@ -26,7 +28,8 @@ const DisplayCartCard = ({ id, imgSrc, name, shortNote }) => ( ); DisplayCartCard.propTypes = { - imageName: PropTypes.string.isRequired, + id: PropTypes.number.isRequired, + imgSrc: PropTypes.string.isRequired, name: PropTypes.string.isRequired, shortNote: PropTypes.string.isRequired, }; diff --git a/src/components/Card/DisplayItemCard.js b/src/components/Card/DisplayItemCard.js index 0ab3200..8bb085b 100644 --- a/src/components/Card/DisplayItemCard.js +++ b/src/components/Card/DisplayItemCard.js @@ -2,86 +2,89 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import { FaCog, FaArrowRight, FaSyncAlt } from 'react-icons/fa'; -import colorWheel from '../../components/asset/small_color_wheel.png'; import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; +import colorWheel from '../asset/small_color_wheel.png'; import { RESERVE_CARS, USERS_DASHBOARD } from '../../routes/routeConstants'; -const DisplayItemCard = ({ id, name, description, pricePerHr, seating_capacity, imgSrc }) => { +const DisplayItemCard = ({ + id, name, description, pricePerHr, seatingCapacity, imgSrc, +}) => { const username = useSelector((state) => state.authentication.authenticatedUser.username); const navigate = useNavigate(); const [rotation, setRotation] = useState(0); const handleReserveClick = () => { navigate(`${USERS_DASHBOARD}/${RESERVE_CARS}`, { - state: { id, username, name } + state: { id, username, name }, }); - } + }; const handleRotate = () => { setRotation((prevRotation) => (prevRotation + 90) % 360); }; return ( - - - - - - Rotate vehicle - - - - + + + + + + Rotate vehicle + + + + {name} - {description} + {description} - + Rent Price per Hour {pricePerHr} - - + + Seating Capacity - {seating_capacity} - - + {seatingCapacity} + + Currently available for booking? Yes - - + + Minimum Rental Duration 4 hrs - +
- 5.9% APR Representative + 5.9% APR Representative DISCOVER MORE MODEL - Color Wheel + Color Wheel - - + + - - Reserve - + + Reserve + - + -
+
-)}; + ); +}; DisplayItemCard.propTypes = { id: PropTypes.number.isRequired, name: PropTypes.string.isRequired, description: PropTypes.string.isRequired, pricePerHr: PropTypes.number.isRequired, - seating_capacity: PropTypes.number.isRequired, - imgSrc: PropTypes.string.isRequired + seatingCapacity: PropTypes.number.isRequired, + imgSrc: PropTypes.string.isRequired, }; const Container = styled.div` diff --git a/src/components/DeleteCars/DeleteList.js b/src/components/DeleteCars/DeleteList.js index c252642..632a396 100644 --- a/src/components/DeleteCars/DeleteList.js +++ b/src/components/DeleteCars/DeleteList.js @@ -1,45 +1,45 @@ import React from 'react'; -import { useSelector } from "react-redux"; +import { useSelector } from 'react-redux'; import EachCarDelete from './EachCarDelete'; const DeleteList = () => { - const cars = useSelector((state) => state.cars.cars) -// const mockData = [ -// { -// "id": 3, -// "name": "Car1", -// "description": "Description for Car1", -// "removed": false -// }, -// { -// "id": 4, -// "name": "Car1111", -// "description": "Description for Car1", -// "removed": false -// } -// ]; -// const cars = mockData; + const cars = useSelector((state) => state.cars.cars); + // const mockData = [ + // { + // "id": 3, + // "name": "Car1", + // "description": "Description for Car1", + // "removed": false + // }, + // { + // "id": 4, + // "name": "Car1111", + // "description": "Description for Car1", + // "removed": false + // } + // ]; + // const cars = mockData; return ( <>

Cars List

- - - - - - - - {cars.map((car) => ( - - ))} - + + + + + + + + {cars.map((car) => ( + + ))} +
Car TitleStatus
Car TitleStatus
); }; -export default DeleteList; \ No newline at end of file +export default DeleteList; diff --git a/src/components/DeleteCars/EachCarDelete.js b/src/components/DeleteCars/EachCarDelete.js index 6c81a40..b249524 100644 --- a/src/components/DeleteCars/EachCarDelete.js +++ b/src/components/DeleteCars/EachCarDelete.js @@ -1,38 +1,37 @@ import PropTypes from 'prop-types'; -import { useDispatch, useSelector } from "react-redux"; -import { deleteCar } from "../../redux/thunk"; -import { markCarDelete } from "../../redux/cars/carsSlice"; +import { useDispatch } from 'react-redux'; +import { deleteCar } from '../../redux/thunk'; +import { removeMarkStatus } from '../../redux/cars/carsSlice'; -const EachCarDelete = ({car}) => { - const { - name, - id, - removed - } = car; - const dispatch = useDispatch(); - const handleDelete = () => { - dispatch(deleteCar(id)); - if(!removed) { - dispatch(markCarDelete(id)) - } +const EachCarDelete = ({ car }) => { + const { + name, + id, + removed, + } = car; + const dispatch = useDispatch(); + const handleDelete = () => { + if (removed) { + return; } - - - return ( - - {name} - - - ) -} + dispatch(deleteCar(id)); + dispatch(removeMarkStatus(id)); + }; + return ( + + {name} + + + ); +}; EachCarDelete.propTypes = { - car: PropTypes.shape({ - name: PropTypes.string.isRequired, - id: PropTypes.number.isRequired, - removed: PropTypes.bool.isRequired, - }).isRequired, + car: PropTypes.shape({ + name: PropTypes.string.isRequired, + id: PropTypes.number.isRequired, + removed: PropTypes.bool.isRequired, + }).isRequired, }; export default EachCarDelete; diff --git a/src/components/Form/FormComponent2.js b/src/components/Form/FormComponent2.js index 6d1766c..69eb446 100644 --- a/src/components/Form/FormComponent2.js +++ b/src/components/Form/FormComponent2.js @@ -25,17 +25,17 @@ FormComponent2.propTypes = { name: PropTypes.string.isRequired, description: PropTypes.string.isRequired, pricePerHr: PropTypes.string.isRequired, - sitting_capacity: PropTypes.number.isRequired, + seating_capacity: PropTypes.number.isRequired, rental_duration: PropTypes.number.isRequired, - image: PropTypes.string.isRequired, + // image: PropTypes.string.isRequired, }).isRequired, schema: PropTypes.shape({ name: PropTypes.string.isRequired, description: PropTypes.string.isRequired, pricePerHr: PropTypes.string.isRequired, - sitting_capacity: PropTypes.number.isRequired, + seating_capacity: PropTypes.number.isRequired, rental_duration: PropTypes.number.isRequired, - image: PropTypes.string.isRequired, + // image: PropTypes.string.isRequired, }).isRequired, onSubmit: PropTypes.func.isRequired, children: PropTypes.node.isRequired, diff --git a/src/components/Form/FormField.js b/src/components/Form/FormField.js index 1fba652..0a36224 100644 --- a/src/components/Form/FormField.js +++ b/src/components/Form/FormField.js @@ -19,11 +19,16 @@ export const DateField = ({ handleChange(date); }; - console.log('value fromt eh field', field.value); return ( {label} - helpers.setTouched(true)} /> + helpers.setTouched(true)} + /> {meta.touched && meta.error ? ( {meta.error} ) : null} @@ -39,10 +44,9 @@ DateField.propTypes = { }; export const SelectField = ({ - label, lpiSrc, rpiSrc, className, name, id, options, ...props + label, className, name, id, options, ...props }) => { const [field, meta] = useField(name); - console.log('selected city', field.value); return ( @@ -56,8 +60,6 @@ export const SelectField = ({ ))} - {lpiSrc ? : null} - {lpiSrc ? : null} {meta.touched && meta.error ? ( {meta.error} @@ -68,8 +70,6 @@ export const SelectField = ({ SelectField.propTypes = { label: PropTypes.string.isRequired, - lpiSrc: PropTypes.string.isRequired, - rpiSrc: PropTypes.string.isRequired, className: PropTypes.string.isRequired, name: PropTypes.string.isRequired, id: PropTypes.string.isRequired, @@ -77,12 +77,12 @@ SelectField.propTypes = { PropTypes.shape({ value: PropTypes.string.isRequired, label: PropTypes.string.isRequired, - }) + }), ).isRequired, }; export const TextInputField = ({ - label, lpiSrc, rpiSrc, className, name, placeholder, id, ...props + label, className, name, placeholder, id, ...props }) => { const [field, meta] = useField(name); @@ -93,8 +93,6 @@ export const TextInputField = ({ - {lpiSrc ? : null} - {lpiSrc ? : null} {meta.touched && meta.error ? ( {meta.error} @@ -105,8 +103,6 @@ export const TextInputField = ({ TextInputField.propTypes = { label: PropTypes.string.isRequired, - lpiSrc: PropTypes.string.isRequired, - rpiSrc: PropTypes.string.isRequired, className: PropTypes.string.isRequired, name: PropTypes.string.isRequired, placeholder: PropTypes.string.isRequired, @@ -115,8 +111,6 @@ TextInputField.propTypes = { export const TextAreaInputField = ({ label, - lpiSrc, - rpiSrc, className, name, id, @@ -134,8 +128,6 @@ export const TextAreaInputField = ({ className={className || ''} rows={10} /> - {lpiSrc ? : null} - {rpiSrc ? : null} {meta.touched && meta.error ? ( {meta.error} @@ -146,14 +138,14 @@ export const TextAreaInputField = ({ TextAreaInputField.propTypes = { label: PropTypes.string.isRequired, - lpiSrc: PropTypes.string.isRequired, - rpiSrc: PropTypes.string.isRequired, className: PropTypes.string.isRequired, name: PropTypes.string.isRequired, id: PropTypes.string.isRequired, }; -export const FileInputField = ({ id, label, name, className, ...props }) => { +export const FileInputField = ({ + id, label, name, className, ...props +}) => { const [field, meta, helpers] = useField(name); const handleChange = (event) => { @@ -176,7 +168,7 @@ FileInputField.propTypes = { label: PropTypes.string.isRequired, name: PropTypes.string.isRequired, className: PropTypes.string.isRequired, - id: PropTypes.string.isRequired + id: PropTypes.string.isRequired, }; const DateFieldWrapper = styled.div` diff --git a/src/components/Form/HideableTextFormField.js b/src/components/Form/HideableTextFormField.js index 424627e..e9baf7c 100644 --- a/src/components/Form/HideableTextFormField.js +++ b/src/components/Form/HideableTextFormField.js @@ -16,12 +16,9 @@ import { const HideableTextFormField = ({ label, - lpiSrc, - rpiSrc, className, name, id, - // apiKey, ...props }) => { const [field, meta] = useField(name); @@ -60,12 +57,9 @@ const HideableTextFormField = ({ HideableTextFormField.propTypes = { label: PropTypes.string.isRequired, - lpiSrc: PropTypes.string.isRequired, - rpiSrc: PropTypes.string.isRequired, className: PropTypes.string.isRequired, name: PropTypes.string.isRequired, id: PropTypes.string.isRequired, - // apiKey: PropTypes.string, }; const VisibiltyToggleIconsArea = styled.div` diff --git a/src/components/Img/Img.js b/src/components/Img/Img.js index 50fdabf..c27ac09 100644 --- a/src/components/Img/Img.js +++ b/src/components/Img/Img.js @@ -2,9 +2,7 @@ import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import React from 'react'; -const Img = ({ src, alt, className }) => { -return ; -} +const Img = ({ src, alt, className }) => ; const Imgg = styled.img` width: 100%; diff --git a/src/components/Link/Link.js b/src/components/Link/Link.js index ca46a2c..decff9a 100644 --- a/src/components/Link/Link.js +++ b/src/components/Link/Link.js @@ -54,7 +54,6 @@ export const NavigationBoxLink = styled(RouterLink)` `; NavBoxItem.propTypes = { - icon: PropTypes.node.isRequired, path: PropTypes.string.isRequired, children: PropTypes.node.isRequired, }; diff --git a/src/components/MyReservations/MyReservationsList.js b/src/components/MyReservations/MyReservationsList.js index f36dc5d..740a9e9 100644 --- a/src/components/MyReservations/MyReservationsList.js +++ b/src/components/MyReservations/MyReservationsList.js @@ -1,56 +1,31 @@ -import React, { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -// import { fetchCarReservations, fetchCars } from '../../redux/thunk'; +import React from 'react'; +import { useSelector } from 'react-redux'; const MyReservationsList = () => { - const mockData = [ - { - id: 1, - car: { - id: 3, - name: "Car1" - }, - date: "2023-01-02", - city: "No Peace" - }, - { - id: 2, - car: { - id: 4, - name: "Car2" - }, - date: "2023-01-03", - city: "Tranquil Town" - }, - // Add more mock data as needed - ]; - // const dispatch = useDispatch(); const myReservations = useSelector((state) => state.reservation.reservations); - console.log(myReservations[1]); - console.log(myReservations[1].car.name); -// const myReservations = mockData; + const newReservationName = useSelector((state) => state.reservation.newReservationName); const status = useSelector((state) => state.reservation.status); const error = useSelector((state) => state.reservation.error); - // useEffect(() => { - // dispatch(fetchCarReservations()); - // dispatch(fetchCars()); - // }, [dispatch]); - if (status === 'loading') { return

Loading...

; } if (status === 'failed') { - return

Error: {error}

; + return ( +

+ Error: + {error} +

+ ); } return ( -
+

My Reservations

{myReservations && myReservations.map((reservation) => ( -
- {`Car: ${reservation.car && reservation.car.name ? reservation.car.name : 'No name'}`} +
+ {`Car: ${reservation.car && reservation.car.name ? reservation.car.name : newReservationName}`} {`Date: ${reservation.date}`} {`City: ${reservation.city}`}
diff --git a/src/components/ReserveCars/ReserveCar.js b/src/components/ReserveCars/ReserveCar.js index 2fdab1f..0269f5a 100644 --- a/src/components/ReserveCars/ReserveCar.js +++ b/src/components/ReserveCars/ReserveCar.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import ReserveCarFrom from './ReserveCarForm'; -const ReserveCar = ({id, username, name}) => ( +const ReserveCar = ({ id, username, name }) => (
diff --git a/src/components/ReserveCars/ReserveCarForm.js b/src/components/ReserveCars/ReserveCarForm.js index 7bd75d6..05ecce6 100644 --- a/src/components/ReserveCars/ReserveCarForm.js +++ b/src/components/ReserveCars/ReserveCarForm.js @@ -1,33 +1,34 @@ import PropTypes from 'prop-types'; import React from 'react'; import { format } from 'date-fns'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; import FormComponent from '../Form/FormComponent'; import { ReserveCarSchema, reserveCarInitialValues } from '../../models/reserveCar.model'; import { DateField, SelectField, TextInputField } from '../Form/FormField'; - import FormSubmitButton from '../Button/FormSubmitButton'; import { postReserveCar } from '../../redux/thunk'; +import { MY_RESERVATIONS, USERS_DASHBOARD } from '../../routes/routeConstants'; +import { getNewReservationName } from '../../redux/reservations/reservationSlice'; -const ReserveCarFrom = ({id, username, name}) => { +const ReserveCarFrom = ({ id, username, name }) => { const dispatch = useDispatch(); + const navigate = useNavigate(); + const status = useSelector((state) => state.reservation.status); const handleSubmit = (values) => { const formattedDate = format(values.selectedDate, 'EEE, dd MMM yyyy'); const reservationData = { my_reservation: { - date: formattedDate, - city: values.selectedCity - } + date: formattedDate, + city: values.selectedCity, + }, + }; + dispatch(postReserveCar({ carId: id, reservationData })); + if (status === 'succeeded') { + dispatch(getNewReservationName(name)); + navigate(`${USERS_DASHBOARD}/${MY_RESERVATIONS}`); } - console.log('id', id) - dispatch(postReserveCar({ carId: id, reservationData})); - console.log('Reservation successful'); - console.log(reservationData); - console.log('Picked date is:', formattedDate); - console.log('Picked City is: ', values.selectedCity); - console.log('User name:', username); - console.log('car name: ', name) }; const options = [ diff --git a/src/layout/LandingPage/LandingPageLayout.js b/src/layout/LandingPage/LandingPageLayout.js index d9c3599..6794488 100644 --- a/src/layout/LandingPage/LandingPageLayout.js +++ b/src/layout/LandingPage/LandingPageLayout.js @@ -1,20 +1,14 @@ import React from 'react'; import { Outlet } from 'react-router-dom'; +import Header from './header/Header'; -// import Footer from './footer/Footer'; -import Header from './header/Header'; - -const LandingPageLayout = () => { - // eslint-disable-next-line arrow-body-style - return ( - <> -
-
- -
- {/*