[questions][ui] improve search filter robustness

pull/411/head
Jeff Sieu 3 years ago
parent 9c1e179347
commit 8032f77a70

@ -1,7 +1,6 @@
import { startOfMonth } from 'date-fns';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { CalendarDaysIcon, UserIcon } from '@heroicons/react/24/outline';
import type { QuestionsQuestionType } from '@prisma/client';
import {
Button,
@ -9,10 +8,10 @@ import {
HorizontalDivider,
Select,
TextArea,
TextInput,
Typeahead,
} from '@tih/ui';
import { QUESTION_TYPES } from '~/utils/questions/constants';
import { LOCATIONS, QUESTION_TYPES, ROLES } from '~/utils/questions/constants';
import {
useFormRegister,
useSelectRegister,
@ -83,12 +82,25 @@ export default function ContributeQuestionForm({
</h2>
<div className="flex flex-col flex-wrap items-stretch gap-2 sm:flex-row sm:items-end">
<div className="flex-1 sm:min-w-[150px] sm:max-w-[300px]">
<TextInput
label="Location"
required={true}
startAddOn={CalendarDaysIcon}
startAddOnType="icon"
{...register('location')}
<Controller
control={control}
name="location"
render={({ field }) => (
<Typeahead
label="Location"
options={LOCATIONS}
required={true}
// eslint-disable-next-line @typescript-eslint/no-empty-function
onQueryChange={() => {}}
onSelect={(option) => {
field.onChange(option.value);
}}
{...field}
value={LOCATIONS.find(
(location) => location.value === field.value,
)}
/>
)}
/>
</div>
<div className="flex-1 sm:min-w-[150px] sm:max-w-[300px]">
@ -97,10 +109,12 @@ export default function ContributeQuestionForm({
name="date"
render={({ field }) => (
<MonthYearPicker
monthRequired={true}
value={{
month: ((field.value.getMonth() as number) + 1) as Month,
year: field.value.getFullYear(),
}}
yearRequired={true}
onChange={({ month, year }) =>
field.onChange(startOfMonth(new Date(year, month - 1)))
}
@ -124,12 +138,23 @@ export default function ContributeQuestionForm({
/>
</div>
<div className="flex-1 sm:min-w-[150px] sm:max-w-[200px]">
<TextInput
label="Role"
required={true}
startAddOn={UserIcon}
startAddOnType="icon"
{...register('role')}
<Controller
control={control}
name="role"
render={({ field }) => (
<Typeahead
label="Role"
options={ROLES}
required={true}
// eslint-disable-next-line @typescript-eslint/no-empty-function
onQueryChange={() => {}}
onSelect={(option) => {
field.onChange(option.value);
}}
{...field}
value={ROLES.find((role) => role.value === field.value)}
/>
)}
/>
</div>
</div>

@ -38,7 +38,12 @@ export default function QuestionsHomePage() {
areQuestionTypesInitialized,
] = useSearchFilter<QuestionsQuestionType>('questionTypes', {
queryParamToValue: (param) => {
return param.toUpperCase() as QuestionsQuestionType;
const uppercaseParam = param.toUpperCase();
return (
QUESTION_TYPES.find(
(questionType) => questionType.value.toUpperCase() === uppercaseParam,
)?.value ?? null
);
},
});
const [
@ -47,6 +52,14 @@ export default function QuestionsHomePage() {
isQuestionAgeInitialized,
] = useSearchFilterSingle<QuestionAge>('questionAge', {
defaultValue: 'all',
queryParamToValue: (param) => {
const uppercaseParam = param.toUpperCase();
return (
QUESTION_AGES.find(
(questionAge) => questionAge.value.toUpperCase() === uppercaseParam,
)?.value ?? null
);
},
});
const [selectedRoles, setSelectedRoles, areRolesInitialized] =

@ -80,6 +80,8 @@ export const questionsQuestionRouter = createProtectedRouter()
},
},
});
console.log(input);
return questionsData.map((data) => {
const votes: number = data.votes.reduce(
(previousValue: number, currentValue) => {

@ -76,7 +76,7 @@ export const LOCATIONS: FilterChoices = [
value: 'california',
},
{
id: 'california',
id: 'Hong Kong',
label: 'Hong Kong',
value: 'Hong Kong',
},

@ -5,7 +5,7 @@ export const useSearchFilter = <Value extends string = string>(
name: string,
opts: {
defaultValues?: Array<Value>;
queryParamToValue?: (param: string) => Value;
queryParamToValue?: (param: string) => Value | null;
} = {},
) => {
const { defaultValues, queryParamToValue = (param) => param } = opts;
@ -20,7 +20,11 @@ export const useSearchFilter = <Value extends string = string>(
const query = router.query[name];
if (query) {
const queryValues = Array.isArray(query) ? query : [query];
setFilters(queryValues.map(queryParamToValue) as Array<Value>);
setFilters(
queryValues
.map(queryParamToValue)
.filter((value) => value !== null) as Array<Value>,
);
} else {
// Try to load from local storage
const localStorageValue = localStorage.getItem(name);
@ -48,7 +52,7 @@ export const useSearchFilterSingle = <Value extends string = string>(
name: string,
opts: {
defaultValue?: Value;
queryParamToValue?: (param: string) => Value;
queryParamToValue?: (param: string) => Value | null;
} = {},
) => {
const { defaultValue, queryParamToValue } = opts;

Loading…
Cancel
Save