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 1635b617..076c339a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -33,6 +33,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"
},
"scripts": {
@@ -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 b3d522e5..ba12cadf 100644
--- a/frontend/src/components/FormElements/FormElements.tsx
+++ b/frontend/src/components/FormElements/FormElements.tsx
@@ -1,6 +1,14 @@
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';
type LabelType = React.DetailedHTMLProps<
React.LabelHTMLAttributes,
@@ -73,3 +81,61 @@ export const Button = React.forwardRef(
);
}
);
+
+type Option = {
+ id: string;
+ name: string;
+};
+
+type SelectOption = {
+ value: string;
+ label: string;
+};
+
+type SelectComponentProps = SelectProps & {
+ control: Control;
+ name: Path;
+ datalist: Option[];
+ className?: string;
+ rules?: RegisterOptions;
+};
+
+export const SelectComponent = ({
+ control,
+ name,
+ datalist,
+ className,
+ rules,
+ ...rest
+}: SelectComponentProps) => {
+ const {
+ field: { onChange, value, ref, ...inputProps },
+ } = useController({
+ name,
+ control,
+ rules,
+ });
+
+ const transformedOptions = datalist.map((data) => ({
+ value: data.id,
+ label: data.name,
+ }));
+
+ const selectedOption = transformedOptions.find(
+ (option) => option.value === value
+ );
+
+ return (
+
)}
+
+
+
+ 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 86d4f6e5..aa6bbb35 100644
--- a/frontend/src/components/RideModal/Pages/RideTimes.tsx
+++ b/frontend/src/components/RideModal/Pages/RideTimes.tsx
@@ -166,7 +166,10 @@ const RideTimesPage: React.FC
= ({
watch,
} = methods;
const watchRepeats = watch('repeats');
-
+ const repeatOptions = Object.values(RepeatValues).map((value) => ({
+ id: value,
+ name: value,
+ }));
useEffect(() => {
setIsRepeating(watchRepeats !== RepeatValues.DoesNotRepeat);
}, [watchRepeats]);
@@ -205,13 +208,13 @@ const RideTimesPage: React.FC = ({
Repeats:
diff --git a/frontend/src/components/RideModal/Pages/RiderInfo.tsx b/frontend/src/components/RideModal/Pages/RiderInfo.tsx
index 55afb52f..03b80aee 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 } 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';
@@ -16,6 +21,7 @@ interface FormData {
const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => {
const {
+ control,
register,
handleSubmit,
formState: { errors },
@@ -31,12 +37,20 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => {
const [locationToId, setLocationToId] = useState({});
const { locations } = useLocations();
const { riders } = useRiders();
-
- const beforeSubmit = ({ name, pickupLoc, dropoffLoc }: FormData) => {
- const rider = nameToId[name.toLowerCase()];
+ const beforeSubmit = ({ name, pickupLoc, dropoffLoc }: ObjectType) => {
const startLocation = locationToId[pickupLoc] ?? pickupLoc;
const endLocation = locationToId[dropoffLoc] ?? dropoffLoc;
- onSubmit({ rider, startLocation, endLocation });
+ /**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 payload = {
+ rider: name,
+ startLocation,
+ endLocation,
+ };
+ console.log(payload);
+ onSubmit(payload);
};
useEffect(() => {
@@ -59,7 +73,7 @@ const RiderInfoPage = ({ formData, onBack, onSubmit }: ModalPageProps) => {
Name
-
{
validate: (name: string) =>
nameToId[name.toLowerCase()] !== undefined,
})}
+ /> */}
+
+ name="name"
+ datalist={Object.entries(nameToId).map(([name, id]) => ({
+ id,
+ name,
+ }))}
+ isSearchable={true}
+ control={control}
+ rules={{ required: 'Rider name is required' }}
/>
+
{errors.name && Rider not found
}