이 모든건 likedButton
에서 실행한다.
흐름
- SearchContent의 LikeButton에
song.id
를 넘긴다.
function SearchContent({ songs }: SearchContentProps) {
console.log(songs);
if (songs.length === 0) {
return (
<div className='flex flex-col gap-y-2 w-full px-6 text-neutral-400'>
No songs Found
</div>
);
}
return (
<div className='flex flex-col gap-y-2 w-full px-6'>
{songs.map((song) => (
<div key={song.id} className='flex items-center gap-x-4 w-full'>
<div className='flex-1'>
<MediaItem onClick={() => {}} data={song} />
</div>
<LikeButton songId={song.id} />
</div>
))}
</div>
);
}
- LikedButton 컴포넌트에서 좋아여 상태를 저장할
useState
하나를 만든다.
useUser
에서 가져오는 user
라는 변수에 담긴것
- 추가로 useEffect에서 isLiked일때는 supabaseClient를 사용해서
user_id
와 song_id
를 뺀다.
- isLiked가 아닐때는 supabaseClient를 사용해서
user_id
와 song_id
를 추가한다.
LikeButton 컴포넌트
'use client';
import useAuthModal from '@/hooks/useAuthModal';
import { useUser } from '@/hooks/useUser';
import { useSessionContext } from '@supabase/auth-helpers-react';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import toast from 'react-hot-toast';
import { AiFillHeart, AiOutlineHeart } from 'react-icons/ai';
interface LikeButtonProps {
songId: string;
}
export default function LikeButton({ songId }: LikeButtonProps) {
const router = useRouter();
const { supabaseClient } = useSessionContext();
const authModal = useAuthModal();
const { user } = useUser();
console.log('유저', user);
const [isLiked, setIsLiked] = useState(false);
useEffect(() => {
if (!user?.id) {
return;
}
// 좋아요, 안좋아요를 DB
const fetchData = async () => {
const { data, error } = await supabaseClient
.from('liked_songs')
.select('*')
.eq('user_id', user?.id)
.eq('song_id', songId)
.single();
if (!error && data) {
setIsLiked(true);
}
};
fetchData();
}, [songId, supabaseClient, user?.id]);
const Icon = isLiked ? AiFillHeart : AiOutlineHeart;
const handleLike = async () => {
if (!user) {
return authModal.onOpen();
}
// 이미 좋아요 상태이면! user_id와 song_id를 뺸다.
if (isLiked) {
const { error } = await supabaseClient
.from('liked_songs')
.delete()
.eq('user_id', user?.id)
.eq('song_id', songId);
if (error) {
toast.error(error.message);
} else {
setIsLiked(false);
}
// 좋아요 안 누른 상태이면, song_id와 user_id를 넣는다.
} else {
const { error } = await supabaseClient
.from('liked_songs')
.insert({ song_id: songId, user_id: user.id });
if (error) {
toast.error(error.message);
} else {
setIsLiked(true);
toast.success('Liked!');
}
}
router.refresh();
};
return (
<button onClick={handleLike} className='hover:opacity-75 transition'>
<Icon color={isLiked ? '#22c55e' : 'white'} size={25} />
</button>
);
}