Aristocrat — an invitation-only B2B club and its admin panel

A membership site for a Baku business club that admits members by invitation only. Built full-stack on Next.js: a multi-step application flow, an events calendar and an admin panel the club runs itself — for events, news and incoming applications. There is deliberately no database; all data lives in JSON files on the server.

Visit live site
Overview
Client
Aristocrat Social & Business Club — closed B2B network, Baku
Role
Full-stack development — page architecture, multi-step form logic, Next.js route handlers, a JSON-backed content layer, a JWT-protected admin panel, the component system, animations and the VPS deployment (PM2 + Nginx).
Stack
Next.js · TypeScript · JWT Auth · JSON Storage · Tailwind CSS
Date
August 2026
Languages
3 — AZ / EN / RU
The problem

A site for an invitation-only club has to do two contradictory jobs at once: introduce the club without inviting everyone. A large “sign up” button breaks the claim of exclusivity on the very first screen; a site with no route to apply is simply non-functional. The second problem starts once the site is live. The events calendar is the only visible proof that the club is alive — and a calendar full of past dates says the opposite. Applications are the same: the club's entire intake runs through that form and it must not get lost in an inbox. The site did not just have to be built; it had to be maintainable by the club itself.

What the site includes
  • Multi-step application form — one question at a time, with a progress indicator
  • 2026 annual events calendar with dates and venue details
  • Audience segments: entrepreneurs, startups, senior executives
  • Benefits section: closed network, exclusive events, investment access, knowledge exchange
  • Partners section
  • Editorial sections explaining the philosophy of the club
  • A dedicated events page — upcoming events by date and category (Closed Summit, Informal Meeting, Gala)
  • A dedicated news page
  • Membership split into two tracks: individual (Individuals) and corporate (Companies)
  • Admin panel: create, edit and delete events, with date, venue and category
  • News articles published from the admin panel
  • Applications from the form listed inside the panel
  • Event and news images uploaded straight from the panel
  • JWT-protected admin login — panel routes are closed at middleware level
Architecture
Frontend
Next.js App Router. Home page, membership tracks, events, news and the application pages. The interface runs in three languages and the choice is kept in the browser — there is no separate URL per language, a trade-off explained under the technical decisions below.
Backend
There is no separate API server — the backend is a set of route handlers inside the same Next.js app: receiving applications, writing events and news, handling image uploads. The admin panel lives on the `/admin` routes of that same project, so type definitions, components and the deployment pipeline are shared with the public site.
Data layer
There is no database. Events, news and incoming applications are stored as JSON files on the server's disk: the admin panel writes the file, the pages read it. The reasoning is in the “Why no database?” decision below.
Authentication
A hand-rolled JWT flow: the token is signed server-side and written into an `httpOnly` cookie. Everything under `/admin` is checked both at middleware level and inside each individual route handler.
Media
Event and news images are uploaded from the admin panel and written to the VPS disk; on the site they are served through `next/image`.
Infrastructure
The Next.js server process runs on a VPS under PM2, with Nginx in front as a reverse proxy — SSL, compression and static-file caching sit there.
Technical decisions
01

Why a multi-step form?

A membership application needs a lot of questions. Showing them all on one screen scares people off. I broke the form into steps and added a progress indicator — with one question per screen, people are far more likely to finish what they started.

02

The design filters the audience

The club is not mass-market, and the visual language has to say so: quiet colours, generous whitespace, editorial typography. A bright, cheerful design would have contradicted the message — the site signals who it is inviting through the way it looks, not only through what it says.

03

Static generation for an instant open

The content of the presentation pages rarely changes, so they are generated as ready HTML at build time. There is no server wait — someone arriving with an invitation finds the site already open. Content that does change, like events and news, is read from the server instead.

04

Membership split into two separate tracks

An entrepreneur's individual membership and a company's corporate package are not the same product — the price, the benefits and the person signing off all differ. Separating the two paths in the menu puts each buyer on their own page with the first click. A single “membership” page would have half-answered both.

05

The events page offers a calendar instead of a promise

