Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Create a Custom Sales Widget for Your FlutterFlow App

Build a sales dashboard Component with KPI cards for revenue, order count, and conversion rate displayed in a 2-column GridView. Add a sparkline trend chart using fl_chart LineChart in a Custom Widget. Show a top-5 products ListView ranked by revenue. Pull all data from a pre-aggregated sales_daily Firestore collection populated by a Cloud Function, and filter by date range using Today, This Week, and This Month buttons.

What you'll learn

  • How to create a sales_daily Firestore collection with pre-aggregated revenue, orders, and conversion data
  • How to build KPI metric cards in a 2-column GridView with percentage change indicators
  • How to create a sparkline revenue trend chart Custom Widget using fl_chart LineChart
  • How to filter the dashboard by date range using Today, This Week, and This Month buttons
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read30-40 minFlutterFlow Pro+ (Custom Widget for chart, Cloud Function for aggregation)March 2026RapidDev Engineering Team
TL;DR

Build a sales dashboard Component with KPI cards for revenue, order count, and conversion rate displayed in a 2-column GridView. Add a sparkline trend chart using fl_chart LineChart in a Custom Widget. Show a top-5 products ListView ranked by revenue. Pull all data from a pre-aggregated sales_daily Firestore collection populated by a Cloud Function, and filter by date range using Today, This Week, and This Month buttons.

Building a Sales Dashboard with KPI Cards and Trend Charts in FlutterFlow

E-commerce and CRM apps need at-a-glance sales performance views. This tutorial builds a dashboard Component with key metric cards, a revenue trend sparkline, and a top products ranking — all powered by pre-aggregated Firestore data to keep page loads fast.

Prerequisites

  • A FlutterFlow project on the Pro plan (Custom Widget required for charts)
  • Firestore configured with an orders collection containing order data
  • Firebase Blaze plan for Cloud Function deployment
  • fl_chart package added to Pubspec Dependencies

Step-by-step guide

1

Create the sales_daily Firestore collection and Cloud Function aggregator

Create a sales_daily collection in Firestore. Each document represents one day: date (Timestamp), revenue (double, total sales), orderCount (int), conversionRate (double, 0.0-1.0), topProducts (Array of Map: { name: String, revenue: double, quantity: int }). Deploy a Cloud Function triggered daily via Cloud Scheduler that queries the orders collection for the previous day, sums revenue, counts orders, calculates conversion (orders / unique visitors from an analytics source), and writes the summary document. This pre-aggregation avoids expensive real-time queries on the raw orders collection.

Expected result: Firestore has a sales_daily collection with one document per day containing pre-computed sales metrics.

2

Build KPI metric cards in a 2-column GridView with percentage change indicators

On the dashboard page, add a GridView with crossAxisCount: 2, childAspectRatio: 1.6, crossAxisSpacing: 12, mainAxisSpacing: 12. Add three child Components (MetricCard) with parameters: label (String), value (String), changePercent (double), isPositive (Boolean). Each MetricCard is a Container with borderRadius: 12, elevation: 2, padding: 16. Inside: Column with Text label (bodySmall, grey), Text value (headlineMedium, bold), and a Row with Icon (arrow_upward green or arrow_downward red based on isPositive) + Text changePercent (bodySmall, green or red).

Expected result: Three KPI cards display in a 2-column grid showing revenue, order count, and conversion rate with up/down change indicators.

3

Create a SparklineChart Custom Widget using fl_chart LineChart in minimal mode

Add fl_chart: ^0.65.0 to Pubspec Dependencies. Create a Custom Widget named SparklineChart with parameters: dataPoints (List<double>), color (Color). In the build method, return a SizedBox (height: 80) containing a LineChart. Configure LineChartData with one LineChartBarData: spots mapped from dataPoints (index as x, value as y), isCurved: true, barWidth: 2, color: widget.color, dotData: FlDotData(show: false), belowBarData: BarAreaData(show: true, color: widget.color.withOpacity(0.1)). Hide all axes, grid, border, and titles for a clean sparkline look.

Expected result: A compact sparkline chart renders revenue trends as a smooth curved line with a subtle gradient fill area.

4

Add a top-5 products ListView ranked by revenue from sales_daily data

Below the sparkline, add a Text 'Top Products' (titleMedium, bold) and a ListView (shrinkWrap: true, physics: NeverScrollable) with 5 children. Each item is a Row: rank number Text (bodyLarge, bold, primary color), SizedBox(width: 12), Expanded Column (product name Text bodyMedium, quantity Text bodySmall grey), and trailing revenue Text (bodyLarge, bold). Bind the data from the topProducts array of the current day's sales_daily document. Sort by revenue descending.

Expected result: A ranked list shows the top 5 products by revenue for the selected date range, each with name, quantity sold, and revenue.

5

Add date range filter buttons for Today, This Week, and This Month

At the top of the dashboard, add a Row with three ChoiceChip-style buttons: Today, This Week, This Month. Create a Page State dateRange (String, default 'today'). On button tap, update dateRange. The Backend Query on sales_daily uses Conditional Filters: 'today' filters date == today, 'week' filters date >= 7 days ago, 'month' filters date >= 30 days ago. For multi-day ranges, the KPI values display aggregated sums (total revenue, total orders, average conversion). The sparkline dataPoints list contains one value per day in the range.

