flutter_adminpanel 2.0.3 copy "flutter_adminpanel: ^2.0.3" to clipboard
flutter_adminpanel: ^2.0.3 copied to clipboard

A comprehensive Flutter admin panel library similar to react-admin with universal REST API adapter for any backend

example/lib/main.dart

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize REST API data provider
  final dataProvider = RestDataProvider(
    baseUrl: 'https://api.example.com', // Replace with your API URL
  );

  runApp(HolyAdminApp(dataProvider: dataProvider));
}

class HolyAdminApp extends StatefulWidget {
  final DataProvider dataProvider;

  const HolyAdminApp({super.key, required this.dataProvider});

  @override
  State<HolyAdminApp> createState() => _HolyAdminAppState();
}

class _HolyAdminAppState extends State<HolyAdminApp> {
  final EventStatusService _eventStatusService = EventStatusService();

  @override
  void initState() {
    super.initState();
    _eventStatusService.startAutoUpdate();
  }

  @override
  void dispose() {
    _eventStatusService.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Simple configuration
    final config = AdminConfig(
      appName: 'Holy Admin',
      supportedLanguages: ['en', 'ru', 'hi'],
      defaultLanguage: 'en',
    );

    // Define resources
    final resources = _createResources();

    // Create admin app with holy-admin theme
    return AdminApp(
      config: config,
      dataProvider: widget.dataProvider,
      resources: resources,
      title: 'Holy Admin - Flutter',
      dashboard: HolyDashboard(dataProvider: widget.dataProvider),
    );
  }

  List<Resource> _createResources() {
    return [
      // Countries
      Resource(
        name: 'countries',
        label: 'Countries',
        icon: Icons.public,
        columns: [
          const ColumnConfig(
            key: 'id',
            label: 'ID',
            type: ColumnType.text,
            visible: false,
          ),
          const ColumnConfig(
            key: 'name',
            label: 'Name',
            type: ColumnType.json,
            required: true,
          ),
          const ColumnConfig(
            key: 'info',
            label: 'Information',
            type: ColumnType.json,
          ),
          const ColumnConfig(
            key: 'cities_count',
            label: 'Cities Count',
            type: ColumnType.number,
          ),
          const ColumnConfig(
            key: 'images',
            label: 'Images',
            type: ColumnType.image,
          ),
        ],
      ),

      // Cities
      Resource(
        name: 'cities',
        label: 'Cities',
        icon: Icons.location_city,
        columns: [
          const ColumnConfig(key: 'id', label: 'ID', visible: false),
          const ColumnConfig(
            key: 'name',
            label: 'Name',
            type: ColumnType.json,
            required: true,
          ),
          const ColumnConfig(
            key: 'country',
            label: 'Country',
            type: ColumnType.reference,
            referenceResource: 'countries',
          ),
          const ColumnConfig(
            key: 'spots_count',
            label: 'Spots',
            type: ColumnType.number,
          ),
          const ColumnConfig(
            key: 'routes_count',
            label: 'Routes',
            type: ColumnType.number,
          ),
          const ColumnConfig(
            key: 'events_count',
            label: 'Events',
            type: ColumnType.number,
          ),
        ],
      ),

      // Spots
      Resource(
        name: 'spots',
        label: 'Spots',
        icon: Icons.place,
        columns: [
          const ColumnConfig(key: 'id', label: 'ID', visible: false),
          const ColumnConfig(
            key: 'name',
            label: 'Name',
            type: ColumnType.json,
            required: true,
          ),
          const ColumnConfig(
            key: 'city',
            label: 'City',
            type: ColumnType.reference,
          ),
          const ColumnConfig(key: 'type', label: 'Type'),
          const ColumnConfig(
            key: 'images',
            label: 'Images',
            type: ColumnType.image,
          ),
        ],
      ),

      // Routes
      Resource(
        name: 'routes',
        label: 'Routes',
        icon: Icons.route,
        columns: [
          const ColumnConfig(key: 'id', label: 'ID', visible: false),
          const ColumnConfig(
            key: 'name',
            label: 'Name',
            type: ColumnType.json,
            required: true,
          ),
          const ColumnConfig(
            key: 'images',
            label: 'Images',
            type: ColumnType.image,
          ),
        ],
      ),

      // Events
      Resource(
        name: 'events',
        label: 'Events',
        icon: Icons.event,
        columns: [
          const ColumnConfig(key: 'id', label: 'ID', visible: false),
          const ColumnConfig(
            key: 'name',
            label: 'Name',
            type: ColumnType.json,
            required: true,
          ),
          const ColumnConfig(key: 'type', label: 'Type', required: true),
          const ColumnConfig(
            key: 'time',
            label: 'Date & Time',
            type: ColumnType.date,
            required: true,
          ),
          const ColumnConfig(key: 'status', label: 'Status'),
          const ColumnConfig(
            key: 'capacity',
            label: 'Capacity',
            type: ColumnType.number,
          ),
          const ColumnConfig(key: 'price', label: 'Price'),
        ],
      ),

      // Users
      Resource(
        name: 'users',
        label: 'Users',
        icon: Icons.people,
        columns: [
          const ColumnConfig(key: 'id', label: 'ID', visible: false),
          const ColumnConfig(key: 'name', label: 'Name', required: true),
          const ColumnConfig(
            key: 'email',
            label: 'Email',
            type: ColumnType.email,
            required: true,
          ),
          const ColumnConfig(key: 'phone', label: 'Phone'),
          const ColumnConfig(key: 'role', label: 'Role'),
          const ColumnConfig(
            key: 'points',
            label: 'Points',
            type: ColumnType.number,
          ),
        ],
      ),
    ];
  }
}

