[questions][fix] update roles typeahead

pull/451/head
Jeff Sieu 3 years ago
parent 04e83f6732
commit bd3a546084

@ -1,13 +1,21 @@
import { ROLES } from '~/utils/questions/constants'; import { JobTitleLabels } from '~/components/shared/JobTitles';
import type { ExpandedTypeaheadProps } from './ExpandedTypeahead'; import type { ExpandedTypeaheadProps } from './ExpandedTypeahead';
import ExpandedTypeahead from './ExpandedTypeahead'; import ExpandedTypeahead from './ExpandedTypeahead';
import type { FilterChoices } from '../filter/FilterSection';
export type RoleTypeaheadProps = Omit< export type RoleTypeaheadProps = Omit<
ExpandedTypeaheadProps, ExpandedTypeaheadProps,
'label' | 'onQueryChange' | 'options' 'label' | 'onQueryChange' | 'options'
>; >;
const ROLES: FilterChoices = Object.entries(JobTitleLabels).map(
([slug, label]) => ({
id: slug,
label,
value: slug,
}),
);
export default function RoleTypeahead(props: RoleTypeaheadProps) { export default function RoleTypeahead(props: RoleTypeaheadProps) {
return ( return (
<ExpandedTypeahead <ExpandedTypeahead

@ -1,5 +1,6 @@
import Head from 'next/head'; import Head from 'next/head';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useMemo } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { ArrowSmallLeftIcon } from '@heroicons/react/24/outline'; import { ArrowSmallLeftIcon } from '@heroicons/react/24/outline';
import { Button, Collapsible, Select, TextArea } from '@tih/ui'; import { Button, Collapsible, Select, TextArea } from '@tih/ui';
@ -11,6 +12,7 @@ import FullScreenSpinner from '~/components/questions/FullScreenSpinner';
import { APP_TITLE } from '~/utils/questions/constants'; import { APP_TITLE } from '~/utils/questions/constants';
import createSlug from '~/utils/questions/createSlug'; import createSlug from '~/utils/questions/createSlug';
import relabelQuestionAggregates from '~/utils/questions/relabelQuestionAggregates';
import { useFormRegister } from '~/utils/questions/useFormRegister'; import { useFormRegister } from '~/utils/questions/useFormRegister';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
@ -52,6 +54,14 @@ export default function QuestionPage() {
{ questionId: questionId as string }, { questionId: questionId as string },
]); ]);
const relabeledAggregatedEncounters = useMemo(() => {
if (!aggregatedEncounters) {
return aggregatedEncounters;
}
return relabelQuestionAggregates(aggregatedEncounters);
}, [aggregatedEncounters]);
const utils = trpc.useContext(); const utils = trpc.useContext();
const { data: comments } = trpc.useQuery([ const { data: comments } = trpc.useQuery([
@ -138,11 +148,11 @@ export default function QuestionPage() {
<div className="flex max-w-7xl flex-1 flex-col gap-2"> <div className="flex max-w-7xl flex-1 flex-col gap-2">
<FullQuestionCard <FullQuestionCard
{...question} {...question}
companies={aggregatedEncounters?.companyCounts ?? {}} companies={relabeledAggregatedEncounters?.companyCounts ?? {}}
locations={aggregatedEncounters?.locationCounts ?? {}} locations={relabeledAggregatedEncounters?.locationCounts ?? {}}
questionId={question.id} questionId={question.id}
receivedCount={undefined} receivedCount={undefined}
roles={aggregatedEncounters?.roleCounts ?? {}} roles={relabeledAggregatedEncounters?.roleCounts ?? {}}
timestamp={question.seenAt.toLocaleDateString(undefined, { timestamp={question.seenAt.toLocaleDateString(undefined, {
month: 'short', month: 'short',
year: 'numeric', year: 'numeric',

@ -14,6 +14,7 @@ import QuestionSearchBar from '~/components/questions/QuestionSearchBar';
import CompanyTypeahead from '~/components/questions/typeahead/CompanyTypeahead'; import CompanyTypeahead from '~/components/questions/typeahead/CompanyTypeahead';
import LocationTypeahead from '~/components/questions/typeahead/LocationTypeahead'; import LocationTypeahead from '~/components/questions/typeahead/LocationTypeahead';
import RoleTypeahead from '~/components/questions/typeahead/RoleTypeahead'; import RoleTypeahead from '~/components/questions/typeahead/RoleTypeahead';
import { JobTitleLabels } from '~/components/shared/JobTitles';
import type { QuestionAge } from '~/utils/questions/constants'; import type { QuestionAge } from '~/utils/questions/constants';
import { SORT_TYPES } from '~/utils/questions/constants'; import { SORT_TYPES } from '~/utils/questions/constants';
@ -21,6 +22,7 @@ import { SORT_ORDERS } from '~/utils/questions/constants';
import { APP_TITLE } from '~/utils/questions/constants'; import { APP_TITLE } from '~/utils/questions/constants';
import { QUESTION_AGES, QUESTION_TYPES } from '~/utils/questions/constants'; import { QUESTION_AGES, QUESTION_TYPES } from '~/utils/questions/constants';
import createSlug from '~/utils/questions/createSlug'; import createSlug from '~/utils/questions/createSlug';
import relabelQuestionAggregates from '~/utils/questions/relabelQuestionAggregates';
import { import {
useSearchParam, useSearchParam,
useSearchParamSingle, useSearchParamSingle,
@ -275,7 +277,7 @@ export default function QuestionsBrowsePage() {
return selectedRoles.map((role) => ({ return selectedRoles.map((role) => ({
checked: true, checked: true,
id: role, id: role,
label: role, label: JobTitleLabels[role as keyof typeof JobTitleLabels],
value: role, value: role,
})); }));
}, [selectedRoles]); }, [selectedRoles]);
@ -369,7 +371,7 @@ export default function QuestionsBrowsePage() {
setSelectedRoles([...selectedRoles, option.value]); setSelectedRoles([...selectedRoles, option.value]);
} else { } else {
setSelectedRoles( setSelectedRoles(
selectedCompanies.filter((role) => role !== option.value), selectedRoles.filter((role) => role !== option.value),
); );
} }
}} }}
@ -470,36 +472,37 @@ export default function QuestionsBrowsePage() {
<div className="flex flex-col gap-2 pb-4"> <div className="flex flex-col gap-2 pb-4">
{(questionsQueryData?.pages ?? []).flatMap( {(questionsQueryData?.pages ?? []).flatMap(
({ data: questions }) => ({ data: questions }) =>
questions.map((question) => ( questions.map((question) => {
<QuestionOverviewCard const { companyCounts, locationCounts, roleCounts } =
key={question.id} relabelQuestionAggregates(
answerCount={question.numAnswers} question.aggregatedQuestionEncounters,
companies={ );
question.aggregatedQuestionEncounters.companyCounts
} return (
content={question.content} <QuestionOverviewCard
href={`/questions/${question.id}/${createSlug( key={question.id}
question.content, answerCount={question.numAnswers}
)}`} companies={companyCounts}
locations={ content={question.content}
question.aggregatedQuestionEncounters.locationCounts href={`/questions/${question.id}/${createSlug(
} question.content,
questionId={question.id} )}`}
receivedCount={question.receivedCount} locations={locationCounts}
roles={ questionId={question.id}
question.aggregatedQuestionEncounters.roleCounts receivedCount={question.receivedCount}
} roles={roleCounts}
timestamp={question.seenAt.toLocaleDateString( timestamp={question.seenAt.toLocaleDateString(
undefined, undefined,
{ {
month: 'short', month: 'short',
year: 'numeric', year: 'numeric',
}, },
)} )}
type={question.type} type={question.type}
upvoteCount={question.numVotes} upvoteCount={question.numVotes}
/> />
)), );
}),
)} )}
<Button <Button
disabled={!hasNextPage || isFetchingNextPage} disabled={!hasNextPage || isFetchingNextPage}

@ -15,6 +15,7 @@ import DeleteListDialog from '~/components/questions/DeleteListDialog';
import { Button } from '~/../../../packages/ui/dist'; import { Button } from '~/../../../packages/ui/dist';
import { APP_TITLE } from '~/utils/questions/constants'; import { APP_TITLE } from '~/utils/questions/constants';
import createSlug from '~/utils/questions/createSlug'; import createSlug from '~/utils/questions/createSlug';
import relabelQuestionAggregates from '~/utils/questions/relabelQuestionAggregates';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
export default function ListPage() { export default function ListPage() {
@ -172,37 +173,38 @@ export default function ListPage() {
{lists?.[selectedListIndex] && ( {lists?.[selectedListIndex] && (
<div className="flex flex-col gap-4 pb-4"> <div className="flex flex-col gap-4 pb-4">
{lists[selectedListIndex].questionEntries.map( {lists[selectedListIndex].questionEntries.map(
({ question, id: entryId }) => ( ({ question, id: entryId }) => {
<QuestionListCard const { companyCounts, locationCounts, roleCounts } =
key={question.id} relabelQuestionAggregates(
companies={ question.aggregatedQuestionEncounters,
question.aggregatedQuestionEncounters.companyCounts );
}
content={question.content} return (
href={`/questions/${question.id}/${createSlug( <QuestionListCard
question.content, key={question.id}
)}`} companies={companyCounts}
locations={ content={question.content}
question.aggregatedQuestionEncounters.locationCounts href={`/questions/${question.id}/${createSlug(
} question.content,
questionId={question.id} )}`}
receivedCount={question.receivedCount} locations={locationCounts}
roles={ questionId={question.id}
question.aggregatedQuestionEncounters.roleCounts receivedCount={question.receivedCount}
} roles={roleCounts}
timestamp={question.seenAt.toLocaleDateString( timestamp={question.seenAt.toLocaleDateString(
undefined, undefined,
{ {
month: 'short', month: 'short',
year: 'numeric', year: 'numeric',
}, },
)} )}
type={question.type} type={question.type}
onDelete={() => { onDelete={() => {
deleteQuestionEntry({ id: entryId }); deleteQuestionEntry({ id: entryId });
}} }}
/> />
), );
},
)} )}
{lists[selectedListIndex].questionEntries?.length === 0 && ( {lists[selectedListIndex].questionEntries?.length === 0 && (
<div className="flex w-full items-center justify-center gap-2 rounded-md border border-slate-300 bg-slate-200 p-4 text-slate-600"> <div className="flex w-full items-center justify-center gap-2 rounded-md border border-slate-300 bg-slate-200 p-4 text-slate-600">

@ -0,0 +1,26 @@
import { JobTitleLabels } from '~/components/shared/JobTitles';
import type { AggregatedQuestionEncounter } from '~/types/questions';
export default function relabelQuestionAggregates({
locationCounts,
companyCounts,
roleCounts,
latestSeenAt,
}: AggregatedQuestionEncounter) {
const newRoleCounts = Object.fromEntries(
Object.entries(roleCounts).map(([roleId, count]) => [
JobTitleLabels[roleId as keyof typeof JobTitleLabels],
count,
]),
);
const relabeledAggregate: AggregatedQuestionEncounter = {
companyCounts,
latestSeenAt,
locationCounts,
roleCounts: newRoleCounts,
};
return relabeledAggregate;
}
Loading…
Cancel
Save