Add image upload and edit functions

This commit is contained in:
2025-12-20 16:34:50 +01:00
parent 96fa12993b
commit dfb6f7042a
72 changed files with 7413 additions and 81 deletions

10
src/lib/prisma.ts Normal file
View File

@ -0,0 +1,10 @@
import { PrismaPg } from '@prisma/adapter-pg';
import "dotenv/config";
import { PrismaClient } from '../generated/prisma/client';
const connectionString = `${process.env.DATABASE_URL}`
const adapter = new PrismaPg({ connectionString })
const prisma = new PrismaClient({ adapter })
export { prisma };

43
src/lib/queryArtworks.ts Normal file
View File

@ -0,0 +1,43 @@
// src/lib/artworks/query.ts
import { Prisma } from "@/generated/prisma/client";
import { prisma } from "@/lib/prisma";
export type ArtworkListParams = {
published?: string;
take?: number;
cursor?: string; // artwork.id of the last item from previous page
};
export async function getArtworksPage(params: ArtworkListParams) {
const { published = "all", take = 48, cursor } = params;
const where: Prisma.ArtworkWhereInput = {};
if (published === "published") where.published = true;
else if (published === "unpublished") where.published = false;
else if (published === "needsWork") where.needsWork = true;
const artworks = await prisma.artwork.findMany({
where,
include: {
file: true,
variants: true,
metadata: true,
},
orderBy: [{ createdAt: "desc" }, { id: "asc" }],
take: take + 1, // fetch one extra to know if there is a next page
...(cursor
? {
cursor: { id: cursor },
skip: 1, // skip the cursor item itself
}
: {}),
});
const hasMore = artworks.length > take;
const pageItems = hasMore ? artworks.slice(0, take) : artworks;
const nextCursor = hasMore ? pageItems[pageItems.length - 1]?.id : null;
return { items: pageItems, nextCursor };
}

22
src/lib/s3.ts Normal file
View File

@ -0,0 +1,22 @@
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import "dotenv/config";
export const s3 = new S3Client({
region: "us-east-1",
endpoint: `${process.env.S3_ENDPOINT}`,
forcePathStyle: true,
credentials: {
accessKeyId: `${process.env.S3_ACCESSKEY}`,
secretAccessKey: `${process.env.S3_SECRET}`,
},
});
export async function getSignedImageUrl(key: string, expiresInSec = 3600) {
const command = new GetObjectCommand({
Bucket: `${process.env.BUCKET_NAME}`,
Key: key,
});
return getSignedUrl(s3, command, { expiresIn: expiresInSec });
}

6
src/lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}