Navigation
Dashboards for Data Apps
Build responsive dashboards for analytics, monitoring, and data-driven applications using composable UI components.
Dashboard 01
A KPI row, bar chart, and data table for a general-purpose analytics dashboard.
Dependencies
Overview
996
1,672
5.1%
82.4%
Sales overview
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
This year
$0.8M
+16%Last year
$0.7M
| Invoice | Project | Method | Status | ||||
|---|---|---|---|---|---|---|---|
| INV-0041 | Brand Refresh | Wire Transfer | Jun 30, 2026 | Pending | $4,200.00 | ||
| INV-0040 | API Integration | Credit Card | Jun 15, 2026 | Paid | $1,850.00 | ||
| INV-0039 | Dashboard UI | ACH | Jun 01, 2026 | Overdue | $6,500.00 | ||
| INV-0038 | Mobile App MVP | Wire Transfer | May 28, 2026 | Paid | $9,000.00 | ||
| INV-0037 | SEO Audit | Credit Card | May 10, 2026 | Refunded | $780.00 | ||
| INV-0036 | Data Pipeline | ACH | Apr 25, 2026 | Paid | $3,350.00 | ||
| INV-0035 | Design System | Wire Transfer | Jun 22, 2026 | Pending | $5,400.00 | ||
| INV-0034 | Marketing Site | Credit Card | Apr 18, 2026 | Paid | $2,100.00 | ||
| INV-0033 | Onboarding Flow | ACH | May 31, 2026 | Overdue | $3,950.00 | ||
| INV-0032 | Analytics Setup | Credit Card | Apr 09, 2026 | Paid | $1,280.00 |
import reflex as rx
from components.core.hugeicon import hi
from components.ui.avatar import avatar
from components.ui.badge import badge
from components.ui.checkbox import checkbox
from components.ui.table import table
from native.lib.blocks.bar_chart_02 import bar_chart_02
from native.lib.blocks.kpi_card_01 import kpi_card_01
NAV_ITEMS = [
{"label": "Overview", "icon": "DashboardSquare01Icon"},
{"label": "Analytics", "icon": "ChartBarLineIcon"},
{"label": "Projects", "icon": "FolderIcon"},
{"label": "Team", "icon": "UserGroupIcon"},
{"label": "Settings", "icon": "Settings01Icon"},
]
INVOICES = [
{
"id": "INV-0041",
"client": "Miriam Okafor",
"initials": "MO",
"avatar": "https://i.pravatar.cc/80?img=1",
"project": "Brand Refresh",
"amount": 4200.00,
"method": "Wire Transfer",
"due": "Jun 30, 2026",
"due_date": "2026-06-30",
"status": "Pending",
},
{
"id": "INV-0040",
"client": "Theo Hartmann",
"initials": "TH",
"avatar": "https://i.pravatar.cc/80?img=12",
"project": "API Integration",
"amount": 1850.00,
"method": "Credit Card",
"due": "Jun 15, 2026",
"due_date": "2026-06-15",
"status": "Paid",
},
{
"id": "INV-0039",
"client": "Suki Nakamura",
"initials": "SN",
"avatar": "https://i.pravatar.cc/80?img=5",
"project": "Dashboard UI",
"amount": 6500.00,
"method": "ACH",
"due": "Jun 01, 2026",
"due_date": "2026-06-01",
"status": "Overdue",
},
{
"id": "INV-0038",
"client": "Elias Ferreira",
"initials": "EF",
"avatar": "https://i.pravatar.cc/80?img=3",
"project": "Mobile App MVP",
"amount": 9000.00,
"method": "Wire Transfer",
"due": "May 28, 2026",
"due_date": "2026-05-28",
"status": "Paid",
},
{
"id": "INV-0037",
"client": "Priya Menon",
"initials": "PM",
"avatar": "https://i.pravatar.cc/80?img=9",
"project": "SEO Audit",
"amount": 780.00,
"method": "Credit Card",
"due": "May 10, 2026",
"due_date": "2026-05-10",
"status": "Refunded",
},
{
"id": "INV-0036",
"client": "Dmitri Volkov",
"initials": "DV",
"avatar": "https://i.pravatar.cc/80?img=11",
"project": "Data Pipeline",
"amount": 3350.00,
"method": "ACH",
"due": "Apr 25, 2026",
"due_date": "2026-04-25",
"status": "Paid",
},
{
"id": "INV-0035",
"client": "Amara Diallo",
"initials": "AD",
"avatar": "https://i.pravatar.cc/80?img=16",
"project": "Design System",
"amount": 5400.00,
"method": "Wire Transfer",
"due": "Jun 22, 2026",
"due_date": "2026-06-22",
"status": "Pending",
},
{
"id": "INV-0034",
"client": "Noah Bergström",
"initials": "NB",
"avatar": "https://i.pravatar.cc/80?img=14",
"project": "Marketing Site",
"amount": 2100.00,
"method": "Credit Card",
"due": "Apr 18, 2026",
"due_date": "2026-04-18",
"status": "Paid",
},
{
"id": "INV-0033",
"client": "Lucia Romano",
"initials": "LR",
"avatar": "https://i.pravatar.cc/80?img=20",
"project": "Onboarding Flow",
"amount": 3950.00,
"method": "ACH",
"due": "May 31, 2026",
"due_date": "2026-05-31",
"status": "Overdue",
},
{
"id": "INV-0032",
"client": "Kwame Mensah",
"initials": "KM",
"avatar": "https://i.pravatar.cc/80?img=15",
"project": "Analytics Setup",
"amount": 1280.00,
"method": "Credit Card",
"due": "Apr 09, 2026",
"due_date": "2026-04-09",
"status": "Paid",
},
]
STATUS_CONFIG = {
"Paid": {"variant": "default", "dot": "bg-primary-foreground"},
"Pending": {"variant": "secondary", "dot": "bg-muted-foreground"},
"Overdue": {"variant": "destructive", "dot": "bg-destructive"},
"Refunded": {"variant": "outline", "dot": "bg-muted-foreground"},
}
def main_kpi_section():
return kpi_card_01()
def main_chart_section():
return rx.el.div(
bar_chart_02(), class_name="w-full border border-input/90 rounded-2xl p-4"
)
def render_status_badge(status: str) -> rx.Component:
config = STATUS_CONFIG.get(
status, {"variant": "default", "dot": "bg-muted-foreground"}
)
return badge(
rx.el.span(
class_name=f"inline-block size-1.5 shrink-0 rounded-lg {config['dot']}"
),
status,
variant=config["variant"],
class_name="gap-1.5 text-[11px] font-medium",
)
def render_row(inv: dict) -> rx.Component:
formatted_amount = f"{inv['amount']:,.2f}"
return table.row(
table.cell(
checkbox.root(
checkbox.indicator(),
value=inv["id"],
**{"data-dt-select": "true"},
),
class_name="pl-4 py-2",
),
table.cell(
rx.el.span(
inv["id"],
class_name="font-mono text-xs text-muted-foreground py-2",
)
),
table.cell(
rx.el.div(
avatar.root(
avatar.image(
src=inv["avatar"],
class_name="shrink-0 border border-border grayscale",
),
),
rx.el.span(
inv["client"],
class_name="truncate text-sm font-medium text-foreground",
),
class_name="flex min-w-0 items-center gap-2.5",
),
sort_value=inv["client"],
class_name="py-2",
),
table.cell(
rx.el.span(
inv["project"],
class_name="block max-w-[140px] truncate text-sm text-muted-foreground",
),
class_name="hidden sm:table-cell py-2",
),
table.cell(
rx.el.span(inv["method"], class_name="text-sm text-muted-foreground"),
class_name="hidden md:table-cell py-2",
),
table.cell(
rx.el.span(
inv["due"],
class_name="text-sm text-muted-foreground tabular-nums",
),
sort_value=inv["due_date"],
class_name="hidden md:table-cell py-2",
),
table.cell(render_status_badge(inv["status"])),
table.cell(
rx.el.span(
f"${formatted_amount}",
class_name="block text-right text-sm font-semibold text-foreground tabular-nums",
),
sort_value=inv["amount"],
class_name="py-2",
),
class_name="whitespace-nowrap !py-2",
)
def main_table_section():
return rx.el.div(
table.search(
for_table="invoices-table",
class_name="mb-4 w-full max-w-sm",
),
table.root(
table.header(
table.row(
table.head(
checkbox.root(
checkbox.indicator(),
**{"data-dt-select-all": "true"},
),
class_name="w-10 pl-4",
),
table.head("Invoice"),
table.head("Client", sort_key="client"),
table.head("Project", class_name="hidden sm:table-cell"),
table.head("Method", class_name="hidden md:table-cell"),
table.head(
"Due",
sort_key="due",
class_name="hidden md:table-cell",
),
table.head("Status"),
table.head(
"Amount",
sort_key="amount",
class_name="text-right",
),
)
),
table.body(*[render_row(inv) for inv in INVOICES]),
id="invoices-table",
paginate=True,
page_size=7,
class_name="w-full",
),
class_name="w-full",
)
def main():
return rx.el.main(
rx.el.h1("Overview", class_name="text-2xl font-semibold"),
main_kpi_section(),
main_chart_section(),
main_table_section(),
class_name="w-full flex-1 h-full border border-input/90 overflow-y-auto p-6 flex flex-col gap-6",
)
def sidebar_header():
return rx.el.div(
rx.el.span("Acme", class_name="font-semibold text-lg"),
class_name="flex items-center gap-2 px-4 h-10 shrink-0 border-b border-input/90",
)
def _sidebar_item(label: str, icon: str) -> rx.Component:
return rx.el.div(
hi(icon, class_name="size-4 shrink-0"),
rx.el.span(label, class_name="text-sm"),
class_name="flex items-center gap-2.5 px-4 py-2 rounded-lg cursor-pointer",
)
def sidebar_items():
return rx.el.div(
*[_sidebar_item(i["label"], i["icon"]) for i in NAV_ITEMS],
class_name="flex flex-col gap-1 py-2",
)
def sidebar_footer():
return rx.el.div(
rx.el.div(
"AC",
class_name="size-8 rounded-full bg-muted border border-input/90 flex items-center justify-center text-xs font-medium shrink-0",
),
rx.el.div(
rx.el.p(
"Avery Cole", class_name="text-sm font-medium leading-tight truncate"
),
rx.el.p(
"avery@acme.com",
class_name="text-xs text-muted-foreground leading-tight truncate",
),
class_name="min-w-0",
),
class_name="flex items-center gap-2.5 px-4 py-3 border-t border-input/90 shrink-0",
)
def sidebar():
return rx.el.aside(
sidebar_header(),
sidebar_items(),
rx.el.div(class_name="flex-1"),
sidebar_footer(),
class_name="w-full max-w-64 h-full bg-accent dark:bg-card border-y border-l border-input/90 hidden md:flex md:flex-col",
)
def dashboard_01():
return rx.el.div(
sidebar(),
main(),
class_name="w-full h-screen flex",
)
Dashboard 02
Dashboard with search top bar, avatar, and dashboard placeholder cards.
Dependencies
Overview
Here is what is happening across Acme today.
Total revenue
+12.4%$48.2k
Active users
+5.1%2,840
Conversion
-0.8%3.6%
Performance
+18.2% MoMArea Chart - Gradient
Showing total visitors for the last 6 months
Desktop
Mobile
Recent Activity
Priya Nair deployed acme-web v2.4
2 min ago
Marco Diaz merged PR #482: checkout refactor
1 hour ago
Lena Fischer closed 8 tasks in Sprint 7
3 hours ago
import reflex as rx
from components.core.hugeicon import hi
from components.ui.avatar import avatar
from components.ui.badge import badge
from native.lib.charts.area.v8 import area_chart_with_gradient
NAV_ITEMS = [
{"label": "Overview", "icon": "DashboardSquare01Icon", "active": True},
{"label": "Analytics", "icon": "ChartBarLineIcon", "active": False},
{"label": "Projects", "icon": "FolderIcon", "active": False},
{"label": "Team", "icon": "UserGroupIcon", "active": False},
{"label": "Settings", "icon": "Settings01Icon", "active": False},
]
STATS = [
{"label": "Total revenue", "value": "$48.2k", "delta": "+12.4%"},
{"label": "Active users", "value": "2,840", "delta": "+5.1%"},
{"label": "Conversion", "value": "3.6%", "delta": "-0.8%"},
]
ACTIVITY = [
{
"name": "Priya Nair",
"avatar": "https://i.pravatar.cc/150?img=45",
"icon": "RocketIcon",
"action": "deployed",
"target": "acme-web v2.4",
"time": "2 min ago",
},
{
"name": "Marco Diaz",
"avatar": "https://i.pravatar.cc/150?img=33",
"icon": "GitMergeIcon",
"action": "merged",
"target": "PR #482: checkout refactor",
"time": "1 hour ago",
},
{
"name": "Lena Fischer",
"avatar": "https://i.pravatar.cc/150?img=47",
"icon": "CheckmarkCircle01Icon",
"action": "closed",
"target": "8 tasks in Sprint 7",
"time": "3 hours ago",
},
]
def sidebar_header():
return rx.el.div(
hi("DashboardSquare01Icon", class_name="size-5 shrink-0"),
rx.el.span("Acme", class_name="font-semibold text-base"),
class_name="flex items-center gap-2 px-4 h-14 shrink-0 border-b border-input/90",
)
def _sidebar_item(label: str, icon: str, active: bool = False) -> rx.Component:
return rx.el.div(
hi(icon, class_name="size-4 shrink-0"),
rx.el.span(label, class_name="text-sm"),
class_name=(
"flex items-center gap-2.5 px-3 py-2 rounded-lg cursor-pointer "
+ (
"bg-accent text-accent-foreground"
if active
else "text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"
)
),
)
def sidebar_items():
return rx.el.div(
*[_sidebar_item(i["label"], i["icon"], i["active"]) for i in NAV_ITEMS],
class_name="flex flex-col gap-1 p-2",
)
def sidebar_footer():
return rx.el.div(
avatar.root(
avatar.image(
src="https://i.pravatar.cc/150?img=15",
class_name="shrink-0 border border-input/90 grayscale",
),
avatar.fallback("AC"),
class_name="size-8",
),
rx.el.div(
rx.el.p(
"Avery Cole", class_name="text-sm font-medium leading-tight truncate"
),
rx.el.p(
"avery@acme.com",
class_name="text-xs text-muted-foreground leading-tight truncate",
),
class_name="min-w-0",
),
class_name="flex items-center gap-2.5 px-4 py-3 border-t border-input/90 shrink-0",
)
def sidebar():
return rx.el.aside(
sidebar_header(),
sidebar_items(),
rx.el.div(class_name="flex-1"),
sidebar_footer(),
class_name="w-full max-w-64 h-full bg-accent dark:bg-card border-y border-l border-input/90 hidden md:flex md:flex-col",
)
def navbar():
return rx.el.div(
rx.el.div(
hi("Search01Icon", class_name="size-4 shrink-0 text-muted-foreground"),
rx.el.span(
"Search projects, people...",
class_name="text-sm text-muted-foreground",
),
class_name=(
"flex items-center gap-2 h-9 w-full max-w-sm border border-input/90 "
"rounded-lg px-3 bg-background cursor-pointer"
),
),
rx.el.div(
rx.el.button(
hi("Notification03Icon", class_name="size-5"),
rx.el.span(
"2",
class_name=(
"absolute -top-1 -right-1 flex size-4 items-center justify-center "
"rounded-full bg-primary text-[9px] font-bold text-primary-foreground"
),
),
class_name="relative size-9 flex items-center justify-center rounded-lg hover:bg-accent",
),
avatar.root(
avatar.image(
src="https://i.pravatar.cc/150?img=15",
class_name="shrink-0 border border-input/90 grayscale",
),
avatar.fallback("AC"),
class_name="size-8 cursor-pointer",
),
class_name="flex items-center gap-2",
),
class_name=(
"flex items-center justify-between gap-3 h-14 shrink-0 px-4 sm:px-6 "
"border-b border-input/90 bg-background"
),
)
def _stat_card(label: str, value: str, delta: str) -> rx.Component:
is_negative = delta.startswith("-")
return rx.el.div(
rx.el.div(
rx.el.p(label, class_name="text-sm font-medium text-muted-foreground"),
badge(
delta,
variant="destructive" if is_negative else "secondary",
class_name="text-[11px]",
),
class_name="flex items-center justify-between",
),
rx.el.p(value, class_name="text-3xl font-semibold tracking-tight mt-3"),
class_name="flex-1 border border-input/90 rounded-2xl p-4",
)
def main_stats_section():
return rx.el.div(
*[_stat_card(s["label"], s["value"], s["delta"]) for s in STATS],
class_name="grid gap-4 sm:grid-cols-2 md:grid-cols-3",
)
def main_chart_section():
return rx.el.div(
rx.el.div(
rx.el.p("Performance", class_name="font-medium"),
badge("+18.2% MoM", variant="secondary", class_name="text-[11px]"),
class_name="flex items-center justify-between mb-2",
),
area_chart_with_gradient(),
class_name="md:col-span-2 border border-input/90 rounded-2xl p-4",
)
def _activity_row(item: dict) -> rx.Component:
return rx.el.div(
rx.el.div(
avatar.root(
avatar.image(src=item["avatar"], class_name="shrink-0 grayscale"),
avatar.fallback(item["name"][:2].upper()),
class_name="size-8",
),
rx.el.div(
hi(item["icon"], class_name="size-2.5 text-muted-foreground"),
class_name=(
"absolute -right-1 -bottom-1 flex size-4 items-center justify-center "
"rounded-full border border-input/90 bg-background"
),
),
class_name="relative shrink-0",
),
rx.el.div(
rx.el.p(
rx.el.span(item["name"], class_name="font-medium text-foreground"),
" ",
rx.el.span(item["action"], class_name="text-muted-foreground"),
" ",
rx.el.span(item["target"], class_name="font-medium text-foreground"),
class_name="text-sm leading-snug",
),
rx.el.p(item["time"], class_name="text-xs text-muted-foreground mt-0.5"),
class_name="min-w-0 flex-1",
),
class_name="flex items-start gap-3",
)
def main_activity_section():
return rx.el.div(
rx.el.p("Recent Activity", class_name="font-medium mb-4"),
rx.el.div(
*[_activity_row(item) for item in ACTIVITY],
class_name="flex flex-col gap-4",
),
class_name="border border-input/90 rounded-2xl p-4",
)
def main_performance_section():
return rx.el.div(
main_chart_section(),
main_activity_section(),
class_name="grid gap-4 md:grid-cols-3",
)
def main():
return rx.el.main(
navbar(),
rx.el.div(
rx.el.div(
rx.el.div(
rx.el.h1(
"Overview", class_name="text-2xl font-semibold tracking-tight"
),
rx.el.p(
"Here is what is happening across Acme today.",
class_name="text-sm text-muted-foreground",
),
),
badge(
rx.el.span(class_name="size-1.5 rounded-full bg-primary"),
"Live",
variant="secondary",
class_name="gap-1.5",
),
class_name="flex flex-wrap items-end justify-between gap-3",
),
main_stats_section(),
main_performance_section(),
class_name="flex flex-col gap-4 p-4 sm:p-6",
),
class_name="w-full flex-1 h-full border border-input/90 overflow-y-auto flex flex-col",
)
def dashboard_02():
return rx.el.div(
sidebar(),
main(),
class_name="w-full h-screen flex",
)
Dashboard 03
A complex dashboard with intricate sidebar, menu items, call-to-action card, analytics, and a menu top bar.
Dependencies
Welcome Back, Maya
Here is what is happening across your workspace today.
Monthly Revenue
$48,240
Vs. Last Month
Active Users
8,941
Vs. Last Month
Conversion Rate
3.24%
Vs. Last Month
Revenue
Last 8 Months
Area Chart - Gradient
Showing total visitors for the last 6 months
Desktop
Mobile
Recent Activity
View AllPriya Nair deployed web-app v2.4.0
9:42 AM
Jonas Weber merged PR 482 Checkout Refactor
9:06 AM
Lena Fischer closed 8 tasks in Sprint 7
8:31 AM
Diego Alvarez invited Sofia Rossi to the team
Yesterday
Active Projects
View Allimport reflex as rx
from components.core.hugeicon import hi
from components.ui.avatar import avatar
from components.ui.button import button
from native.lib.charts.area.v8 import area_chart_with_gradient
NAV_ITEMS = [
{"label": "Dashboard", "icon": "DashboardSquare01Icon", "active": True},
{"label": "Projects", "icon": "Folder01Icon", "active": False},
{"label": "Analytics", "icon": "ChartBarLineIcon", "active": False},
{"label": "Team", "icon": "UserGroupIcon", "active": False},
{"label": "Reports", "icon": "GridViewIcon", "active": False},
]
ACTIVE_PROJECTS = [
"Design System",
"API Integration",
"Mobile App",
"Analytics Rebuild",
]
BREADCRUMB_ITEMS = [
{"label": "Acme Inc", "icon": "SquareIcon"},
{"label": "Marketing Site", "icon": None},
{"label": "Preview", "icon": None},
]
STATS = [
{"label": "Monthly Revenue", "value": "$48,240", "delta": "+12.5%"},
{"label": "Active Users", "value": "8,941", "delta": "+4.3%"},
{"label": "Conversion Rate", "value": "3.24%", "delta": "-0.8%"},
]
ACTIVITY = [
{
"name": "Priya Nair",
"avatar": "https://i.pravatar.cc/150?img=45",
"action": "deployed",
"target": "web-app v2.4.0",
"time": "9:42 AM",
},
{
"name": "Jonas Weber",
"avatar": "https://i.pravatar.cc/150?img=33",
"action": "merged",
"target": "PR 482 Checkout Refactor",
"time": "9:06 AM",
},
{
"name": "Lena Fischer",
"avatar": "https://i.pravatar.cc/150?img=47",
"action": "closed",
"target": "8 tasks in Sprint 7",
"time": "8:31 AM",
},
{
"name": "Diego Alvarez",
"avatar": "https://i.pravatar.cc/150?img=11",
"action": "invited",
"target": "Sofia Rossi to the team",
"time": "Yesterday",
},
]
def sidebar_header():
return rx.el.div(
rx.el.div(
hi("DashboardSquare01Icon", class_name="size-5 shrink-0"),
rx.el.span("Acme", class_name="font-semibold text-base"),
class_name="flex items-center gap-2",
),
rx.el.div(
hi("SparklesIcon", class_name="size-3 shrink-0"),
rx.el.span("Pro", class_name="text-xs font-medium"),
class_name="flex items-center gap-1 bg-foreground text-background rounded-full px-2.5 py-1",
),
class_name="flex items-center justify-between px-4 h-14 shrink-0",
)
def new_report_button():
return button(
hi("PlusSignIcon", class_name="size-4"),
rx.el.span("New Report", class_name="text-sm font-medium"),
class_name="w-full",
)
def _section_label(text: str) -> rx.Component:
return rx.el.p(
text,
class_name="px-4 pt-4 pb-1 text-xs font-medium text-muted-foreground",
)
def _sidebar_item(label: str, icon: str, active: bool = False) -> rx.Component:
return rx.el.div(
hi(icon, class_name="size-4 shrink-0"),
rx.el.span(label, class_name="text-sm font-medium"),
class_name=(
"flex items-center gap-2.5 mx-2 px-3 py-2 rounded-lg cursor-pointer "
+ (
"bg-accent text-accent-foreground"
if active
else "text-muted-foreground hover:bg-accent/60 hover:text-accent-foreground"
)
),
)
def sidebar_platform_items():
return rx.el.div(
_section_label("Platform"),
*[_sidebar_item(i["label"], i["icon"], i["active"]) for i in NAV_ITEMS],
class_name="flex flex-col",
)
def _project_item(label: str) -> rx.Component:
return rx.el.div(
hi("Loading03Icon", class_name="size-4 shrink-0 text-muted-foreground"),
rx.el.span(label, class_name="text-sm"),
class_name="flex items-center gap-2.5 mx-2 px-3 py-2 rounded-lg text-muted-foreground hover:bg-accent/60 cursor-pointer",
)
def sidebar_active_projects():
return rx.el.div(
_section_label("Active Projects"),
*[_project_item(p) for p in ACTIVE_PROJECTS],
class_name="flex flex-col",
)
def sidebar_usage_card():
return rx.el.div(
rx.el.div(
rx.el.div(
hi("SparklesIcon", class_name="size-3.5"),
rx.el.span("Monthly Usage", class_name="text-sm font-medium"),
class_name="flex items-center gap-1.5",
),
rx.el.span("Resets May 1", class_name="text-xs text-background/60"),
class_name="flex items-center justify-between",
),
rx.el.p(
"You have used 82% of your plan this cycle. Upgrade for unlimited requests.",
class_name="text-xs text-background/70 mt-2 leading-relaxed",
),
rx.el.div(
rx.el.div(class_name="h-1.5 rounded-full bg-background w-[82%]"),
class_name="h-1.5 w-full rounded-full bg-background/20 mt-3",
),
rx.el.div(
rx.el.span("82% Used", class_name="text-xs font-medium"),
rx.el.span("18% Left", class_name="text-xs text-background/60"),
class_name="flex items-center justify-between mt-1.5",
),
rx.el.button(
hi("Notification03Icon", class_name="size-3.5"),
rx.el.span("Upgrade Plan", class_name="text-sm font-medium"),
class_name="flex items-center justify-center gap-2 h-9 w-full rounded-lg bg-background text-foreground mt-3",
),
class_name="mx-3 mt-4 p-4 rounded-xl bg-foreground text-background",
)
def sidebar_footer():
return rx.el.div(
avatar.root(
avatar.image(
src="https://i.pravatar.cc/150?img=47",
class_name="shrink-0 grayscale",
),
avatar.fallback("MC"),
class_name="size-8",
),
rx.el.div(
rx.el.p(
"Maya Chen", class_name="text-sm font-medium leading-tight truncate"
),
rx.el.p(
"maya@acme.com",
class_name="text-xs text-muted-foreground leading-tight truncate",
),
class_name="min-w-0 flex-1",
),
hi("UnfoldMoreIcon", class_name="size-4 shrink-0 text-muted-foreground"),
class_name="flex items-center gap-2.5 px-4 py-3 border-t border-input/90 shrink-0",
)
def sidebar():
return rx.el.aside(
sidebar_header(),
rx.el.div(new_report_button(), class_name="p-2 w-full"),
rx.el.div(
sidebar_platform_items(),
sidebar_active_projects(),
class_name="flex-1 overflow-y-auto py-3",
),
sidebar_usage_card(),
sidebar_footer(),
class_name="w-full max-w-64 h-full bg-accent dark:bg-card border-y border-l border-input/90 hidden md:flex md:flex-col",
)
def _breadcrumb_item(label: str, icon: str | None, is_last: bool) -> rx.Component:
return rx.el.div(
hi(icon, class_name="size-3.5 shrink-0") if icon else rx.el.div(),
rx.el.span(
label,
class_name=(
"text-sm " + ("font-semibold" if is_last else "text-muted-foreground")
),
),
hi("ArrowDown01Icon", class_name="size-3.5 shrink-0 text-muted-foreground"),
class_name="flex items-center gap-1.5",
)
def breadcrumb():
items = []
for i, crumb in enumerate(BREADCRUMB_ITEMS):
items.append(
_breadcrumb_item(
crumb["label"], crumb["icon"], i == len(BREADCRUMB_ITEMS) - 1
)
)
if i < len(BREADCRUMB_ITEMS) - 1:
items.append(rx.el.span("/", class_name="text-muted-foreground/50"))
return rx.el.div(*items, class_name="flex items-center gap-2.5")
def topbar_search():
return rx.el.div(
hi("Search01Icon", class_name="size-4 shrink-0 text-muted-foreground"),
rx.el.span("Search...", class_name="text-sm text-muted-foreground flex-1"),
rx.el.kbd(
"⌘K",
class_name="text-[10px] font-medium text-muted-foreground bg-muted rounded px-1.5 py-0.5",
),
class_name="hidden lg:flex items-center gap-2 h-9 w-64 rounded-lg border border-input/90 px-3 bg-background",
)
def topbar_status_pill():
return rx.el.div(
rx.el.span(class_name="size-1.5 rounded-full bg-orange-500"),
rx.el.span("Degraded", class_name="text-xs font-medium"),
class_name="hidden sm:flex items-center gap-1.5 h-9 rounded-lg border border-input/90 px-3",
)
def topbar():
return rx.el.div(
rx.el.div(
hi(
"SidebarLeftIcon",
class_name="size-4 shrink-0 text-muted-foreground hidden md:block",
),
class_name="flex items-center gap-4 min-w-0",
),
rx.el.div(
topbar_search(),
topbar_status_pill(),
rx.el.button(
hi("Notification03Icon", class_name="size-4.5"),
rx.el.span(
class_name="absolute top-1.5 right-1.5 size-1.5 rounded-full bg-foreground"
),
class_name="relative size-9 flex items-center justify-center rounded-lg hover:bg-accent shrink-0",
),
avatar.root(
avatar.image(
src="https://i.pravatar.cc/150?img=47",
class_name="shrink-0 grayscale",
),
avatar.fallback("MC"),
class_name="size-8 shrink-0 cursor-pointer",
),
class_name="flex items-center gap-3 shrink-0",
),
class_name="flex items-center justify-between gap-4 h-14 shrink-0 px-4 sm:px-6 border-b border-input/90 bg-background",
)
def _stat_card(label: str, value: str, delta: str) -> rx.Component:
is_negative = delta.startswith("-")
return rx.el.div(
rx.el.div(
rx.el.p(label, class_name="text-sm text-muted-foreground"),
rx.el.div(
hi(
"ArrowDownRight01Icon" if is_negative else "ArrowUpRight01Icon",
class_name="size-3.5",
),
rx.el.span(delta, class_name="text-sm font-medium"),
class_name=(
"flex items-center gap-1 "
+ ("text-muted-foreground" if is_negative else "text-emerald-600")
),
),
class_name="flex items-center justify-between",
),
rx.el.p(value, class_name="text-3xl font-bold tracking-tight mt-3"),
rx.el.p("Vs. Last Month", class_name="text-xs text-muted-foreground mt-2"),
class_name="flex-1 border border-input/90 rounded-2xl p-5",
)
def main_stats_section():
return rx.el.div(
*[_stat_card(s["label"], s["value"], s["delta"]) for s in STATS],
class_name="grid gap-4 sm:grid-cols-2 md:grid-cols-3",
)
def main_chart_section():
return rx.el.div(
rx.el.div(
rx.el.div(
rx.el.p("Revenue", class_name="font-semibold"),
rx.el.p("Last 8 Months", class_name="text-sm text-muted-foreground"),
),
rx.el.span(
"+18.2% YTD",
class_name="text-xs font-medium bg-muted rounded-lg px-2.5 py-1.5 h-fit",
),
class_name="flex items-start justify-between mb-4",
),
area_chart_with_gradient(),
class_name="lg:col-span-2 border border-input/90 rounded-2xl p-5",
)
def _activity_row(item: dict) -> rx.Component:
return rx.el.div(
avatar.root(
avatar.image(src=item["avatar"], class_name="shrink-0 grayscale"),
avatar.fallback(item["name"][:2].upper()),
class_name="size-9",
),
rx.el.div(
rx.el.p(
rx.el.span(item["name"], class_name="font-semibold text-foreground"),
" ",
rx.el.span(item["action"], class_name="text-muted-foreground"),
" ",
rx.el.span(item["target"], class_name="font-semibold text-foreground"),
class_name="text-sm leading-snug",
),
rx.el.p(item["time"], class_name="text-xs text-muted-foreground mt-1"),
class_name="min-w-0 flex-1",
),
class_name="flex items-start gap-3 py-3 border-b border-input/60 last:border-0",
)
def main_activity_section():
return rx.el.div(
rx.el.div(
rx.el.p("Recent Activity", class_name="font-semibold"),
rx.el.span(
"View All",
class_name="text-sm text-muted-foreground cursor-pointer hover:text-foreground",
),
class_name="flex items-center justify-between mb-1",
),
rx.el.div(
*[_activity_row(item) for item in ACTIVITY],
class_name="flex flex-col",
),
class_name="border border-input/90 rounded-2xl p-5",
)
def main_performance_section():
return rx.el.div(
main_chart_section(),
main_activity_section(),
class_name="grid gap-4 lg:grid-cols-3",
)
def main_active_projects_header():
return rx.el.div(
rx.el.p("Active Projects", class_name="font-semibold"),
rx.el.span(
"View All",
class_name="text-sm text-muted-foreground cursor-pointer hover:text-foreground",
),
class_name="flex items-center justify-between p-5 border border-input/90 rounded-2xl",
)
def main_header_row():
return rx.el.div(
rx.el.div(
rx.el.h1(
"Welcome Back, Maya", class_name="text-3xl font-bold tracking-tight"
),
rx.el.p(
"Here is what is happening across your workspace today.",
class_name="text-sm text-muted-foreground mt-1",
),
),
rx.el.button(
hi("ArrowUpRight01Icon", class_name="size-4"),
rx.el.span("Export Report", class_name="text-sm font-medium"),
class_name="flex items-center gap-2 h-9 rounded-lg border border-input/90 px-3 shrink-0",
),
class_name="flex flex-wrap items-end justify-between gap-3",
)
def main():
return rx.el.main(
topbar(),
rx.el.div(
main_header_row(),
main_stats_section(),
main_performance_section(),
main_active_projects_header(),
class_name="flex flex-col gap-4 p-4 sm:p-6",
),
class_name="w-full flex-1 h-full border border-input/90 overflow-y-auto flex flex-col",
)
def dashboard_03():
return rx.el.div(
sidebar(),
main(),
class_name="w-full h-screen flex",
)