feat: add prisma support, admin panel and auth
This commit is contained in:
150
app/admin/actions.ts
Normal file
150
app/admin/actions.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
'use server';
|
||||
|
||||
import { prisma } from '@/app/lib/prisma';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { cookies } from 'next/headers';
|
||||
import { redirect } from 'next/navigation';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { encrypt } from '@/app/lib/auth';
|
||||
|
||||
/* ────── Auth Actions ────── */
|
||||
|
||||
export async function authenticate(formData: FormData) {
|
||||
const username = formData.get('username') as string;
|
||||
const password = formData.get('password') as string;
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { username } });
|
||||
|
||||
if (!user || !(await bcrypt.compare(password, user.password))) {
|
||||
return { error: 'Geçersiz kullanıcı adı veya şifre' };
|
||||
}
|
||||
|
||||
// Create session
|
||||
const expires = new Date(Date.now() + 2 * 60 * 60 * 1000); // 2 hours
|
||||
const session = await encrypt({ userId: user.id, username: user.username, expires });
|
||||
|
||||
(await cookies()).set('session', session, { expires, httpOnly: true });
|
||||
|
||||
redirect('/admin');
|
||||
}
|
||||
|
||||
export async function signout() {
|
||||
(await cookies()).set('session', '', { expires: new Date(0) });
|
||||
redirect('/login');
|
||||
}
|
||||
|
||||
export async function createCategory(formData: FormData) {
|
||||
const title = formData.get('title') as string;
|
||||
const externalId = formData.get('externalId') as string;
|
||||
|
||||
await prisma.category.create({
|
||||
data: {
|
||||
title,
|
||||
externalId: externalId || null,
|
||||
restaurantId: (await prisma.restaurant.findFirst())?.id || '',
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath('/admin/categories');
|
||||
revalidatePath('/');
|
||||
}
|
||||
|
||||
export async function updateCategory(id: string, formData: FormData) {
|
||||
const title = formData.get('title') as string;
|
||||
const externalId = formData.get('externalId') as string;
|
||||
|
||||
await prisma.category.update({
|
||||
where: { id },
|
||||
data: {
|
||||
title,
|
||||
externalId: externalId || null,
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath('/admin/categories');
|
||||
revalidatePath('/');
|
||||
}
|
||||
|
||||
export async function deleteCategory(id: string) {
|
||||
// Optional: check if there are items first, or let prisma handles cascade if configured
|
||||
await prisma.item.deleteMany({ where: { categoryId: id } });
|
||||
await prisma.category.delete({ where: { id } });
|
||||
|
||||
revalidatePath('/admin/categories');
|
||||
revalidatePath('/');
|
||||
}
|
||||
|
||||
/* ────── Item Actions ────── */
|
||||
|
||||
export async function createItem(formData: FormData) {
|
||||
const name = formData.get('name') as string;
|
||||
const categoryId = formData.get('categoryId') as string;
|
||||
const ingredients = formData.get('ingredients') as string;
|
||||
const tasteProfile = formData.get('tasteProfile') as string;
|
||||
const grapeVariety = formData.get('grapeVariety') as string;
|
||||
const priceInput = formData.get('price') as string;
|
||||
|
||||
let price;
|
||||
try {
|
||||
// Try to parse as JSON if it looks like an object, otherwise keep as string
|
||||
price = (priceInput.startsWith('{') || priceInput.startsWith('['))
|
||||
? JSON.parse(priceInput)
|
||||
: priceInput;
|
||||
} catch (e) {
|
||||
price = priceInput;
|
||||
}
|
||||
|
||||
await prisma.item.create({
|
||||
data: {
|
||||
name,
|
||||
categoryId,
|
||||
ingredients: ingredients || null,
|
||||
tasteProfile: tasteProfile || null,
|
||||
grapeVariety: grapeVariety || null,
|
||||
price,
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath('/admin/items');
|
||||
revalidatePath('/');
|
||||
}
|
||||
|
||||
export async function updateItem(id: string, formData: FormData) {
|
||||
const name = formData.get('name') as string;
|
||||
const categoryId = formData.get('categoryId') as string;
|
||||
const ingredients = formData.get('ingredients') as string;
|
||||
const tasteProfile = formData.get('tasteProfile') as string;
|
||||
const grapeVariety = formData.get('grapeVariety') as string;
|
||||
const priceInput = formData.get('price') as string;
|
||||
|
||||
let price;
|
||||
try {
|
||||
price = (priceInput.startsWith('{') || priceInput.startsWith('['))
|
||||
? JSON.parse(priceInput)
|
||||
: priceInput;
|
||||
} catch (e) {
|
||||
price = priceInput;
|
||||
}
|
||||
|
||||
await prisma.item.update({
|
||||
where: { id },
|
||||
data: {
|
||||
name,
|
||||
categoryId,
|
||||
ingredients: ingredients || null,
|
||||
tasteProfile: tasteProfile || null,
|
||||
grapeVariety: grapeVariety || null,
|
||||
price,
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath('/admin/items');
|
||||
revalidatePath('/');
|
||||
}
|
||||
|
||||
export async function deleteItem(id: string) {
|
||||
await prisma.item.delete({ where: { id } });
|
||||
|
||||
revalidatePath('/admin/items');
|
||||
revalidatePath('/');
|
||||
}
|
||||
Reference in New Issue
Block a user