Full-stack web development
Africa Safari Escapes — A Case Study
A production travel website built from scratch: public-facing pages, a flight search engine, an admin dashboard, a safari shop, and a custom design system — all shipped as a single full-stack application.
Project Overview
Africa Safari Escapes is a full-stack travel website serving a real business. The brief called for a premium, conversion-focused public site alongside a protected admin dashboard — all built on a modern React + TypeScript + Express stack with server-side rendering for SEO.
Every feature was designed and implemented end-to-end: information architecture, component design, backend API routes, database schema, third-party integrations, and a bespoke colour and typography system that runs consistently across every page and form.
Live production site
africasafariescapes.com
This case study is the site you are currently viewing. Every feature described below is live and in production.
View live siteTech Stack
React 19 + TypeScript
Strict typing throughout; zero any-casts in application code
Vite + SSR
Server-side rendering via Express for SEO and social previews
Tailwind CSS + shadcn/ui
Semantic CSS variable colour system; 40+ pre-built components extended
Express API routes
Provider-agnostic booking adapter, inbox, auth, and file upload endpoints
Drizzle ORM + MySQL
Typed schema migrations; users, documents, and company structure tables
BetterAuth
Session-based authentication with protected admin routes
Motion (Framer)
Scroll-triggered entrance animations and hover states site-wide
React Router v8
Data router with SSR loaders; 20+ routes including dynamic blog slugs
What Was Built
Flight Search Widget
A Skyscanner-style search widget with return/one-way toggle, airport autocomplete (IATA code-first scoring, portal-rendered dropdowns), passenger and cabin class selectors, and a provider-agnostic backend adapter ready for live API credentials.
Custom Design System
A site-wide colour system using CSS variables — each form field type (name, email, phone, date, budget, etc.) has a unique semantic colour applied consistently across every page. Labels, placeholders, and focus states all follow a single source of truth in globals.css.
Admin Dashboard
A protected dashboard with tab navigation via URL search params, stats overview, document management, user management, and a company structure directory. Auth-aware header with session management and sign-out.
Safari Shop
A full e-commerce storefront integrated with GoDaddy Commerce — product catalogue, category filtering, product detail pages, cart, and checkout. Product images sourced and placed via a managed media slot system.
Multi-page Public Site
20+ pages including destinations, packages, city stays, car hire, transfers, hotels, vetted accommodation, blog (with dynamic slug routing), and a marketing landing page system — each with full SEO metadata, Open Graph tags, and JSON-LD structured data.
Enquiry & Booking Forms
Multiple context-specific forms (general enquiry, flight booking, car hire, transfers, city tour) all wired to a shared Inbox backend with email notifications. Each form uses the bespoke colour system and accessible label/placeholder standards.
Key Technical Decisions
Portal rendering for dropdowns
Date pickers and autocomplete dropdowns render via createPortal into document.body with getBoundingClientRect positioning — preventing z-index conflicts with sibling sections and overflow:hidden clipping.
Provider-agnostic flight adapter
The flight search backend is built as a clean adapter layer in booking-api.ts — the frontend and API route are fully wired; swapping in live Falcon Flights credentials requires only filling in one adapter file.
Content layer for inline editing
All user-visible copy lives in src/content/ as typed JSON, scaffolded with Zod schemas. This keeps every text element inline-editable from the canvas without touching source code.
SSR-first for SEO
Every public page uses React Router v8 data loaders and @dr.pogodin/react-helmet for server-side head collection — titles, descriptions, canonical URLs, Open Graph, and JSON-LD are all in the first HTML byte that crawlers receive.
Interested in working together?
This project demonstrates end-to-end full-stack capability — from database schema and API design through to pixel-level UI and SEO. If you are looking for a developer who can own a product from brief to production, get in touch.