import clsx from 'clsx'; import { useMemo, useState } from 'react'; import { ChatBubbleBottomCenterTextIcon, CheckIcon, EyeIcon, TrashIcon, } from '@heroicons/react/24/outline'; import type { QuestionsQuestionType } from '@prisma/client'; import { Button } from '@tih/ui'; import { useProtectedCallback } from '~/utils/questions/useProtectedCallback'; import { useQuestionVote } from '~/utils/questions/useVote'; import AddToListDropdown from '../../AddToListDropdown'; import type { CreateQuestionEncounterData } from '../../forms/CreateQuestionEncounterForm'; import CreateQuestionEncounterForm from '../../forms/CreateQuestionEncounterForm'; import QuestionAggregateBadge from '../../QuestionAggregateBadge'; import QuestionTypeBadge from '../../QuestionTypeBadge'; import VotingButtons from '../../VotingButtons'; import type { CountryInfo } from '~/types/questions'; type UpvoteProps = | { showVoteButtons: true; upvoteCount: number; } | { showVoteButtons?: false; upvoteCount?: never; }; type DeleteProps = | { onDelete: () => void; showDeleteButton: true; } | { onDelete?: never; showDeleteButton?: false; }; type AnswerStatisticsProps = | { answerCount: number; showAnswerStatistics: true; } | { answerCount?: never; showAnswerStatistics?: false; }; type AggregateStatisticsProps = | { companies: Record; countries: Record; roles: Record; showAggregateStatistics: true; } | { companies?: never; countries?: never; roles?: never; showAggregateStatistics?: false; }; type ActionButtonProps = | { actionButtonLabel: string; onActionButtonClick: () => void; showActionButton: true; } | { actionButtonLabel?: never; onActionButtonClick?: never; showActionButton?: false; }; type ReceivedStatisticsProps = | { receivedCount: number; showReceivedStatistics: true; } | { receivedCount?: never; showReceivedStatistics?: false; }; type CreateEncounterProps = | { createEncounterButtonText: string; onReceivedSubmit: (data: CreateQuestionEncounterData) => Promise; showCreateEncounterButton: true; } | { createEncounterButtonText?: never; onReceivedSubmit?: never; showCreateEncounterButton?: false; }; type AddToListProps = | { showAddToList: true; } | { showAddToList?: false; }; export type BaseQuestionCardProps = ActionButtonProps & AddToListProps & AggregateStatisticsProps & AnswerStatisticsProps & CreateEncounterProps & DeleteProps & ReceivedStatisticsProps & UpvoteProps & { content: string; hideCard?: boolean; questionId: string; showHover?: boolean; timestamp: string | null; truncateContent?: boolean; type: QuestionsQuestionType; }; export default function BaseQuestionCard({ questionId, companies, answerCount, content, receivedCount, type, showVoteButtons, showAggregateStatistics, showAnswerStatistics, showReceivedStatistics, showCreateEncounterButton, createEncounterButtonText, showActionButton, actionButtonLabel, onActionButtonClick, upvoteCount, hideCard, timestamp, roles, countries, showHover, onReceivedSubmit, showDeleteButton, showAddToList, onDelete, truncateContent = true, }: BaseQuestionCardProps) { const [showReceivedForm, setShowReceivedForm] = useState(false); const { handleDownvote, handleUpvote, vote } = useQuestionVote(questionId); const locations = useMemo(() => { if (countries === undefined) { return undefined; } const countryCount: Record = {}; // Decompose countries for (const country of Object.keys(countries)) { const { total } = countries[country]; countryCount[country] = total; } return countryCount; }, [countries]); const handleCreateEncounterClick = useProtectedCallback(() => { setShowReceivedForm(true); }); const cardContent = ( <> {showVoteButtons && ( )}
{showAggregateStatistics && ( <> )} {timestamp !== null &&

{timestamp}

} {showAddToList && (
)}
{showActionButton && (

{content}

{!showReceivedForm && (showAnswerStatistics || showReceivedStatistics || showCreateEncounterButton) && (
{showAnswerStatistics && (
)} {showReceivedForm && ( { setShowReceivedForm(false); }} onSubmit={async (data) => { await onReceivedSubmit?.(data); }} /> )}
); return (
{cardContent} {showDeleteButton && (
)}
); }