ahmad@abboud.dev · bash
tty1
Last login: just now on ttys001
ahmad@abboud.dev · portfolio shell v1.0
▸ mounting /projects … ok
▸ loading identity … ok
▸ 2 phone lines, 1 timezone, 0 recruiters harmed
 
Ahmad Abboud
Senior Full-Stack Engineer · Tech Lead
I drag factories into the 21st century.
 
You have a shell. Most of it is locked.
Type -h to see what you can run.
// no javascript. the shell is off, but everything it prints is written out beside it.
type -h and hit enter
ahmad@abboud:~$ open nilverde

Nilverde

Company site & catalogue

A company website whose catalogue is shaped like the printed one it replaced (category, subcategory, product), and which still renders when the database is empty

Screenshots

A company site for Nilverde with a product catalogue behind it. The catalogue is organised category → subcategory → product, deliberately mirroring the structure of the printed catalogue the company already used, so the people maintaining it don’t have to translate between two mental models to find anything.

Built on the Next.js App Router with React Server Components, so catalogue pages are rendered on the server and ship no client JavaScript for what is, in the end, a list of products. Tailwind for styling, TypeScript throughout.

Supabase, optionally

Postgres via Supabase holds the catalogue, with read-only public row-level security policies: the site can read, and nothing reaching it can write.

The Supabase client is lazy and returns null when it isn’t configured. When the environment variables are missing or the tables are empty, the site falls back to bundled seed data and stays fully renderable. That means a clone builds and runs before anyone has provisioned a database, and a bad deploy degrades to sample content instead of a stack trace.

Layout

Routes for home, about, contact, the catalogue index, a category page listing its subcategories and products, a subcategory page, and a product detail page. Data access is a small set of typed helpers over one schema file that also carries the RLS policies, so the shape of the database and the shape of the TypeScript types are edited next to each other.

▸ stack

Next.js 16React Server ComponentsTailwind CSS 4SupabaseTypeScript