'use server';
import bcrypt from 'bcryptjs'; import { redirect } from 'next/navigation'; import { revalidatePath } from 'next/cache'; import { prisma } from '@/lib/prisma'; import { createSession,destroySession,requireAdmin } from '@/lib/auth'; import { saveImage } from '@/lib/uploads'; import { syncAllDwz } from '@/lib/dwz';
const slugify=(v:string)=>v.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g,'').replace(/ß/g,'ss').replace(/[^a-z0-9]+/g,'-').replace(/(^-|-$)/g,'');
export async function loginAction(f:FormData){const username=String(f.get('username')||''),password=String(f.get('password')||'');const u=await prisma.adminUser.findUnique({where:{username}});if(!u||!(await bcrypt.compare(password,u.passwordHash)))redirect('/admin/login?error=1');await createSession(u.id);redirect('/admin')}
export async function logoutAction(){await destroySession();redirect('/admin/login')}
export async function createEventAction(f:FormData){await requireAdmin();await prisma.event.create({data:{title:String(f.get('title')),category:String(f.get('category')),startsAt:new Date(String(f.get('startsAt'))),location:String(f.get('location')),description:String(f.get('description')||'')||null,published:f.get('published')==='on'}});revalidatePath('/');revalidatePath('/termine');redirect('/admin/termine')}
export async function updateEventAction(id:number,f:FormData){await requireAdmin();await prisma.event.update({where:{id},data:{title:String(f.get('title')),category:String(f.get('category')),startsAt:new Date(String(f.get('startsAt'))),location:String(f.get('location')),description:String(f.get('description')||'')||null,published:f.get('published')==='on'}});revalidatePath('/');revalidatePath('/termine');redirect('/admin/termine')}
export async function deleteEventAction(id:number){await requireAdmin();await prisma.event.delete({where:{id}});revalidatePath('/');revalidatePath('/termine');redirect('/admin/termine')}
export async function createPostAction(f:FormData){await requireAdmin();const title=String(f.get('title'));let slug=slugify(String(f.get('slug')||title));if(await prisma.post.findUnique({where:{slug}}))slug=`${slug}-${Date.now()}`;const coverImage=await saveImage(f.get('coverImage') as File);const gallery=(await Promise.all((f.getAll('gallery') as File[]).map(saveImage))).filter(Boolean) as string[];await prisma.post.create({data:{slug,title,category:String(f.get('category')||'')||null,author:String(f.get('author')),publishedAt:new Date(String(f.get('publishedAt'))),excerpt:String(f.get('excerpt')),content:String(f.get('content')),coverImage,gallery,published:f.get('published')==='on'}});revalidatePath('/');revalidatePath('/aktuelles');redirect('/admin/beitraege')}
export async function updatePostAction(id:number,f:FormData){await requireAdmin();const p=await prisma.post.findUniqueOrThrow({where:{id}});const newCover=await saveImage(f.get('coverImage') as File);const added=(await Promise.all((f.getAll('gallery') as File[]).map(saveImage))).filter(Boolean) as string[];await prisma.post.update({where:{id},data:{title:String(f.get('title')),category:String(f.get('category')||'')||null,author:String(f.get('author')),publishedAt:new Date(String(f.get('publishedAt'))),excerpt:String(f.get('excerpt')),content:String(f.get('content')),coverImage:newCover??p.coverImage,gallery:added.length?[...p.gallery,...added]:p.gallery,published:f.get('published')==='on'}});revalidatePath('/');revalidatePath('/aktuelles');redirect('/admin/beitraege')}
export async function deletePostAction(id:number){await requireAdmin();await prisma.post.delete({where:{id}});revalidatePath('/');revalidatePath('/aktuelles');redirect('/admin/beitraege')}
export async function updateTrainingAction(id:number,f:FormData){await requireAdmin();await prisma.trainingTime.update({where:{id},data:{title:String(f.get('title')),weekday:String(f.get('weekday')),time:String(f.get('time')),location:String(f.get('location')),note:String(f.get('note')||'')||null}});revalidatePath('/');revalidatePath('/verein/trainingszeiten');redirect('/admin/trainingszeiten')}
export async function changePasswordAction(f:FormData){await requireAdmin();const username=String(f.get('username')),password=String(f.get('password'));if(password.length<10)throw new Error('Mindestens 10 Zeichen');await prisma.adminUser.update({where:{username},data:{passwordHash:await bcrypt.hash(password,12)}});redirect('/admin/passwoerter?ok=1')}
export async function addPlayerAction(f:FormData){await requireAdmin();await prisma.player.create({data:{teamNumber:Number(f.get('teamNumber')),boardNumber:Number(f.get('boardNumber')),firstName:String(f.get('firstName')),lastName:String(f.get('lastName')),nuLigaPersonId:String(f.get('nuLigaPersonId')||'')||null}});revalidatePath('/mannschaften/erste-mannschaft');revalidatePath('/mannschaften/zweite-mannschaft');redirect('/admin/spieler')}
export async function deletePlayerAction(id:number){await requireAdmin();await prisma.player.delete({where:{id}});revalidatePath('/mannschaften/erste-mannschaft');revalidatePath('/mannschaften/zweite-mannschaft');redirect('/admin/spieler')}
export async function syncDwzAction(){await requireAdmin();await syncAllDwz();revalidatePath('/mannschaften/erste-mannschaft');revalidatePath('/mannschaften/zweite-mannschaft');redirect('/admin/spieler?sync=1')}
