Part 11 of 13 · Elite Limo Booking

Achievable Wins: A Booking History and an App-Like Feel

Elite Limo Booking dashboard showing a customer's booking history alongside a Progressive Web App installation on a smartphone for an app-like booking experience.

After live tracking humbled me, I wanted wins that would fully land. Two were sitting right there, a booking history so returning customers see their rides, and the app-like feel, the site installable on a phone home screen with its own icon. Both shipped completely, and both taught me something transferable. This post is the pair.

The history is the history shortcode, and its design question was identity, who is asking for whose rides. Customers do not have passwords here, their identity is their verified phone, so history reuses the OTP flow from earlier, enter your phone, receive a code, verify, and only then does the server fetch rides for that phone:

public function get_booking_history($phone) {
    global $wpdb;
    return $wpdb->get_results($wpdb->prepare(
        'SELECT id, pickup_location, dropoff_location,
                ride_date, status, total_amount
         FROM ' . $this->table_bookings . '
         WHERE customer_phone = %s
         ORDER BY ride_date DESC LIMIT 20',
        $phone
    ));
}

The privacy point hides in what the function requires, a verified phone, never a phone typed into a URL or form and trusted. Without the OTP gate, anyone could read anyone’s ride history by guessing numbers. Identity earned through verification, then a prepared query scoped hard to that identity, that is the entire pattern for personal data.

The app-like feel is the progressive web app pair, a manifest and a service worker. The manifest is a small JSON file telling phones how to treat the site when installed:

{
  "name": "Elite Limo Booking",
  "short_name": "EliteLimo",
  "start_url": "/book/",
  "display": "standalone",
  "background_color": "#111827",
  "theme_color": "#111827",
  "icons": [{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" }]
}

display standalone is the magic word, opened from the home screen icon, the site runs without browser chrome, no address bar, and reads as an app. The service worker is the second requirement for installability, a JavaScript file the browser runs beside the site, and even a minimal one that caches the shell makes install prompts eligible and the booking page open instantly on repeat visits:

self.addEventListener('install', function(e) {
    e.waitUntil(caches.open('elb-v1').then(function(c) {
        return c.addAll(['/book/', '/style.css']);
    }));
});

One rule cost me an hour, service workers register only over HTTPS, on plain HTTP the registration silently fails. Together, an afternoon of work, and the booking system installs on a phone like an app, no app store involved.

A few things people ask me about this

Why does my service worker not register? Almost always HTTPS. Service workers require a secure origin, on plain HTTP registration fails silently. Localhost is the one exemption for development.

How do I make my site installable like an app? A web app manifest linked in the page head, with name, icons, start_url, and display standalone, plus a registered service worker. Browsers then offer add to home screen.

Next

The core was complete, and a real ride service still needed its human touches, choosing a vehicle class, talking to your driver, feeling safe. Those features, honestly told, are the next post.

Leave a Reply

Your email address will not be published. Required fields are marked *