Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration of React-Select into Add Student, proper styling and cust… #554

Merged
merged 1 commit into from
Nov 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 161 additions & 23 deletions frontend/src/components/Modal/RiderModalInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';
import { useForm, SubmitHandler, Controller } from 'react-hook-form';
import Select, { StylesConfig } from 'react-select';
import cn from 'classnames';
import { Button, Input, Label } from '../FormElements/FormElements';
import styles from './ridermodal.module.css';
@@ -12,11 +13,16 @@ type ModalFormProps = {
rider?: Rider;
};

type NeedOption = {
value: Accessibility | string;
label: string;
};

type FormData = {
name: string;
netid: string;
phoneNumber: string;
needs: Accessibility[];
needs: NeedOption[];
address: string;
joinDate: string;
endDate: string;
@@ -29,23 +35,99 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
setFormData,
rider,
}) => {
const [showCustomInput, setShowCustomInput] = useState(false);
const [customNeed, setCustomNeed] = useState('');

const {
register,
control,
formState: { errors },
handleSubmit,
getValues,
setValue,
} = useForm<FormData>({
defaultValues: {
name: (rider?.firstName ?? '') + (rider?.lastName ?? ''),
netid: rider?.email.split('@')[0] ?? '',
phoneNumber: rider?.phoneNumber ?? '',
needs: [],
needs:
rider?.accessibility?.map((need) => ({
value: need as Accessibility,
label: need,
})) ?? [],
address: rider?.address ?? '',
joinDate: rider?.joinDate ?? '',
endDate: rider?.endDate ?? '',
},
});

const customStyles: StylesConfig<NeedOption, true> = {
option: (baseStyles, { data }) => ({
...baseStyles,
...(data.value === 'OTHER' && {
color: '#0066cc',
fontStyle: 'italic',
backgroundColor: '#f8f9fa',
borderTop: '1px solid #e9ecef',
marginTop: '4px',
paddingTop: '8px',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
'&:before': {
content: '"+"',
marginRight: '8px',
fontSize: '14px',
fontWeight: 'bold',
},
'&:hover': {
backgroundColor: '#e9ecef',
color: '#004c99',
},
}),
}),
menu: (baseStyles) => ({
...baseStyles,
padding: '4px 0',
}),
};

const handleNeedsChange = (
selectedOptions: readonly NeedOption[] | null,
{ action }: any
) => {
if (selectedOptions?.some((option) => option.value === 'OTHER')) {
const filteredOptions = [
...selectedOptions.filter((opt) => opt.value !== 'OTHER'),
];
setValue('needs', filteredOptions);
setShowCustomInput(true);
setCustomNeed('');
} else {
setValue('needs', selectedOptions ? [...selectedOptions] : []);
setShowCustomInput(false);
}
};

const handleAddCustomNeed = () => {
if (customNeed.trim()) {
const currentNeeds = getValues('needs') || [];
const newNeed: NeedOption = {
value: customNeed.toUpperCase().replace(/\s+/g, '_'),
label: customNeed.trim(),
};

setValue('needs', [...currentNeeds, newNeed]);
setCustomNeed('');
setShowCustomInput(false);
}
};

const handleCancelCustomNeed = () => {
setCustomNeed('');
setShowCustomInput(false);
};

const beforeSubmit: SubmitHandler<FormData> = ({
name,
netid,
@@ -56,7 +138,7 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
endDate,
}) => {
const email = netid ? `${netid}@cornell.edu` : undefined;
const accessibility = needs;
const accessibility = needs.map((option) => option.value.toString());
const nameParts = name.trim().split(/\s+/);
const firstName =
nameParts.length > 1 ? nameParts.slice(0, -1).join(' ') : nameParts[0];
@@ -74,7 +156,6 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
};

console.log('Form payload:', payload);

onSubmit(payload);
};

@@ -86,7 +167,14 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
const localUserType = localStorage.getItem('userType');
const isEditing = rider !== undefined;
const isStudentEditing = isEditing && localUserType === 'Rider';
const [needsOption, setNeedsOption] = useState('');

const needsOptions: NeedOption[] = [
...Object.values(Accessibility).map((value) => ({
value: value as Accessibility,
label: value,
})),
{ value: 'OTHER', label: 'Add Custom Need' },
];

