- Next.js 14 with App Router and TypeScript - Prisma ORM with PostgreSQL database - Event creation with share links - Calendar availability selection - Password-protected analytics dashboard - Stripe-inspired UI design - Docker configuration for deployment
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { prisma } from '@/lib/db';
|
|
import { nanoid } from 'nanoid';
|
|
import bcrypt from 'bcryptjs';
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
const { title, description, startDate, endDate, adminPassword } = body;
|
|
|
|
// Validation
|
|
if (!title || !startDate || !endDate || !adminPassword) {
|
|
return NextResponse.json(
|
|
{ error: 'Missing required fields: title, startDate, endDate, adminPassword' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const start = new Date(startDate);
|
|
const end = new Date(endDate);
|
|
|
|
if (start > end) {
|
|
return NextResponse.json(
|
|
{ error: 'Start date must be before or equal to end date' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Generate unique share code
|
|
const shareCode = nanoid(8);
|
|
|
|
// Hash admin password
|
|
const adminPasswordHash = await bcrypt.hash(adminPassword, 12);
|
|
|
|
// Create event
|
|
const event = await prisma.event.create({
|
|
data: {
|
|
title,
|
|
description: description || null,
|
|
startDate: start,
|
|
endDate: end,
|
|
shareCode,
|
|
adminPasswordHash,
|
|
},
|
|
});
|
|
|
|
const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
|
|
|
|
return NextResponse.json({
|
|
id: event.id,
|
|
shareCode: event.shareCode,
|
|
shareUrl: `${appUrl}/event/${event.shareCode}`,
|
|
analyticsUrl: `${appUrl}/event/${event.shareCode}/analytics`,
|
|
}, { status: 201 });
|
|
|
|
} catch (error) {
|
|
console.error('Error creating event:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to create event' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|