As developers, we learn best by building real projects. I wanted to challenge myself to create something that felt like a production-ready full-stack app β not just another todo list.
Thatβs how I built Elan Royale, a luxury restaurant reservation system where users can book a table, make a deposit, and receive instant confirmation.
This project not only helped me practice Next.js, Prisma, and full-stack development, but also gave me something powerful to showcase in my portfolio.
βΈ»
π₯ The Problem I Wanted to Solve
Restaurants often rely on manual reservations (phone calls, paper logs) which can be messy and lead to errors. I wanted to create a modern solution that:
β’ Lets users easily reserve a table online.
β’ Collects a deposit using Stripe payments.
β’ Automatically confirms and stores the booking.
This was the idea behind Elan Royale.
βΈ»
π Tech Stack
I picked technologies that are used in real production apps:
β’ Next.js 15 β for server-side rendering and API routes.
β’ Prisma ORM β to model and interact with the database.
β’ TailwindCSS β for fast, modern, responsive styling.
β’ Stripe β for payment gateway integration.
β’ Vercel β for smooth deployment and hosting.
βΈ»
βοΈ Building the System
Hereβs how I built it step by step:
- Setting up Next.js
I started by creating a Next.js app using the App Router. This gave me a strong foundation with server-side rendering and API routes.
- Designing the UI
Using TailwindCSS, I designed a clean, modern interface.
β’ A Hero section to showcase the restaurantβs luxury feel.
β’ A Reservation Form with fields for name, email, phone, party size, date/time, and notes.
Reserve a Table
- Database with Prisma
I defined the reservation schema in Prisma:
model Reservation {
id String @id @default(cuid())
name String
email String
phone String
partySize Int
reservationTime DateTime
area String
notes String?
createdAt DateTime @default(now())
}
This made it easy to create and query reservations in the database.
- API Routes
I created an API route (/api/reservations) to handle saving reservations into the database.
export async function POST(req: Request) {
const body = await req.json();
const reservation = await prisma.reservation.create({ data: body });
return NextResponse.json(reservation, { status: 201 });
}
- Stripe Payment Integration
Before confirming a reservation, the system redirects users to Stripe Checkout to pay a deposit.
β’ User fills the form β saved in DB.
β’ Stripe Checkout opens β user pays.
β’ On success, they are redirected to /confirmation.
const paymentRes = await fetch("/api/create-checkout-session", { ... });
const data = await paymentRes.json();
window.location.href = data.url;
- Confirmation Page
After payment, users land on a Confirmation Page showing reservation details.
π Reservation Confirmed!
Thank you for booking with Elan Royale.
β‘ Challenges I Faced & How I Solved Them
1. Prisma errors β Fixed by handling missing/invalid input properly in API.
2. Hero image loading slowly β Solved by switching to next/image for optimization.
3. useSearchParams error in Next.js 15 β Solved by wrapping in to support client-side params.
π¨ Final Result
β
Users can make a reservation online.
β
Payment deposit handled with Stripe.
β
Confirmation page with booking details.
β
Fully deployed to Vercel.
π Live Demo: [elan-royale.vercel.app]
π GitHub Repo: github.com/Aisha-Aliyu/elan-royale.git
βΈ»

π‘ Lessons Learned
β’ Next.js App Router makes full-stack projects much cleaner.
β’ Prisma is powerful for database modeling and migrations.
β’ Stripe integration is smooth but requires careful error handling.
β’ Deployment on Vercel is fast and beginner-friendly.
βΈ»
β Conclusion
This project showed me how to bring together frontend, backend, database, and payments into one seamless full-stack app.
If youβd like to check it out, hereβs the live demo and GitHub repo.
Iβm also open to collaborations and freelance opportunities in full-stack web development β feel free to connect! π
Top comments (0)