/// Enhanced dashboard widget with quick access to Events Management
class HolyDashboard extends StatelessWidget {
  final DataProvider dataProvider;

  const HolyDashboard({super.key, required this.dataProvider});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(24),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Welcome Header
          Row(
            children: [
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: const Color(0xFFA855F7).withOpacity(0.1),
                  borderRadius: BorderRadius.circular(12),
                ),
                child: const Icon(
                  Icons.dashboard,
                  size: 48,
                  color: Color(0xFFA855F7),
                ),
              ),
              const SizedBox(width: 24),
              const Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Welcome to Holy Admin',
                      style: TextStyle(
                        fontSize: 32,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    SizedBox(height: 8),
                    Text(
                      'Manage your spiritual events, locations, and content',
                      style: TextStyle(fontSize: 16, color: Color(0xFF94A3B8)),
                    ),
                  ],
                ),
              ),
            ],
          ),
          const SizedBox(height: 32),

          // Quick Actions
          const Text(
            'Quick Actions',
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 16),

          // Action Cards
          Expanded(
            child: GridView.count(
              crossAxisCount: 3,
              crossAxisSpacing: 16,
              mainAxisSpacing: 16,
              childAspectRatio: 1.5,
              children: [
                _buildQuickActionCard(
                  context,
                  title: 'Events Management',
                  description:
                      'Manage spiritual events with calendar and analytics',
                  icon: Icons.event,
                  color: const Color(0xFFA855F7),
                  onTap: () {
                    Navigator.of(context).push(
                      MaterialPageRoute(
                        builder: (context) => Scaffold(
                          body: EventsDashboard(
                            events: [], // TODO: Load events from dataProvider
                          ),
                        ),
                      ),
                    );
                  },
                ),
                _buildQuickActionCard(
                  context,
                  title: 'Countries & Cities',
                  description: 'Manage geographical locations',
                  icon: Icons.public,
                  color: Colors.blue,
                  onTap: () {
                    // Navigate to countries list
                  },
                ),
                _buildQuickActionCard(
                  context,
                  title: 'Sacred Spots',
                  description: 'Manage spiritual locations',
                  icon: Icons.place,
                  color: Colors.teal,
                  onTap: () {
                    // Navigate to spots list
                  },
                ),
                _buildQuickActionCard(
                  context,
                  title: 'Routes',
                  description: 'Manage pilgrimage routes',
                  icon: Icons.route,
                  color: Colors.orange,
                  onTap: () {
                    // Navigate to routes list
                  },
                ),
                _buildQuickActionCard(
                  context,
                  title: 'Users',
                  description: 'Manage user accounts',
                  icon: Icons.people,
                  color: Colors.green,
                  onTap: () {
                    // Navigate to users list
                  },
                ),
                _buildQuickActionCard(
                  context,
                  title: 'Analytics',
                  description: 'View platform statistics',
                  icon: Icons.analytics,
                  color: Colors.indigo,
                  onTap: () {
                    // Navigate to analytics
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildQuickActionCard(
    BuildContext context, {
    required String title,
    required String description,
    required IconData icon,
    required Color color,
    required VoidCallback onTap,
  }) {
    return Card(
      elevation: 2,
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(12),
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: color.withOpacity(0.1),
                  shape: BoxShape.circle,
                ),
                child: Icon(icon, size: 48, color: color),
              ),
              const SizedBox(height: 16),
              Text(
                title,
                style: const TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 8),
              Text(
                description,
                style: TextStyle(fontSize: 12, color: Colors.grey[600]),
                textAlign: TextAlign.center,
                maxLines: 2,
                overflow: TextOverflow.ellipsis,
              ),
            ],
          ),
        ),
      ),
    );
  }
}