[questions][ui] add comments & commments page

pull/346/head
wlren 3 years ago
parent 2680f7fec6
commit 685f5483f6

@ -0,0 +1,38 @@
import { format } from 'date-fns';
import VotingButtons from './VotingButtons';
export type CommentListItemProps = {
authorImageUrl: string;
authorName: string;
content: string;
createdAt: Date;
upvoteCount: number;
};
export default function CommentListItem({
authorImageUrl,
authorName,
content,
createdAt,
upvoteCount,
}: CommentListItemProps) {
return (
<div className="flex gap-4 border bg-white p-2 ">
<VotingButtons size="sm" upvoteCount={upvoteCount} />
<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>
</div>
);
}

@ -0,0 +1,38 @@
import { format } from 'date-fns';
import VotingButtons from '../VotingButtons';
export type FullAnswerCardProps = {
authorImageUrl: string;
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,39 +1,45 @@
import { useRouter } from 'next/router';
import { useForm } from 'react-hook-form';
import { ArrowSmallLeftIcon } from '@heroicons/react/24/outline';
import { Button, Collapsible, Select, TextArea } from '@tih/ui';
import { Button, Select, TextArea } from '@tih/ui';
import AnswerCard from '~/components/questions/card/AnswerCard';
import FullQuestionCard from '~/components/questions/card/FullQuestionCard';
import FullAnswerCard from '~/components/questions/card/FullAnswerCard';
import CommentListItem from '~/components/questions/CommentListItem';
import { SAMPLE_QUESTION } from '~/utils/questions/constants';
import {
SAMPLE_ANSWER,
SAMPLE_ANSWER_COMMENT,
SAMPLE_QUESTION,
} from '~/utils/questions/constants';
import { useFormRegister } from '~/utils/questions/useFormRegister';
export type AnswerData = {
answerContent: string;
export type AnswerCommentData = {
commentContent: string;
};
export default function QuestionPage() {
const router = useRouter();
const {
register: formRegister,
handleSubmit,
formState: { isDirty, isValid },
} = useForm<AnswerData>({ mode: 'onChange' });
const register = useFormRegister(formRegister);
const question = SAMPLE_QUESTION;
register: comRegister,
handleSubmit: handleCommentSubmit,
formState: { isDirty: isCommentDirty, isValid: isCommentValid },
} = useForm<AnswerCommentData>({ mode: 'onChange' });
const commentRegister = useFormRegister(comRegister);
const question = SAMPLE_QUESTION;
const comment = SAMPLE_ANSWER_COMMENT;
const handleBackNavigation = () => {
router.back();
};
const handleSubmitAnswer = (data: AnswerData) => {
const handleSubmitComment = (data: AnswerCommentData) => {
// eslint-disable-next-line no-console
console.log(data);
};
return (
<div className="flex">
<div className="flex w-full flex-1 items-stretch pb-4">
<div className="flex items-baseline gap-2 py-4 pl-4">
<Button
addonPosition="start"
@ -43,71 +49,66 @@ export default function QuestionPage() {
variant="secondary"
onClick={handleBackNavigation}></Button>
</div>
<div className="flex flex-col items-center overflow-y-auto py-4 px-5">
<div className="flex max-w-7xl flex-col gap-2">
<FullQuestionCard {...question} showVoteButtons={true} />
<div className="flex w-full justify-center overflow-y-auto py-4 px-5">
<div className="flex max-w-7xl flex-1 flex-col gap-2">
<FullAnswerCard {...SAMPLE_ANSWER} />
<div className="mx-2">
<Collapsible label="256 comments">
<div>Comment placeholder</div>
</Collapsible>
</div>
<form onSubmit={handleSubmit(handleSubmitAnswer)}>
<TextArea
{...register('answerContent', { minLength: 1, required: true })}
label="Contribute your answer"
required={true}
resize="vertical"
rows={5}
/>
<div className="mt-2 flex justify-end">
<Button
disabled={!isDirty || !isValid}
label="Contribute"
type="submit"
variant="primary"
<form
className="mb-2"
onSubmit={handleCommentSubmit(handleSubmitComment)}>
<TextArea
{...commentRegister('commentContent', {
minLength: 1,
required: true,
})}
label="Post a comment"
required={true}
resize="vertical"
rows={2}
/>
</div>
</form>
<div className="my-2 flex items-baseline justify-between">
<p>{question.answerCount} answers</p>
<div className="flex items-baseline gap-2">
<span aria-hidden={true} className="text-sm">
Sort by:
</span>
<Select
display="inline"
isLabelHidden={true}
label="Sort by"
options={[
{
label: 'Most recent',
value: 'most-recent',
},
{
label: 'Most upvotes',
value: 'most-upvotes',
},
]}
value="most-recent"
onChange={(value) => {
// eslint-disable-next-line no-console
console.log(value);
}}></Select>
</div>
</div>
<div className="my-3 flex justify-between">
<div className="flex items-baseline gap-2">
<span aria-hidden={true} className="text-sm">
Sort by:
</span>
<Select
display="inline"
isLabelHidden={true}
label="Sort by"
options={[
{
label: 'Most recent',
value: 'most-recent',
},
{
label: 'Most upvotes',
value: 'most-upvotes',
},
]}
value="most-recent"
onChange={(value) => {
// eslint-disable-next-line no-console
console.log(value);
}}></Select>
</div>
<Button
disabled={!isCommentDirty || !isCommentValid}
label="Post"
type="submit"
variant="primary"
/>
</div>
</form>
{Array.from({ length: question.answerCount }).map((_, index) => (
<AnswerCard
// eslint-disable-next-line react/no-array-index-key
key={index}
authorImageUrl="https://avatars.githubusercontent.com/u/66356390?v=4"
authorName="James Smith"
content="Hello"
createdAt={new Date()}
href={`${router.asPath}/answer/1/1`}
upvoteCount={10}
/>
))}
{Array.from({ length: question.commentCount }).map((_, index) => (
<CommentListItem
// eslint-disable-next-line react/no-array-index-key
key={index}
{...comment}
/>
))}
</div>
</div>
</div>
</div>

@ -5,24 +5,41 @@ import { Button, Collapsible, Select, TextArea } from '@tih/ui';
import AnswerCard from '~/components/questions/card/AnswerCard';
import FullQuestionCard from '~/components/questions/card/FullQuestionCard';
import CommentListItem from '~/components/questions/CommentListItem';
import { SAMPLE_QUESTION } from '~/utils/questions/constants';
import {
SAMPLE_ANSWER,
SAMPLE_QUESTION,
SAMPLE_QUESTION_COMMENT,
} from '~/utils/questions/constants';
import { useFormRegister } from '~/utils/questions/useFormRegister';
export type AnswerQuestionData = {
answerContent: string;
};
export type QuestionCommentData = {
commentContent: string;
};
export default function QuestionPage() {
const router = useRouter();
const {
register: formRegister,
register: ansRegister,
handleSubmit,
formState: { isDirty, isValid },
} = useForm<AnswerQuestionData>({ mode: 'onChange' });
const register = useFormRegister(formRegister);
const question = SAMPLE_QUESTION;
const answerRegister = useFormRegister(ansRegister);
const {
register: comRegister,
handleSubmit: handleCommentSubmit,
formState: { isDirty: isCommentDirty, isValid: isCommentValid },
} = useForm<QuestionCommentData>({ mode: 'onChange' });
const commentRegister = useFormRegister(comRegister);
const question = SAMPLE_QUESTION;
const comment = SAMPLE_QUESTION_COMMENT;
const handleBackNavigation = () => {
router.back();
};
@ -32,8 +49,13 @@ export default function QuestionPage() {
console.log(data);
};
const handleSubmitComment = (data: QuestionCommentData) => {
// eslint-disable-next-line no-console
console.log(data);
};
return (
<div className="flex">
<div className="flex w-full flex-1 items-stretch pb-4">
<div className="flex items-baseline gap-2 py-4 pl-4">
<Button
addonPosition="start"
@ -43,23 +65,107 @@ export default function QuestionPage() {
variant="secondary"
onClick={handleBackNavigation}></Button>
</div>
<div className="flex flex-col items-center overflow-y-auto py-4 px-5">
<div className="flex max-w-7xl flex-col gap-2">
<div className="flex w-full justify-center overflow-y-auto py-4 px-5">
<div className="flex max-w-7xl flex-1 flex-col gap-2">
<FullQuestionCard {...question} showVoteButtons={true} />
<div className="mx-2">
<Collapsible label="256 comments">
<div>Comment placeholder</div>
<Collapsible label={`${question.commentCount} comment(s)`}>
<form
className="mb-2"
onSubmit={handleCommentSubmit(handleSubmitComment)}>
<TextArea
{...commentRegister('commentContent', {
minLength: 1,
required: true,
})}
label="Post a comment"
required={true}
resize="vertical"
rows={2}
/>
<div className="my-3 flex justify-between">
<div className="flex items-baseline gap-2">
<span aria-hidden={true} className="text-sm">
Sort by:
</span>
<Select
display="inline"
isLabelHidden={true}
label="Sort by"
options={[
{
label: 'Most recent',
value: 'most-recent',
},
{
label: 'Most upvotes',
value: 'most-upvotes',
},
]}
value="most-recent"
onChange={(value) => {
// eslint-disable-next-line no-console
console.log(value);
}}></Select>
</div>
<Button
disabled={!isCommentDirty || !isCommentValid}
label="Post"
type="submit"
variant="primary"
/>
</div>
</form>
{Array.from({ length: question.commentCount }).map((_, index) => (
<CommentListItem
// eslint-disable-next-line react/no-array-index-key
key={index}
{...comment}
/>
))}
</Collapsible>
</div>
<form onSubmit={handleSubmit(handleSubmitAnswer)}>
<TextArea
{...register('answerContent', { minLength: 1, required: true })}
{...answerRegister('answerContent', {
minLength: 1,
required: true,
})}
label="Contribute your answer"
required={true}
resize="vertical"
rows={5}
/>
<div className="mt-2 flex justify-end">
<div className="mt-3 mb-1 flex justify-between">
<div className="flex items-baseline justify-start gap-2">
<p>{question.answerCount} answers</p>
<div className="flex items-baseline gap-2">
<span aria-hidden={true} className="text-sm">
Sort by:
</span>
<Select
display="inline"
isLabelHidden={true}
label="Sort by"
options={[
{
label: 'Most recent',
value: 'most-recent',
},
{
label: 'Most upvotes',
value: 'most-upvotes',
},
]}
value="most-recent"
onChange={(value) => {
// eslint-disable-next-line no-console
console.log(value);
}}></Select>
</div>
</div>
<Button
disabled={!isDirty || !isValid}
label="Contribute"
@ -68,44 +174,13 @@ export default function QuestionPage() {
/>
</div>
</form>
<div className="my-2 flex items-baseline justify-between">
<p>{question.answerCount} answers</p>
<div className="flex items-baseline gap-2">
<span aria-hidden={true} className="text-sm">
Sort by:
</span>
<Select
display="inline"
isLabelHidden={true}
label="Sort by"
options={[
{
label: 'Most recent',
value: 'most-recent',
},
{
label: 'Most upvotes',
value: 'most-upvotes',
},
]}
value="most-recent"
onChange={(value) => {
// eslint-disable-next-line no-console
console.log(value);
}}></Select>
</div>
</div>
{Array.from({ length: question.answerCount }).map((_, index) => (
<AnswerCard
// eslint-disable-next-line react/no-array-index-key
key={index}
authorImageUrl="https://avatars.githubusercontent.com/u/66356390?v=4"
authorName="James Smith"
content="Hello"
createdAt={new Date()}
{...SAMPLE_ANSWER}
href={`${router.asPath}/answer/1/1`}
upvoteCount={10}
/>
))}
</div>

Loading…
Cancel
Save