From 9d59a190b366ae784e6776755ce880a985fecea4 Mon Sep 17 00:00:00 2001 From: andrew Date: Thu, 14 Mar 2024 23:44:17 -0400 Subject: [PATCH 1/8] allow the drop down displaying all locations without having to clear the text first --- .../components/RideModal/Pages/RiderInfo.tsx | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/RideModal/Pages/RiderInfo.tsx b/frontend/src/components/RideModal/Pages/RiderInfo.tsx index e6039330..1bb5cce8 100644 --- a/frontend/src/components/RideModal/Pages/RiderInfo.tsx +++ b/frontend/src/components/RideModal/Pages/RiderInfo.tsx @@ -93,15 +93,12 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => {
-
From d7b87fbc19258aed5cee21c2672afcd2f2fd71e3 Mon Sep 17 00:00:00 2001 From: Desmond Date: Sun, 24 Mar 2024 23:21:09 -0400 Subject: [PATCH 2/8] Select Component Addition --- frontend/package.json | 3 +- .../components/FormElements/FormElements.tsx | 30 ++++++++++++++ .../components/RideModal/Pages/RiderInfo.tsx | 40 ++++--------------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 56701963..65e89c7b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,11 +33,12 @@ "react-router-dom": "^5.3.4", "react-router-hash-link": "^2.4.0", "react-scripts": "4.0.3", + "react-select": "^5.8.0", "reactjs-popup": "^2.0.4", "typescript": "^4.8.4" }, "scripts": { - "start": "react-scripts start", + "start": "react-scripts --openssl-legacy-provider start", "build": "react-scripts build", "tsc": "../node_modules/.bin/tsc --noEmit false", "lint": "eslint . --ext .js --ext .jsx --ext .ts --ext .tsx --fix", diff --git a/frontend/src/components/FormElements/FormElements.tsx b/frontend/src/components/FormElements/FormElements.tsx index b3d522e5..a8cb0f04 100644 --- a/frontend/src/components/FormElements/FormElements.tsx +++ b/frontend/src/components/FormElements/FormElements.tsx @@ -1,6 +1,7 @@ import React, { SelectHTMLAttributes } from 'react'; import cn from 'classnames'; import styles from './formelements.module.css'; +import Select,{Props as SelectProps} from 'react-select'; type LabelType = React.DetailedHTMLProps< React.LabelHTMLAttributes, @@ -73,3 +74,32 @@ export const Button = React.forwardRef( ); } ); + +type DataList = { + id: string; + name: string; +}; + +type SelectComponentProps =SelectProps & { + datalist: DataList[]; + className?: string; +}; + +export const SelectComponent: React.FC = ({ + datalist, + className, + ...rest +}) => { + const transformedOptions = datalist.map((data) => ({ + value: data.id, + label: data.name, + })); + + return ( + + + {errors.pickupLoc && (

Please enter a location

)} @@ -93,29 +87,11 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => {
- - + + {errors.dropoffLoc?.type === 'required' && (

Please enter a location

)} From df85b4184bd167704535b3385f0a2bfd874339da Mon Sep 17 00:00:00 2001 From: Desmond Date: Sun, 24 Mar 2024 23:31:40 -0400 Subject: [PATCH 3/8] Prettier fix --- .../src/components/FormElements/FormElements.tsx | 6 +++--- .../src/components/RideModal/Pages/RiderInfo.tsx | 16 +++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/FormElements/FormElements.tsx b/frontend/src/components/FormElements/FormElements.tsx index a8cb0f04..38727187 100644 --- a/frontend/src/components/FormElements/FormElements.tsx +++ b/frontend/src/components/FormElements/FormElements.tsx @@ -1,7 +1,7 @@ import React, { SelectHTMLAttributes } from 'react'; import cn from 'classnames'; import styles from './formelements.module.css'; -import Select,{Props as SelectProps} from 'react-select'; +import Select, { Props as SelectProps } from 'react-select'; type LabelType = React.DetailedHTMLProps< React.LabelHTMLAttributes, @@ -80,7 +80,7 @@ type DataList = { name: string; }; -type SelectComponentProps =SelectProps & { +type SelectComponentProps = SelectProps & { datalist: DataList[]; className?: string; }; @@ -102,4 +102,4 @@ export const SelectComponent: React.FC = ({ {...rest} /> ); -}; \ No newline at end of file +}; diff --git a/frontend/src/components/RideModal/Pages/RiderInfo.tsx b/frontend/src/components/RideModal/Pages/RiderInfo.tsx index 302980f5..c37e98c7 100644 --- a/frontend/src/components/RideModal/Pages/RiderInfo.tsx +++ b/frontend/src/components/RideModal/Pages/RiderInfo.tsx @@ -3,7 +3,12 @@ import { useForm } from 'react-hook-form'; import cn from 'classnames'; import { ObjectType, Location, Rider } from '../../../types'; import { ModalPageProps } from '../../Modal/types'; -import { Button, Input, Label, SelectComponent } from '../../FormElements/FormElements'; +import { + Button, + Input, + Label, + SelectComponent, +} from '../../FormElements/FormElements'; import styles from '../ridemodal.module.css'; import { useRiders } from '../../../context/RidersContext'; import { useLocations } from '../../../context/LocationsContext'; @@ -75,7 +80,7 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => { - + {errors.pickupLoc && (

Please enter a location

@@ -87,11 +92,8 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => {
- - + + {errors.dropoffLoc?.type === 'required' && (

Please enter a location

)} From 07b0790c63d22d773928b8a952964e1a6311b999 Mon Sep 17 00:00:00 2001 From: Desmond Date: Wed, 27 Mar 2024 13:02:06 -0400 Subject: [PATCH 4/8] Fixed implementation of Select works as expected --- .../components/FormElements/FormElements.tsx | 20 ++++++++++ .../components/RideModal/Pages/RiderInfo.tsx | 40 +++++++++++++++---- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/FormElements/FormElements.tsx b/frontend/src/components/FormElements/FormElements.tsx index 38727187..2d818e53 100644 --- a/frontend/src/components/FormElements/FormElements.tsx +++ b/frontend/src/components/FormElements/FormElements.tsx @@ -2,6 +2,7 @@ import React, { SelectHTMLAttributes } from 'react'; import cn from 'classnames'; import styles from './formelements.module.css'; import Select, { Props as SelectProps } from 'react-select'; +import { Control, useController } from 'react-hook-form'; type LabelType = React.DetailedHTMLProps< React.LabelHTMLAttributes, @@ -81,11 +82,15 @@ type DataList = { }; type SelectComponentProps = SelectProps & { + control: Control; + name: string; datalist: DataList[]; className?: string; }; export const SelectComponent: React.FC = ({ + control, + name, datalist, className, ...rest @@ -95,10 +100,25 @@ export const SelectComponent: React.FC = ({ label: data.name, })); + const { + field: { ref, onChange, value, ...inputProps }, + } = useController({ + name, + control, + }); + + const selectedOption = transformedOptions.find( + (option) => option.value === value + ); + return ( - {Object.values(RepeatValues).map((repeatValue) => ( - - ))} - + datalist={repeatOptions} + className={styles.customSelect} + rules={{ required: 'Please enter a time' }} + /> {errors.repeats?.type === 'required' && (

Please enter a time

)} diff --git a/frontend/src/components/RideModal/Pages/RiderInfo.tsx b/frontend/src/components/RideModal/Pages/RiderInfo.tsx index 9997016e..33df13ac 100644 --- a/frontend/src/components/RideModal/Pages/RiderInfo.tsx +++ b/frontend/src/components/RideModal/Pages/RiderInfo.tsx @@ -26,19 +26,20 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => { const [locationToId, setLocationToId] = useState({}); const { locations } = useLocations(); const { riders } = useRiders(); - const beforeSubmit = ({ name, pickupLoc, dropoffLoc }: ObjectType) => { - const rider = nameToId[name.toLowerCase()]; - /** - * Currently pickupLoc and dropoffLoc are received from the useController as an object - * {value:id, label : name} - * Intended refactor should only send in value + const startLocation = locationToId[pickupLoc] ?? pickupLoc; + const endLocation = locationToId[dropoffLoc] ?? dropoffLoc; + /**Payload needed because the form is registered to expect rider instead of name + * If name passed straightaway it results in the database receiving an empty field for rider + * */ - const startLocation = - locationToId[pickupLoc[pickupLoc.label]] ?? pickupLoc.value; - const endLocation = - locationToId[dropoffLoc[dropoffLoc.label]] ?? dropoffLoc.value; - onSubmit({ rider, startLocation, endLocation }); + const payload = { + rider: name, + startLocation, + endLocation, + }; + console.log(payload); + onSubmit(payload); }; useEffect(() => { @@ -61,7 +62,7 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => {
- { validate: (name: string) => nameToId[name.toLowerCase()] !== undefined, })} + /> */} + ({ + id, + name, + }))} + isSearchable={true} + control={control} + rules={{ required: 'Rider name is required' }} /> + {errors.name &&

Rider not found

} {riders.map((r) => ( @@ -92,6 +104,7 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => { datalist={locations} isSearchable={true} control={control} + rules={{ required: 'Pickup Location is required' }} /> {errors.pickupLoc && ( @@ -112,6 +125,7 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => { datalist={locations} isSearchable={true} control={control} + rules={{ required: 'Dropoff Location is required' }} /> {errors.dropoffLoc?.type === 'required' && (

Please enter a location

diff --git a/frontend/src/components/RideModal/RideModal.tsx b/frontend/src/components/RideModal/RideModal.tsx index 2292b2f0..d7fb269c 100644 --- a/frontend/src/components/RideModal/RideModal.tsx +++ b/frontend/src/components/RideModal/RideModal.tsx @@ -163,8 +163,6 @@ const RideModal = ({ open, close, ride, editSingle }: RideModalProps) => { }; } - console.log(rideData); - if (ride) { // scheduled ride if (ride.type === 'active') { From 8318ad85ba2f5187bf1ad329cc02cb54d8f0c80d Mon Sep 17 00:00:00 2001 From: Desmond Atikpui Date: Sat, 5 Oct 2024 11:14:11 -0400 Subject: [PATCH 6/8] React-Select Integration and Ride Modal --- frontend/package-lock.json | 217 ++++++++++++++++++ frontend/package.json | 5 +- .../components/FormElements/FormElements.tsx | 18 +- .../src/components/Modal/RiderModalInfo.tsx | 22 +- .../src/components/RideModal/Pages/Driver.tsx | 18 +- .../components/RideModal/Pages/RideTimes.tsx | 20 +- .../components/RideModal/Pages/RiderInfo.tsx | 10 +- .../src/components/RideModal/RideModal.tsx | 116 ++++------ .../components/RideModal/ridemodal.module.css | 213 ++++++++++++----- package-lock.json | 44 ++-- 10 files changed, 505 insertions(+), 178 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a8cc84a3..bae02004 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -37,6 +37,7 @@ "react-router-dom": "^6.26.2", "react-router-hash-link": "^2.4.3", "react-scripts": "^5.0.1", + "react-select": "^5.8.1", "reactjs-popup": "^2.0.6" }, "devDependencies": { @@ -2568,6 +2569,135 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", + "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", + "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -4778,6 +4908,15 @@ "@types/react-router-dom": "^5.3.0" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", + "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -9121,6 +9260,12 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -9811,6 +9956,21 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -16470,6 +16630,43 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/react-select": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.1.tgz", + "integrity": "sha512-RT1CJmuc+ejqm5MPgzyZujqDskdvB9a9ZqrdnVLsvAHjJ3Tj0hELnLeVPQlmYdVKCdCpxanepl6z7R5KhXhWzg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/reactjs-popup": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/reactjs-popup/-/reactjs-popup-2.0.6.tgz", @@ -17944,6 +18141,12 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -18955,6 +19158,20 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 78a55d79..076c339a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,10 +33,11 @@ "react-router-dom": "^6.26.2", "react-router-hash-link": "^2.4.3", "react-scripts": "^5.0.1", + "react-select": "^5.8.1", "reactjs-popup": "^2.0.6" }, "scripts": { - "start": "react-scripts --openssl-legacy-provider start", + "start": "react-scripts start", "build": "react-scripts build", "tsc": "../node_modules/.bin/tsc --noEmit false", "lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix", @@ -71,4 +72,4 @@ "eslint-plugin-react-hooks": "^4.6.0", "prettier": "2.8.8" } -} \ No newline at end of file +} diff --git a/frontend/src/components/FormElements/FormElements.tsx b/frontend/src/components/FormElements/FormElements.tsx index 616a287d..1e35d94f 100644 --- a/frontend/src/components/FormElements/FormElements.tsx +++ b/frontend/src/components/FormElements/FormElements.tsx @@ -2,7 +2,7 @@ import React, { SelectHTMLAttributes } from 'react'; import cn from 'classnames'; import styles from './formelements.module.css'; import Select, { ActionMeta, Props as SelectProps } from 'react-select'; -import { Control, RegisterOptions, useController } from 'react-hook-form'; +import { Control, RegisterOptions, useController, Path, FieldValues } from 'react-hook-form'; type LabelType = React.DetailedHTMLProps< React.LabelHTMLAttributes, @@ -86,25 +86,25 @@ type SelectOption = { label: string; }; -type SelectComponentProps = SelectProps & { - control: Control; - name: string; +type SelectComponentProps = SelectProps & { + control: Control; + name: Path; datalist: Option[]; className?: string; - rules?: RegisterOptions; + rules?: RegisterOptions; }; -export const SelectComponent: React.FC = ({ +export const SelectComponent = ({ control, name, datalist, className, rules, ...rest -}) => { +}: SelectComponentProps) => { const { field: { onChange, value, ref, ...inputProps }, - } = useController({ + } = useController({ name, control, rules, @@ -132,4 +132,4 @@ export const SelectComponent: React.FC = ({ {...rest} /> ); -}; +}; \ No newline at end of file diff --git a/frontend/src/components/Modal/RiderModalInfo.tsx b/frontend/src/components/Modal/RiderModalInfo.tsx index fbf7907d..185ab7bc 100644 --- a/frontend/src/components/Modal/RiderModalInfo.tsx +++ b/frontend/src/components/Modal/RiderModalInfo.tsx @@ -1,7 +1,12 @@ import React, { useState } from 'react'; import { useForm, SubmitHandler } from 'react-hook-form'; import cn from 'classnames'; -import { Button, Input, Label } from '../FormElements/FormElements'; +import { + Button, + Input, + Label, + SelectComponent, +} from '../FormElements/FormElements'; import styles from './ridermodal.module.css'; import { ObjectType, Accessibility, Rider } from '../../types/index'; @@ -31,6 +36,7 @@ const RiderModalInfo: React.FC = ({ rider, }) => { const { + control, register, formState: { errors }, handleSubmit, @@ -181,6 +187,20 @@ const RiderModalInfo: React.FC = ({

)}
+ +
+ + name="needs" + datalist={Object.entries(Accessibility).map(([key, value]) => ({ + id: key, + name: value, + }))} + isSearchable={true} + control={control} + isMulti={true} + rules={{ required: 'Rider name is required' }} + /> +
{errors.driver?.type === 'required' && ( -

- Please select a driver -

+

Please select a driver

)}
diff --git a/frontend/src/components/RideModal/Pages/RideTimes.tsx b/frontend/src/components/RideModal/Pages/RideTimes.tsx index dd4e9cae..83ba7a9d 100644 --- a/frontend/src/components/RideModal/Pages/RideTimes.tsx +++ b/frontend/src/components/RideModal/Pages/RideTimes.tsx @@ -13,7 +13,6 @@ import { Button, Input, Label, - SelectComponent, } from '../../FormElements/FormElements'; import styles from '../ridemodal.module.css'; import { useDate } from '../../../context/date'; @@ -211,13 +210,18 @@ const RideTimesPage: React.FC = ({
- + {errors.repeats?.type === 'required' && (

Please enter a time

)} diff --git a/frontend/src/components/RideModal/Pages/RiderInfo.tsx b/frontend/src/components/RideModal/Pages/RiderInfo.tsx index cab83d3a..03b80aee 100644 --- a/frontend/src/components/RideModal/Pages/RiderInfo.tsx +++ b/frontend/src/components/RideModal/Pages/RiderInfo.tsx @@ -20,7 +20,13 @@ interface FormData { } const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => { - const { control, register, handleSubmit, formState, getValues } = useForm({ + const { + control, + register, + handleSubmit, + formState: { errors }, + getValues, + } = useForm({ defaultValues: { name: formData?.rider ?? '', pickupLoc: formData?.pickupLoc ?? '', @@ -79,7 +85,7 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => { nameToId[name.toLowerCase()] !== undefined, })} /> */} - name="name" datalist={Object.entries(nameToId).map(([name, id]) => ({ id, diff --git a/frontend/src/components/RideModal/RideModal.tsx b/frontend/src/components/RideModal/RideModal.tsx index a8e26358..23212786 100644 --- a/frontend/src/components/RideModal/RideModal.tsx +++ b/frontend/src/components/RideModal/RideModal.tsx @@ -16,8 +16,54 @@ type RideModalProps = { editSingle?: boolean; }; +const getRideData = (ride: Ride | undefined) => { + if (ride) { + let rideData: ObjectType = { + date: format_date(ride.startTime), + pickupTime: moment(ride.startTime).format('kk:mm'), + dropoffTime: moment(ride.endTime).format('kk:mm'), + rider: `${ride.rider.firstName} ${ride.rider.lastName}`, + pickupLoc: ride.startLocation.id + ? ride.startLocation.name + : ride.startLocation.address, + dropoffLoc: ride.endLocation.id + ? ride.endLocation.name + : ride.endLocation.address, + }; + if (ride.recurring) { + let repeats; + let days; + const startDay = moment(ride.startTime).weekday(); + + if (ride.recurringDays!.length === 5) { + repeats = RepeatValues.Daily; + } else if ( + ride.recurringDays!.length === 1 && + ride.recurringDays![0] === startDay + ) { + repeats = RepeatValues.Weekly; + } else { + repeats = RepeatValues.Custom; + const numToDay = ['', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri']; + days = ride.recurringDays!.reduce((prev, curr) => { + return { ...prev, [numToDay[curr]]: '1' }; + }, {} as ObjectType); + } + + rideData = { + ...rideData, + repeats, + days, + endDate: format_date(ride.endDate), + }; + } + return rideData; + } + return {}; +}; + const RideModal = ({ open, close, ride, editSingle }: RideModalProps) => { - const originalRideData = getRideData(); + const originalRideData = getRideData(ride); const [formData, setFormData] = useState(originalRideData); const [isOpen, setIsOpen] = useState(open !== undefined ? open : false); const [currentPage, setCurrentPage] = useState(0); @@ -25,54 +71,6 @@ const RideModal = ({ open, close, ride, editSingle }: RideModalProps) => { const { showToast } = useToast(); const { refreshRides } = useRides(); - // using function instead of const so the function can be hoisted and - // not get in the way of the state and hooks - function getRideData() { - if (ride) { - let rideData: ObjectType = { - date: format_date(ride.startTime), - pickupTime: moment(ride.startTime).format('kk:mm'), - dropoffTime: moment(ride.endTime).format('kk:mm'), - rider: `${ride.rider.firstName} ${ride.rider.lastName}`, - pickupLoc: ride.startLocation.id - ? ride.startLocation.name - : ride.startLocation.address, - dropoffLoc: ride.endLocation.id - ? ride.endLocation.name - : ride.endLocation.address, - }; - if (ride.recurring) { - let repeats; - let days; - const startDay = moment(ride.startTime).weekday(); - - if (ride.recurringDays!.length === 5) { - repeats = RepeatValues.Daily; - } else if ( - ride.recurringDays!.length === 1 && - ride.recurringDays![0] === startDay - ) { - repeats = RepeatValues.Weekly; - } else { - repeats = RepeatValues.Custom; - const numToDay = ['', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri']; - days = ride.recurringDays!.reduce((prev, curr) => { - return { ...prev, [numToDay[curr]]: '1' }; - }, {} as ObjectType); - } - - rideData = { - ...rideData, - repeats, - days, - endDate: format_date(ride.endDate), - }; - } - return rideData; - } - return {}; - } - const goNextPage = () => setCurrentPage((p) => p + 1); const goPrevPage = () => setCurrentPage((p) => p - 1); @@ -100,19 +98,6 @@ const RideModal = ({ open, close, ride, editSingle }: RideModalProps) => { const submitData = () => setIsSubmitted(true); - /** - * Converts a ride that repeats into a number array representation used by - * the internal representation of a ride - * - * @param date a string representation of the ride start date - * @param repeats an enum representing how often this ride repeats: Daily, - * Weekly, or Custom - * @param days Used if the ride repeats on custom days. An object that - * maps days (Mon, Tue, Wed, Thur, Fri) to strings, where the string value is - * non-empty if the ride repeats on that day - * @returns a number array containing the days of the week where the ride repeats, - * with Monday represented as 1, Tuesday represented as 2, etc. - */ const getRecurringDays = ( date: string, repeats: RepeatValues, @@ -203,10 +188,8 @@ const RideModal = ({ open, close, ride, editSingle }: RideModalProps) => { closeModal(); showToast(ride ? 'Ride edited.' : 'Ride added.', ToastStatus.SUCCESS); } - }, [closeModal, formData, isSubmitted, ride]); + }, [closeModal, formData, isSubmitted, ride, editSingle, refreshRides, showToast]); - // have to do a ternary operator on the entire modal - // because otherwise the pages would show up wrongly return ride ? ( <> { ) : ( <> - {/* only have a button if this modal is not controlled by a table */} {!open && } { ); }; -export default RideModal; +export default RideModal; \ No newline at end of file diff --git a/frontend/src/components/RideModal/ridemodal.module.css b/frontend/src/components/RideModal/ridemodal.module.css index 7dc194fa..beb8f9a8 100644 --- a/frontend/src/components/RideModal/ridemodal.module.css +++ b/frontend/src/components/RideModal/ridemodal.module.css @@ -1,116 +1,215 @@ +/* General form styles */ .form { display: flex; flex-direction: column; - align-items: center; -} - -.error { - color: #eb0023; - font-size: 0.7rem; + width: 100%; + height: 100%; } .inputContainer { margin-bottom: 1.5rem; + width: 100%; } -.btnContainer { - display: flex; +.error { + color: #dc3545; + font-size: 0.8rem; + margin-top: 0.25rem; } -.btnContainer > button { - margin: 0 0.75rem; +.label { + display: block; + margin-bottom: 0.5rem; + font-weight: 600; + color: #333; } -.rideTime { +/* Input styles */ +input[type="date"], +input[type="time"], +select { + width: 100%; + padding: 0.75rem; + font-size: 1rem; + border: 1px solid #ced4da; + border-radius: 4px; + background-color: #fff; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} + +input[type="date"]:focus, +input[type="time"]:focus, +select:focus { + outline: none; + border-color: #80bdff; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +/* Styled select */ +select { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23333' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 0.75rem center; + background-size: 12px; + padding-right: 2.5rem; +} + +/* RideTimes and DriverPage shared styles */ +.rideTime, +.drivers { display: grid; grid-template-columns: repeat(2, 1fr); - grid-gap: 1rem; -} - -.col1 { - grid-column: 1; + grid-gap: 1.25rem; } -.col2 { - grid-column: 2; +.col1, .col2 { + display: flex; + flex-direction: column; } .colSpan { - grid-column: 1/-1; -} - -.select { - border: none; - border-radius: 0.25rem; - font-size: 1rem; - padding: 0.25rem; - background-color: #eae9e9; + grid-column: 1 / -1; } +/* Day selector styles */ .day { - border-radius: 40%; - height: 1.25rem; - width: 1.25rem; - border: none; + border-radius: 50%; + height: 2.25rem; + width: 2.25rem; + border: 2px solid #6c757d; padding: 0; cursor: pointer; - margin: 0 0.125rem; - background-color: rgba(0, 0, 0, 0.1); + margin: 0 0.25rem; + background-color: transparent; + color: #6c757d; + font-weight: 600; + transition: all 0.2s ease-in-out; } .day:focus { - box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.5); + outline: none; + box-shadow: 0 0 0 3px rgba(108, 117, 125, 0.5); } .daySelected { - background-color: black; + background-color: #000; color: white; + border-color: #000; } +/* DriverPage specific styles */ .drivers { display: flex; - flex-wrap: wrap; - max-width: 30rem; - justify-content: center; + flex-direction: column; + max-height: 300px; + overflow-y: auto; + border: 1px solid #ced4da; + border-radius: 4px; + background-color: #f8f9fa; } .driver { display: flex; - flex-direction: column; align-items: center; - margin: 0 0.625rem; + padding: 1rem; + border-bottom: 1px solid #e9ecef; + transition: background-color 0.2s ease; +} + +.driver:last-child { + border-bottom: none; +} + +.driver:hover { + background-color: #e9ecef; } .driverLabel { - margin: 0; + flex-grow: 1; + margin-left: 1rem; + font-size: 1rem; + color: #333; + cursor: pointer; } .driverRadio { - margin: 0; + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + width: 20px; + height: 20px; + border: 2px solid #ced4da; + border-radius: 50%; + outline: none; + transition: all 0.2s ease; +} + +.driverRadio:checked { + border-color: #000; + background-color: #000; + box-shadow: inset 0 0 0 4px #fff; } .driverRadio:focus { - outline: 3px solid black; + box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.25), inset 0 0 0 4px #fff; } -.rider { - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(2, 1fr); - column-gap: 1rem; - row-gap: 1rem; +/* Button styles */ +.btnContainer { + display: flex; + justify-content: space-between; + margin-top: auto; } -.name { - grid-column: 1/3; - grid-row: 1; +.btnContainer button { + padding: 0.75rem 1.5rem; + font-size: 1rem; + border-radius: 4px; + cursor: pointer; + transition: all 0.2s ease; + background-color: #000; + color: #fff; + border: none; } -.nameInput { - font-size: 1.5rem; - width: 100%; +.btnContainer button:hover { + background-color: #333; } -.label { - display: block; +.btnContainer button[type="button"] { + background-color: #fff; + color: #000; + border: 1px solid #000; +} + +.btnContainer button[type="button"]:hover { + background-color: #000; + color: #fff; +} + +/* Loading state */ +.loading { + text-align: center; + color: #6c757d; + font-style: italic; } + +/* Responsive adjustments */ +@media (max-width: 500px) { + .rideTime, + .drivers { + grid-template-columns: 1fr; + } + + .btnContainer { + flex-direction: column; + gap: 1rem; + } + + .btnContainer button { + width: 100%; + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c63f577d..7d8a8bea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1066,9 +1066,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -1086,8 +1086,8 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, @@ -1128,9 +1128,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001663", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", - "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", + "version": "1.0.30001664", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", + "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==", "dev": true, "funding": [ { @@ -1345,9 +1345,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.27", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", - "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", + "version": "1.5.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.30.tgz", + "integrity": "sha512-sXI35EBN4lYxzc/pIGorlymYNzDBOqkSlVRe6MkgBsW/hW1tpC/HDJ2fjG7XnjakzfLEuvdmux0Mjs6jHq4UOA==", "dev": true, "license": "ISC" }, @@ -1627,9 +1627,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.1.tgz", - "integrity": "sha512-EwcbfLOhwVMAfatfqLecR2yv3dE5+kQ8kx+Rrt0DvDXEVwW86KQ/xbMDQhtp5l42VXukD5SOF8mQQHbaNtO0CQ==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "dev": true, "license": "MIT", "dependencies": { @@ -1726,9 +1726,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.36.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz", - "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==", + "version": "7.37.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.0.tgz", + "integrity": "sha512-IHBePmfWH5lKhJnJ7WB1V+v/GolbB0rjS8XYVCSQCZKaQCAUhMoVoOEn1Ef8Z8Wf0a7l8KTJvuZg5/e4qrZ6nA==", "dev": true, "license": "MIT", "dependencies": { @@ -4029,9 +4029,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -4049,8 +4049,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" From ba4f32de34b71a882e4c2a1610a8e579ee1ff36c Mon Sep 17 00:00:00 2001 From: Desmond Atikpui Date: Sat, 5 Oct 2024 11:17:28 -0400 Subject: [PATCH 7/8] Prettier --- .../src/components/FormElements/FormElements.tsx | 10 ++++++++-- .../src/components/RideModal/Pages/RideTimes.tsx | 6 +----- frontend/src/components/RideModal/RideModal.tsx | 12 ++++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/FormElements/FormElements.tsx b/frontend/src/components/FormElements/FormElements.tsx index 1e35d94f..ba12cadf 100644 --- a/frontend/src/components/FormElements/FormElements.tsx +++ b/frontend/src/components/FormElements/FormElements.tsx @@ -2,7 +2,13 @@ import React, { SelectHTMLAttributes } from 'react'; import cn from 'classnames'; import styles from './formelements.module.css'; import Select, { ActionMeta, Props as SelectProps } from 'react-select'; -import { Control, RegisterOptions, useController, Path, FieldValues } from 'react-hook-form'; +import { + Control, + RegisterOptions, + useController, + Path, + FieldValues, +} from 'react-hook-form'; type LabelType = React.DetailedHTMLProps< React.LabelHTMLAttributes, @@ -132,4 +138,4 @@ export const SelectComponent = ({ {...rest} /> ); -}; \ No newline at end of file +}; diff --git a/frontend/src/components/RideModal/Pages/RideTimes.tsx b/frontend/src/components/RideModal/Pages/RideTimes.tsx index 83ba7a9d..aa6bbb35 100644 --- a/frontend/src/components/RideModal/Pages/RideTimes.tsx +++ b/frontend/src/components/RideModal/Pages/RideTimes.tsx @@ -9,11 +9,7 @@ import { import cn from 'classnames'; import moment from 'moment'; import { ModalPageProps } from '../../Modal/types'; -import { - Button, - Input, - Label, -} from '../../FormElements/FormElements'; +import { Button, Input, Label } from '../../FormElements/FormElements'; import styles from '../ridemodal.module.css'; import { useDate } from '../../../context/date'; import { format_date, checkBounds } from '../../../util/index'; diff --git a/frontend/src/components/RideModal/RideModal.tsx b/frontend/src/components/RideModal/RideModal.tsx index 23212786..22e97a7d 100644 --- a/frontend/src/components/RideModal/RideModal.tsx +++ b/frontend/src/components/RideModal/RideModal.tsx @@ -188,7 +188,15 @@ const RideModal = ({ open, close, ride, editSingle }: RideModalProps) => { closeModal(); showToast(ride ? 'Ride edited.' : 'Ride added.', ToastStatus.SUCCESS); } - }, [closeModal, formData, isSubmitted, ride, editSingle, refreshRides, showToast]); + }, [ + closeModal, + formData, + isSubmitted, + ride, + editSingle, + refreshRides, + showToast, + ]); return ride ? ( <> @@ -242,4 +250,4 @@ const RideModal = ({ open, close, ride, editSingle }: RideModalProps) => { ); }; -export default RideModal; \ No newline at end of file +export default RideModal; From d097aa54443e774ad44a27d48aca348d97772b3b Mon Sep 17 00:00:00 2001 From: Desmond Atikpui Date: Sat, 5 Oct 2024 11:17:46 -0400 Subject: [PATCH 8/8] Prettier for CSS --- .../components/RideModal/ridemodal.module.css | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/RideModal/ridemodal.module.css b/frontend/src/components/RideModal/ridemodal.module.css index beb8f9a8..d45447cd 100644 --- a/frontend/src/components/RideModal/ridemodal.module.css +++ b/frontend/src/components/RideModal/ridemodal.module.css @@ -25,8 +25,8 @@ } /* Input styles */ -input[type="date"], -input[type="time"], +input[type='date'], +input[type='time'], select { width: 100%; padding: 0.75rem; @@ -37,8 +37,8 @@ select { transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } -input[type="date"]:focus, -input[type="time"]:focus, +input[type='date']:focus, +input[type='time']:focus, select:focus { outline: none; border-color: #80bdff; @@ -65,7 +65,8 @@ select { grid-gap: 1.25rem; } -.col1, .col2 { +.col1, +.col2 { display: flex; flex-direction: column; } @@ -179,13 +180,13 @@ select { background-color: #333; } -.btnContainer button[type="button"] { +.btnContainer button[type='button'] { background-color: #fff; color: #000; border: 1px solid #000; } -.btnContainer button[type="button"]:hover { +.btnContainer button[type='button']:hover { background-color: #000; color: #fff; } @@ -212,4 +213,4 @@ select { .btnContainer button { width: 100%; } -} \ No newline at end of file +}