Merge branch 'questions/backend-integration-2' of github.com:yangshun/tech-interview-handbook into questions/backend-integration-2

* 'questions/backend-integration-2' of github.com:yangshun/tech-interview-handbook:
  [question][fix] fix search filters
  [questions][ui] remove ui-patch components
pull/355/head
wlren 3 years ago
commit 8af58fe87a

@ -3,7 +3,14 @@ import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form'; import { Controller, useForm } from 'react-hook-form';
import { CalendarDaysIcon, UserIcon } from '@heroicons/react/24/outline'; import { CalendarDaysIcon, UserIcon } from '@heroicons/react/24/outline';
import type { QuestionsQuestionType } from '@prisma/client'; import type { QuestionsQuestionType } from '@prisma/client';
import { Button, Collapsible, Select, TextArea, TextInput } from '@tih/ui'; import {
Button,
CheckboxInput,
Collapsible,
Select,
TextArea,
TextInput,
} from '@tih/ui';
import { QUESTION_TYPES } from '~/utils/questions/constants'; import { QUESTION_TYPES } from '~/utils/questions/constants';
import { import {
@ -11,7 +18,6 @@ import {
useSelectRegister, useSelectRegister,
} from '~/utils/questions/useFormRegister'; } from '~/utils/questions/useFormRegister';
import Checkbox from './ui-patch/Checkbox';
import CompaniesTypeahead from '../shared/CompaniesTypeahead'; import CompaniesTypeahead from '../shared/CompaniesTypeahead';
import type { Month } from '../shared/MonthYearPicker'; import type { Month } from '../shared/MonthYearPicker';
import MonthYearPicker from '../shared/MonthYearPicker'; import MonthYearPicker from '../shared/MonthYearPicker';
@ -148,10 +154,11 @@ export default function ContributeQuestionForm({
</div> */} </div> */}
<div className="bg-primary-50 fixed bottom-0 left-0 w-full px-4 py-3 sm:flex sm:flex-row sm:justify-between sm:px-6"> <div className="bg-primary-50 fixed bottom-0 left-0 w-full px-4 py-3 sm:flex sm:flex-row sm:justify-between sm:px-6">
<div className="mb-1 flex"> <div className="mb-1 flex">
<Checkbox <CheckboxInput
checked={canSubmit}
label="I have checked that my question is new" label="I have checked that my question is new"
onChange={handleCheckSimilarQuestions}></Checkbox> value={canSubmit}
onChange={handleCheckSimilarQuestions}
/>
</div> </div>
<div className=" flex gap-x-2"> <div className=" flex gap-x-2">
<button <button

@ -1,8 +1,5 @@
import { MagnifyingGlassIcon } from '@heroicons/react/24/outline'; import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import { Collapsible, TextInput } from '@tih/ui'; import { CheckboxInput, Collapsible, RadioList, TextInput } from '@tih/ui';
import Checkbox from '../ui-patch/Checkbox';
import RadioGroup from '../ui-patch/RadioGroup';
export type FilterOption<V extends string = string> = { export type FilterOption<V extends string = string> = {
checked: boolean; checked: boolean;
@ -66,17 +63,29 @@ export default function FilterSection<
/> />
)} )}
{isSingleSelect ? ( {isSingleSelect ? (
<RadioGroup <div className="px-1.5">
radioData={options} <RadioList
onChange={(value) => { label=""
onOptionChange(value); value={options.find((option) => option.checked)?.value}
}}></RadioGroup> onChange={(value) => {
onOptionChange(value);
}}>
{options.map((option) => (
<RadioList.Item
key={option.value}
label={option.label}
value={option.value}
/>
))}
</RadioList>
</div>
) : ( ) : (
<div className="mx-1"> <div className="px-1.5">
{options.map((option) => ( {options.map((option) => (
<Checkbox <CheckboxInput
key={option.value} key={option.value}
{...option} label={option.label}
value={option.checked}
onChange={(checked) => { onChange={(checked) => {
onOptionChange(option.value, checked); onOptionChange(option.value, checked);
}} }}

@ -1,25 +0,0 @@
import { useId } from 'react';
export type CheckboxProps = {
checked: boolean;
label: string;
onChange: (checked: boolean) => void;
};
export default function Checkbox({ label, checked, onChange }: CheckboxProps) {
const id = useId();
return (
<div className="flex items-center">
<input
checked={checked}
className="text-primary-600 focus:ring-primary-500 h-4 w-4 rounded border-gray-300"
id={id}
type="checkbox"
onChange={(event) => onChange(event.target.checked)}
/>
<label className="ml-3 min-w-0 flex-1 text-gray-700" htmlFor={id}>
{label}
</label>
</div>
);
}

@ -1,36 +0,0 @@
export type RadioProps = {
onChange: (value: string) => void;
radioData: Array<RadioData>;
};
export type RadioData = {
checked: boolean;
label: string;
value: string;
};
export default function RadioGroup({ radioData, onChange }: RadioProps) {
return (
<div className="mx-1 space-y-1">
{radioData.map((radio) => (
<div key={radio.value} className="flex items-center">
<input
checked={radio.checked}
className="text-primary-600 focus:ring-primary-500 h-4 w-4 border-gray-300"
type="radio"
value={radio.value}
onChange={(event) => {
const target = event.target as HTMLInputElement;
onChange(target.value);
}}
/>
<label
className="ml-3 min-w-0 flex-1 text-gray-700"
htmlFor={radio.value}>
{radio.label}
</label>
</div>
))}
</div>
);
}

@ -1,5 +1,5 @@
import { subMonths, subYears } from 'date-fns'; import { subMonths, subYears } from 'date-fns';
import { useRouter } from 'next/router'; import Router, { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import { NoSymbolIcon } from '@heroicons/react/24/outline'; import { NoSymbolIcon } from '@heroicons/react/24/outline';
import type { QuestionsQuestionType } from '@prisma/client'; import type { QuestionsQuestionType } from '@prisma/client';
@ -120,8 +120,9 @@ export default function QuestionsHomePage() {
})); }));
}, [selectedLocations]); }, [selectedLocations]);
const handleLandingQuery = (data: LandingQueryData) => { const handleLandingQuery = async (data: LandingQueryData) => {
const { company, location, questionType } = data; const { company, location, questionType } = data;
setSelectedCompanies([company]); setSelectedCompanies([company]);
setSelectedLocations([location]); setSelectedLocations([location]);
setSelectedQuestionTypes([questionType as QuestionsQuestionType]); setSelectedQuestionTypes([questionType as QuestionsQuestionType]);
@ -142,11 +143,15 @@ export default function QuestionsHomePage() {
areLocationsInitialized, areLocationsInitialized,
]); ]);
const { pathname } = router;
useEffect(() => { useEffect(() => {
if (areFiltersInitialized && !loaded) { if (areFiltersInitialized) {
// Update query params // Router.replace used instead of router.replace to avoid
router.replace({ // the page reloading itself since the router.replace
pathname: router.pathname, // callback changes on every page load
Router.replace({
pathname,
query: { query: {
companies: selectedCompanies, companies: selectedCompanies,
locations: selectedLocations, locations: selectedLocations,
@ -169,7 +174,7 @@ export default function QuestionsHomePage() {
areFiltersInitialized, areFiltersInitialized,
hasLanded, hasLanded,
loaded, loaded,
router, pathname,
selectedCompanies, selectedCompanies,
selectedLocations, selectedLocations,
selectedQuestionAge, selectedQuestionAge,
@ -180,7 +185,7 @@ export default function QuestionsHomePage() {
return null; return null;
} }
const filterSidebar = ( const filterSidebar = (
<div className="divide-y divide-slate-200 px-4"> <div className="mt-2 divide-y divide-slate-200 px-4">
<FilterSection <FilterSection
label="Company" label="Company"
options={companyFilterOptions} options={companyFilterOptions}

@ -37,15 +37,8 @@ export const useSearchFilter = <Value extends string = string>(
(newFilters: Array<Value>) => { (newFilters: Array<Value>) => {
setFilters(newFilters); setFilters(newFilters);
localStorage.setItem(name, JSON.stringify(newFilters)); localStorage.setItem(name, JSON.stringify(newFilters));
router.replace({
pathname: router.pathname,
query: {
...router.query,
[name]: newFilters,
},
});
}, },
[name, router], [name],
); );
return [filters, setFiltersCallback, isInitialized] as const; return [filters, setFiltersCallback, isInitialized] as const;
@ -66,9 +59,7 @@ export const useSearchFilterSingle = <Value extends string = string>(
return [ return [
filters[0], filters[0],
(value: Value) => { (value: Value) => setFilters([value]),
setFilters([value]);
},
isInitialized, isInitialized,
] as const; ] as const;
}; };

Loading…
Cancel
Save