[resumes][feat] Update vote animation (#396)

Co-authored-by: Terence Ho <>
pull/397/head
Terence 2 years ago committed by GitHub
parent a879639b53
commit cf1852a302
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,5 @@
import clsx from 'clsx'; import clsx from 'clsx';
import type { Dispatch, SetStateAction } from 'react';
import { useState } from 'react'; import { useState } from 'react';
import type { SubmitHandler } from 'react-hook-form'; import type { SubmitHandler } from 'react-hook-form';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
@ -8,7 +9,7 @@ import {
} from '@heroicons/react/20/solid'; } from '@heroicons/react/20/solid';
import { FaceSmileIcon } from '@heroicons/react/24/outline'; import { FaceSmileIcon } from '@heroicons/react/24/outline';
import { Vote } from '@prisma/client'; import { Vote } from '@prisma/client';
import { Button, Spinner, TextArea } from '@tih/ui'; import { Button, TextArea } from '@tih/ui';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
@ -32,6 +33,9 @@ export default function ResumeCommentListItem({
const isCommentOwner = userId === comment.user.userId; const isCommentOwner = userId === comment.user.userId;
const [isEditingComment, setIsEditingComment] = useState(false); const [isEditingComment, setIsEditingComment] = useState(false);
const [upvoteAnimation, setUpvoteAnimation] = useState(false);
const [downvoteAnimation, setDownvoteAnimation] = useState(false);
const { const {
register, register,
handleSubmit, handleSubmit,
@ -104,16 +108,31 @@ export default function ResumeCommentListItem({
setValue('description', value.trim(), { shouldDirty: true }); setValue('description', value.trim(), { shouldDirty: true });
}; };
const onVote = async (value: Vote) => { const onVote = async (
value: Vote,
setAnimation: Dispatch<SetStateAction<boolean>>,
) => {
setAnimation(true);
if (commentVotesQuery.data?.userVote?.value === value) { if (commentVotesQuery.data?.userVote?.value === value) {
return commentVotesDeleteMutation.mutate({ return commentVotesDeleteMutation.mutate(
commentId: comment.id, {
}); commentId: comment.id,
},
{
onSettled: async () => setAnimation(false),
},
);
} }
return commentVotesUpsertMutation.mutate({ return commentVotesUpsertMutation.mutate(
commentId: comment.id, {
value, commentId: comment.id,
}); value,
},
{
onSettled: async () => setAnimation(false),
},
);
}; };
return ( return (
@ -201,20 +220,28 @@ export default function ResumeCommentListItem({
commentVotesDeleteMutation.isLoading commentVotesDeleteMutation.isLoading
} }
type="button" type="button"
onClick={() => onVote(Vote.UPVOTE)}> onClick={() => onVote(Vote.UPVOTE, setUpvoteAnimation)}>
<ArrowUpCircleIcon <ArrowUpCircleIcon
className={clsx( className={clsx(
'h-4 w-4', 'h-4 w-4',
commentVotesQuery.data?.userVote?.value === Vote.UPVOTE commentVotesQuery.data?.userVote?.value === Vote.UPVOTE ||
upvoteAnimation
? 'fill-indigo-500' ? 'fill-indigo-500'
: 'fill-gray-400', : 'fill-gray-400',
userId && 'hover:fill-indigo-500', userId &&
!downvoteAnimation &&
!upvoteAnimation &&
'hover:fill-indigo-500',
upvoteAnimation &&
'animate-[bounce_0.5s_infinite] cursor-default',
)} )}
/> />
</button> </button>
<div className="text-xs"> <div className="text-xs">
{commentVotesQuery.data?.numVotes ?? 0} {commentVotesQuery.data?.numVotes ?? 0}
</div> </div>
<button <button
disabled={ disabled={
!userId || !userId ||
@ -223,14 +250,20 @@ export default function ResumeCommentListItem({
commentVotesDeleteMutation.isLoading commentVotesDeleteMutation.isLoading
} }
type="button" type="button"
onClick={() => onVote(Vote.DOWNVOTE)}> onClick={() => onVote(Vote.DOWNVOTE, setDownvoteAnimation)}>
<ArrowDownCircleIcon <ArrowDownCircleIcon
className={clsx( className={clsx(
'h-4 w-4', 'h-4 w-4',
commentVotesQuery.data?.userVote?.value === Vote.DOWNVOTE commentVotesQuery.data?.userVote?.value === Vote.DOWNVOTE ||
downvoteAnimation
? 'fill-red-500' ? 'fill-red-500'
: 'fill-gray-400', : 'fill-gray-400',
userId && 'hover:fill-red-500', userId &&
!downvoteAnimation &&
!upvoteAnimation &&
'hover:fill-red-500',
downvoteAnimation &&
'animate-[bounce_0.5s_infinite] cursor-default',
)} )}
/> />
</button> </button>
@ -243,12 +276,6 @@ export default function ResumeCommentListItem({
Edit Edit
</button> </button>
)} )}
{(commentVotesQuery.isLoading ||
commentVotesUpsertMutation.isLoading ||
commentVotesDeleteMutation.isLoading) && (
<Spinner label="loading votes..." size="xs" />
)}
</div> </div>
</div> </div>
</div> </div>

Loading…
Cancel
Save