mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 20:13:49 +00:00
Continue work on brewery page, implement like system
This commit is contained in:
@@ -6,7 +6,7 @@ import UserContext from '@/contexts/userContext';
|
||||
import { FaRegEdit } from 'react-icons/fa';
|
||||
import beerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult';
|
||||
import { z } from 'zod';
|
||||
import useGetLikeCount from '@/hooks/useGetLikeCount';
|
||||
import useGetBeerPostLikeCount from '@/hooks/useBeerPostLikeCount';
|
||||
import useTimeDistance from '@/hooks/useTimeDistance';
|
||||
import BeerPostLikeButton from './BeerPostLikeButton';
|
||||
|
||||
@@ -20,7 +20,7 @@ const BeerInfoHeader: FC<{
|
||||
const idMatches = user && beerPost.postedBy.id === user.id;
|
||||
const isPostOwner = !!(user && idMatches);
|
||||
|
||||
const { likeCount, mutate } = useGetLikeCount(beerPost.id);
|
||||
const { likeCount, mutate } = useGetBeerPostLikeCount(beerPost.id);
|
||||
|
||||
return (
|
||||
<main className="card flex flex-col justify-center bg-base-300">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import useCheckIfUserLikesBeerPost from '@/hooks/useCheckIfUserLikesBeerPost';
|
||||
import sendLikeRequest from '@/requests/sendLikeRequest';
|
||||
import sendBeerPostLikeRequest from '@/requests/sendBeerPostLikeRequest';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { FaThumbsUp, FaRegThumbsUp } from 'react-icons/fa';
|
||||
|
||||
import useGetLikeCount from '@/hooks/useGetLikeCount';
|
||||
import useGetBeerPostLikeCount from '@/hooks/useBeerPostLikeCount';
|
||||
import LikeButton from '../ui/LikeButton';
|
||||
|
||||
const BeerPostLikeButton: FC<{
|
||||
beerPostId: string;
|
||||
mutateCount: ReturnType<typeof useGetLikeCount>['mutate'];
|
||||
mutateCount: ReturnType<typeof useGetBeerPostLikeCount>['mutate'];
|
||||
}> = ({ beerPostId, mutateCount }) => {
|
||||
const { isLiked, mutate: mutateLikeStatus } = useCheckIfUserLikesBeerPost(beerPostId);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -19,7 +19,7 @@ const BeerPostLikeButton: FC<{
|
||||
const handleLike = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
await sendLikeRequest(beerPostId);
|
||||
await sendBeerPostLikeRequest(beerPostId);
|
||||
|
||||
await Promise.all([mutateCount(), mutateLikeStatus()]);
|
||||
setLoading(false);
|
||||
@@ -28,30 +28,7 @@ const BeerPostLikeButton: FC<{
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={`btn-sm btn gap-2 rounded-2xl lg:btn-md ${
|
||||
!isLiked ? 'btn-ghost outline' : 'btn-primary'
|
||||
}`}
|
||||
onClick={() => {
|
||||
handleLike();
|
||||
}}
|
||||
disabled={loading}
|
||||
>
|
||||
{isLiked ? (
|
||||
<>
|
||||
<FaThumbsUp className="lg:text-2xl" />
|
||||
Liked
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FaRegThumbsUp className="lg:text-2xl" />
|
||||
Like
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
return <LikeButton isLiked={!!isLiked} handleLike={handleLike} loading={loading} />;
|
||||
};
|
||||
|
||||
export default BeerPostLikeButton;
|
||||
|
||||
@@ -4,12 +4,12 @@ import Image from 'next/image';
|
||||
import beerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult';
|
||||
import { z } from 'zod';
|
||||
import UserContext from '@/contexts/userContext';
|
||||
import useGetLikeCount from '@/hooks/useGetLikeCount';
|
||||
import useGetBeerPostLikeCount from '@/hooks/useBeerPostLikeCount';
|
||||
import BeerPostLikeButton from '../BeerById/BeerPostLikeButton';
|
||||
|
||||
const BeerCard: FC<{ post: z.infer<typeof beerPostQueryResult> }> = ({ post }) => {
|
||||
const { user } = useContext(UserContext);
|
||||
const { mutate, likeCount } = useGetLikeCount(post.id);
|
||||
const { mutate, likeCount } = useGetBeerPostLikeCount(post.id);
|
||||
|
||||
return (
|
||||
<div className="card card-compact bg-base-300" key={post.id}>
|
||||
@@ -27,14 +27,14 @@ const BeerCard: FC<{ post: z.infer<typeof beerPostQueryResult> }> = ({ post }) =
|
||||
<div className="card-body justify-between">
|
||||
<div className="space-y-1">
|
||||
<Link href={`/beers/${post.id}`}>
|
||||
<h2 className="link-hover link overflow-hidden whitespace-normal text-2xl font-bold lg:truncate lg:text-3xl">
|
||||
<h3 className="link-hover link overflow-hidden whitespace-normal text-2xl font-bold lg:truncate lg:text-3xl">
|
||||
{post.name}
|
||||
</h2>
|
||||
</h3>
|
||||
</Link>
|
||||
<Link href={`/breweries/${post.brewery.id}`}>
|
||||
<h3 className="text-md link-hover link whitespace-normal lg:truncate lg:text-xl">
|
||||
<h4 className="text-md link-hover link whitespace-normal lg:truncate lg:text-xl">
|
||||
{post.brewery.name}
|
||||
</h3>
|
||||
</h4>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
43
src/components/BreweryIndex/BreweryCard.tsx
Normal file
43
src/components/BreweryIndex/BreweryCard.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import UserContext from '@/contexts/userContext';
|
||||
import useGetBreweryPostLikeCount from '@/hooks/useGetBreweryPostLikeCount';
|
||||
import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult';
|
||||
import { FC, useContext } from 'react';
|
||||
import { Link } from 'react-daisyui';
|
||||
import { z } from 'zod';
|
||||
import Image from 'next/image';
|
||||
import BreweryPostLikeButton from './BreweryPostLikeButton';
|
||||
|
||||
const BreweryCard: FC<{ brewery: z.infer<typeof BreweryPostQueryResult> }> = ({
|
||||
brewery,
|
||||
}) => {
|
||||
const { user } = useContext(UserContext);
|
||||
const { likeCount, mutate } = useGetBreweryPostLikeCount(brewery.id);
|
||||
return (
|
||||
<div className="card" key={brewery.id}>
|
||||
<figure className="card-image h-96">
|
||||
{brewery.breweryImages.length > 0 && (
|
||||
<Image
|
||||
src={brewery.breweryImages[0].path}
|
||||
alt={brewery.name}
|
||||
width="1029"
|
||||
height="110"
|
||||
/>
|
||||
)}
|
||||
</figure>
|
||||
<div className="card-body space-y-3">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold">
|
||||
<Link href={`/breweries/${brewery.id}`}>{brewery.name}</Link>
|
||||
</h2>
|
||||
<h3 className="text-xl font-semibold">{brewery.location}</h3>
|
||||
</div>
|
||||
liked by {likeCount} users
|
||||
{user && (
|
||||
<BreweryPostLikeButton breweryPostId={brewery.id} mutateCount={mutate} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BreweryCard;
|
||||
30
src/components/BreweryIndex/BreweryPostLikeButton.tsx
Normal file
30
src/components/BreweryIndex/BreweryPostLikeButton.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import useCheckIfUserLikesBreweryPost from '@/hooks/useCheckIfUserLikesBreweryPost';
|
||||
import useGetBreweryPostLikeCount from '@/hooks/useGetBreweryPostLikeCount';
|
||||
import sendBreweryPostLikeRequest from '@/requests/sendBreweryPostLikeRequest';
|
||||
import { FC, useState } from 'react';
|
||||
import LikeButton from '../ui/LikeButton';
|
||||
|
||||
const BreweryPostLikeButton: FC<{
|
||||
breweryPostId: string;
|
||||
mutateCount: ReturnType<typeof useGetBreweryPostLikeCount>['mutate'];
|
||||
}> = ({ breweryPostId, mutateCount }) => {
|
||||
const { isLiked, mutate: mutateLikeStatus } =
|
||||
useCheckIfUserLikesBreweryPost(breweryPostId);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const handleLike = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await sendBreweryPostLikeRequest(breweryPostId);
|
||||
await Promise.all([mutateCount(), mutateLikeStatus()]);
|
||||
setIsLoading(false);
|
||||
} catch (e) {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return <LikeButton isLiked={!!isLiked} handleLike={handleLike} loading={isLoading} />;
|
||||
};
|
||||
|
||||
export default BreweryPostLikeButton;
|
||||
37
src/components/ui/LikeButton.tsx
Normal file
37
src/components/ui/LikeButton.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { FC } from 'react';
|
||||
import { FaThumbsUp, FaRegThumbsUp } from 'react-icons/fa';
|
||||
|
||||
interface LikeButtonProps {
|
||||
isLiked: boolean;
|
||||
handleLike: () => Promise<void>;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const LikeButton: FC<LikeButtonProps> = ({ isLiked, handleLike, loading }) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={`btn-sm btn gap-2 rounded-2xl lg:btn-md ${
|
||||
!isLiked ? 'btn-ghost outline' : 'btn-primary'
|
||||
}`}
|
||||
onClick={() => {
|
||||
handleLike();
|
||||
}}
|
||||
disabled={loading}
|
||||
>
|
||||
{isLiked ? (
|
||||
<>
|
||||
<FaThumbsUp className="lg:text-2xl" />
|
||||
Liked
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FaRegThumbsUp className="lg:text-2xl" />
|
||||
Like
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default LikeButton;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FC } from 'react';
|
||||
|
||||
const BeerPostLoadingCard: FC = () => {
|
||||
const LoadingCard: FC = () => {
|
||||
return (
|
||||
<div className="card bg-base-300">
|
||||
<figure className="h-96 border-8 border-base-300 bg-base-300">
|
||||
@@ -23,4 +23,4 @@ const BeerPostLoadingCard: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default BeerPostLoadingCard;
|
||||
export default LoadingCard;
|
||||
Reference in New Issue
Block a user