Add image upload and edit functions
This commit is contained in:
99
src/components/artworks/ArtworkGallery.tsx
Normal file
99
src/components/artworks/ArtworkGallery.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
"use client"
|
||||
|
||||
// import { PortfolioImage } from "@/generated/prisma";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ArtworkWithRelations } from "@/types/Artwork";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { Button } from "../ui/button";
|
||||
|
||||
export default function ArtworkGallery({
|
||||
initialArtworks,
|
||||
initialCursor,
|
||||
}: {
|
||||
initialArtworks: ArtworkWithRelations[];
|
||||
initialCursor: string | null;
|
||||
}) {
|
||||
const searchParams = useSearchParams();
|
||||
const published = searchParams.get("published") ?? "all";
|
||||
|
||||
const [artworks, setArtworks] = useState(initialArtworks);
|
||||
const [cursor, setCursor] = useState<string | null>(initialCursor);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const loadMore = async () => {
|
||||
if (!cursor || loading) return;
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const qs = new URLSearchParams();
|
||||
qs.set("published", published);
|
||||
qs.set("cursor", cursor);
|
||||
qs.set("take", "48");
|
||||
|
||||
const res = await fetch(`/api/artworks/page?${qs.toString()}`, {
|
||||
method: "GET",
|
||||
cache: "no-store",
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error("Failed to load more artworks");
|
||||
|
||||
const data: { items: ArtworkWithRelations[]; nextCursor: string | null } =
|
||||
await res.json();
|
||||
|
||||
setArtworks((prev) => [...prev, ...data.items]);
|
||||
setCursor(data.nextCursor);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col gap-4">
|
||||
<div
|
||||
className="flex flex-wrap gap-4"
|
||||
>
|
||||
{artworks.map((artwork) => (
|
||||
<div key={artwork.id} style={{ width: 200, height: 200 }}>
|
||||
<Link href={`/artworks/${artwork.id}`}>
|
||||
<div
|
||||
className={cn(
|
||||
"overflow-hidden transition-all duration-100",
|
||||
"w-full h-full",
|
||||
"hover:border-2 border-transparent"
|
||||
)}
|
||||
style={{
|
||||
'--tw-border-opacity': 1,
|
||||
} as React.CSSProperties}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"relative w-full h-full"
|
||||
)}
|
||||
>
|
||||
<Image
|
||||
src={`/api/image/thumbnail/${artwork.file.fileKey}.webp`}
|
||||
alt={artwork.altText ?? artwork.name ?? "Image"}
|
||||
fill
|
||||
className={cn("object-cover"
|
||||
)}
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{cursor ? (
|
||||
<div className="flex justify-center">
|
||||
<Button onClick={loadMore} disabled={loading}>
|
||||
{loading ? "Loading..." : "Load more"}
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user