[questions][ui] broken upvote

pull/355/head
wlren 3 years ago
parent 59a29ef3f1
commit 18a9f62b12

@ -3,30 +3,30 @@ import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
import type { ButtonSize } from '@tih/ui'; import type { ButtonSize } from '@tih/ui';
import { Button } 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; size?: ButtonSize;
upvoteCount: number; upvoteCount: number;
}; };
export default function VotingButtons({ export default function VotingButtons({
voteState,
onDownvote,
onUpvote,
upvoteCount, upvoteCount,
size = 'md', size = 'md',
}: VotingButtonsProps) { }: VotingButtonsProps) {
const handleUpvote = (event: React.MouseEvent) => { const upvoteButtonVarient =
event.preventDefault(); voteState === VoteState.UPVOTE ? 'secondary' : 'tertiary';
const downvoteButtonVarient =
event.stopPropagation(); voteState === VoteState.DOWNVOTE ? 'secondary' : 'tertiary';
console.log('upvote');
};
const handleDownVote = (event: React.MouseEvent) => {
event.preventDefault();
event.stopPropagation();
console.log('downvote');
};
return ( return (
<div className="flex flex-col items-center"> <div className="flex flex-col items-center">
<Button <Button
@ -34,8 +34,12 @@ export default function VotingButtons({
isLabelHidden={true} isLabelHidden={true}
label="Upvote" label="Upvote"
size={size} size={size}
variant="tertiary" variant={upvoteButtonVarient}
onClick={handleUpvote} onClick={(event) => {
event.preventDefault();
event.stopPropagation();
onUpvote();
}}
/> />
<p>{upvoteCount}</p> <p>{upvoteCount}</p>
<Button <Button
@ -43,8 +47,12 @@ export default function VotingButtons({
isLabelHidden={true} isLabelHidden={true}
label="Downvote" label="Downvote"
size={size} size={size}
variant="tertiary" variant={downvoteButtonVarient}
onClick={handleDownVote} onClick={(event) => {
event.preventDefault();
event.stopPropagation();
onDownvote();
}}
/> />
</div> </div>
); );

@ -1,13 +1,13 @@
import { format } from 'date-fns'; import { format } from 'date-fns';
import { import { ChatBubbleLeftRightIcon } from '@heroicons/react/24/outline';
ChatBubbleBottomCenterTextIcon,
ChatBubbleLeftRightIcon,
} from '@heroicons/react/24/outline';
import type { VotingButtonsProps } from '../VotingButtons'; import type {
VotingButtonsCallbackProps,
VotingButtonsProps,
} from '../VotingButtons';
import VotingButtons from '../VotingButtons'; import VotingButtons from '../VotingButtons';
export type AnswerCardProps = { export type AnswerCardProps = VotingButtonsCallbackProps & {
authorImageUrl: string; authorImageUrl: string;
authorName: string; authorName: string;
commentCount?: number; commentCount?: number;
@ -18,6 +18,9 @@ export type AnswerCardProps = {
}; };
export default function AnswerCard({ export default function AnswerCard({
voteState,
onDownvote,
onUpvote,
authorName, authorName,
authorImageUrl, authorImageUrl,
upvoteCount, upvoteCount,
@ -28,7 +31,13 @@ export default function AnswerCard({
}: AnswerCardProps) { }: AnswerCardProps) {
return ( return (
<article className="flex gap-4 rounded-md border bg-white p-2"> <article className="flex gap-4 rounded-md border bg-white p-2">
<VotingButtons size={votingButtonsSize} upvoteCount={upvoteCount} /> <VotingButtons
size={votingButtonsSize}
upvoteCount={upvoteCount}
voteState={voteState}
onDownvote={onDownvote}
onUpvote={onUpvote}
/>
<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 <img

@ -2,6 +2,7 @@ import type { QuestionsQuestionType } from '@prisma/client';
import { Badge } from '@tih/ui'; import { Badge } from '@tih/ui';
import QuestionTypeBadge from '../QuestionTypeBadge'; import QuestionTypeBadge from '../QuestionTypeBadge';
import type { VotingButtonsCallbackProps } from '../VotingButtons';
import VotingButtons from '../VotingButtons'; import VotingButtons from '../VotingButtons';
type UpvoteProps = type UpvoteProps =
@ -14,17 +15,21 @@ type UpvoteProps =
upvoteCount?: never; upvoteCount?: never;
}; };
export type FullQuestionCardProps = UpvoteProps & { export type FullQuestionCardProps = UpvoteProps &
company: string; VotingButtonsCallbackProps & {
content: string; company: string;
location: string; content: string;
receivedCount: number; location: string;
role: string; receivedCount: number;
timestamp: string; role: string;
type: QuestionsQuestionType; timestamp: string;
}; type: QuestionsQuestionType;
};
export default function FullQuestionCard({ export default function FullQuestionCard({
voteState,
onDownvote,
onUpvote,
company, company,
content, content,
showVoteButtons, showVoteButtons,
@ -37,7 +42,14 @@ export default function FullQuestionCard({
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}
voteState={voteState}
onDownvote={onDownvote}
onUpvote={onUpvote}
/>
)}
<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>

@ -3,6 +3,7 @@ import type { QuestionsQuestionType } from '@prisma/client';
import { Badge, Button } from '@tih/ui'; import { Badge, Button } from '@tih/ui';
import QuestionTypeBadge from '../QuestionTypeBadge'; import QuestionTypeBadge from '../QuestionTypeBadge';
import type { VotingButtonsCallbackProps } from '../VotingButtons';
import VotingButtons from '../VotingButtons'; import VotingButtons from '../VotingButtons';
type UpvoteProps = type UpvoteProps =
@ -39,7 +40,8 @@ type ActionButtonProps =
export type QuestionCardProps = ActionButtonProps & export type QuestionCardProps = ActionButtonProps &
StatisticsProps & StatisticsProps &
UpvoteProps & { UpvoteProps &
VotingButtonsCallbackProps & {
company: string; company: string;
content: string; content: string;
href?: string; href?: string;
@ -51,6 +53,9 @@ export type QuestionCardProps = ActionButtonProps &
}; };
export default function QuestionCard({ export default function QuestionCard({
voteState,
onDownvote,
onUpvote,
company, company,
answerCount, answerCount,
content, content,
@ -68,7 +73,14 @@ export default function QuestionCard({
}: QuestionCardProps) { }: QuestionCardProps) {
return ( return (
<article className="flex gap-4 rounded-md border border-slate-300 bg-white p-4 hover:bg-slate-50"> <article className="flex gap-4 rounded-md border border-slate-300 bg-white p-4 hover:bg-slate-50">
{showVoteButtons && <VotingButtons upvoteCount={upvoteCount} />} {showVoteButtons && (
<VotingButtons
upvoteCount={upvoteCount}
voteState={voteState}
onDownvote={onDownvote}
onUpvote={onUpvote}
/>
)}
<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">

@ -10,6 +10,7 @@ import FullScreenSpinner from '~/components/questions/FullScreenSpinner';
import createSlug from '~/utils/questions/createSlug'; import createSlug from '~/utils/questions/createSlug';
import { useFormRegister } from '~/utils/questions/useFormRegister'; import { useFormRegister } from '~/utils/questions/useFormRegister';
import { useVote } from '~/utils/questions/useVote';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
export type AnswerQuestionData = { export type AnswerQuestionData = {
@ -39,6 +40,7 @@ export default function QuestionPage() {
const commentRegister = useFormRegister(comRegister); const commentRegister = useFormRegister(comRegister);
const { questionId } = router.query; const { questionId } = router.query;
const [handleUpvote, handleDownvote, voteState] = useVote();
const { data: question } = trpc.useQuery([ const { data: question } = trpc.useQuery([
'questions.questions.getQuestionById', 'questions.questions.getQuestionById',
@ -112,6 +114,9 @@ export default function QuestionPage() {
<div className="flex w-full justify-center overflow-y-auto py-4 px-5"> <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"> <div className="flex max-w-7xl flex-1 flex-col gap-2">
<FullQuestionCard <FullQuestionCard
voteState={voteState}
onDownvote={() => handleDownvote(questionId as string)}
onUpvote={() => handleUpvote(questionId as string)}
{...question} {...question}
receivedCount={0} // TODO: Change to actual value receivedCount={0} // TODO: Change to actual value
showVoteButtons={true} showVoteButtons={true}

@ -24,6 +24,7 @@ import {
useSearchFilter, useSearchFilter,
useSearchFilterSingle, useSearchFilterSingle,
} from '~/utils/questions/useSearchFilter'; } from '~/utils/questions/useSearchFilter';
import { useVote } from '~/utils/questions/useVote';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
export default function QuestionsHomePage() { export default function QuestionsHomePage() {
@ -144,7 +145,7 @@ export default function QuestionsHomePage() {
]); ]);
const { pathname } = router; const { pathname } = router;
const [handleDownvote, handleUpvote, voteState] = useVote();
useEffect(() => { useEffect(() => {
if (areFiltersInitialized) { if (areFiltersInitialized) {
// Router.replace used instead of router.replace to avoid // Router.replace used instead of router.replace to avoid
@ -292,14 +293,17 @@ export default function QuestionsHomePage() {
question.content, question.content,
)}`} )}`}
location={question.location} location={question.location}
receivedCount={0} // TODO: Implement received count receivedCount={0}
role={question.role} role={question.role}
timestamp={question.seenAt.toLocaleDateString(undefined, { timestamp={question.seenAt.toLocaleDateString(undefined, {
month: 'short', month: 'short',
year: 'numeric', year: 'numeric',
})} })}
type={question.type} type={question.type} // TODO: Implement received count
upvoteCount={question.numVotes} upvoteCount={question.numVotes}
voteState={voteState}
onDownvote={() => handleDownvote(question.id)}
onUpvote={() => handleUpvote(question.id)}
/> />
))} ))}
{questions?.length === 0 && ( {questions?.length === 0 && (

@ -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;
};
Loading…
Cancel
Save