From 18a9f62b12ea57fecd5a9d0153734d5cbd821dd4 Mon Sep 17 00:00:00 2001 From: wlren Date: Mon, 10 Oct 2022 18:32:45 +0800 Subject: [PATCH] [questions][ui] broken upvote --- .../components/questions/VotingButtons.tsx | 48 +++++++++++-------- .../components/questions/card/AnswerCard.tsx | 23 ++++++--- .../questions/card/FullQuestionCard.tsx | 32 +++++++++---- .../questions/card/QuestionCard.tsx | 16 ++++++- .../[questionId]/[questionSlug]/index.tsx | 5 ++ apps/portal/src/pages/questions/index.tsx | 10 ++-- apps/portal/src/utils/questions/useVote.ts | 19 ++++++++ 7 files changed, 111 insertions(+), 42 deletions(-) create mode 100644 apps/portal/src/utils/questions/useVote.ts diff --git a/apps/portal/src/components/questions/VotingButtons.tsx b/apps/portal/src/components/questions/VotingButtons.tsx index 51b96b34..fd730b63 100644 --- a/apps/portal/src/components/questions/VotingButtons.tsx +++ b/apps/portal/src/components/questions/VotingButtons.tsx @@ -3,30 +3,30 @@ import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline'; import type { ButtonSize } from '@tih/ui'; import { Button } from '@tih/ui'; -export type VotingButtonsProps = { +import { VoteState } from '~/utils/questions/useVote'; + +export type VotingButtonsCallbackProps = { + onDownvote: () => void; + onUpvote: () => void; + voteState: VoteState; +}; + +export type VotingButtonsProps = VotingButtonsCallbackProps & { size?: ButtonSize; upvoteCount: number; }; export default function VotingButtons({ + voteState, + onDownvote, + onUpvote, upvoteCount, size = 'md', }: VotingButtonsProps) { - const handleUpvote = (event: React.MouseEvent) => { - event.preventDefault(); - - event.stopPropagation(); - console.log('upvote'); - }; - - const handleDownVote = (event: React.MouseEvent) => { - event.preventDefault(); - - event.stopPropagation(); - - console.log('downvote'); - }; - + const upvoteButtonVarient = + voteState === VoteState.UPVOTE ? 'secondary' : 'tertiary'; + const downvoteButtonVarient = + voteState === VoteState.DOWNVOTE ? 'secondary' : 'tertiary'; return (
); diff --git a/apps/portal/src/components/questions/card/AnswerCard.tsx b/apps/portal/src/components/questions/card/AnswerCard.tsx index cf0b4676..eab32d95 100644 --- a/apps/portal/src/components/questions/card/AnswerCard.tsx +++ b/apps/portal/src/components/questions/card/AnswerCard.tsx @@ -1,13 +1,13 @@ import { format } from 'date-fns'; -import { - ChatBubbleBottomCenterTextIcon, - ChatBubbleLeftRightIcon, -} from '@heroicons/react/24/outline'; +import { ChatBubbleLeftRightIcon } from '@heroicons/react/24/outline'; -import type { VotingButtonsProps } from '../VotingButtons'; +import type { + VotingButtonsCallbackProps, + VotingButtonsProps, +} from '../VotingButtons'; import VotingButtons from '../VotingButtons'; -export type AnswerCardProps = { +export type AnswerCardProps = VotingButtonsCallbackProps & { authorImageUrl: string; authorName: string; commentCount?: number; @@ -18,6 +18,9 @@ export type AnswerCardProps = { }; export default function AnswerCard({ + voteState, + onDownvote, + onUpvote, authorName, authorImageUrl, upvoteCount, @@ -28,7 +31,13 @@ export default function AnswerCard({ }: AnswerCardProps) { return (
- +
- {showVoteButtons && } + {showVoteButtons && ( + + )}
{altText} diff --git a/apps/portal/src/components/questions/card/QuestionCard.tsx b/apps/portal/src/components/questions/card/QuestionCard.tsx index 36d17d69..99abe5dd 100644 --- a/apps/portal/src/components/questions/card/QuestionCard.tsx +++ b/apps/portal/src/components/questions/card/QuestionCard.tsx @@ -3,6 +3,7 @@ import type { QuestionsQuestionType } from '@prisma/client'; import { Badge, Button } from '@tih/ui'; import QuestionTypeBadge from '../QuestionTypeBadge'; +import type { VotingButtonsCallbackProps } from '../VotingButtons'; import VotingButtons from '../VotingButtons'; type UpvoteProps = @@ -39,7 +40,8 @@ type ActionButtonProps = export type QuestionCardProps = ActionButtonProps & StatisticsProps & - UpvoteProps & { + UpvoteProps & + VotingButtonsCallbackProps & { company: string; content: string; href?: string; @@ -51,6 +53,9 @@ export type QuestionCardProps = ActionButtonProps & }; export default function QuestionCard({ + voteState, + onDownvote, + onUpvote, company, answerCount, content, @@ -68,7 +73,14 @@ export default function QuestionCard({ }: QuestionCardProps) { return (
- {showVoteButtons && } + {showVoteButtons && ( + + )}
diff --git a/apps/portal/src/pages/questions/[questionId]/[questionSlug]/index.tsx b/apps/portal/src/pages/questions/[questionId]/[questionSlug]/index.tsx index 8e73f2f4..19479ae1 100644 --- a/apps/portal/src/pages/questions/[questionId]/[questionSlug]/index.tsx +++ b/apps/portal/src/pages/questions/[questionId]/[questionSlug]/index.tsx @@ -10,6 +10,7 @@ import FullScreenSpinner from '~/components/questions/FullScreenSpinner'; import createSlug from '~/utils/questions/createSlug'; import { useFormRegister } from '~/utils/questions/useFormRegister'; +import { useVote } from '~/utils/questions/useVote'; import { trpc } from '~/utils/trpc'; export type AnswerQuestionData = { @@ -39,6 +40,7 @@ export default function QuestionPage() { const commentRegister = useFormRegister(comRegister); const { questionId } = router.query; + const [handleUpvote, handleDownvote, voteState] = useVote(); const { data: question } = trpc.useQuery([ 'questions.questions.getQuestionById', @@ -112,6 +114,9 @@ export default function QuestionPage() {
handleDownvote(questionId as string)} + onUpvote={() => handleUpvote(questionId as string)} {...question} receivedCount={0} // TODO: Change to actual value showVoteButtons={true} diff --git a/apps/portal/src/pages/questions/index.tsx b/apps/portal/src/pages/questions/index.tsx index ac53be59..33eb7aa3 100644 --- a/apps/portal/src/pages/questions/index.tsx +++ b/apps/portal/src/pages/questions/index.tsx @@ -24,6 +24,7 @@ import { useSearchFilter, useSearchFilterSingle, } from '~/utils/questions/useSearchFilter'; +import { useVote } from '~/utils/questions/useVote'; import { trpc } from '~/utils/trpc'; export default function QuestionsHomePage() { @@ -144,7 +145,7 @@ export default function QuestionsHomePage() { ]); const { pathname } = router; - + const [handleDownvote, handleUpvote, voteState] = useVote(); useEffect(() => { if (areFiltersInitialized) { // Router.replace used instead of router.replace to avoid @@ -292,14 +293,17 @@ export default function QuestionsHomePage() { question.content, )}`} location={question.location} - receivedCount={0} // TODO: Implement received count + receivedCount={0} role={question.role} timestamp={question.seenAt.toLocaleDateString(undefined, { month: 'short', year: 'numeric', })} - type={question.type} + type={question.type} // TODO: Implement received count upvoteCount={question.numVotes} + voteState={voteState} + onDownvote={() => handleDownvote(question.id)} + onUpvote={() => handleUpvote(question.id)} /> ))} {questions?.length === 0 && ( diff --git a/apps/portal/src/utils/questions/useVote.ts b/apps/portal/src/utils/questions/useVote.ts new file mode 100644 index 00000000..6b821c61 --- /dev/null +++ b/apps/portal/src/utils/questions/useVote.ts @@ -0,0 +1,19 @@ +import { useState } from 'react'; + +export const enum VoteState { + NO_VOTE, + UPVOTE, + DOWNVOTE, +} + +export const useVote = () => { + const [voteState, setVoteState] = useState(VoteState.NO_VOTE); + + const handleUpvote = (id: string, voteState) => { + // + }; + + const handleDownvote = (id: string) => {}; + + return [handleUpvote, handleDownvote, voteState] as const; +};