return (
<form onSubmit={handleSubmit(beforeSubmit)} className={styles.form}>
@@ -106,6 +194,7 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
/>
{errors.name && <p className={styles.error}>Name cannot be empty</p>}
</div>

<div className={cn(styles.gridR1, styles.gridCSmall2)}>
<Label className={styles.label} htmlFor="netid">
NetID:{' '}
@@ -125,6 +214,7 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
<p className={styles.error}>NetId cannot be empty</p>
)}
</div>

<div className={cn(styles.gridR1, styles.gridCSmall3)}>
<Label className={styles.label} htmlFor="phoneNumber">
Phone Number:{' '}
@@ -144,26 +234,69 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
)}
</div>

{/* Replacing SelectComponent with native <select> */}
<div className={cn(styles.gridR2, styles.gridCBig1)}>
<Label className={styles.label} htmlFor="needs">
Needs:{' '}
</Label>
<select
id="needs"
{...register('needs', { required: true })}
multiple
className={styles.firstRow}
>
{Object.entries(Accessibility).map(([key, value]) => (
<option key={key} value={value}>
{value}
</option>
))}
</select>
{errors.needs && (
<p className={styles.error}>Please select at least one need</p>
)}
<div className={styles.needsContainer}>
<Controller
name="needs"
control={control}
rules={{ required: true }}
render={({ field: { onChange, value, ...field } }) => (
<Select<NeedOption, true>
{...field}
value={value}
isMulti
options={needsOptions}
className={styles.customSelect}
classNamePrefix="customSelectValueContainer"
placeholder="Select needs..."
styles={customStyles}
onChange={(newValue, actionMeta) =>
handleNeedsChange(newValue, actionMeta)
}
/>
)}
/>
{showCustomInput && (
<div className={styles.customNeedInput}>
<input
type="text"
value={customNeed}
onChange={(e) => setCustomNeed(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
handleAddCustomNeed();
}
}}
placeholder="Type custom need"
className={styles.customNeedField}
autoFocus
/>
<div className={styles.customNeedActions}>
<button
type="button"
onClick={handleAddCustomNeed}
className={styles.customNeedButton}
>
</button>
<button
type="button"
onClick={handleCancelCustomNeed}
className={styles.customNeedButton}
>
</button>
</div>
</div>
)}
{errors.needs && (
<p className={styles.error}>Please select at least one need</p>
)}
</div>
</div>

<div className={cn(styles.gridR2, styles.gridCBig2)}>
@@ -178,11 +311,13 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
})}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add validate: isAddress, under pattern

type="text"
aria-required="true"
style={{ height: '60px' }}
/>
{errors.address && (
<p className={styles.error}>Please enter an address</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to <p className={styles.errorMsg}>{errors.address.message}</p>

)}
</div>

