Evently β Documentation
A complete, production-ready Event Management System and ticketing platform built with Next.js 16, React 19, TypeScript, and MongoDB. This guide walks you through installation, configuration, architecture, and the full REST API.
What is this?
Evently is a full-stack template that ships two products in one codebase:
π Public Events Website
A polished, SEO-ready marketing site with a dynamic landing page, event catalogue, event detail & registration, speaker and venue directories, a job board, certificate verification, testimonials, newsletter, and contact forms.
π οΈ Management Dashboards
Role-based dashboards for Super Admins and Organizers β events, sessions, tickets, registrations, waitlists, speakers, sponsors, exhibitors, venues, badges, certificates, expenses, CRM, subscriptions, and full site settings β plus an attendee area, all backed by a typed REST API.
Tip: The full rendered version of this documentation is also available inside the running app at the /documentation route.
Features
π« Events & Ticketing
Create, publish and cancel events with drafts. Multiple ticket tiers per event with pricing, quantity, sale windows, and per-order limits.
π Registrations
Attendee registration with unique confirmation codes, quantity, totals, coupon discounts, and a guarded status workflow.
β³ Waitlists
Automatic waitlisting for sold-out events with a 48-hour notification hold, conversion to registration, and expiry via cron.
ποΈ Sessions & Agenda
Multi-track agendas with rooms, time windows, concurrent sessions, and speaker assignments.
π€ Speakers & Sponsors
Speaker profiles with bios and socials; tiered sponsors (platinumβpartner) and exhibitor booth management.
ποΈ Venues
Venue directory with type (indoor / outdoor / virtual / hybrid), capacity, amenities and location.
β Check-in & Badges
QR-based or manual check-in with digital badges (VIP / sponsor flags, custom templates).
π Certificates
Issue post-event certificates (workshop / training / webinar / conference) with a public verification endpoint.
π₯ Roles & Dashboards
Three roles β Super Admin, Organizer, Attendee β each with a dedicated dashboard and middleware-protected routes.
π³ Subscriptions & Plans
Organizer subscription plans (monthly / yearly / one-time) with feature limits and status (active / trialing / canceled / expired).
π Analytics
Revenue, registrations, occupancy and expense reporting with charts on the Super Admin and Organizer dashboards.
π€ CRM & Job Board
Lightweight CRM for organizer contacts, plus a public careers page with an application pipeline (new β hired).
π¨ Dynamic Landing Page
Hero, features, testimonials, team, FAQ, newsletter and branding β all editable from the admin without touching code.
π€ AI Event Templates
Template-driven event creation with suggested titles, descriptions, ticket tiers, agenda items and SEO keywords.
π‘οΈ Audit Logging
Every sensitive action recorded with actor, resource, IP and details (auto-expires after 365 days).
Tech Stack
| Layer | Technology | Notes |
|---|---|---|
| Framework | Next.js 16.2 (App Router, Turbopack) | Server Components, Route Handlers, middleware |
| UI Runtime | React 19 | Latest concurrent React |
| Language | TypeScript | Strict, fully typed models & APIs |
| Database | MongoDB + Mongoose 8 | Schema models in /model |
| Auth | NextAuth v5 + JWT (jsonwebtoken) | Session for pages, Bearer JWT for API |
| Styling | Tailwind CSS v4 | CSS variables, dark mode via next-themes |
| UI Components | Radix UI + shadcn-style components | In /components/ui |
| Forms | React Hook Form + Zod | Shared schemas in lib/validation-schema |
| Tables | TanStack Table + dnd-kit | Reusable data-table in /components/data-table |
| Charts | Recharts | Dashboard & report analytics |
| Animation | Framer Motion | Landing-page motion |
| Media | Cloudinary + react-dropzone | Image hosting & uploads |
| PDF / QR | jsPDF + qrcode | Badges, certificates, exports |
| Nodemailer (SMTP) | Transactional mail | |
| Editor | TipTap / SunEditor | Rich-text for legal & content |
| State | Zustand | User, breadcrumb & table stores |
| Package Manager | pnpm | Use pnpm for installs |
Requirements
Before installing, make sure you have the following available:
- Node.js 18.18+ (Node 20 LTS or newer recommended).
- pnpm β install with
npm install -g pnpm. - MongoDB database β a free MongoDB Atlas cluster or a local
mongodinstance. - Cloudinary account (optional, for image uploads) β configured later from the admin panel.
- SMTP credentials (optional, for email) β e.g. Gmail App Password, SendGrid, Mailgun.
Note: Cloudinary and SMTP are not required to boot the app. You can configure them later from Super Admin β Settings. The build itself does not require a reachable database.
Quick Start
-
Unzip & install dependencies
# from the project root pnpm install -
Create your environment file
Copy the example and fill in the values (see Environment Variables).
cp .env.example .env.local -
Run the development server
pnpm devOpen
http://localhost:3000β the public site loads. Staff dashboards live at/super-adminand/organizer; attendees use/attendee. -
Build for production
pnpm build pnpm start
| Script | Command | Purpose |
|---|---|---|
dev | next dev --turbopack | Local development with hot reload |
build | next build --turbopack | Production build |
start | next start | Serve the production build |
lint | eslint | Lint the codebase |
generate-postman | node scripts/generate-postman.js | Regenerate the Postman API collection |
Environment Variables
Create .env.local in the project root. Required keys are marked below.
# ββ Core ββββββββββββββββββββββββββββββββββββββββββββββ
MONGODB_URI="mongodb+srv://user:pass@cluster.mongodb.net/event-management"
AUTH_SECRET="a-long-random-secret-string"
NEXTAUTH_SECRET="a-long-random-secret-string"
NEXTAUTH_URL="http://localhost:3000"
AUTH_TRUST_HOST="true"
JWT_SECRET="a-long-random-secret-string"
# ββ Public URLs βββββββββββββββββββββββββββββββββββββββ
NEXT_PUBLIC_SITE_URL="http://localhost:3000"
NEXT_API_URL="http://localhost:3000"
# ββ Cron (waitlist expiry authorization) ββββββββββββββ
CRON_SECRET="a-random-cron-secret"
# ββ SMTP fallback (optional β preferably set in admin Settings) ββ
SMTP_HOST="smtp.gmail.com"
SMTP_PORT="587"
SMTP_SECURE="false"
SMTP_USER="you@gmail.com"
SMTP_PASS="your-app-password"
FROM_EMAIL="you@gmail.com"
FROM_NAME="Evently"
# ββ Cloudinary (optional β preferably set in admin Settings) ββ
CLOUDINARY_CLOUD_NAME=""
CLOUDINARY_API_KEY=""
CLOUDINARY_API_SECRET=""
| Variable | Required | Description |
|---|---|---|
MONGODB_URI | β Yes | MongoDB connection string. The app uses the database template-event-management (set in config/database.ts). |
AUTH_SECRET / NEXTAUTH_SECRET | β Yes | Secret used to sign sessions. Generate with openssl rand -base64 32. |
JWT_SECRET | β Yes | Secret used to sign the API Bearer JWTs. |
NEXTAUTH_URL / AUTH_TRUST_HOST | β Yes | Canonical app URL + trust the deployment host. |
NEXT_PUBLIC_SITE_URL / NEXT_API_URL | Recommended | Absolute URLs for metadata, sitemap, and server-side fetches. |
CRON_SECRET | Recommended | Authorizes the waitlist-expiry cron endpoint. |
SMTP_* / CLOUDINARY_* | Optional | Fallbacks when the corresponding admin Settings are empty. |
Important: SMTP and Cloudinary credentials are read first from the database Settings (set in the admin), and only fall back to env variables. Configuring them in the admin panel is the recommended path.
First-Run Setup
On its first connection to an empty database, the app auto-creates a default Super Admin so you can sign in immediately.
| Default admin email | admin@evently.com |
| Default password | ChangeMe123! |
| Login page | /staff/login β routes to /super-admin/dashboard |
-
Start the app & sign in
Run
pnpm dev, open/staff/login, and sign in with the default Super Admin credentials above. -
Seed demo data (optional)
Open Super Admin β Seed (or POST
/api/events/seedas a Super Admin) to populate demo organizers, attendees, venues, events, tickets, registrations, speakers, sponsors, team members, contacts and newsletter subscribers.Warning: Seeding replaces demo content and is intended for a fresh/dev database only. Do not run it against production data.
-
Secure the account
Immediately change the default Super Admin password (and email) from Profile / Settings before going live.
Demo Accounts
The default Super Admin is created automatically on first run. Additional demo organizer and attendee accounts are created by the seeder β the exact emails and shared password are listed on the Super Admin β Seed page after seeding.
| Role | Login Page | Password | |
|---|---|---|---|
| Super Admin | admin@evently.com | /staff/login | ChangeMe123! |
| Organizer | see Seed page | /staff/login | see Seed page |
| Attendee | see Seed page | /login | see Seed page |
Before going live: change the default Super Admin credentials and never run the seeder against production data.
Project Structure
The project follows the Next.js App Router convention with route groups for clean separation between public, auth, and dashboard areas.
Note: In Next.js 16 the middleware file is named proxy.ts (with a default export), not middleware.ts. Route protection logic lives there.
User Roles & Access
Three roles drive access control. Staff (Super Admin, Organizer) sign in at /staff/login; attendees sign in at /login.
| Capability | Super Admin | Organizer | Attendee |
|---|---|---|---|
| Dashboard | β Platform-wide | β Own events | β Own activity |
| Events / Sessions / Tickets | β All | β Own | browse / register |
| Registrations & Check-in | β All | β Own events | own only |
| Speakers / Sponsors / Venues | β | β Own | browse |
| Waitlist / Badges / Certificates | β | β Own | own only |
| Users / Team / Plans / CRM | β | β | β |
| Expenses / Subscriptions | β All | β Own | β |
| Settings / Seed / Audit Logs | β | β | β |
Routing & Pages
Page URLs are centralised in lib/routes.ts via the ROUTES helper. Middleware (proxy.ts) guards dashboard routes and redirects users to the correct area based on their role.
Public routes
/ | Landing page (dynamic, admin-editable) |
/events Β· /events/[slug] | Event catalogue & detail with registration |
/speakers Β· /venues | Speaker & venue directories |
/jobs Β· /jobs/apply | Careers board & application form |
/testimonials/submit | Submit a platform testimonial |
/badge/[id] Β· /certificates/verify | Public badge view & certificate verification |
/about-us Β· /contact-us | Content & contact pages |
/privacy-policy Β· /terms-and-conditions | Legal pages (rich-text from settings) |
Auth routes
/login Β· /register | Attendee auth |
/staff/login | Staff (super admin / organizer) auth |
/forgot-password Β· /reset-password | Password recovery |
Dashboard roots
/super-admin/* | dashboard, events, sessions, tickets, registrations, waitlist, venues, speakers, sponsors, exhibitors, badges, certificates, volunteers, users, team, expenses, coupons, crm, plans, subscriptions, jobs, newsletter, contact, audit-logs, settings, seed |
/organizer/* | dashboard, events, sessions, tickets, registrations, venues, speakers, sponsors, expenses, subscription, profile |
/attendee/* | dashboard, registrations, waitlist, badges, certificates, agenda, profile |
Authentication
The template uses a hybrid auth model:
- NextAuth v5 session protects pages via the
proxy.tsmiddleware and stores the access token in the session. - Bearer JWT protects the REST API. Tokens are signed with
JWT_SECRETand verified by the API auth helper.
Login flow
Calling a protected endpoint
fetch("/api/events/attendee/registrations", {
headers: { "Authorization": `Bearer ${token}` }
})
Every protected handler is wrapped with asyncHandler, which connects to the database, verifies the Bearer token, enforces an optional allowed-roles list, and validates the request body against a Zod schema before your handler runs. Passwords are hashed with bcrypt; email verification uses a time-limited OTP and password reset uses a signed token delivered by email.
Admin Settings
Almost everything is configurable from Super Admin β Settings β no code edits needed. Settings are stored as a single document and cached (revalidated when saved).
| Section | What it controls |
|---|---|
| General | Site name, tagline, email, phone, address, social links, favicon, currency, maintenance mode. |
| Cloudinary | Cloud name, API key/secret, upload folder β powers all image uploads. |
| SMTP | Host, port, security, user/pass, from-name/email. Includes a Send test email action. |
| Metadata | SEO title, application name, description, keywords, Open Graph image. |
| Legal & About | Rich-text About Us, Privacy Policy, Terms & Conditions and Testimonials content. |
| Landing Page | The full dynamic homepage builder + brand colors (see below). |
Tip: Turn on Maintenance Mode in General settings to show a maintenance screen to public visitors while you make changes.
Theming & Branding
The design system is driven by CSS variables in app/globals.css and Tailwind v4 tokens. Light and dark modes are handled by next-themes. The template ships a green & white theme by default.
Brand colors
Primary, secondary and accent brand colors are exposed as CSS variables. The public site and dashboards read the admin-configured colors from the landingPage branding settings, applied through a scoped wrapper (brandVars() in the layouts) so the UI restyles without touching component classes. Defaults live in lib/landing-page-defaults.ts.
// lib/landing-page-defaults.ts
BRAND_DEFAULTS = {
primaryColor: "#16a34a", /* green-600 */
secondaryColor: "#22c55e", /* green-500 */
accentColor: "#06b6d4", /* cyan-500 */
}
Change the brand colors
Set them from Super Admin β Settings β Landing Page (branding). The public site and admin dashboards pick them up automatically.
Logo & favicon
Upload your logo and favicon under Settings β General; they are wired into the header and document <head> automatically.
Landing Page Builder
The homepage is fully data-driven from Settings β Landing Page. Each section can be edited and populated with images without touching code.
| Section | Editable Content |
|---|---|
| Hero | Badge, title, description, background image, CTA labels, and stat counters. |
| Features | Section heading + feature items (icon, title, description). |
| Testimonials | User-submitted testimonials (rating, content) with approval & feature toggles, shown in a carousel. |
| Team | Public team members (name, role, bio, avatar, socials). |
| FAQ & Newsletter | Frequently asked questions and the newsletter signup block. |
| Branding | Primary, secondary & accent brand colors for the site. |
Sensible defaults ship in lib/landing-page-defaults.ts, so the homepage looks complete before you customise anything.
Database Models
All Mongoose schemas live in /model (28 total). Every model includes timestamps and a softDelete flag (records are flagged, not physically removed).
| Model | Purpose |
|---|---|
Event | Core event β title, dates, venue, category, status, speakers, sponsors, capacity, featured. |
Session | Agenda session β time window, track, room, speaker(s), concurrent flag. |
Ticket | Ticket tier β name, price, quantity, sold, sale window, max per order. |
Registration | Attendee registration β quantity, total, status, confirmation code, check-in state. |
Waitlist | Sold-out queue β status, 48-hour notification window, conversion. |
Speaker Β· Sponsor Β· Exhibitor | Speaker profiles; tiered sponsors; exhibition booth holders. |
Venue | Venue β type (indoor/outdoor/virtual/hybrid), capacity, amenities. |
Badge Β· Certificate | Check-in badges (QR, VIP flags); post-event certificates + verification. |
Plan Β· OrganizerSubscription | Organizer plans (pricing/interval); subscription assignment & status. |
Coupon Β· CRM | Discount codes; organizer contact/relationship records. |
Volunteer Β· Agenda | Volunteer registrations; event schedule/itinerary. |
JobApplication | Career applications β resume, cover letter, status pipeline. |
AIEventTemplate | AI-suggested event templates (titles, agenda, tickets, SEO). |
User Β· Team | Platform users (role/auth); public About-page team members. |
Expense | Categorised business expenses linked to events. |
Contact Β· Newsletter Β· Testimonial | Contact submissions; subscribers; user testimonials. |
Notification Β· AuditLog Β· Settings | In-app notifications; audit trail (365-day TTL); singleton settings. |
Lifecycles & Status Enums
Event
Registration & Ticket
Registration: confirmed Β· pending Β· cancelled Β· waitlisted. Ticket: active Β· sold_out Β· cancelled. When a ticket sells out, new registrations are added to the Waitlist.
Waitlist
When a spot opens, the next person is notified and holds it for 48 hours. If they don't convert, a cron job marks them expired and notifies the next in line.
Other enums
| Venue type | indoor Β· outdoor Β· virtual Β· hybrid |
| Sponsor tier | platinum Β· gold Β· silver Β· bronze Β· partner |
| Subscription | active Β· trialing Β· canceled Β· expired |
| Coupon | percentage Β· fixed |
| Volunteer | registered Β· confirmed Β· checked_in Β· completed Β· cancelled |
| Job application | new Β· reviewed Β· shortlisted Β· interviewed Β· rejected Β· hired |
| Contact | new Β· in_progress Β· resolved Β· closed |
| Expense category | venue Β· catering Β· marketing Β· equipment Β· speakers Β· staff Β· travel Β· other |
Cron Jobs
A single scheduled job keeps the waitlist moving. It releases expired 48-hour holds, promotes the next person in the queue, and sends the relevant emails.
Authorized with the CRON_SECRET (Bearer header). Recommended cadence: every 15 minutes.
Schedule it with a Vercel Cron entry or an external scheduler (e.g. cron-job.org) hitting the endpoint with Authorization: Bearer <CRON_SECRET>.
API Conventions
All endpoints live under /api. The main API is namespaced under /api/events. NextAuth's handler lives at /api/auth/[...nextauth].
Standard response envelope
{
"status": true,
"message": "Operation successful!",
"data": { /* payload or null */ },
"pagination": { /* present on list endpoints */ }
}
Authentication header
Authorization: Bearer <jwt-token>
| Code | Meaning |
|---|---|
200 / 201 | Success |
400 | Validation failed |
401 | Missing / invalid / expired token |
403 | Authenticated but not permitted (wrong role) |
404 | Resource not found |
409 | Conflict (e.g. email in use, already registered, sold out) |
500 | Server error |
Public = no token required Β· Auth = Bearer token + role required
Tip: A ready-to-import postman_collection.json ships in the project root (regenerate with pnpm generate-postman).
Auth API
Base path: /api/events/auth
Authenticate a user. Body: { email, password }. Returns { token, role }.
Create an attendee account. Body: { name, email, password, phone? }.
Return the current authenticated user's profile.
Email a password-reset token. Body: { email }.
Set a new password using the emailed token. Body: { token, password }.
Change password. Body: { currentPassword, newPassword }.
Public API
Base path: /api/events/public β no authentication required.
Attendee API
Base path: /api/events/attendee β requires an attendee Bearer token.
Organizer API
Base path: /api/events/organizer β requires an organizer Bearer token. Scoped to the organizer's own resources.
Super Admin API
Base path: /api/events/super-admin β requires a Super Admin Bearer token. Full CRUD across every module. Each resource below supports the standard set (GET list & [id], POST, PUT, DELETE) unless noted.
Dashboard & Platform
Events & Content
People & Growth
Settings
Notifications & Seed
Base path: /api/events/notifications
List the current user's notifications with unread count.
Mark a single notification as read.
Populate the database with demo data. Use only in development.
Deployment
The app deploys anywhere that runs Node.js. Vercel is the simplest path.
Vercel
Push to Git
Push the project to a GitHub/GitLab repo.
Import to Vercel
Create a new project and import the repo.
Add environment variables
Copy every key from your
.env.localinto the Vercel project settings. SetNEXTAUTH_URLand the public URLs to your production domain.Add the waitlist cron
Configure a Vercel Cron (or external scheduler) to POST
/api/events/cron/waitlist-expiryevery ~15 min with theCRON_SECRET.Deploy
Vercel builds with
pnpm buildautomatically.
Self-hosted / VPS
pnpm install
pnpm build
pnpm start # serves on port 3000 β put Nginx/PM2 in front
Production checklist: set strong AUTH_SECRET/JWT_SECRET/CRON_SECRET, point all URLs to your domain, configure SMTP & Cloudinary in admin Settings, change the default Super Admin credentials, and never run the seeder against production data.
Troubleshooting & FAQ
Which login page do I use?
Staff (Super Admin, Organizer) sign in at /staff/login; attendees at /login. New registrations are created with the attendee role.
The build fails trying to reach the database
The template is designed to build without a live DB β settings are skipped during the build phase and DB-backed pages are dynamic. Make sure you're on the latest code and that config/database.ts only reads MONGODB_URI lazily (inside dbConnect).
Database connection fails at runtime
Verify MONGODB_URI and that your IP is whitelisted in MongoDB Atlas (Network Access). The app uses the database name template-event-management.
Emails aren't sending
Configure SMTP in Settings β SMTP and use the Send test email button. For Gmail, use an App Password, not your account password.
Image uploads fail
Fill in Cloudinary credentials under Settings β Cloudinary. Without them, image upload features are disabled.
Waitlist holds never expire
The /api/events/cron/waitlist-expiry job must run on a schedule with the correct CRON_SECRET. Check your Vercel Cron / external scheduler.
Build error: middleware not found
This project uses Next.js 16, where middleware is proxy.ts with a default export β do not rename it to middleware.ts.
Public site shows a maintenance screen
Maintenance Mode is enabled in Settings β General. Turn it off to restore the public site.
Support & Credits
Thank you for choosing Evently β Event Management System. We hope it accelerates your project.
π Documentation
This guide is bundled as documentation.html / documentation.pdf and is also served live at /documentation.
π Support
For help, use the support channel listed on the item's download page. Please include your environment details and any error messages.
Built with
Next.js Β· React Β· TypeScript Β· MongoDB Β· Mongoose Β· Tailwind CSS Β· Radix UI Β· NextAuth Β· Zod Β· React Hook Form Β· TanStack Table Β· Recharts Β· Framer Motion Β· Cloudinary Β· Nodemailer Β· jsPDF Β· qrcode Β· TipTap Β· Zustand.
Enjoying the template? A rating and review are hugely appreciated and help us keep improving it.