The biggest doubt about a closed club is whether anything actually happens there. A list of events with dates and categories closes that doubt at a glance — the answer comes from the data itself, not from a paragraph of copy. This is the section that turns the site from a static brochure into the club's live shop window.

06

The Baku skyline in the background, not a stock photo

The club is not an international network; it is the business environment of one specific city. The hero carries the recognisable Baku skyline, so a visitor understands within a second where this club sits and among whom. A neutral stock photograph would have filled the same space and said nothing.

07

Why no database?

The club's entire dataset is a handful of records: dozens of events a year, a few dozen news items, a few applications a month. Setting up a relational database at that volume means another process, another backup regime and migration discipline — for no real gain. The data lives in JSON files on the server: the admin panel writes the file, the page reads it. A backup is a copied folder, and the history of the content is visible in the files themselves. This is not a “there was no time to set up a database” decision — it is a decision sized to the load. A database becomes necessary when the write rate rises and several people start editing at once; not before. The hard part of engineering is not adding technology, it is the discipline of not adding what is not needed.

08

A calendar only counts as proof while it is current

I argued above that the events page is the club's live shop window — that is true only while the calendar stays current. A page full of past dates shows a club that has stopped, not one that is running. So events do not live in code, they live in the admin panel: the club adds a new date itself, without me. Here the admin panel is not an extra feature — it is the mechanism keeping the site's main argument standing.

09

Applications land in the panel, not in an inbox

A membership application is the most valuable piece of data this club handles. A form that relies on an email notification alone disappears behind one spam filter, and the worst part is that nobody knows it disappeared. So every application is stored on the server and shown as a list in the admin panel — the club can go back to it whenever it wants.

10

The session token lives in an httpOnly cookie

The panel holds the club's event plan and the personal details of the business people applying to it — in a club whose whole proposition is privacy, that is the most sensitive part of the system. Had the token been kept in `localStorage`, any XSS hole could read it. An `httpOnly` cookie is invisible to JavaScript, and `SameSite` stops the token from riding along on requests issued by another site. The check is not only in middleware but inside every route handler: hiding an interface is not protection, only appearance.

11

A VPS, because written files have to survive

The site writes its own data to the server's disk: JSON files and uploaded images. In a serverless environment the file system is ephemeral — the panel writes something and the next deployment erases it. So the application runs on a VPS: PM2 keeps the Next.js process alive, Nginx handles SSL and static files in front. Working on JSON only makes sense where there is a persistent disk — the two are not separate choices, they are the same one.

12

Three languages on one URL — a deliberate trade-off

The interface runs in three languages, but each one does not get its own URL: the choice is kept in the browser. The price of that is that search engines do not index the three languages as separate pages. Here the trade-off is acceptable, because a club member does not arrive from a Google search — they arrive by invitation, from a direct link. If organic search were a channel, language would have to be split at route level; in this project that work would have been complexity serving nobody.

Results

The site has been live since August 2026. The club manages its events calendar, news and incoming membership applications from the admin panel itself, so keeping the calendar current — the site's main argument — no longer depends on a developer. Mobile performance has been measured and sits below target; optimisation is planned and the figure will be published here once it improves.

Questions about this project
Does the club need a developer to add an event or a news item?
No. Events, news and their images are managed from the admin panel — the club updates the calendar itself, with no code change involved.
Where do submissions from the application form go?
Every application is stored on the server and listed in the admin panel, so nothing depends on an email notification alone. The club can go back to past applications at any time.
Why does the project have no database?
The club's data volume is small — dozens of events and news items a year, a few applications a month. At that load a relational database would demand another process and a backup regime without adding anything. The data is stored in JSON files on the server; moving to a database is a planned step for when the write rate rises, not an outstanding task.
Who built the site and the admin panel?
Every layer — the frontend, the Next.js route handlers, the content layer, the admin panel, the authentication and the VPS deployment — was written by Nurlan Qadirov.
How many languages does the site run in?
The interface runs in three: Azerbaijani, English and Russian. There is no separate URL per language — the choice is kept in the browser. That is a deliberate trade-off, because the club's audience arrives by invitation rather than through search.

Tell me about your project — I usually reply the same day.

Nurlan Qadirov — Baku, Azerbaijan