<div className={cn(styles.gridR3, styles.gridCAll)}>
<p>Duration</p>
<div className={styles.lastRow}>
@@ -202,7 +337,9 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
<p className={styles.error}>Please enter a join date</p>
)}
</div>
<p className={styles.to}>to</p>
<div className={styles.to}>
<p></p>
</div>
<div>
<Label className={styles.label} htmlFor="endDate">
End Date:{' '}
@@ -231,6 +368,7 @@ const RiderModalInfo: React.FC<ModalFormProps> = ({
</div>
</div>
</div>

<div className={styles.buttonContainer}>
<Button
type="button"
162 changes: 154 additions & 8 deletions frontend/src/components/Modal/modal.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* Modal Styles */
.background {
position: fixed;
background-color: rgba(13, 13, 13, 0.6);
@@ -35,6 +36,7 @@
.closeBtn:focus {
outline: 3px solid black;
}

.topContainer {
display: flex;
justify-content: space-between;
@@ -59,25 +61,169 @@
display: inline-block;
}

@media screen and (max-height: 600px) {
.modal {
/* Form Styles */
.form {
display: flex;
flex-direction: column;
align-items: center;
max-width: 100%;
}

.inputContainer {
margin-bottom: 1.5rem;
}

/* Common input styles */
.inputContainer input[type='text'],
.inputContainer input[type='tel'],
.inputContainer input[type='date'],
.inputContainer select {
border: 1px solid #808080;
width: 100%;
border-radius: 6px;
height: 1.75rem;
font-size: 1rem;
}

/* Grid Layout */
.rideTime {
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: repeat(3, 1fr);
column-gap: 2rem;
row-gap: 2rem;
}

/* Grid Column Definitions */
.gridCSmall1 {
grid-column: 1 / 5;
}
.gridCSmall2 {
grid-column: 5 / 7;
}
.gridCSmall3 {
grid-column: 7 / 11;
}
.gridCBig1 {
grid-column: 1 / 5;
}
.gridCBig2 {
grid-column: 5 / 11;
}
.gridCAll {
grid-column: 1 / span 6;
}

/* Grid Row Definitions */
.gridR1 {
grid-row: 1;
}
.gridR2 {
grid-row: 2;
}
.gridR3 {
grid-row: 3;
}

/* Additional Styles */
.duration {
font-size: 0.9rem;
}

.to {
font-size: 0.9rem;
margin: 0 1rem;
}

.error {
color: #eb0023;
font-size: 0.8rem;
padding: 0.25rem;
}

.riderDate {
font-size: 1rem !important;
color: #808080;
}

.firstRow {
max-width: 100%;
}

.lastRow {
display: flex;
}

.buttonContainer {
display: flex;
justify-content: flex-end;
width: 100%;
}

.submit {
margin-left: 1.5rem;
}

.editIcon {
width: 4rem;
height: auto;
}

.editRiderButton {
margin: 0;
border: 0;
padding: 0;
background: none;
cursor: pointer;
}

.label {
font-size: smaller;
color: #000000;
}

/* React-Select Custom Styles */
:global(.select__control) {
min-height: 1.75rem !important;
border: 1px solid #808080 !important;
}

:global(.select__value-container) {
padding: 0 8px !important;
}

:global(.select__input) {
margin: 0 !important;
padding: 0 !important;
}

/* Media Queries */
@media screen and (max-width: 1092px) {
.form {
display: block;
max-width: 100%;
max-height: 100%;
overflow-y: scroll;
}
.page {
max-width: 100%;

.rideTime {
display: block;
}

.label {
font-weight: bold;
}

.lastRow {
display: block;
margin: 0;
}
}

@media screen and (max-width: 768px) {
@media screen and (max-height: 600px), screen and (max-width: 768px) {
.modal {
max-width: 100%;
max-height: 100%;
overflow-y: scroll;
}

.page {
max-width: 100%;
display: block;
271 changes: 186 additions & 85 deletions frontend/src/components/Modal/ridermodal.module.css
Original file line number Diff line number Diff line change
@@ -1,167 +1,268 @@
.form {
display: flex;
flex-direction: column;
align-items: center;
max-width: 100%;
width: 100%;
height: 100%;
}

.inputContainer {
margin-bottom: 1.5rem;
width: 100%;
}

.inputContainer input[type='text'],
.inputContainer input[type='tel'],
.inputContainer input[type='date'],
.inputContainer select {
border: 1px solid #808080;
width: 100%;
border-radius: 6px;
height: 1.75rem; /* Adjust height as needed */
font-size: 1rem; /* Adjust font size as needed */
/* Add any other relevant styling here */
.error {
color: #dc3545;
font-size: 0.8rem;
margin-top: 0.25rem;
}

.label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: #333;
}

/* Input styles */
.inputContainer input[type='text'],
.inputContainer input[type='tel'],
.inputContainer input[type='date'],
.inputContainer select {
border: 1px solid #808080;
.inputContainer input[type='date'] {
width: 100%;
border-radius: 6px;
height: 1.75rem; /* Adjust height as needed */
font-size: 1rem; /* Adjust font size as needed */
/* Add any other relevant styling here */
height: 42px;
padding: 0 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;
}

.inputContainer input[type='text']:focus,
.inputContainer input[type='tel']:focus,
.inputContainer input[type='date']:focus {
border-color: #000;
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.25);
outline: none;
}

/* Grid Layout */
.rideTime {
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-template-columns: repeat(10, 1fr);
grid-template-rows: repeat(3, 1fr);
column-gap: 2rem;
row-gap: 2rem;
column-gap: 2rem;
row-gap: 2rem;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(3, auto);
gap: 1.25rem;
}

/* Grid positioning classes */
.gridCSmall1 {
grid-column: 1 / 5;
grid-column: 1 / 5;
}

.gridCSmall2 {
grid-column: 5 / 7;
grid-column: 5 / 7;
grid-column: 5 / 8;
}

.gridCSmall3 {
grid-column: 7 / 11;
grid-column: 7 / 11;
grid-column: 8 / 13;
}

.gridCBig1 {
grid-column: 1 / 5;
grid-column: 1 / 5;
grid-column: 1 / 7;
}
.gridCBig2 {
grid-column: 5 / 11;
grid-column: 5 / 11;
grid-column: 7 / 13;
}
.gridCAll {
grid-column: 1 / span 6;
grid-column: 1 / span 7;
}

.duration {
font-size: 0.9rem;
.gridR1 {
grid-row: 1;
}
.gridR2 {
grid-row: 2;
}
.gridR3 {
grid-row: 3;
}

/* Duration section */
.lastRow {
display: flex;
gap: 1.25rem;
align-items: center;
}

.to {
font-size: 0.9rem;
grid-column: 3 / span 1;
margin-left: 70%;
margin-top: 5%;
font-size: 1.5rem;
height: 100%;
}

.end {
grid-column: 4 / span 2;
/* Select input styles */
.customSelect {
width: 100%;
}

.gridR1 {
grid-row: 1;
.customSelect :global(.customSelectValueContainer__control) {
max-height: 60px;
min-height: 60px;
overflow-y: auto;
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;
}
.gridR2 {
grid-row: 2;

.customSelect :global(.customSelectValueContainer__value-container) {
max-height: 55px;
overflow-y: auto;
padding: 0 8px;
}
.gridR3 {
grid-row: 3;

.customSelect :global(.customSelectValueContainer__input-container input) {
box-shadow: none !important;
}

.error {
color: #eb0023;
font-size: 0.8rem;
padding: 0.25rem;
.needsContainer {
display: flex;
flex-direction: column;
gap: 8px;
}

.riderDate {
font-size: 1rem !important;
color: #808080;
color: #808080;
.customNeedInput {
display: flex;
align-items: center;
gap: 8px;
margin-top: 8px;
}

.firstRow {
max-width: 100%;
max-width: 100%;
.customNeedField {
flex: 1;
height: 32px;
padding: 0 12px;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 0.875rem;
}

.lastRow {
.customNeedField:focus {
outline: none;
border-color: #000;
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
}

.customNeedActions {
display: flex;
gap: 4px;
}

.to {
margin: 0 1rem;
.customNeedButton {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border: 1px solid #ced4da;
border-radius: 4px;
background: white;
cursor: pointer;
transition: all 0.2s;
font-size: 16px;
}

/* Green confirm button */
.customNeedButton:first-child {
color: #28a745;
border-color: #28a745;
}

.customNeedButton:first-child:hover {
background: #28a745;
color: white;
}

/* Red cancel button */
.customNeedButton:last-child {
color: #dc3545;
border-color: #dc3545;
}

.customNeedButton:last-child:hover {
background: #dc3545;
color: white;
}

/* Button container */
.buttonContainer {
display: flex;
justify-content: flex-end;
width: 100%;
margin-top: 2rem;
gap: 1rem;
}

.buttonContainer button {
padding: 0.75rem 1.5rem;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
}

.submit {
margin-left: 1.5rem;
background-color: #000;
color: #fff;
border: none;
}

.editIcon {
width: 4rem;
height: auto;
.submit:hover {
background-color: #333;
}

.editRiderButton {
margin: 0;
border: 0;
padding: 0;
background: none;
cursor: pointer;
.cancel {
background-color: #fff;
color: #000;
border: 1px solid #000;
}

.label {
font-size: smaller;
color: #000000;
.cancel:hover {
background-color: #000;
color: #fff;
}

@media screen and (max-width: 1092px) {
/* Responsive styles */
@media (max-width: 1092px) {
.form {
display: block;
max-width: 100%;
}

.rideTime {
display: block;
display: flex;
flex-direction: column;
gap: 1.25rem;
}

.label {
font-weight: bold;
}

.lastRow {
display: block;
flex-direction: column;
gap: 1rem;
}

.buttonContainer {
flex-direction: column;
}

.buttonContainer button {
width: 100%;
}
}

/* Date input specific styles */
.riderDate {
width: 100%;
min-width: 200px;
}

/* First row inputs */
.firstRow {
width: 100%;
}
1 change: 0 additions & 1 deletion frontend/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@ export enum Accessibility {
KNEE_SCOOTER = 'Knee Scooter',
LOW_VISION = 'Low Vision/Blind',
SERVICE_ANIMALS = 'Service Animal',
OTHER = 'Other',
}

export type Availability = {
1 change: 0 additions & 1 deletion server/src/models/rider.ts
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@ export enum Accessibility {
KNEE_SCOOTER = 'Knee Scooter',
LOW_VISION = 'Low Vision/Blind',
SERVICE_ANIMALS = 'Service Animal',
OTHER = 'Other',
}

export enum Organization {

Unchanged files with check annotations Beta

const Toast = ({ message, toastType }: toastProps) => {
return typeof toastType === 'undefined' ||
toastType == ToastStatus.SUCCESS ? (

Check warning on line 13 in frontend/src/components/ConfirmationToast/ConfirmationToast.tsx

GitHub Actions / check

Expected '===' and instead saw '=='

Check warning on line 13 in frontend/src/components/ConfirmationToast/ConfirmationToast.tsx

GitHub Actions / check

Expected '===' and instead saw '=='
<div className={`${styles.toast} ${styles.successToast}`}>
<img alt="toast check" src={check} />
<p className={styles.toasttext}>{message}</p>
const netId = email.split('@')[0];
const fmtPhone = formatPhone(phoneNumber);
const formatAvail = (availability: {

Check warning on line 38 in frontend/src/components/EmployeeCards/EmployeeCards.tsx

GitHub Actions / check

'formatAvail' is assigned a value but never used

Check warning on line 38 in frontend/src/components/EmployeeCards/EmployeeCards.tsx

GitHub Actions / check

'formatAvail' is assigned a value but never used
[key: string]: { startTime: string; endTime: string };
}) => {
if (!availability) {
};
const isAdmin = isDriver !== undefined;
const isBoth = isDriver && isDriver == true;

Check warning on line 55 in frontend/src/components/EmployeeCards/EmployeeCards.tsx

GitHub Actions / check

Expected '===' and instead saw '=='

Check warning on line 55 in frontend/src/components/EmployeeCards/EmployeeCards.tsx

GitHub Actions / check

Expected '===' and instead saw '=='
const roles = (): string => {
if (isBoth) return 'Admin • Driver';
if (isAdmin) return 'Admin';
return 'Driver';
};
const userInfo = {

Check warning on line 62 in frontend/src/components/EmployeeCards/EmployeeCards.tsx

GitHub Actions / check

'userInfo' is assigned a value but never used

Check warning on line 62 in frontend/src/components/EmployeeCards/EmployeeCards.tsx

GitHub Actions / check

'userInfo' is assigned a value but never used
id,
firstName,
lastName,
import React, { useCallback, useEffect, useState } from 'react';
import cn from 'classnames';
import moment from 'moment';
import { useFormContext, UseFormRegister } from 'react-hook-form';

Check warning on line 4 in frontend/src/components/EmployeeModal/WorkingHours.tsx

GitHub Actions / check

'UseFormRegister' is defined but never used

Check warning on line 4 in frontend/src/components/EmployeeModal/WorkingHours.tsx

GitHub Actions / check

'UseFormRegister' is defined but never used
import styles from './employeemodal.module.css';
import { Input, Label } from '../FormElements/FormElements';
import { WeekProvider, useWeek } from './WeekContext';
import React, { useState, useRef } from 'react';
import { CSVLink } from 'react-csv';
import ScheduledTable from '../UserTables/ScheduledTable';
import { Driver } from '../../types/index';

Check warning on line 4 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'Driver' is defined but never used

Check warning on line 4 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'Driver' is defined but never used
import styles from './exportPreview.module.css';
import { useEmployees } from '../../context/EmployeesContext';
import ExportButton from '../ExportButton/ExportButton';

Check warning on line 7 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'ExportButton' is defined but never used

Check warning on line 7 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'ExportButton' is defined but never used
import { useDate } from '../../context/date';
import { format_date } from '../../util';
import axios from '../../util/axios';
const ExportPreview = () => {
const { drivers } = useEmployees();

Check warning on line 13 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'drivers' is assigned a value but never used

Check warning on line 13 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'drivers' is assigned a value but never used
const [downloadData, setDownloadData] = useState<string>('');
const { curDate } = useDate();
const csvLink = useRef<
const today = format_date(curDate);
const downloadCSV = () => {

Check warning on line 22 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'downloadCSV' is assigned a value but never used

Check warning on line 22 in frontend/src/components/ExportPreview/ExportPreview.tsx

GitHub Actions / check

'downloadCSV' is assigned a value but never used
axios
.get(`/api/rides/download?date=${today}`, {
responseType: 'text',
import React, { SelectHTMLAttributes } from 'react';

Check warning on line 1 in frontend/src/components/FormElements/FormElements.tsx

GitHub Actions / check

'SelectHTMLAttributes' is defined but never used

Check warning on line 1 in frontend/src/components/FormElements/FormElements.tsx

GitHub Actions / check

'SelectHTMLAttributes' is defined but never used
import cn from 'classnames';
import styles from './formelements.module.css';
import Select, { ActionMeta, Props as SelectProps } from 'react-select';