Part 9 of 13 · Elite Limo Booking

Building the Driver Side: Dashboards and Drag-to-Assign

Driver dispatch dashboard showing drag-and-drop ride assignment with a driver dashboard displaying assigned bookings in a limo booking system.

A booking that no driver knows about is just a database row. The other half of a ride platform is dispatch, the admin sees incoming rides, picks a driver, assigns, and the driver sees it on their own dashboard. Building this side taught me the working pattern behind every live dashboard, and the security line that AJAX handlers must never skip.

The assignment flow is JavaScript talking to WordPress AJAX. The admin clicks assign on a ride, picks a driver in a modal, and this real code from the plugin fires:

function handleDriverAssignment(e) {
    e.preventDefault();

    const bookingId = jQuery('#assignBookingId').val();
    const driverId  = jQuery('#driverSelect').val();

    if (!driverId) { alert('Please select a driver'); return; }

    jQuery.post(ajaxurl, {
        action:       'elite_limo_ajax',
        elite_action: 'assign_driver',
        booking_id:   bookingId,
        driver_id:    driverId,
        nonce:        '<?php echo wp_create_nonce('elite_limo_nonce'); ?>'
    }, function(response) {
        if (response.success) {
            location.reload();
        } else {
            alert('Failed to assign driver: ' + response.message);
        }
    });
}

The routing is worth understanding once, deeply. action is what WordPress uses to find my registered handler. elite_action is my own sub-router, one AJAX endpoint, many operations, assign_driver, update_ride_status, cancel_ride, all dispatched inside handle_ajax by a switch. And the nonce is the line that must never be skipped. A nonce is a token proving the request came from a page WordPress generated for this user, and the PHP side refuses anything without it:

public function handle_ajax() {
    if (!wp_verify_nonce($_POST['nonce'], 'elite_limo_nonce')) {
        wp_send_json_error(['message' => 'Security check failed']);
    }
    // ... route $_POST['elite_action'] to the right operation
}

Without that check, any page on the internet could post to my endpoint and assign drivers on a stranger’s site, that attack has a name, cross-site request forgery, and the nonce is WordPress’s standard shield against it. Every state-changing AJAX operation gets a nonce check, no exceptions, and admin-only operations additionally check current_user_can.

The dashboard’s live feel comes from the humblest technique there is, polling. The rides list refetches every five seconds, so new bookings and status changes appear without anyone pressing reload. Polling is not glamorous, real-time systems use fancier transport, but for a dispatch screen watched by one admin, a five-second poll through the same AJAX door is simple, reliable, and finished the same day. The driver’s own dashboard is the mirror image, rendered by the driver shortcode, showing rides where the booking row’s driver_id matches them, updated by the same polling.

A few things people ask me about this

What is a WordPress nonce actually for? It proves the request originated from a page WordPress served to this user, blocking forged requests from other sites. Create with wp_create_nonce, verify with wp_verify_nonce, on every state-changing request.

How do dashboards update without reloading? Simplest is polling, JavaScript refetches the data every few seconds through the same AJAX endpoint and re-renders. Upgrade to push transports only when polling measurably fails you.

Next

Assignment worked, and ambition pointed at the flagship, live GPS tracking of the ride on a map. The feature that looked easy and humbled me is the next post.

Leave a Reply

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