[questions][ui] update answer card

pull/355/head
Jeff Sieu 3 years ago
parent 8af58fe87a
commit b9ff8157af

@ -25,8 +25,8 @@ export default function QuestionSearchBar<
onFilterOptionsToggle, onFilterOptionsToggle,
}: QuestionSearchBarProps<SortOptions>) { }: QuestionSearchBarProps<SortOptions>) {
return ( return (
<div className="flex items-center gap-2"> <div className="flex items-center gap-4">
<div className="flex-1 pt-1"> <div className="flex-1">
<TextInput <TextInput
isLabelHidden={true} isLabelHidden={true}
label="Search by content" label="Search by content"
@ -35,17 +35,19 @@ export default function QuestionSearchBar<
startAddOnType="icon" startAddOnType="icon"
/> />
</div> </div>
<span aria-hidden={true} className="pl-3 pr-1 pt-1 text-sm"> <div className="flex items-center gap-2">
Sort by: <span aria-hidden={true} className="align-middle text-sm font-medium">
</span> Sort by:
<Select </span>
display="inline" <Select
isLabelHidden={true} display="inline"
label="Sort by" isLabelHidden={true}
options={sortOptions} label="Sort by"
value={sortValue} options={sortOptions}
onChange={onSortChange} value={sortValue}
/> onChange={onSortChange}
/>
</div>
<div className="lg:hidden"> <div className="lg:hidden">
<Button <Button
addonPosition="start" addonPosition="start"

@ -0,0 +1,17 @@
import type { QuestionsQuestionType } from '@prisma/client';
import { Badge } from '@tih/ui';
import { QUESTION_TYPES } from '~/utils/questions/constants';
export type QuestionTypeBadgeProps = {
type: QuestionsQuestionType;
};
export default function QuestionTypeBadge({ type }: QuestionTypeBadgeProps) {
return (
<Badge
label={QUESTION_TYPES.find(({ value }) => value === type)!.label}
variant="info"
/>
);
}

@ -1,48 +1,52 @@
import { format } from 'date-fns'; import { format } from 'date-fns';
import { ChatBubbleBottomCenterTextIcon } from '@heroicons/react/24/outline';
import withHref from '~/utils/questions/withHref'; import type { VotingButtonsProps } from '../VotingButtons';
import VotingButtons from '../VotingButtons'; import VotingButtons from '../VotingButtons';
export type AnswerCardProps = { export type AnswerCardProps = {
authorImageUrl: string; authorImageUrl: string;
authorName: string; authorName: string;
commentCount: number; commentCount?: number;
content: string; content: string;
createdAt: Date; createdAt: Date;
upvoteCount: number; upvoteCount: number;
votingButtonsSize: VotingButtonsProps['size'];
}; };
function AnswerCardWithoutHref({ export default function AnswerCard({
authorName, authorName,
authorImageUrl, authorImageUrl,
upvoteCount, upvoteCount,
content, content,
createdAt, createdAt,
commentCount, commentCount,
votingButtonsSize,
}: AnswerCardProps) { }: AnswerCardProps) {
return ( return (
<div className="flex gap-4 rounded-md border bg-white p-2 hover:bg-slate-50"> <article className="flex gap-4 rounded-md border bg-white p-2">
<VotingButtons size="sm" upvoteCount={upvoteCount} /> <VotingButtons size={votingButtonsSize} upvoteCount={upvoteCount} />
<div className="mt-1 flex flex-col gap-1"> <div className="flex flex-col gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<img <img
alt={`${authorName} profile picture`} alt={`${authorName} profile picture`}
className="h-8 w-8 rounded-full" className="h-8 w-8 rounded-full"
src={authorImageUrl}></img> src={authorImageUrl}></img>
<h1 className="font-bold">{authorName}</h1> <h1 className="font-bold">{authorName}</h1>
<p className="pt-1 text-xs font-extralight"> <p className="text-xs font-extralight">
Posted on: {format(createdAt, 'Pp')} Posted on: {format(createdAt, 'Pp')}
</p> </p>
</div> </div>
<p className="pl-1 pt-1">{content}</p> <p>{content}</p>
<p className="py-1 pl-3 text-sm font-light underline underline-offset-4"> {commentCount !== undefined && (
{commentCount} comment(s) <div className="flex items-center gap-2 text-slate-500">
</p> <ChatBubbleBottomCenterTextIcon className="h-6 w-6" />
<p className="text-sm font-medium">
{commentCount} {commentCount === 1 ? 'comment' : 'comments'}
</p>
</div>
)}
</div> </div>
</div> </article>
); );
} }
const AnswerCard = withHref(AnswerCardWithoutHref);
export default AnswerCard;

@ -1,38 +1,11 @@
import { format } from 'date-fns'; import type { AnswerCardProps } from './AnswerCard';
import AnswerCard from './AnswerCard';
import VotingButtons from '../VotingButtons'; export type FullAnswerCardProps = Omit<
AnswerCardProps,
'commentCount' | 'votingButtonsSize'
>;
export type FullAnswerCardProps = { export default function FullAnswerCard(props: FullAnswerCardProps) {
authorImageUrl: string; return <AnswerCard {...props} votingButtonsSize="md" />;
authorName: string;
content: string;
createdAt: Date;
upvoteCount: number;
};
export default function FullAnswerCard({
authorImageUrl,
authorName,
content,
createdAt,
upvoteCount,
}: FullAnswerCardProps) {
return (
<article className="flex gap-4 rounded-md border border-slate-300 bg-white p-4">
<VotingButtons upvoteCount={upvoteCount}></VotingButtons>
<div className="mt-1 flex flex-col gap-1">
<div className="flex items-center gap-2">
<img
alt={`${authorName} profile picture`}
className="h-8 w-8 rounded-full"
src={authorImageUrl}></img>
<h1 className="font-bold">{authorName}</h1>
<p className="pt-1 text-xs font-extralight">
Posted on: {format(createdAt, 'Pp')}
</p>
</div>
<p className="pl-1 pt-1">{content}</p>
</div>
</article>
);
} }

@ -1,5 +1,7 @@
import type { QuestionsQuestionType } from '@prisma/client';
import { Badge } from '@tih/ui'; import { Badge } from '@tih/ui';
import QuestionTypeBadge from '../QuestionTypeBadge';
import VotingButtons from '../VotingButtons'; import VotingButtons from '../VotingButtons';
type UpvoteProps = type UpvoteProps =
@ -19,7 +21,7 @@ export type FullQuestionCardProps = UpvoteProps & {
receivedCount: number; receivedCount: number;
role: string; role: string;
timestamp: string; timestamp: string;
type: string; type: QuestionsQuestionType;
}; };
export default function FullQuestionCard({ export default function FullQuestionCard({
@ -32,18 +34,18 @@ export default function FullQuestionCard({
location, location,
type, type,
}: FullQuestionCardProps) { }: FullQuestionCardProps) {
const altText = company + ' logo'; const altText = `${company} logo`;
return ( return (
<article className="flex gap-4 rounded-md border border-slate-300 bg-white p-4"> <article className="flex gap-4 rounded-md border border-slate-300 bg-white p-4">
{showVoteButtons && <VotingButtons upvoteCount={upvoteCount} />} {showVoteButtons && <VotingButtons upvoteCount={upvoteCount} />}
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<img alt={altText} src="https://logo.clearbit.com/google.com"></img> <img alt={altText} src="https://logo.clearbit.com/google.com"></img>
<h2 className="ml-2 text-xl">{company}</h2>
</div> </div>
<div className="flex items-baseline justify-between"> <div className="flex items-baseline justify-between">
<div className="flex items-center gap-2 text-slate-500"> <div className="flex items-center gap-2 text-slate-500">
<Badge label={type} variant="primary" /> <Badge label={company} variant="primary" />
<QuestionTypeBadge type={type} />
<p className="text-xs"> <p className="text-xs">
{timestamp} · {location} · {role} {timestamp} · {location} · {role}
</p> </p>

@ -0,0 +1,15 @@
import withHref from '~/utils/questions/withHref';
import type { AnswerCardProps } from './AnswerCard';
import AnswerCard from './AnswerCard';
export type QuestionAnswerCardProps = Required<
Omit<AnswerCardProps, 'votingButtonsSize'>
>;
function QuestionAnswerCardWithoutHref(props: QuestionAnswerCardProps) {
return <AnswerCard {...props} votingButtonsSize="sm" />;
}
const QuestionAnswerCard = withHref(QuestionAnswerCardWithoutHref);
export default QuestionAnswerCard;

@ -1,9 +1,8 @@
import { import { ChatBubbleBottomCenterTextIcon } from '@heroicons/react/24/outline';
ChatBubbleBottomCenterTextIcon, import type { QuestionsQuestionType } from '@prisma/client';
// EyeIcon,
} from '@heroicons/react/24/outline';
import { Badge, Button } from '@tih/ui'; import { Badge, Button } from '@tih/ui';
import QuestionTypeBadge from '../QuestionTypeBadge';
import VotingButtons from '../VotingButtons'; import VotingButtons from '../VotingButtons';
type UpvoteProps = type UpvoteProps =
@ -48,7 +47,7 @@ export type QuestionCardProps = ActionButtonProps &
receivedCount: number; receivedCount: number;
role: string; role: string;
timestamp: string; timestamp: string;
type: string; type: QuestionsQuestionType;
}; };
export default function QuestionCard({ export default function QuestionCard({
@ -73,8 +72,8 @@ export default function QuestionCard({
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<div className="flex items-baseline justify-between"> <div className="flex items-baseline justify-between">
<div className="flex items-baseline gap-2 text-slate-500"> <div className="flex items-baseline gap-2 text-slate-500">
<h2 className="ml-1 text-lg">{company}</h2> <Badge label={company} variant="primary" />
<Badge label={type} variant="primary" /> <QuestionTypeBadge type={type} />
<p className="text-xs"> <p className="text-xs">
{timestamp} · {location} · {role} {timestamp} · {location} · {role}
</p> </p>

@ -3,8 +3,8 @@ 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';
import AnswerCard from '~/components/questions/card/AnswerCard';
import FullQuestionCard from '~/components/questions/card/FullQuestionCard'; import FullQuestionCard from '~/components/questions/card/FullQuestionCard';
import QuestionAnswerCard from '~/components/questions/card/QuestionAnswerCard';
import CommentListItem from '~/components/questions/CommentListItem'; import CommentListItem from '~/components/questions/CommentListItem';
import FullScreenSpinner from '~/components/questions/FullScreenSpinner'; import FullScreenSpinner from '~/components/questions/FullScreenSpinner';
@ -233,7 +233,7 @@ export default function QuestionPage() {
</div> </div>
</form> </form>
{(answers ?? []).map((answer) => ( {(answers ?? []).map((answer) => (
<AnswerCard <QuestionAnswerCard
key={answer.id} key={answer.id}
authorImageUrl={answer.userImage} authorImageUrl={answer.userImage}
authorName={answer.user} authorName={answer.user}

@ -302,7 +302,7 @@ export default function QuestionsHomePage() {
upvoteCount={question.numVotes} upvoteCount={question.numVotes}
/> />
))} ))}
{(questions ?? []).length === 0 && ( {questions?.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">
<NoSymbolIcon className="h-6 w-6" /> <NoSymbolIcon className="h-6 w-6" />
<p>Nothing found. Try changing your search filters.</p> <p>Nothing found. Try changing your search filters.</p>

Loading…
Cancel
Save