[questions][feat] add similar questions

pull/468/head
Jeff Sieu 3 years ago
parent 5adc9d4a15
commit 04464f927f

@ -1,6 +1,6 @@
import { Fragment, useState } from 'react';
import { Dialog, Transition } from '@headlessui/react';
import { HorizontalDivider } from '@tih/ui';
import { HorizontalDivider, useToast } from '@tih/ui';
import DiscardDraftDialog from './DiscardDraftDialog';
import type { ContributeQuestionFormProps } from './forms/ContributeQuestionForm';
@ -21,6 +21,8 @@ export default function ContributeQuestionDialog({
}: ContributeQuestionDialogProps) {
const [showDiscardDialog, setShowDiscardDialog] = useState(false);
const { showToast } = useToast();
const handleDraftDiscard = () => {
setShowDiscardDialog(false);
onCancel();
@ -75,6 +77,14 @@ export default function ContributeQuestionDialog({
<div className="mt-2">
<ContributeQuestionForm
onDiscard={() => setShowDiscardDialog(true)}
onSimilarQuestionFound={() => {
onCancel();
showToast({
title:
'Your response has been recorded. Draft discarded.',
variant: 'success',
});
}}
onSubmit={(data) => {
onSubmit(data);
onCancel();

@ -88,10 +88,12 @@ type ReceivedStatisticsProps =
type CreateEncounterProps =
| {
createEncounterButtonText: string;
onReceivedSubmit: (data: CreateQuestionEncounterData) => void;
showCreateEncounterButton: true;
}
| {
createEncounterButtonText?: never;
onReceivedSubmit?: never;
showCreateEncounterButton?: false;
};
@ -132,6 +134,7 @@ export default function BaseQuestionCard({
showAnswerStatistics,
showReceivedStatistics,
showCreateEncounterButton,
createEncounterButtonText,
showActionButton,
actionButtonLabel,
onActionButtonClick,
@ -238,7 +241,7 @@ export default function BaseQuestionCard({
<Button
addonPosition="start"
icon={CheckIcon}
label="I received this too"
label={createEncounterButtonText}
size="sm"
variant="tertiary"
onClick={(event) => {

@ -3,10 +3,10 @@ import BaseQuestionCard from './BaseQuestionCard';
export type SimilarQuestionCardProps = Omit<
BaseQuestionCardProps & {
showActionButton: true;
showAggregateStatistics: false;
showActionButton: false;
showAggregateStatistics: true;
showAnswerStatistics: false;
showCreateEncounterButton: false;
showCreateEncounterButton: true;
showDeleteButton: false;
showHover: true;
showReceivedStatistics: false;
@ -22,26 +22,20 @@ export type SimilarQuestionCardProps = Omit<
| 'showHover'
| 'showReceivedStatistics'
| 'showVoteButtons'
> & {
onSimilarQuestionClick: () => void;
};
>;
export default function SimilarQuestionCard(props: SimilarQuestionCardProps) {
const { onSimilarQuestionClick, ...rest } = props;
return (
<BaseQuestionCard
actionButtonLabel="Yes, this is my question"
showActionButton={true}
showAggregateStatistics={false}
showActionButton={false}
showAggregateStatistics={true}
showAnswerStatistics={false}
showCreateEncounterButton={false}
showCreateEncounterButton={true}
showDeleteButton={false}
showHover={true}
showReceivedStatistics={false}
showVoteButtons={false}
onActionButtonClick={onSimilarQuestionClick}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{...(rest as any)}
{...props}
/>
);
}

@ -8,6 +8,7 @@ import { CheckboxInput } from '@tih/ui';
import { Button, HorizontalDivider, Select, TextArea } from '@tih/ui';
import { QUESTION_TYPES } from '~/utils/questions/constants';
import relabelQuestionAggregates from '~/utils/questions/relabelQuestionAggregates';
import {
useFormRegister,
useSelectRegister,
@ -35,12 +36,14 @@ export type ContributeQuestionData = {
export type ContributeQuestionFormProps = {
onDiscard: () => void;
onSimilarQuestionFound: () => void;
onSubmit: (data: ContributeQuestionData) => void;
};
export default function ContributeQuestionForm({
onSubmit,
onDiscard,
onSimilarQuestionFound,
onSubmit,
}: ContributeQuestionFormProps) {
const {
control,
@ -61,6 +64,21 @@ export default function ContributeQuestionForm({
keepPreviousData: true,
},
);
const utils = trpc.useContext();
const { mutateAsync: addEncounterAsync } = trpc.useMutation(
'questions.questions.encounters.user.create',
{
onSuccess: () => {
utils.invalidateQueries(
'questions.questions.encounters.getAggregatedEncounters',
);
utils.invalidateQueries('questions.questions.getQuestionById');
},
},
);
const questionContent = watch('questionContent');
const register = useFormRegister(formRegister);
const selectRegister = useSelectRegister(formRegister);
@ -192,11 +210,19 @@ export default function ContributeQuestionForm({
}}
/>
<div className="flex flex-col gap-y-2">
{similarQuestions?.map((question) => (
{similarQuestions?.map((question) => {
const { companyCounts, countryCounts, roleCounts } =
relabelQuestionAggregates(question.aggregatedQuestionEncounters);
return (
<SimilarQuestionCard
key={question.id}
companies={companyCounts}
content={question.content}
countries={countryCounts}
createEncounterButtonText="Yes, this is my question"
questionId={question.id}
roles={roleCounts}
timestamp={
question.seenAt.toLocaleDateString(undefined, {
month: 'short',
@ -204,12 +230,22 @@ export default function ContributeQuestionForm({
}) ?? null
}
type={question.type}
onSimilarQuestionClick={() => {
// eslint-disable-next-line no-console
console.log('hi!');
onReceivedSubmit={async (data) => {
await addEncounterAsync({
cityId: data.cityId,
companyId: data.company,
countryId: data.countryId,
questionId: question.id,
role: data.role,
seenAt: data.seenAt,
stateId: data.stateId,
});
onSimilarQuestionFound();
}}
/>
))}
);
})}
{similarQuestions?.length === 0 && (
<p className="font-semibold text-slate-900">
No similar questions found.
@ -217,7 +253,7 @@ export default function ContributeQuestionForm({
)}
</div>
<div
className="bg-primary-50 flex w-full justify-end gap-y-2 py-3 shadow-[0_0_0_100vmax_theme(colors.primary.50)]"
className="bg-primary-50 flex w-full justify-between gap-y-2 py-3 shadow-[0_0_0_100vmax_theme(colors.primary.50)]"
style={{
// Hack to make the background bleed outside the container
clipPath: 'inset(0 -100vmax)',

@ -193,6 +193,7 @@ export default function QuestionPage() {
{...question}
companies={relabeledAggregatedEncounters?.companyCounts ?? {}}
countries={relabeledAggregatedEncounters?.countryCounts ?? {}}
createEncounterButtonText="I received this too"
questionId={question.id}
receivedCount={undefined}
roles={relabeledAggregatedEncounters?.roleCounts ?? {}}

@ -1,8 +1,6 @@
import { z } from 'zod';
import { TRPCError } from '@trpc/server';
import { JobTitleLabels } from '~/components/shared/JobTitles';
import { createProtectedRouter } from '../context';
import { SortOrder } from '~/types/questions.d';
@ -14,7 +12,7 @@ export const questionsQuestionEncounterUserRouter = createProtectedRouter()
companyId: z.string(),
countryId: z.string(),
questionId: z.string(),
role: z.nativeEnum(JobTitleLabels),
role: z.string(),
seenAt: z.date(),
stateId: z.string().nullish(),
}),

Loading…
Cancel
Save