WebAdmin Dashboard Package ๐ŸŽจ

A professional Flutter package for building beautiful, fully-customizable admin dashboards with minimal boilerplate. Features automatic menu generation from a single page configuration, responsive sidebar navigation, and pre-built dashboard components.

โœจ Features

  • ๐Ÿš€ Declarative Page Configuration: Define pages once in a single list, automatic menu generation
  • ๐Ÿ“Š Pre-built Dashboard Cards: Revenue, Warehouse, Growth, MetalPrices, and Chart components
  • ๐Ÿงญ Smart Sidebar Navigation: Top and bottom menu sections with automatic routing
  • ๐Ÿ“ˆ Integrated Charts: fl_chart integration for data visualization
  • ๐ŸŽจ Fully Customizable: Colors, styles, icons, and layouts
  • ๐ŸŒ“ Light & Dark Theme Support: Material3 with seamless theme switching
  • ๐Ÿ“ฑ Desktop Optimized: Perfect for macOS, Windows, Linux desktop apps
  • โšก Zero Boilerplate: No manual switch statements or menu management
  • ๐Ÿ“„ Beautiful Headers: Full-height PageHeader with descriptions
  • ๐Ÿ”„ Automatic Routing: Page builder pattern for effortless navigation

๐Ÿš€ Getting Started

Add this to your package's pubspec.yaml file:

dependencies:
  webadmin: ^0.0.6

Then run:

flutter pub get

๐Ÿ“– Complete Usage Guide

1. The Simplest Way - Automatic Menu Generation โญ

Define all your pages in a single list. Everything else is automatic!

import 'package:flutter/material.dart';
import 'package:webadmin/webadmin.dart';

class AdminDashboard extends StatefulWidget {
  @override
  State<AdminDashboard> createState() => _AdminDashboardState();
}

class _AdminDashboardState extends State<AdminDashboard> {
  int selectedIndex = 0;

  // Define ALL pages in a single list - that's it!
  late final List<DashboardPage> pages = [
    DashboardPage(
      icon: Icons.dashboard,
      title: 'Dashboard',
      route: 'dashboard',
      description: 'View your dashboard metrics',
      builder: (context) => const DashboardScreen(),
    ),
    DashboardPage(
      icon: Icons.bar_chart,
      title: 'Analytics',
      route: 'analytics',
      description: 'Analyze trends and performance',
      builder: (context) => const AnalyticsScreen(),
    ),
    DashboardPage(
      icon: Icons.settings,
      title: 'Settings',
      route: 'settings',
      description: 'Configure application settings',
      builder: (context) => const SettingsScreen(),
    ),
  ];

  // Split pages: top 2 pages in top menu, rest in bottom
  List<DashboardPage> get topPages => pages.sublist(0, 2);
  List<DashboardPage> get bottomPages => pages.sublist(2);

  @override
  Widget build(BuildContext context) {
    final currentPage = pages[selectedIndex];

    return Scaffold(
      body: DashboardLayout(
        topItems: topPages.map((p) => p.toMenuItem()).toList(),
        bottomItems: bottomPages.map((p) => p.toMenuItem()).toList(),
        selectedIndex: selectedIndex,
        onSelect: (index) => setState(() => selectedIndex = index),
        brandTitle: 'My Admin',
        currentPage: currentPage,
        contentWidget: pages[selectedIndex].builder(context),
        showPageHeader: true,
        showHeaderIcon: true,
        headerTitleSize: 28.0,
        headerDescriptionSize: 16.0,
      ),
    );
  }
}
}

// Your screen implementations
class DashboardScreen extends StatelessWidget {
  const DashboardScreen({super.key});
  @override
  Widget build(BuildContext context) => const Placeholder();
}

class AnalyticsScreen extends StatelessWidget {
  const AnalyticsScreen({super.key});
  @override
  Widget build(BuildContext context) => const Placeholder();
}

class SettingsScreen extends StatelessWidget {
  const SettingsScreen({super.key});
  @override
  Widget build(BuildContext context) => const Placeholder();
}

2. DashboardLayout - Complete Layout Control ๐ŸŽฏ

The DashboardLayout widget handles the entire dashboard structure:

DashboardLayout(
  // Navigation menu configuration
  topItems: topPages.map((p) => p.toMenuItem()).toList(),
  bottomItems: bottomPages.map((p) => p.toMenuItem()).toList(),
  selectedIndex: selectedIndex,
  onSelect: (index) => setState(() => selectedIndex = index),
  
  // Layout configuration
  brandTitle: 'My Admin',
  currentPage: currentPage,
  contentWidget: pages[selectedIndex].builder(context),
  
  // Header customization
  showPageHeader: true,          // Toggle header visibility
  showHeaderIcon: true,          // Toggle icon in header
  headerTitleSize: 28.0,         // Customize title font size
  headerDescriptionSize: 16.0,   // Customize description font size
)

3. Using DashboardPage Model

// DashboardPage has these properties:
DashboardPage(
  icon: Icons.dashboard,           // Menu icon
  title: 'Dashboard',              // Menu label & page title
  route: 'dashboard',              // Route identifier
  description: 'Main dashboard',   // Subtitle shown in header
  builder: (context) => MyWidget(), // Widget to display for this page
)

