feat: skeleton loader

This commit is contained in:
trafficlunar 2025-04-13 23:31:06 +01:00
parent c1f8a9fdba
commit 48b001377a
2 changed files with 39 additions and 3 deletions

View file

@ -9,6 +9,7 @@ import Carousel from "../carousel";
import LikeButton from "../like-button";
import FilterSelect from "./filter-select";
import Pagination from "./pagination";
import Skeleton from "./skeleton";
interface Props {
isLoggedIn: boolean;
@ -106,9 +107,9 @@ export default function MiiList({ isLoggedIn, userId }: Props) {
<Link href={`/mii/${mii.id}`} className="font-bold text-2xl overflow-hidden text-ellipsis text-nowrap" title={mii.name}>
{mii.name}
</Link>
<div id="tags" className="flex flex-wrap gap-1 *:px-2 *:py-1 *:bg-orange-300 *:rounded-full *:text-xs">
<div id="tags" className="flex flex-wrap gap-1">
{mii.tags.map((tag) => (
<Link href={{ query: { tags: tag } }} key={tag}>
<Link href={{ query: { tags: tag } }} key={tag} className="px-2 py-1 bg-orange-300 rounded-full text-xs">
{tag}
</Link>
))}
@ -130,8 +131,15 @@ export default function MiiList({ isLoggedIn, userId }: Props) {
) : (
<p className="text-xl font-semibold text-center mt-10">No results found.</p>
)
) : error ? (
<p className="text-xl text-red-400 font-semibold text-center mt-10">Error: {error}</p>
) : (
<>{error && <p className="text-xl text-red-400 font-semibold text-center mt-10">Error: {error}</p>}</>
// Show skeleton when data is loading
<div className="grid grid-cols-4 gap-4 max-lg:grid-cols-3 max-sm:grid-cols-2 max-[25rem]:grid-cols-1">
{Array.from({ length: 24 }).map((_, i) => (
<Skeleton key={i} />
))}
</div>
)}
{data && <Pagination lastPage={data.lastPage} />}

View file

@ -0,0 +1,28 @@
export default function Skeleton() {
return (
<div className="flex flex-col bg-zinc-50 rounded-3xl border-2 border-zinc-300 shadow-lg p-3 animate-pulse">
{/* Carousel Skeleton */}
<div className="relative rounded-xl bg-zinc-300 border-2 border-zinc-300 mb-1">
<div className="aspect-[3/2]"></div>
</div>
{/* Content */}
<div className="p-4 flex flex-col gap-1 h-full">
{/* Name */}
<div className="h-7 bg-zinc-300 rounded w-2/3 mb-0.5" />
{/* Tags */}
<div className="flex flex-wrap gap-1">
<div className="px-4 py-2 bg-orange-200 rounded-full w-14 h-6" />
<div className="px-4 py-2 bg-orange-200 rounded-full w-10 h-6" />
</div>
{/* Bottom row */}
<div className="mt-0.5 grid grid-cols-2 items-center">
<div className="h-6 w-12 bg-red-200 rounded" />
<div className="h-4 w-24 bg-zinc-200 rounded justify-self-end" />
</div>
</div>
</div>
);
}