Modern event discovery and management platform built with Next.js, Clerk, Prisma, and Tailwind CSS.
Eventify lets admins and organizers publish events, collect RSVPs, and send automated reminders while giving attendees rich search, filtering, an animation-rich browsing experience, and agenda tools.
- Live demo: https://eventifylive.vercel.app
Screenshots:
- Overview
- Key Features
- Tech Stack
- Architecture / Folder Structure
- Getting Started
- Development
- Testing
- Deployment
- Known Limitations & Roadmap
- Contributing
- License
Eventify is a full-stack web application built on the Next.js App Router. It supports authenticated, role-based experiences via Clerk, with dedicated dashboards for admins and organizers and a PostgreSQL database managed through Prisma.
It provides:
- Creation and moderation tools for events
- Attendee RSVP flows with reminder scheduling
- Automated transactional emails via Brevo
- Timezone-aware ordering and agenda tools
- A highly animated UI powered by Motion One and custom 3D/tilt effects
-
Role-based access control
Admin, organizer, and user roles enforced at the middleware layer, with onboarding gates and protected routes for admin/organizer dashboards and event creation flows. -
Profile & contact management
Uses Clerk’sUserButtonas the entry point to the account menu and extends theUserProfileview with a role-aware contact panel.
Organizers and admins get a dedicated phone number section (linked from an extra “Contact” item in theUserButtonmenu) so they can keep their event contact details in sync with their profile. -
Event lifecycle management
Create, update, and delete server actions validate business rules (time zone-aware date checks, contact requirements), normalize search fields, and revalidate relevant pages and cached lists. -
Advanced filtering and search
Search across title, location, category, date, and organizer with pagination helpers for organizer/admin views and homepage data loaders. Ordering is viewer timezone-aware so “today” and “upcoming” are computed correctly. -
Timezone-aware scheduling & viewing
Events are stored with both their absolute UTC timestamp and precomputed local keys (eventLocalDateKeyandeventLocalMinuteOfDay) in the event’s own timezone.
On the frontend, a viewer timezone context detects the user’s timezone and orders lists (Home, Agenda, dashboards) by their local day. UI components expose a toggle between event timezone and viewer timezone so start times, “today”, and reminder windows are consistent and predictable. -
RSVP system
Tracks attendee status, reminder preferences, and unique per-user/event combinations in the database schema. Server actions enforce unique(user, event)constraints and keep reminders in sync with RSVP changes. -
Featured events
Featured events are automatically derived from RSVP thresholds with environment-configurable limits, plus explicit admin overrides. This allows “organic” popularity to surface events while still giving admins final control. -
Automated reminders
A cron endpoint/api/cron/send-reminders(secured by shared secret header) selects due reminders and dispatches transactional emails via Brevo (Transactional Emails API). Reminder types include day-of and 48-hours-before windows. -
Email templates
Reminder emails are built with React Email (sharedEmailLayout+ reusable UI primitives ) and rendered to HTML on the server before sending. Templates can be previewed locally vianpm run preview:email. -
Agenda & upcoming events
Dedicated Agenda and Upcoming pages honor the viewer’s timezone for ordering and “today” logic. Data loaders and cookie-based timezone detection ensure consistent behavior across devices and sessions. -
End-to-end coverage
Playwright tests cover authentication, onboarding, event creation, filters, agenda flows, reminders, and role guards. Test flows rely on pre-seeded data and a dedicated E2E environment.
-
Motion One–driven interface
Pervasive micro-interactions across cards, lists, navigation, onboarding flows, forms, and search/filters give the app a premium feel while honoringprefers-reduced-motion. -
3D and tilt effects on event cards
ArcEventCardcomponents use perspective transforms, hover-driven floating states, and mirrored rotations in carousels so leading and trailing cards rotate in opposite directions. -
Agenda’s
TiltedInfiniteListengine
Combines tilt, 3D perspective, parallax, autoplay, scroll/drag physics, and recentering of the peeked item to create an immersive, timeline-like event browsing experience (some of these features are turned off for performance e.g. parallax effect). -
Animated backgrounds with OGL
Plasma, Threads, and Ripple Grid backgrounds render dynamic WebGL scenes with mouse/scroll interaction and safe fallbacks for reduced-motion users. -
Animated icon system
Lordicon-based icon components with configurablein,hover,click,loop, andmorphanimations provide rich feedback for key actions (navigation, empty states, reminders, etc.). -
Animated typography & UI polish
Kinetic headings, animated counters, button/hover feedback, and interactive search/filter panels with tuned easing/durations. The design emphasizes smooth micro-interactions, sensible defaults, and graceful behavior when animations are disabled.
- Framework: Next.js 15 (App Router) with React 19 and TypeScript
- Styling: Tailwind CSS 4 + custom animated components and Radix UI primitives
- UI & Animation: Motion One, OGL-powered backgrounds, Lordicon-based icon system
- Auth: Clerk (user management, sessions, role metadata) with middleware-enforced RBAC
- Database: PostgreSQL (Neon-friendly) via Prisma, with generated client in
src/generated/prisma - Email: Brevo (Transactional) + React Email templates (server-rendered to HTML)
- Testing: Vitest + Testing Library (unit/integration), Playwright (end-to-end flows)
High-level layout:
src/app/– Next.js App Router routes- Public pages (home, event details, about, etc.)
(dashboard)area with admin, organizer, agenda, RSVP, and email template routes- API routes and cron endpoints under
/api
src/components/– UI building blocks and complex widgets- Forms, cards, animated backgrounds, navigation
- Agenda widgets, admin/organizer dashboards
- Animated text, icons, motion utilities
src/lib/– Shared utilities- Data fetching and pagination helpers
- Timezone and ordering helpers
- Constants (featured thresholds, pagination)
- Prisma client, reminder helpers, animation presets, cleanup routines
src/contexts/– React context providers (event state, viewer timezone, menu context, etc.)src/schemas/– Zod schemas used across forms and server actionsprisma/– Database schema and seed scripts (including E2E seed)e2e/– Playwright specs, auth fixtures, helpers, and global setup
Example tree (simplified):
src/
app/
(dashboard)/
admin/
organizer/
agenda/
api/
events/
rsvp/
cron/
components/
Home/
Menu/
Agenda/
common/
contexts/
lib/
schemas/
prisma/
schema.prisma
seed-e2e.ts
e2e/
helpers/
01_smoke.spec.ts
02_events.spec.ts
...- Node.js 18+
- npm (or pnpm/yarn if you adapt commands)
- A PostgreSQL database (e.g., Neon or any compatible provider)
npm install
# or: pnpm install / yarn installCreate a .env file (or .env.local for Next.js) with the following keys (adapt as needed):
Core
DATABASE_URL– PostgreSQL connection string for PrismaNEXT_PUBLIC_SITE_URL– Base site URL for metadata/SEO (defaults tohttp://localhost:3000if unset)
Clerk / Auth
CLERK_SECRET_KEY– Clerk backend secret keyNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY– Clerk frontend publishable keyCLERK_WEBHOOK_SECRET– Svix secret used to validate Clerk webhooks that sync users/roles into the database
Email / Reminders
RESEND_API_KEY– Resend API key for transactional emailsEMAIL_FROM_ADDRESS– Verified sender address used by Resend for reminder emails
Payments / Stripe
STRIPE_SECRET_KEY– Stripe secret key used for PaymentIntents, refunds, and Connect onboardingSTRIPE_WEBHOOK_SECRET– Signing secret for/api/webhooks/stripeSTRIPE_CONNECT_WEBHOOK_SECRET– Signing secret for/api/webhooks/stripe-connect(Events on connected accounts)PLATFORM_FEE_BPS(optional) – Platform fee in basis points for destination charges. Current product direction uses1000(10%).PLATFORM_FEE_CENTS(optional) – Flat platform fee in cents for destination charges. When this is set to a value greater than0, it takes precedence overPLATFORM_FEE_BPS.STRIPE_ESTIMATED_FEE_BPS(optional) – Preview-only Stripe fee estimate in basis points (defaults to290).STRIPE_ESTIMATED_FIXED_FEE_CENTS(optional) – Preview-only fixed Stripe fee estimate in minor currency units (defaults to30).REFUND_REQUEST_CUTOFF_HOURS(optional) – Buyer refund-request cutoff window before the event starts (defaults to4)
Stripe webhook events currently handled:
payment_intent.succeededpayment_intent.processingpayment_intent.canceledpayment_intent.payment_failedrefund.updatedcharge.dispute.createdcharge.dispute.updatedcharge.dispute.closed
Stripe Connect webhook setup:
- Create a second Stripe webhook endpoint configured to listen to
Events on connected accounts. - Point it to
/api/webhooks/stripe-connect. - Subscribe at minimum to
account.updated. - Save that endpoint's signing secret to
STRIPE_CONNECT_WEBHOOK_SECRET.
One-off Stripe Connect bootstrap (sandbox/dev):
- Dry-run (organizers only):
npm run bootstrap:stripe-connect - Apply changes:
npm run bootstrap:stripe-connect -- --apply - Repair stale/missing account ids explicitly:
npm run bootstrap:stripe-connect -- --apply --repair-missing - Optional cohort flags:
--include-admins,--only-missing,--only-clerk-id=<id>,--limit=<n>,--json-report=<path>
Cron / Featured Events
CRON_SECRET– Shared secret required (header + query) to access/api/cron/send-remindersFEATURED_THRESHOLD(optional) – Server-side default auto-feature threshold for confirmed RSVPsNEXT_PUBLIC_FEATURED_THRESHOLD(optional) – Client-side copy of the threshold for UI/tooltips
Debug / Flags
NEXT_PUBLIC_DEBUG_EVENTS(optional) – Enable client debug mode for event contextNEXT_PUBLIC_E2E(optional) – Flag to enable E2E-specific behavior/guards in UI and server actions
For end-to-end (E2E) testing, the project uses a separate environment file at the repo root: .env.e2e.
This file points to a dedicated test database and a test-only Clerk environment so Playwright runs can safely reset and seed data without touching your main development or production DB.
Minimum keys:
NODE_ENV="test"– ensures the app/tooling run in test modeDATABASE_URL– test database (e.g., a separate Neon branch namede2e)NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY– Clerk publishable key for the test environmentCLERK_SECRET_KEY– Clerk secret key for the test environmentCLERK_WEBHOOK_SECRET– Svix signing secret for Clerk webhooks in the test environment
Additional E2E-related variables:
NEXT_PUBLIC_FEATURED_THRESHOLD/FEATURED_THRESHOLD– testing threshold (e.g.2confirmed RSVPs)NEXT_PUBLIC_E2E– set to1to enable E2E-specific behaviorPW_INTERACTIVE– set to1for more interactive Playwright runs when needed
Dev/test users in Clerk are configured via a set of E2E_* variables, for example:
E2E_FRESH_EMAIL,E2E_FRESH_PASSWORD,E2E_FRESH_USERNAMEE2E_USER_CLERK_ID,E2E_USER_EMAIL,E2E_USER_PASSWORD,E2E_USER_USERNAMEE2E_ORG_CLERK_ID,E2E_ORG_EMAIL,E2E_ORG_PASSWORD,E2E_ORG_USERNAME,E2E_ORG_PHONEE2E_ADMIN_CLERK_ID,E2E_ADMIN_EMAIL,E2E_ADMIN_PASSWORD,E2E_ADMIN_USERNAME,E2E_ADMIN_PHONE
During E2E runs, the Playwright global-setup script uses these values to reconcile Clerk and the database:
- If a dev user from
.env.e2edoes not exist in Clerk, it is created. - If it exists but its email/username differs from
.env.e2e, it is updated in Clerk. - After the E2E seed runs (which inserts users with placeholder
clerkIdvalues such ase2e_admin), the setup step rewrites those records to use the real Clerk user IDs.
This means you do not have to manually align the database with Clerk; keeping .env.e2e in sync with your dev users is enough.
Generate the Prisma client and push/migrate the schema:
# Generate Prisma client
npx prisma generate
# Apply schema to the database
npx prisma db push # or: npx prisma migrate devE2E seed data (used by Playwright flows) is available via:
npm run e2e:reset # pushes schema to .env.e2e database
npm run e2e:seed # seeds test users/events/remindersDemo seed data (dev/sandbox, reuses existing users) is available via:
npm run seed:demo
npm run seed:demo -- --with-payment-fixturesPayment fixtures created with --with-payment-fixtures are DB-only synthetic records for UI/testing and are not backed by real Stripe PaymentIntents.
Common development commands:
-
Start the dev server (with Turbopack):
npm run dev
-
Lint the project:
npm run lint
-
Build and preview production:
npm run build npm run start
-
Preview email templates locally:
npm run preview:email
Eventify has unit, integration, and end-to-end tests.
-
Location:
src/**/__tests__and related test files -
Commands:
npm test # run unit/integration tests npm run test:watch # watch mode npm run test:ci # CI mode with coverage
Requires .env.e2e, a dedicated test DB, and seeded data.
Typical flow:
npm run pree2e # reset schema + seed E2E DB
npm run e2e # run Playwright tests in headless mode
npm run e2e:ui # run Playwright with UI
npm run e2e:report # open HTML report (if configured)Playwright specs cover:
- Homepage smoke flows
- Onboarding and role guards
- Event creation and editing
- Search filters and pagination
- Agenda / TiltedInfiniteList behavior
- Reminder scheduling and “too close to event” guards
Eventify is designed for deployment on Vercel with a managed PostgreSQL provider such as Neon:
-
Provision Database
Create a PostgreSQL instance (e.g., Neon) and setDATABASE_URLin your hosting environment. -
Set Environment Variables
Configure the same env vars used locally (DATABASE_URL, Clerk keys, Resend keys,CRON_SECRET, etc.) in your Vercel project settings. -
Migrations / Schema
Runprisma db pushorprisma migrate deployagainst the production database before (or as part of) deployment. -
Clerk Setup
- Configure redirect URLs to match your deployed domain.
- Set webhook endpoint to
/api/webhooks/clerkusingCLERK_WEBHOOK_SECRET.
-
Email & Cron
-
Set
BREVO_API_KEYandEMAIL_FROM_ADDRESS. -
Configure an external cron (e.g., Vercel Cron) to call:
Authorization: Bearer <CRON_SECRET>
-
Once configured, pushing to your main branch can trigger automatic deployments via Vercel.
- Reminder delivery depends on externally scheduled cron jobs; missing or misconfigured secrets will prevent sending and only log errors.
- Pick a provider and integrate image and video to events.
- Add Organizer's exclusive page profile, save previous organized events and maybe introduce a score functionality.
- Dynamic pages for events.
- Make full use of RSVPs "status" property, can be useful with payment integration.
This code is for personal use only and is not authorized for commercial use or redistribution without the author's explicit permission.



