diff --git a/apps/portal/src/components/questions/card/FullQuestionCard.tsx b/apps/portal/src/components/questions/card/FullQuestionCard.tsx index 2e86d6a0..57245e1e 100644 --- a/apps/portal/src/components/questions/card/FullQuestionCard.tsx +++ b/apps/portal/src/components/questions/card/FullQuestionCard.tsx @@ -5,6 +5,7 @@ export type QuestionOverviewCardProps = Omit< QuestionCardProps & { showActionButton: false; showAnswerStatistics: false; + showDeleteButton: false; showReceivedStatistics: true; showVoteButtons: true; }, @@ -24,6 +25,7 @@ export default function FullQuestionCard(props: QuestionOverviewCardProps) { showAnswerStatistics={false} showReceivedStatistics={true} showVoteButtons={true} + truncateContent={false} /> ); } diff --git a/apps/portal/src/components/questions/card/QuestionCard.tsx b/apps/portal/src/components/questions/card/QuestionCard.tsx index 63ba7a5a..55c87957 100644 --- a/apps/portal/src/components/questions/card/QuestionCard.tsx +++ b/apps/portal/src/components/questions/card/QuestionCard.tsx @@ -1,6 +1,8 @@ +import clsx from 'clsx'; import { useState } from 'react'; import { ChatBubbleBottomCenterTextIcon, + CheckIcon, EyeIcon, TrashIcon, } from '@heroicons/react/24/outline'; @@ -80,6 +82,7 @@ export type QuestionCardProps = ActionButtonProps & role: string; showHover?: boolean; timestamp: string; + truncateContent?: boolean; type: QuestionsQuestionType; }; @@ -104,6 +107,7 @@ export default function QuestionCard({ onReceivedSubmit, showDeleteButton, onDelete, + truncateContent = true, }: QuestionCardProps) { const [showReceivedForm, setShowReceivedForm] = useState(false); const { handleDownvote, handleUpvote, vote } = useQuestionVote(questionId); @@ -147,7 +151,9 @@ export default function QuestionCard({ )}
-

{content}

+

+ {content} +

{(showAnswerStatistics || showReceivedStatistics) && (
@@ -161,17 +167,26 @@ export default function QuestionCard({ /> )} {showReceivedStatistics && ( -
)} diff --git a/apps/portal/src/components/questions/card/QuestionListCard.tsx b/apps/portal/src/components/questions/card/QuestionListCard.tsx index f10431a6..2921a117 100644 --- a/apps/portal/src/components/questions/card/QuestionListCard.tsx +++ b/apps/portal/src/components/questions/card/QuestionListCard.tsx @@ -6,15 +6,15 @@ import QuestionCard from './QuestionCard'; export type QuestionListCardProps = Omit< QuestionCardProps & { showActionButton: false; + showAnswerStatistics: false; showDeleteButton: true; - showUserStatistics: false; showVoteButtons: false; }, | 'actionButtonLabel' | 'onActionButtonClick' | 'showActionButton' + | 'showAnswerStatistics' | 'showDeleteButton' - | 'showUserStatistics' | 'showVoteButtons' >; @@ -23,9 +23,9 @@ function QuestionListCardWithoutHref(props: QuestionListCardProps) { ); diff --git a/apps/portal/src/components/questions/forms/ContributeQuestionForm.tsx b/apps/portal/src/components/questions/forms/ContributeQuestionForm.tsx index fa8c4409..d1523579 100644 --- a/apps/portal/src/components/questions/forms/ContributeQuestionForm.tsx +++ b/apps/portal/src/components/questions/forms/ContributeQuestionForm.tsx @@ -8,7 +8,6 @@ import { HorizontalDivider, Select, TextArea, - Typeahead, } from '@tih/ui'; import { LOCATIONS, QUESTION_TYPES, ROLES } from '~/utils/questions/constants'; diff --git a/apps/portal/src/components/questions/forms/CreateQuestionEncounterForm.tsx b/apps/portal/src/components/questions/forms/CreateQuestionEncounterForm.tsx index b753ccbe..40dc05be 100644 --- a/apps/portal/src/components/questions/forms/CreateQuestionEncounterForm.tsx +++ b/apps/portal/src/components/questions/forms/CreateQuestionEncounterForm.tsx @@ -8,6 +8,7 @@ import MonthYearPicker from '~/components/shared/MonthYearPicker'; import LocationTypeahead from '../typeahead/LocationTypeahead'; import RoleTypeahead from '../typeahead/RoleTypeahead'; +import CompanyTypeahead from '../typeahead/CompanyTypeahead'; export type CreateQuestionEncounterData = { company: string; @@ -25,6 +26,8 @@ export default function CreateQuestionEncounterForm({ onCancel, onSubmit, }: CreateQuestionEncounterFormProps) { + const [step, setStep] = useState(0); + const [selectedCompany, setSelectedCompany] = useState(null); const [selectedLocation, setSelectedLocation] = useState(null); const [selectedRole, setSelectedRole] = useState(null); @@ -43,67 +46,104 @@ export default function CreateQuestionEncounterForm({ }} />
-

I saw this question at

-
- { - setSelectedCompany(company); +

I saw this question at

+ {step === 0 && ( +
+ { + setSelectedCompany(company); + setStep(step + 1); + }} + isLabelHidden={true} + onSelect={({ value: company }) => { + setSelectedCompany(company); + }} + /> +
+ )} + {step === 1 && ( +
+ { + setSelectedLocation(location); + setStep(step + 1); + }} + isLabelHidden={true} + placeholder="Other location" + // eslint-disable-next-line @typescript-eslint/no-empty-function + onQueryChange={() => {}} + onSelect={({ value: location }) => { + setSelectedLocation(location); + }} + /> +
+ )} + {step === 2 && ( +
+ { + setSelectedRole(role); + setStep(step + 1); + }} + placeholder="Other role" + // eslint-disable-next-line @typescript-eslint/no-empty-function + onQueryChange={() => {}} + onSelect={({ value: role }) => { + setSelectedRole(role); + }} + /> +
+ )} + {step === 3 && ( + { + setSelectedDate( + startOfMonth(new Date(value.year, value.month - 1)), + ); }} /> -
-
- {}} - onSelect={({ value: location }) => { - setSelectedLocation(location); + )} + {step < 3 && ( +
-

for

-
- {}} - onSelect={({ value: role }) => { - setSelectedRole(role); + )} + {step === 3 && ( +
-

for

- { - setSelectedDate( - startOfMonth(new Date(value.year, value.month - 1)), - ); - }} - /> -
); diff --git a/apps/portal/src/components/questions/typeahead/CompanyTypeahead.tsx b/apps/portal/src/components/questions/typeahead/CompanyTypeahead.tsx new file mode 100644 index 00000000..c61d1e6c --- /dev/null +++ b/apps/portal/src/components/questions/typeahead/CompanyTypeahead.tsx @@ -0,0 +1,41 @@ +import { useMemo, useState } from 'react'; + +import { trpc } from '~/utils/trpc'; + +import type { ExpandedTypeaheadProps } from './ExpandedTypeahead'; +import ExpandedTypeahead from './ExpandedTypeahead'; + +export type CompanyTypeaheadProps = Omit< + ExpandedTypeaheadProps, + 'label' | 'onQueryChange' | 'options' +>; + +export default function CompanyTypeahead(props: CompanyTypeaheadProps) { + const [query, setQuery] = useState(''); + + const { data: companies } = trpc.useQuery([ + 'companies.list', + { + name: query, + }, + ]); + + const companyOptions = useMemo(() => { + return ( + companies?.map(({ id, name }) => ({ + id, + label: name, + value: id, + })) ?? [] + ); + }, [companies]); + + return ( + + ); +} diff --git a/apps/portal/src/components/questions/typeahead/ExpandedTypeahead.tsx b/apps/portal/src/components/questions/typeahead/ExpandedTypeahead.tsx new file mode 100644 index 00000000..05d34195 --- /dev/null +++ b/apps/portal/src/components/questions/typeahead/ExpandedTypeahead.tsx @@ -0,0 +1,37 @@ +import type { ComponentProps } from 'react'; +import { Button, Typeahead } from '@tih/ui'; + +type RequireAllOrNone = T | { [K in keyof T]?: never }; + +type TypeaheadProps = ComponentProps; +type TypeaheadOption = TypeaheadProps['options'][number]; + +export type ExpandedTypeaheadProps = RequireAllOrNone<{ + onSuggestionClick: (option: TypeaheadOption) => void; + suggestedCount: number; +}> & + TypeaheadProps; + +export default function ExpandedTypeahead({ + suggestedCount = 0, + onSuggestionClick, + ...typeaheadProps +}: ExpandedTypeaheadProps) { + const suggestions = typeaheadProps.options.slice(0, suggestedCount); + + return ( +
+ {suggestions.map((suggestion) => ( +
+ ); +} diff --git a/apps/portal/src/components/questions/typeahead/LocationTypeahead.tsx b/apps/portal/src/components/questions/typeahead/LocationTypeahead.tsx index dd2a5b2d..0f13ca5e 100644 --- a/apps/portal/src/components/questions/typeahead/LocationTypeahead.tsx +++ b/apps/portal/src/components/questions/typeahead/LocationTypeahead.tsx @@ -1,12 +1,19 @@ -import type { ComponentProps } from 'react'; -import { Typeahead } from '@tih/ui'; - import { LOCATIONS } from '~/utils/questions/constants'; -type TypeaheadProps = ComponentProps; +import type { ExpandedTypeaheadProps } from './ExpandedTypeahead'; +import ExpandedTypeahead from './ExpandedTypeahead'; -export type LocationTypeaheadProps = Omit; +export type LocationTypeaheadProps = Omit< + ExpandedTypeaheadProps, + 'label' | 'options' +>; export default function LocationTypeahead(props: LocationTypeaheadProps) { - return ; + return ( + + ); } diff --git a/apps/portal/src/components/questions/typeahead/RoleTypeahead.tsx b/apps/portal/src/components/questions/typeahead/RoleTypeahead.tsx index cb260125..da899ac7 100644 --- a/apps/portal/src/components/questions/typeahead/RoleTypeahead.tsx +++ b/apps/portal/src/components/questions/typeahead/RoleTypeahead.tsx @@ -1,12 +1,19 @@ -import type { ComponentProps } from 'react'; -import { Typeahead } from '@tih/ui'; - import { ROLES } from '~/utils/questions/constants'; -type TypeaheadProps = ComponentProps; +import type { ExpandedTypeaheadProps } from './ExpandedTypeahead'; +import ExpandedTypeahead from './ExpandedTypeahead'; -export type RoleTypeaheadProps = Omit; +export type RoleTypeaheadProps = Omit< + ExpandedTypeaheadProps, + 'label' | 'options' +>; export default function RoleTypeahead(props: RoleTypeaheadProps) { - return ; + return ( + + ); }