// Convert to menu item automatically:
DashboardMenuItem item = page.toMenuItem();
// Returns: DashboardMenuItem(icon: Icons.dashboard, label: 'Dashboard')

3. Dashboard Cards

// Revenue Card
RevenueCard(
  amount: 45230,
  title: 'Today\'s Revenue',
)

// Warehouse Card
WarehouseCard(
  productCount: 128,
  buyAmount: 89342,
)

// Growth Card
GrowthCard(
  label: 'Last Month',
  percent: 0.18,
  color: Colors.green,
  icon: Icons.trending_up,
)

// Metal Prices Card
MetalPricesCard(
  goldPrice: 112.7,
  silverPrice: 1.36,
)

// Gold Price Chart
GoldPriceChart(
  values: [108, 109, 110, 111, 113, 114, 115],
)

4. Sidebar Component (Manual)

If you want to use sidebar separately:

DashboardSidebar(
  topItems: [
    DashboardMenuItem(icon: Icons.dashboard, label: 'Dashboard'),
    DashboardMenuItem(icon: Icons.bar_chart, label: 'Analytics'),
  ],
  bottomItems: [
    DashboardMenuItem(icon: Icons.settings, label: 'Settings'),
  ],
  selectedIndex: 0,
  onSelect: (index) {
    setState(() => selectedIndex = index);
  },
  brandTitle: 'Admin Panel',
)

5. PageHeader Widget

Container(
  color: Colors.white,
  child: Padding(
    padding: const EdgeInsets.all(20),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          'Dashboard',
          style: Theme.of(context).textTheme.headlineSmall,
        ),
        Text(
          'Welcome to your admin panel',
          style: Theme.of(context).textTheme.bodySmall,
        ),
      ],
    ),
  ),
)

6. Theme Support

MaterialApp(
  theme: ThemeData(
    brightness: Brightness.light,
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: Colors.blue,
      brightness: Brightness.light,
    ),
  ),
  darkTheme: ThemeData(
    brightness: Brightness.dark,
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: Colors.blue,
      brightness: Brightness.dark,
    ),
  ),
  themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
)

๐Ÿ“š Full Working Example

See the /example folder for a complete application with:

  • 6 demo pages (Dashboard, Analytics, Products, Users, Settings, Help)
  • Automatic menu generation from DashboardPage list
  • Light/Dark theme switching
  • Dashboard cards with real layout
  • Responsive design

Run it:

cd example
flutter run -d macos  # or your device

๐Ÿงจ Components Reference

DashboardPage Model โญ

Automatic menu generation magic!

  • icon: Icon for sidebar menu
  • title: Page title and menu label
  • route: Route identifier
  • description: Optional subtitle
  • builder: Widget builder function
  • toMenuItem(): Convert to DashboardMenuItem automatically

DashboardSidebar

  • 260px width fixed sidebar
  • Top and bottom menu sections
  • Customizable brand title
  • Selected item highlighting (blue 20% opacity background)
  • Dark theme: Color(0xFF1A1F3A) background
  • Responsive to theme changes
  • Static header container
  • Displays current page title and description
  • Automatically updates when page changes
  • Customizable colors and styling
  • Perfect for breadcrumbs or actions

Dashboard Cards

Card Purpose Usage
RevenueCard Show monetary values RevenueCard(amount: 45230, title: 'Revenue')
WarehouseCard Display inventory stats WarehouseCard(productCount: 128, buyAmount: 89342)
GrowthCard Show percentage trends GrowthCard(label: 'Growth', percent: 0.18, color: Colors.green)
MetalPricesCard Display commodity prices MetalPricesCard(goldPrice: 112.7, silverPrice: 1.36)
GoldPriceChart Line chart visualization GoldPriceChart(values: [108, 109, 110, ...])

๐Ÿ“‹ Migration Guide: Manual โ†’ Automatic

Before (Manual approach)

// Multiple lists to maintain
late final topMenuItems = const [...];\nlate final bottomMenuItems = const [...];\n\n// Manual routing with switch
Widget _buildContent() {
  switch(selectedIndex) {
    case 0: return Dashboard();
    case 1: return Analytics();
    ...
  }
}

After (Automatic approach)

// Single list, everything auto-wired
late final pages = [DashboardPage(...), ...];

// Automatic menu generation
topItems: pages.map((p) => p.toMenuItem()).toList()

// Automatic routing
page.builder(context)

๐ŸŽฏ Best Practices

  1. Define pages in order: Top pages first, then bottom pages
  2. Use meaningful icons: Match icons to page purpose
  3. Keep descriptions short: 1-2 sentences max
  4. Provide builder functions: Make screens stateless when possible
  5. Split pages logically: Main features on top, utilities on bottom

๐Ÿ› Troubleshooting

Pages not showing in menu?

  • Ensure topItems and bottomItems are properly mapped from DashboardPage
  • Check that sublist indices match your pages count

Header not updating?

  • Wrap header in pages[selectedIndex] - should auto-update
  • Check that currentPage is accessed correctly

Theme not switching?

  • Use ThemeMode.dark / ThemeMode.light in MaterialApp
  • Ensure dark theme is defined in darkTheme property

๐Ÿ“ž Support

For issues, suggestions, or contributions, visit:

๐Ÿ“„ License

MIT License - See LICENSE file for details