Overview
The dashboard is the central hub for delivery riders, displaying wallet balance, earnings summary, quick action buttons, and performance statistics. It provides riders with a comprehensive view of their delivery operations and financial status.
Dashboard Layout
Main Dashboard Component
The dashboard combines multiple features into a cohesive interface.
src/modules/dashboard/parcels/riders/home/index.tsx
import { getUserWalletQueryOptions } from "@/lib/tanstack-query/query-options/users" ;
import { formatCurrency } from "@/utils/currency" ;
import { Storage , StorageKeys } from "@/utils/storage" ;
import { useQuery } from "@tanstack/react-query" ;
import { useRouter } from "expo-router" ;
import { Avatar , Button , Skeleton } from "heroui-native" ;
import { ImageBackground , Text , View } from "react-native" ;
import { RiderAccountStats } from "./account-stats" ;
import { AvailableDeliveries } from "./available-deliveries" ;
export function RidersHomePage () {
const user = Storage . getObject ( StorageKeys . USER ) as User ;
const router = useRouter ();
const { data : walletResponse , isLoading } = useQuery (
getUserWalletQueryOptions (),
);
const wallet = walletResponse ?. data ;
const accountBalance = wallet ?. balance ? + wallet . balance : 0 ;
const totalEarnings = wallet ?. totalEarned ? + wallet . totalEarned : 0 ;
return (
< View className = "pt-4" >
{ /* Welcome Header */ }
< View className = "flex-row items-center justify-between" >
< Text className = "text-lg text-secondary font-semibold" >
Hello < Text className = "text-accent" > { user . fullName } </ Text > 👋
</ Text >
< Avatar size = "sm" alt = { user . fullName } >
< Avatar.Fallback > { getInitials ( user . fullName ) } </ Avatar.Fallback >
</ Avatar >
</ View >
{ /* Wallet Section */ }
< View className = "rounded-2xl mt-4 relative" >
< ImageBackground source = { require ( "@/assets/images/level-curves.png" ) } >
< View className = "p-4" >
< View className = "flex-row items-center gap-2 mb-1" >
< Ionicons name = "wallet-outline" size = { 20 } color = "white" />
< Text className = "text-lg text-white font-semibold" > Balance </ Text >
</ View >
< Text className = "text-xs text-white/70 mb-3" >
Your total available earnings
</ Text >
< View className = "flex-row items-baseline gap-2 mb-4" >
{ isLoading ? (
< Skeleton className = "w-24 h-6 rounded-lg" />
) : (
< Text className = "text-3xl text-white font-bold" >
{ AppConfig . currency . symbol } { formatCurrency ( accountBalance ) }
</ Text >
) }
</ View >
< View className = "flex-row items-center" >
< Button
size = "sm"
onPress = { () => router . push ( "/(parcel)/(stack)/request-payment" ) }
>
< Ionicons name = "cash-outline" size = { 16 } color = "white" />
< Text className = "text-white font-medium ml-1" >
Request Payment
</ Text >
</ Button >
< Button
size = "sm"
variant = "ghost"
onPress = { () => router . push ( "/(parcel)/(tabs)/transactions" ) }
>
< Ionicons name = "list-outline" size = { 16 } color = "white" />
< Text className = "text-white font-medium ml-1" > Transactions </ Text >
</ Button >
</ View >
</ View >
</ ImageBackground >
</ View >
{ /* Account Stats */ }
< RiderAccountStats totalEarnings = { totalEarnings } />
{ /* Available Deliveries */ }
< AvailableDeliveries />
</ View >
);
}
Wallet Balance Display
The wallet balance card shows the rider’s current available balance with a visually appealing design.
Key Features
Real-time Balance Displays the rider’s current wallet balance fetched from the API.
Quick Actions Provides instant access to request payment and view transactions.
Visual Design Features an attractive background with gradient overlay.
Loading States Shows skeleton loaders while fetching wallet data.
Account Statistics
The statistics section displays key performance metrics for the rider.
src/modules/dashboard/parcels/riders/home/account-stats.tsx
import { getRiderAccountStatQueryOptions } from "@/lib/tanstack-query/query-options/users" ;
import { formatCurrency } from "@/utils/currency" ;
import { useQuery } from "@tanstack/react-query" ;
import { Skeleton } from "heroui-native" ;
import { FlatList , Text , View } from "react-native" ;
export function RiderAccountStats ({ totalEarnings } : RiderAccountStatsProps ) {
const user = Storage . getObject ( StorageKeys . USER );
const { data : accountStatsResponse , isLoading } = useQuery (
getRiderAccountStatQueryOptions ( user . id ),
);
const STATS = [
{
label: "Total revenue" ,
value: ` ${ AppConfig . currency . symbol } ${ formatCurrency ( totalEarnings ) } ` ,
},
{
label: "Total deliveries today" ,
value: accountStatsResponse ?. data ?. total_deliveries_today ,
},
{
label: "Total deliveries" ,
value: accountStatsResponse ?. data ?. total_orders_delivered ,
},
{
label: "Cancelled Orders" ,
value: accountStatsResponse ?. data ?. total_orders_cancelled ,
},
];
return (
< View className = "mt-4" >
< Text className = "text-base text-secondary font-semibold mb-2" >
Statistics
</ Text >
< FlatList
data = { STATS }
horizontal
showsHorizontalScrollIndicator = { false }
contentContainerStyle = { { gap: 16 } }
renderItem = { ({ item }) => (
< View className = "bg-muted/10 rounded-lg p-4 min-w-[230px]" >
< Text className = "text-gray-500 text-sm h-14" > { item . label } </ Text >
{ isLoading ? (
< Skeleton className = "w-24 h-6 rounded-lg" />
) : (
< Text className = "font-semibold text-lg" > { item . value } </ Text >
) }
</ View >
) }
/>
</ View >
);
}
Statistics Cards
Total Revenue
Deliveries Today
Total Deliveries
Cancelled Orders
Displays the total earnings accumulated by the rider across all completed deliveries.
Shows the number of deliveries completed on the current day.
Indicates lifetime delivery count for the rider.
Tracks the number of cancelled delivery orders.
Quick Actions
The dashboard provides two primary action buttons:
Navigates to the payout request screen where riders can withdraw their earnings to mobile money or bank accounts.
Opens the transaction history screen to review all wallet activities and earnings.
Available Deliveries Preview
The bottom section of the dashboard shows a preview of available delivery requests.
src/modules/dashboard/parcels/riders/home/available-deliveries.tsx
import { ShipmentCard } from "@/components/shipment-card" ;
import { getShipmentsQueryOptions } from "@/lib/tanstack-query/query-options/shipment" ;
import { FlashList } from "@shopify/flash-list" ;
import { useQuery } from "@tanstack/react-query" ;
import { Link } from "expo-router" ;
export function AvailableDeliveries () {
const user = Storage . getObject ( StorageKeys . USER ) as User ;
const { data : shipmentsResponse , isLoading , refetch } = useQuery (
getShipmentsQueryOptions ( user . id )
);
const shipments = shipmentsResponse ?. data . items || [];
return (
< View className = "mt-4" >
< Text className = "text-base text-secondary font-semibold mb-2" >
Available deliveries
</ Text >
{ shipments . length === 0 ? (
< Empty />
) : (
< FlashList
data = { shipments }
renderItem = { ({ item }) => (
< Link asChild href = { `/shipments/ ${ item . reference } ` } >
< ShipmentCard shipment = { item } />
</ Link >
) }
keyExtractor = { ( item ) => item . id }
/>
) }
</ View >
);
}
Features
Real-time Updates : Automatically refreshes when the screen comes into focus
Empty State : Shows a helpful message when no deliveries are available
Quick Navigation : Tap any delivery card to view full details
FlashList Performance : Uses optimized list rendering for smooth scrolling
Data Fetching
The dashboard uses TanStack Query for efficient data fetching and caching:
// Wallet data
const { data : walletResponse , isLoading } = useQuery (
getUserWalletQueryOptions (),
);
// Account statistics
const { data : accountStatsResponse } = useQuery (
getRiderAccountStatQueryOptions ( user . id ),
);
// Available shipments
const { data : shipmentsResponse } = useQuery (
getShipmentsQueryOptions ( user . id )
);
All data is cached and automatically revalidated to ensure riders see the most up-to-date information.
Loading States
The dashboard implements skeleton loaders for a smooth user experience:
{ isLoading ? (
< Skeleton className = "w-24 h-6 rounded-lg" />
) : (
< Text className = "text-3xl text-white font-bold" >
{ AppConfig . currency . symbol } { formatCurrency ( accountBalance ) }
</ Text >
)}
Responsive Design
The dashboard adapts to different screen sizes:
Mobile : Vertical scrolling layout with full-width cards
Tablet : Optimized spacing with flexible card widths
Web : Centered content with maximum width constraints
Deliveries Browse and accept delivery requests.
Transactions View detailed transaction history.
Payouts Request withdrawals to your account.