fromis_9/frontend/src/pages/mobile/album/Album.jsx

60 lines
1.8 KiB
React
Raw Normal View History

import { motion } from 'framer-motion';
import { useQuery } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { getAlbums } from '@/api';
/**
* Mobile 앨범 목록 페이지
*/
function MobileAlbum() {
const navigate = useNavigate();
const { data: albums = [], isLoading: loading } = useQuery({
queryKey: ['albums'],
queryFn: getAlbums,
});
if (loading) {
return (
<div className="flex items-center justify-center h-64">
<div className="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin" />
</div>
);
}
return (
<div className="px-4 py-4">
<div className="grid grid-cols-2 gap-4">
{albums.map((album, index) => (
<motion.div
key={album.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.05 }}
onClick={() => navigate(`/album/${encodeURIComponent(album.title)}`)}
className="bg-white rounded-2xl overflow-hidden shadow-md"
>
<div className="aspect-square bg-gray-200">
{album.cover_thumb_url && (
<img
src={album.cover_thumb_url}
alt={album.title}
className="w-full h-full object-cover"
/>
)}
</div>
<div className="p-3">
<p className="font-semibold text-sm truncate">{album.title}</p>
<p className="text-xs text-gray-400 mt-0.5">
{album.album_type_short} · {album.release_date?.slice(0, 4)}
</p>
</div>
</motion.div>
))}
</div>
</div>
);
}
export default MobileAlbum;