Skip to main content

Overview

The Rodando Driver app includes three specialized modal components for handling trip-related interactions. These components are built with Ionic Angular and use the ModalController for presentation and dismissal.

TripAssignedModalComponent

Displays trip details when a new trip is assigned to a driver, with a countdown timer for acceptance.

Component Metadata

selector
string
default:"app-trip-assigned-modal"
The component selector
standalone
boolean
default:"true"
Standalone component that can be imported directly
changeDetection
ChangeDetectionStrategy
default:"OnPush"
Uses OnPush change detection for optimal performance

Features

  • Countdown timer: Shows remaining seconds to accept/decline the trip
  • Trip summary: Displays distance and duration estimates
  • Route visualization: Shows origin and destination addresses with icons
  • Payment information: Displays payment method and estimated price
  • Action buttons: Accept or Decline buttons that integrate with TripFacade

State Management

The component uses NgRx facade pattern:
private facade = inject(TripFacade);
vm = this.facade.modalVm; // Computed signal with trip data
The modalVm signal provides:
vm.remainingSec
number | null
Remaining seconds for the driver to respond
vm.distanceText
string
Formatted distance text (e.g., “5.2 km”)
vm.durationText
string
Formatted duration text (e.g., “15 min”)
vm.originLabel
string
Origin address or location name
vm.destinationLabel
string
Destination address or location name
vm.priceText
string
Formatted price text with currency

Methods

onAccept()
() => void
Accepts the trip offer by calling facade.acceptOffer()
onDecline()
() => void
Declines the trip offer by calling facade.declineOffer()

Usage Example

import { ModalController } from '@ionic/angular';
import { TripAssignedModalComponent } from '@/app/shared/components/trip-assigned-modal.component/trip-assigned-modal.component';

export class TripService {
  constructor(private modalCtrl: ModalController) {}

  async showTripAssignment() {
    const modal = await this.modalCtrl.create({
      component: TripAssignedModalComponent,
      cssClass: 'trip-assigned-modal',
      backdropDismiss: false
    });

    await modal.present();
    const result = await modal.onDidDismiss();
    // Handle result
  }
}

DriverConfirmOrderModalComponent

Allows drivers to confirm payment collection at the end of a trip, including base fare, waiting charges, and payment method.

Component Metadata

selector
string
default:"app-driver-confirm-order-modal"
The component selector
standalone
boolean
default:"true"
Standalone component that can be imported directly

Input Properties

Passenger Information

passengerName
string
default:"'Pasajero'"
The name of the passenger for this trip

Route Information

originLabel
string
default:"''"
The origin address or location name
destinationLabel
string
default:"''"
The destination address or location name
distanceText
string
default:"'—'"
Formatted distance text (e.g., “8.5 km”)
durationText
string
default:"'—'"
Formatted duration text (e.g., “20 min”)

Pricing Information

base
number | null
default:"null"
The base fare amount for the trip
waitingExtra
number | null
default:"null"
Additional charge for waiting time, if applicable
total
number | null
default:"null"
Total amount to charge the passenger
currency
string
default:"'CUP'"
Currency code for displaying amounts

Waiting Information

waitingReason
string | null
default:"null"
Optional reason for the waiting charge
waitingSeconds
number | null
default:"null"
Number of seconds the driver waited

Payment Method

paymentMode
'cash' | 'card' | 'wallet' | string
default:"'cash'"
The payment method for this trip

Computed Properties

hasWaitingExtra
boolean
Returns true if there is a waiting charge greater than zero
waitingClock
string
Formats waitingSeconds as mm:ss (e.g., “05:30”)

Methods

cancel()
() => void
Dismisses the modal with { confirmed: false } and role 'cancel'
confirm()
() => void
Dismisses the modal with { confirmed: true } and role 'confirm'

Usage Example

import { ModalController } from '@ionic/angular';
import { DriverConfirmOrderModalComponent } from '@/app/shared/components/driver-confirm-order-modal/driver-confirm-order-modal.component';

export class TripService {
  constructor(private modalCtrl: ModalController) {}

  async confirmPayment(tripData: any) {
    const modal = await this.modalCtrl.create({
      component: DriverConfirmOrderModalComponent,
      componentProps: {
        passengerName: tripData.passenger.name,
        originLabel: tripData.origin.address,
        destinationLabel: tripData.destination.address,
        distanceText: tripData.distance,
        durationText: tripData.duration,
        base: tripData.pricing.base,
        waitingExtra: tripData.pricing.waitingCharge,
        total: tripData.pricing.total,
        currency: 'CUP',
        waitingSeconds: tripData.waitingTime,
        waitingReason: tripData.waitingReason,
        paymentMode: tripData.paymentMethod
      },
      cssClass: 'confirm-order-modal'
    });

    await modal.present();
    const { data, role } = await modal.onDidDismiss();
    
    if (role === 'confirm' && data?.confirmed) {
      // Process payment confirmation
    }
  }
}

