Initial commit: Craft2Prints with Stages 1-3
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
'use server';
|
||||
|
||||
import { redirect } from 'next/navigation';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
|
||||
function slugify(input: string) {
|
||||
return input
|
||||
.toUpperCase()
|
||||
.trim()
|
||||
.replace(/[^A-Z0-9]+/g, '_')
|
||||
.replace(/^_+|_+$/g, '');
|
||||
}
|
||||
|
||||
async function uniqueSlug(base: string) {
|
||||
let slug = base || 'GALLERY';
|
||||
let n = 2;
|
||||
while (await prisma.galleryCategory.findUnique({ where: { slug } })) {
|
||||
slug = `${base}_${n}`;
|
||||
n += 1;
|
||||
}
|
||||
return slug;
|
||||
}
|
||||
|
||||
async function fileToDataUrl(file: File): Promise<string> {
|
||||
const bytes = Buffer.from(await file.arrayBuffer());
|
||||
const mimeType = file.type || 'image/png';
|
||||
return `data:${mimeType};base64,${bytes.toString('base64')}`;
|
||||
}
|
||||
|
||||
export async function uploadGalleryPhoto(formData: FormData) {
|
||||
const caption = String(formData.get('caption') ?? '').trim();
|
||||
const categoryId = String(formData.get('categoryId') ?? '').trim() || null;
|
||||
const file = formData.get('image') as File | null;
|
||||
|
||||
if (!file || file.size === 0) {
|
||||
throw new Error('A photo is required.');
|
||||
}
|
||||
|
||||
const imageDataUrl = await fileToDataUrl(file);
|
||||
|
||||
await prisma.galleryPhoto.create({
|
||||
data: {
|
||||
imageDataUrl,
|
||||
caption: caption || null,
|
||||
categoryId,
|
||||
},
|
||||
});
|
||||
|
||||
redirect('/admin/gallery');
|
||||
}
|
||||
|
||||
export async function deleteGalleryPhoto(formData: FormData) {
|
||||
const id = String(formData.get('id') ?? '');
|
||||
if (!id) return;
|
||||
|
||||
await prisma.galleryPhoto.delete({ where: { id } });
|
||||
redirect('/admin/gallery');
|
||||
}
|
||||
|
||||
export async function createGalleryCategory(formData: FormData) {
|
||||
const name = String(formData.get('name') ?? '').trim();
|
||||
if (!name) throw new Error('Category name is required.');
|
||||
|
||||
const slug = await uniqueSlug(slugify(name));
|
||||
|
||||
await prisma.galleryCategory.create({ data: { name, slug } });
|
||||
|
||||
redirect('/admin/gallery/categories');
|
||||
}
|
||||
|
||||
export async function deleteGalleryCategory(formData: FormData) {
|
||||
const id = String(formData.get('id') ?? '');
|
||||
if (!id) return;
|
||||
|
||||
const inUse = await prisma.galleryPhoto.count({ where: { categoryId: id } });
|
||||
if (inUse > 0) {
|
||||
redirect('/admin/gallery/categories?error=in_use');
|
||||
}
|
||||
|
||||
await prisma.galleryCategory.delete({ where: { id } });
|
||||
redirect('/admin/gallery/categories');
|
||||
}
|
||||
Reference in New Issue
Block a user