// PROJECT_

UnderEvents

React 18

01. LIVE_DEMO

// DEMO
LIVE

// LIVE PREVIEW

UnderEvents

VISIT_SITE

02. PROJECT_OVERVIEW

Final group project for the Soy Henry Full-Stack bootcamp: a complete e-commerce platform for underground and niche events across Europe, built and shipped by a team simulating a real software company — Scrum ceremonies, Jira boards and sprint planning included. I led frontend design and architecture, defining the component structure, state management and UI/UX from scratch. React SPA on the frontend with Auth0 login, Stripe ticket checkout, interactive Leaflet maps and EN/DE multilingual support. Node.js REST API on the backend with RS256 JWT validation, Stripe webhook order lifecycle, Brevo transactional email and Redis caching.

Status

Active Development

Scope

Full-Stack Architecture

Primary Stack

React 18

Repo

Public

03. TECH_STACK & ARCHITECTURE

//React SPA on Vercel — Redux store as single source of truth, all server state flows through Thunk actions

//Node.js REST API on Railway — service layer pattern: routes → controllers → services → Sequelize models

//Auth0 covers both ends: loginWithPopup on client, RS256 JWT + jwks-rsa validation on server

//Stripe Elements on client (PCI scope minimal) + webhooks on server drive the full order lifecycle

//Brevo transactional email triggered server-side on payment success and failure

//ioredis caches event listings and filter results — reduces repeat DB hits on high-traffic reads

React 18 + Vite

Frontend — UI Framework

SPA with 72 components. Vite replaces CRA for faster HMR. Protected routes via React Router DOM v6 — vercel.json rewrite rule for correct SPA refresh behavior.

Redux Toolkit

Frontend — State Management

Centralized store for events, filters, user session and cart. Async Thunk actions + Axios handle all API calls. Single source of truth between components.

Auth0

Frontend + Backend — Authentication

OAuth 2.0 / OpenID Connect. loginWithPopup on client — on first login, user is created in DB via POST /users. RS256 JWT passed as Bearer token on every protected API call. express-jwt + jwks-rsa validate it server-side — no secret stored.

Stripe

Frontend + Backend — Payments

@stripe/react-stripe-js Elements on the client — raw card data never touches the app. Server creates payment intents and listens to webhooks: on success, Order + Ticket statuses update and Brevo triggers a confirmation email.

Node.js 18 + Express 4

Backend — Runtime & API

RESTful API with /events and /users route groups. Middleware chain: CORS → bodyParser → morgan → JWT validation → controller. Service layer pattern separates route logic from business logic.

PostgreSQL + Sequelize v6

Backend — Database

5 models: Event, User, Ticket, Order, Reviews. UUID primary keys. Associations: User→Event, Order↔Event (junction table order_event), Order→Ticket. Deployed on Railway via DATABASE_URL.

Leaflet + React Leaflet

Frontend — Maps

Interactive venue maps on event detail pages. Marker clusters for multi-event views. Tile layers loaded lazily — no map overhead on pages that don't need it.

i18next

Frontend — Internationalization

EN / DE language support with browser language detection. All UI strings externalized to JSON translation files — zero configuration for end users.

Brevo API + ioredis

Backend — Email & Caching

Brevo HTTP API replaced Nodemailer for higher deliverability — HTML templates dispatched on payment success and failure. ioredis caches high-frequency event listing and filter queries to reduce DB load.

Bootstrap 5 + Styled Components

Frontend — Styling

Bootstrap handles responsive grid and layout. Styled Components drive the custom gold/dark theme via CSS variables — component-scoped styles with no class name collisions.

Formik + Yup + Chart.js

Frontend — Forms & Analytics

Schema-based validation for event creation and profile forms. Admin dashboard renders Chart.js charts for ticket sales, event metrics and user activity over time.

Mocha + Chai + Supertest

Backend — Testing

Integration tests hit the real Express app instance via Supertest — no port binding needed. Tests run against the actual middleware chain and DB models.