DriverWaitingPenaltyModalComponent

Notifies the driver about waiting penalties when a passenger delays pickup, showing real-time waiting duration and associated charges.

Component Metadata

selector
string
default:"app-driver-waiting-penalty-modal"
The component selector
standalone
boolean
default:"true"
Standalone component that can be imported directly

Input Properties

Passenger Information

passengerName
string
default:"'Pasajero'"
The name of the passenger

Pricing Information

base
number | null
default:"null"
The base fare for the trip
extra
number | null
default:"null"
The additional waiting penalty charge
total
number | null
default:"null"
Total fare including waiting penalty
currency
string
default:"'CUP'"
Currency code for displaying amounts

Waiting Information

waitingSeconds
number
default:"0"
Current waiting duration in seconds (can be updated in real-time)
waitingReason
string | null
default:"null"
Optional reason for the waiting situation

Properties

clock
string
default:"'00:00'"
Formatted waiting time display in mm:ss format

Lifecycle Hooks

ngOnInit()
() => void
Initializes the clock display on component initialization
ngOnChanges(changes: SimpleChanges)
(changes: SimpleChanges) => void
Updates the clock display when waitingSeconds input changes, enabling real-time updates

Methods

onConfirm()
() => void
Dismisses the modal with { action: 'confirm' } - driver confirms the waiting penalty
onReject()
() => void
Dismisses the modal with { action: 'reject' } - driver disputes the waiting penalty

Private Methods

updateClock()
() => void
Updates the clock property by converting waitingSeconds to mm:ss format

Usage Example

import { ModalController } from '@ionic/angular';
import { DriverWaitingPenaltyModalComponent } from '@/app/shared/components/driver-waiting-penalty-modal/driver-waiting-penalty-modal.component';

export class TripService {
  constructor(private modalCtrl: ModalController) {}

  async showWaitingPenalty(tripData: any) {
    const modal = await this.modalCtrl.create({
      component: DriverWaitingPenaltyModalComponent,
      componentProps: {
        passengerName: tripData.passenger.name,
        base: tripData.pricing.base,
        extra: tripData.pricing.waitingPenalty,
        total: tripData.pricing.total,
        currency: 'CUP',
        waitingSeconds: tripData.waitingTime,
        waitingReason: 'Passenger delayed at pickup location'
      },
      cssClass: 'waiting-penalty-modal',
      backdropDismiss: false
    });

    await modal.present();
    
    // Optional: Update waiting time in real-time
    const interval = setInterval(() => {
      modal.componentProps = {
        ...modal.componentProps,
        waitingSeconds: modal.componentProps.waitingSeconds + 1
      };
    }, 1000);

    const { data } = await modal.onDidDismiss();
    clearInterval(interval);
    
    if (data?.action === 'confirm') {
      // Apply waiting penalty
    } else if (data?.action === 'reject') {
      // Handle penalty rejection
    }
  }
}

Real-time Updates

The component implements OnChanges to support real-time waiting time updates:
// Update the modal's waiting time dynamically
await modal.componentProps = {
  ...modal.componentProps,
  waitingSeconds: newWaitingSeconds
};
The clock display automatically updates when waitingSeconds changes.

Common Patterns

All trip modal components can be customized with CSS classes:
const modal = await this.modalCtrl.create({
  component: TripAssignedModalComponent,
  cssClass: ['trip-modal', 'custom-modal'],
  // Additional options
});

Handling Dismissal

All modals return data on dismissal:
const { data, role } = await modal.onDidDismiss();

switch (role) {
  case 'confirm':
    // Handle confirmation
    break;
  case 'cancel':
    // Handle cancellation
    break;
}

Preventing Dismissal

For critical decisions, prevent backdrop dismissal:
const modal = await this.modalCtrl.create({
  component: TripAssignedModalComponent,
  backdropDismiss: false,
  // Force user to make a decision
});

Source Code References

  • TripAssignedModalComponent: src/app/shared/components/trip-assigned-modal.component/
  • DriverConfirmOrderModalComponent: src/app/shared/components/driver-confirm-order-modal/
  • DriverWaitingPenaltyModalComponent: src/app/shared/components/driver-waiting-penalty-modal/

Build docs developers (and LLMs) love