[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 { 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 (
<div className="flex flex-col items-center">
<Button
@ -34,8 +34,12 @@ export default function VotingButtons({
isLabelHidden={true}
label="Upvote"
size={size}
variant="tertiary"
onClick={handleUpvote}
variant={upvoteButtonVarient}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
onUpvote();
}}
/>
<p>{upvoteCount}</p>
<Button
@ -43,8 +47,12 @@ export default function VotingButtons({
isLabelHidden={true}
label="Downvote"
size={size}
variant="tertiary"
onClick={handleDownVote}
variant={downvoteButtonVarient}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
onDownvote();
}}
/>
</div>
);

@ -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 (
<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 items-center gap-2">
<img

@ -2,6 +2,7 @@ import type { QuestionsQuestionType } from '@prisma/client';
import { Badge } from '@tih/ui';
import QuestionTypeBadge from '../QuestionTypeBadge';
import type { VotingButtonsCallbackProps } from '../VotingButtons';
import VotingButtons from '../VotingButtons';
type UpvoteProps =
@ -14,17 +15,21 @@ type UpvoteProps =
upvoteCount?: never;
};
export type FullQuestionCardProps = UpvoteProps & {
company: string;
content: string;
location: string;
receivedCount: number;
role: string;
timestamp: string;
type: QuestionsQuestionType;
};
export type FullQuestionCardProps = UpvoteProps &
VotingButtonsCallbackProps & {
company: string;
content: string;
location: string;
receivedCount: number;
role: string;
timestamp: string;
type: QuestionsQuestionType;
};
export default function FullQuestionCard({
voteState,
onDownvote,
onUpvote,
company,
content,
showVoteButtons,
@ -37,7 +42,14 @@ export default function FullQuestionCard({
const altText = `${company} logo`;
return (
<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 items-center gap-2">
<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 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 (
<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 items-baseline justify-between">
<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 { 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() {
<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
voteState={voteState}
onDownvote={() => handleDownvote(questionId as string)}
onUpvote={() => handleUpvote(questionId as string)}
{...question}
receivedCount={0} // TODO: Change to actual value
showVoteButtons={true}

@ -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 && (

@ -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