jv_JACQUESVAN DEN BERG
CV
All projectsDEVELOPMENT JOURNAL / Hosted
Web development / Vaal Car Hire Website

The fleet catalogue is really a state-management problem

A searchable fleet for customers. A practical management system for the team.

Open website Explore the stack
Vaal Car Hire Website: Public website · desktop capture
Public website · desktop captureOPEN IMAGE ↗
THE SHORT VERSION

What I built.

Vaal Car Hire Website is part of my portfolio of websites and applications.

  • Filterable fleet and vehicle detail views.
  • Enquiry forms and WhatsApp contact paths.
  • Authenticated CMS for fleet, categories, enquiries and settings.
  • Page metadata, sitemap and structured data.
TOOLS & RESPONSIBILITIES

Under the hood.

01

Nuxt 4 / Vue

Public pages and staff interface

02

Supabase

Fleet data and authentication

03

Composables

Catalogue, listing, enquiries and SEO

04

Nuxt UI

Shared interface components

CONCEPTUAL IMPLEMENTATION FLOW
  1. Catalogue data
  2. Reactive category + filters
  3. Computed fleet list
  4. Vehicle details
  5. Enquiry
THE WORK ON SCREEN

A closer look.

Vaal Car Hire Website: Public website · desktop capture
01 / Public website · desktop capture · Open full image ↗
BUILD NOTES / 01

Finding the right vehicle

For a vehicle-hire business, a website needs to help someone answer a practical question: which vehicle suits my trip, and how do I get in touch? I approached Vaal Car Hire as a customer journey, from exploring the fleet to making an enquiry.

BUILD NOTES / 02

Inside useFleetListing

The fleet listing gets its source vehicles from useFleetCatalog. Filtering lives in utility functions, while computed values derive category counts, passenger bounds, price bounds and the visible vehicles. That keeps the page from becoming the place where every bit of fleet logic accumulates.

There is also a distinction between editing the filters and applying them. Until filtersApplied becomes true, the computed list clears the optional constraints before filtering. Sorting remains part of the filter state, with price_asc as the default.

BUILD NOTES / 03

A category should survive the URL

The category is synchronised with route.query.category. Changing it uses router.replace and preserves the other query parameters. The code maps the internal mini_bus category to minibuses in the URL, then normalises the incoming value when reading it back.

That is the kind of unglamorous detail I like discussing: internal identifiers, readable URLs and reactive state need to agree. The other filters are local reactive state in this composable; I would not describe the entire filter selection as shareable through the URL.

BUILD NOTES / 04

The customer is only half the audience

I treated content management as part of the product, rather than something to add after the public pages were finished. A fleet changes. Contact details change. The useful version of this website is one the business can keep current.

BUILD NOTES / 05

What I take from it

The lesson here is that a good business website has two audiences: the visitor trying to do something, and the person responsible for keeping it useful. Both deserve a clear interface.

WRITTEN BY JACQUES VAN DEN BERGNext build: Credence Website
↑ ↓ to navigateEnter to selectEsc to close