Expected result: Switching between Today, This Week, and This Month updates all KPI cards, the sparkline chart, and the top products list.

Complete working example

SparklineChart Custom Widget
1// Custom Widget: SparklineChart
2// Pubspec: fl_chart: ^0.65.0
3
4import 'package:flutter/material.dart';
5import 'package:fl_chart/fl_chart.dart';
6
7class SparklineChart extends StatelessWidget {
8 final double width;
9 final double height;
10 final List<double> dataPoints;
11 final Color color;
12
13 const SparklineChart({
14 Key? key,
15 required this.width,
16 this.height = 80,
17 required this.dataPoints,
18 this.color = Colors.blue,
19 }) : super(key: key);
20
21 @override
22 Widget build(BuildContext context) {
23 if (dataPoints.isEmpty) {
24 return SizedBox(width: width, height: height);
25 }
26
27 final spots = dataPoints
28 .asMap()
29 .entries
30 .map((e) => FlSpot(e.key.toDouble(), e.value))
31 .toList();
32
33 return SizedBox(
34 width: width,
35 height: height,
36 child: LineChart(
37 LineChartData(
38 gridData: const FlGridData(show: false),
39 titlesData: const FlTitlesData(show: false),
40 borderData: FlBorderData(show: false),
41 lineTouchData: LineTouchData(
42 touchTooltipData: LineTouchTooltipData(
43 getTooltipItems: (spots) => spots.map((s) =>
44 LineTooltipItem(
45 '\$${s.y.toStringAsFixed(0)}',
46 const TextStyle(color: Colors.white, fontSize: 12),
47 ),
48 ).toList(),
49 ),
50 ),
51 lineBarsData: [
52 LineChartBarData(
53 spots: spots,
54 isCurved: true,
55 color: color,
56 barWidth: 2,
57 isStrokeCapRound: true,
58 dotData: const FlDotData(show: false),
59 belowBarData: BarAreaData(
60 show: true,
61 color: color.withOpacity(0.1),
62 ),
63 ),
64 ],
65 ),
66 ),
67 );
68 }
69}

Common mistakes when creating a Custom Sales Widget for Your FlutterFlow App

Why it's a problem: Querying the raw orders collection for real-time aggregation on every dashboard load

How to avoid: Pre-aggregate daily summaries into a sales_daily collection using a Cloud Function. The dashboard reads one summary document instead of thousands of orders.

Why it's a problem: Using fl_chart without hiding axes, grid, and titles for the sparkline

How to avoid: Set gridData: FlGridData(show: false), titlesData: FlTitlesData(show: false), borderData: FlBorderData(show: false) for a clean minimal sparkline.

Why it's a problem: Displaying conversion rate as a raw decimal like 0.032 instead of a percentage

How to avoid: Multiply the stored decimal by 100 and format with one decimal place: '${(conversionRate * 100).toStringAsFixed(1)}%' displays as '3.2%'.

Best practices

  • Pre-aggregate sales data with a scheduled Cloud Function to keep dashboard loads under 1 second
  • Store topProducts as an array of maps inside the daily summary to avoid extra collection queries
  • Show percentage change compared to the previous period (yesterday, last week) for context on each KPI
  • Use green for positive change and red for negative change — universal visual language for financial data
  • Keep the sparkline height to 60-100 pixels so it stays compact while still showing the trend shape
  • Add touch tooltips on the sparkline so users can tap a point to see the exact revenue value for that day
  • Default to Today view for the fastest initial load — single document read

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I need to build a sales dashboard in FlutterFlow with KPI metric cards (revenue, orders, conversion rate), a sparkline trend chart using fl_chart, a top products list, and date range filters. Show me the Firestore data model, widget tree, and Custom Widget code for the sparkline.

FlutterFlow Prompt

Create a dashboard page with a row of three metric cards at the top, a small line chart below showing revenue trends, and a list of top-selling products underneath. Add filter buttons for Today, This Week, and This Month.

Frequently asked questions

How do I calculate conversion rate if I do not track unique visitors?

Use a proxy metric like orders divided by app sessions. Alternatively, skip conversion rate and replace that KPI card with average order value (total revenue / order count).

Can I use fl_chart for bar charts or pie charts on the dashboard?

Yes. fl_chart supports LineChart, BarChart, PieChart, RadarChart, and ScatterChart. Create separate Custom Widgets for each chart type using the same package.

How often should the Cloud Function run to update sales_daily?

Run it once daily after midnight (e.g., 1:00 AM) to aggregate the previous day's data. For near-real-time today data, run it every hour and overwrite today's document.

What if the sparkline has only one data point for the Today view?

A single point cannot render a line. Show a Text value instead of the sparkline when dataPoints.length < 2, or include the previous day as a second point for comparison.

Can I export the dashboard data as a CSV?

Yes. Create a Custom Action that queries sales_daily for the selected range, formats each document as a CSV row, and uses the url_launcher or share_plus package to share the file.

Can RapidDev help build a full analytics and reporting platform?

Yes. RapidDev can implement multi-metric dashboards, automated report generation, email report scheduling, user segmentation analytics, and custom chart visualizations.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.