easy_dev_toolkit 0.2.0 copy "easy_dev_toolkit: ^0.2.0" to clipboard
easy_dev_toolkit: ^0.2.0 copied to clipboard

A comprehensive Flutter toolkit with responsive sizing, adaptive widgets, networking, and storage utilities.

example/lib/main.dart

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // Initialize connectivity monitoring
  await ConnectivityService.initialize();
  // Initialize storage
  await AppStorage.init();
  
  runApp(const DemoApp());
}

class DemoApp extends StatelessWidget {
  const DemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ListenableBuilder(
      listenable: EasyTheme.instance,
      builder: (context, _) {
        return MaterialApp(
          title: "Easy Dev Toolkit Pro",
          debugShowCheckedModeBanner: false,
          theme: EasyTheme.light(),
          darkTheme: EasyTheme.dark(),
          themeMode: EasyTheme.mode,
          home: const DashboardScreen(),
        );
      },
    );
  }
}

class DashboardScreen extends StatefulWidget {
  const DashboardScreen({super.key});

  @override
  State<DashboardScreen> createState() => _DashboardScreenState();
}

class _DashboardScreenState extends State<DashboardScreen> {
  final TextEditingController _searchController = TextEditingController();
  int _selectedDateIndex = 0;

  Widget _responsiveCard(String title, Color color, IconData icon) {
    return Container(
      padding: EdgeInsets.all(AppSpacing.md),
      decoration: BoxDecoration(
        color: color.withValues(alpha: 0.1),
        borderRadius: AppRadius.roundedMd,
        border: Border.all(color: color.withValues(alpha: 0.5)),
      ),
      child: Row(
        children: [
          Icon(icon, color: color),
          AppSpacing.gutterMd,
          Text(
            title,
            style: context.textTheme.titleMedium?.copyWith(
              color: color,
              fontWeight: FontWeight.bold,
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    // Initialize responsive sizing
    SizeConfig.init(context);

    return Scaffold(
      appBar: EasyAppBar.simple(
        title: "Toolkit Pro Showcase",
        actions: [
          IconButton(
            icon: Icon(context.isDarkMode ? Icons.light_mode : Icons.dark_mode),
            onPressed: () => EasyTheme.toggle(),
          ),
          IconButton(
            icon: const Icon(Icons.calendar_month),
            onPressed: () => context.push(const FullCalendarScreen()),
          ),
        ],
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.symmetric(vertical: 20.h),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const OfflineBanner(),
            
            // 1. Profile Header Section
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16.w),
              child: ProfileHeader(
                name: "John Developer",
                email: "john.dev@toolkit.com",
                avatar: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
              ),
            ),
            
            SizedBox(height: 16.h),

            // Pro: Responsive Builder Section
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16.w),
              child: ResponsiveBuilder(
                mobile: _responsiveCard("Mobile Layout Active", Colors.orange, Icons.phone_android),
                tablet: _responsiveCard("Tablet Layout Active", Colors.green, Icons.tablet_mac),
                desktop: _responsiveCard("Desktop Layout Active", Colors.blue, Icons.desktop_windows),
              ),
            ),
            
            SizedBox(height: 24.h),

            // 2. Horizontal Date Selector Section
            Padding(
              padding: EdgeInsets.only(left: 16.w, bottom: 8.h),
              child: Text(
                "Select Schedule",
                style: context.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
              ),
            ),
            HorizontalDateSelector(
              days: List.generate(14, (i) => DateSelectorDay.fromDateTime(
                DateTime.now().add(Duration(days: i)),
              )),
              initialSelectedIndex: _selectedDateIndex,
              onDateSelected: (index) {
                setState(() => _selectedDateIndex = index);
                EasyToast.show("Selected day: $index");
              },
            ),

            SizedBox(height: 24.h),

            // 3. Glassmorphism & Stats Section
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16.w),
              child: Row(
                children: [
                  Expanded(
                    child: GlassCard(
                      height: 120.h,
                      color: Colors.blue,
                      opacity: 0.15,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          const Icon(Icons.auto_graph, color: Colors.blue),
                          SizedBox(height: 8.h),
                          Text("Efficiency", style: context.textTheme.bodySmall),
                          Text("92%", style: context.textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold)),
                        ],
                      ),
                    ),
                  ),
                  SizedBox(width: 12.w),
                  Expanded(
                    child: GlassCard(
                      height: 120.h,
                      color: Colors.purple,
                      opacity: 0.15,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          const Icon(Icons.timer, color: Colors.purple),
                          SizedBox(height: 8.h),
                          Text("Time Logged", style: context.textTheme.bodySmall),
                          Text("38.5h", style: context.textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold)),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),

            SizedBox(height: 24.h),

            // 4. Adaptive Widgets Showcase
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16.w),
              child: Container(
                padding: EdgeInsets.all(16.w),
                decoration: BoxDecoration(
                  color: context.theme.cardColor,
                  borderRadius: BorderRadius.circular(16),
                  border: Border.all(color: context.theme.dividerColor.withValues(alpha: 0.1)),
                ),
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text("Adaptive Badge", style: context.textTheme.bodyMedium),
                        const AdaptiveBadge(label: "New Feature", backgroundColor: Colors.green),
                      ],
                    ),
                    SizedBox(height: 16.h),
                    AdaptiveTextField(
                      controller: _searchController,
                      label: "Search Projects (Debounced)",
                      prefixIcon: const Icon(Icons.search),
                      onChanged: (val) {
                        EasyDebounce.run("search", AppDurations.medium, () {
                          EasyToast.show("Debounced Search: $val");
                        });
                      },
                    ),
                    SizedBox(height: 16.h),
                    AdaptiveButton.filled(
                      text: "Submit Draft",
                      onPressed: () => EasyToast.show("Draft Submitted"),
                    ),
                  ],
                ),
              ),
            ),

            SizedBox(height: 24.h),

            // 5. Grid View Showcase
            Padding(
              padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 8.h),
              child: Text(
                "Quick Actions",
                style: context.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
              ),
            ),
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16.w),
              child: AdaptiveGrid(
                children: [
                  ReusableCard(title: "Security", subtitle: "Key management", icon: Icons.security, onTap: () {}),
                  ReusableCard(title: "Network", subtitle: "Check status", icon: Icons.wifi, onTap: () {}),
                  ReusableCard(title: "Storage", subtitle: "Cache settings", icon: Icons.storage, onTap: () {}),
                  ReusableCard(title: "History", subtitle: "Recent logs", icon: Icons.history, onTap: () {}),
                ],
              ),
            ),
            
            SizedBox(height: 24.h),

            // 6. Networking & Utilities
            AdaptiveListTile(
              title: "Networking Demo (EasyApi)",
              subtitle: "Fetching from JSONPlaceholder",
              leading: Icons.cloud_download_outlined,
              trailing: const Icon(Icons.arrow_forward_ios, size: 14),
              onTap: () => context.push(const NetworkDemoScreen()),
            ),
            AdaptiveListTile(
              title: "Utilities & Security",
              subtitle: "Encryption, Storage, & Validators",
              leading: Icons.settings_suggest_outlined,
              trailing: const Icon(Icons.arrow_forward_ios, size: 14),
              onTap: () => context.push(const UtilitiesDemoScreen()),
            ),
            AdaptiveListTile(
              title: "UI & Feedback",
              subtitle: "Dialogs, Loaders, & Skeletons",
              leading: Icons.brush_outlined,
              trailing: const Icon(Icons.arrow_forward_ios, size: 14),
              onTap: () => context.push(const UIDemoScreen()),
            ),
          ],
        ),
      ),
    );
  }
}

class UtilitiesDemoScreen extends StatefulWidget {
  const UtilitiesDemoScreen({super.key});

  @override
  State<UtilitiesDemoScreen> createState() => _UtilitiesDemoScreenState();
}

class _UtilitiesDemoScreenState extends State<UtilitiesDemoScreen> {
  final TextEditingController _encryptController = TextEditingController();
  final TextEditingController _storageKeyController = TextEditingController();
  final TextEditingController _storageValueController = TextEditingController();
  
  String _encryptedText = "";
  String _decryptedText = "";
  String _storedValue = "";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: EasyAppBar.simple(title: "Utilities & Security"),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(16.w),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _sectionTitle("Encryption (AES-256)"),
            AdaptiveTextField(
              controller: _encryptController,
              label: "Text to Encrypt",
              hint: "Enter sensitive data",
            ),
            SizedBox(height: 12.h),
            Row(
              children: [
                Expanded(
                  child: AdaptiveButton(
                    text: "Encrypt",
                    onPressed: () {
                      if (_encryptController.text.isEmpty) return;
                      setState(() {
                        _encryptedText = EncryptionUtil.encrypt(_encryptController.text);
                      });
                    },
                  ),
                ),
                SizedBox(width: 8.w),
                Expanded(
                  child: AdaptiveButton.filled(
                    text: "Decrypt",
                    onPressed: () {
                      if (_encryptedText.isEmpty) return;
                      setState(() {
                        _decryptedText = EncryptionUtil.decrypt(_encryptedText);
                      });
                    },
                  ),
                ),
              ],
            ),
            if (_encryptedText.isNotEmpty) ...[
              SizedBox(height: 8.h),
              Text("Encrypted: $_encryptedText", style: context.textTheme.bodySmall?.copyWith(fontStyle: FontStyle.italic)),
            ],
            if (_decryptedText.isNotEmpty) ...[
              SizedBox(height: 4.h),
              Text("Decrypted: $_decryptedText", style: context.textTheme.bodyMedium?.copyWith(color: Colors.green, fontWeight: FontWeight.bold)),
            ],

            SizedBox(height: 32.h),
            _sectionTitle("Local Storage (AppStorage)"),
            AdaptiveTextField(
              controller: _storageKeyController,
              label: "Key",
            ),
            SizedBox(height: 8.h),
            AdaptiveTextField(
              controller: _storageValueController,
              label: "Value",
            ),
            SizedBox(height: 12.h),
            Row(
              children: [
                Expanded(
                  child: AdaptiveButton(
                    text: "Save",
                    onPressed: () async {
                      await AppStorage.write(_storageKeyController.text, _storageValueController.text);
                      EasyToast.show("Saved successfully");
                    },
                  ),
                ),
                SizedBox(width: 8.w),
                Expanded(
                  child: AdaptiveButton.filled(
                    text: "Read",
                    onPressed: () async {
                      final val = AppStorage.read<String>(_storageKeyController.text);
                      setState(() => _storedValue = val ?? "Not found");
                    },
                  ),
                ),
              ],
            ),
            if (_storedValue.isNotEmpty) ...[
              SizedBox(height: 12.h),
              Text("Result: $_storedValue", style: context.textTheme.titleMedium),
            ],

            SizedBox(height: 32.h),
            _sectionTitle("Extensions Showcase"),
            _extensionItem("String.capitalize()", "hello world".capitalize()),
            _extensionItem("String.isValidEmail", "test@mail".isValidEmail.toString()),
            _extensionItem("DateTime.timeAgo", DateTime.now().subtract(const Duration(hours: 5)).timeAgo()),
            _extensionItem("Responsive Sizing", "Width: ${100.w.toStringAsFixed(1)}, Height: ${100.h.toStringAsFixed(1)}"),
          ],
        ),
      ),
    );
  }

  Widget _sectionTitle(String title) => Padding(
    padding: EdgeInsets.only(bottom: 12.h),
    child: Text(title, style: context.textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold)),
  );

  Widget _extensionItem(String title, String result) => Padding(
    padding: EdgeInsets.only(bottom: 8.h),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Text(title, style: context.textTheme.bodyMedium),
        Text(result, style: context.textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.bold, color: Colors.blue)),
      ],
    ),
  );
}

class UIDemoScreen extends StatelessWidget {
  const UIDemoScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: EasyAppBar.simple(title: "UI & Feedback"),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(16.w),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text("Skeleton Loader Demo", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
            SizedBox(height: 12.h),
            const SkeletonLoader(height: 100, borderRadius: 12),
            SizedBox(height: 12.h),
            Row(
              children: [
                const SkeletonLoader(width: 60, height: 60, shape: BoxShape.circle),
                SizedBox(width: 12.w),
                const Expanded(
                  child: Column(
                    children: [
                      SkeletonLoader(height: 14),
                      SizedBox(height: 8),
                      SkeletonLoader(height: 14, width: 150),
                    ],
                  ),
                ),
              ],
            ),

            SizedBox(height: 32.h),
            const Text("Feedback Components", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
            SizedBox(height: 12.h),
            AdaptiveButton(
              text: "Show Adaptive Dialog",
              onPressed: () => EasyDialog.show(
                context,
                title: "Confirm Action",
                message: "This will demonstrate the adaptive nature of our toolkit.",
                onConfirm: () => EasyToast.show("Confirmed!"),
              ),
            ),
            SizedBox(height: 12.h),
            AdaptiveButton.filled(
              text: "Show Loading Overlay",
              onPressed: () {
                EasyLoader.show(context);
                Future.delayed(const Duration(seconds: 2), () => EasyLoader.hide(context));
              },
            ),
          ],
        ),
      ),
    );
  }
}

class NetworkDemoScreen extends StatefulWidget {
  const NetworkDemoScreen({super.key});

  @override
  State<NetworkDemoScreen> createState() => _NetworkDemoScreenState();
}

class _NetworkDemoScreenState extends State<NetworkDemoScreen> {
  List<dynamic> _posts = [];
  bool _loading = false;
  String? _error;

  @override
  void initState() {
    super.initState();
    _fetchData();
  }

  Future<void> _fetchData() async {
    setState(() {
      _loading = true;
      _error = null;
    });

    final response = await EasyApi.get(
      'https://jsonplaceholder.typicode.com/posts',
      useCache: true,
      ttl: const Duration(minutes: 5),
    );

    if (response.isSuccess) {
      setState(() {
        _posts = (response.data as List).take(10).toList();
        _loading = false;
      });
    } else {
      setState(() {
        _error = response.error;
        _loading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: EasyAppBar.simple(title: "EasyApi Demo"),
      body: _loading
          ? const Center(child: CircularProgressIndicator())
          : _error != null
              ? Center(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Icon(Icons.error_outline, size: 60, color: Colors.red),
                      SizedBox(height: 16.h),
                      Text("Error: $_error"),
                      const SizedBox(height: 16),
                      AdaptiveButton(text: "Retry", onPressed: _fetchData),
                    ],
                  ),
                )
              : RefreshIndicator(
                  onRefresh: _fetchData,
                  child: ListView.separated(
                    padding: const EdgeInsets.all(16),
                    itemCount: _posts.length,
                    separatorBuilder: (_, __) => const SizedBox(height: 12),
                    itemBuilder: (context, i) {
                      final post = _posts[i];
                      return ReusableCard(
                        title: post['title'],
                        subtitle: post['body'],
                        icon: Icons.article_outlined,
                        onTap: () {},
                      );
                    },
                  ),
                ),
    );
  }
}

class FullCalendarScreen extends StatelessWidget {
  const FullCalendarScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: EasyAppBar.simple(title: "Calendar View"),
      body: Column(
        children: [
          TimeLogCalendar(
            initialDate: DateTime.now(),
            onDateSelected: (date) {
              EasyToast.show("Date set to: ${date.day}/${date.month}");
            },
          ),
          const Expanded(
            child: Center(
              child: EmptyState(
                title: "No appointments",
                message: "Select a date to view your logs.",
              ),
            ),
          ),
        ],
      ),
    );
  }
}
4
likes
160
points
269
downloads

Publisher

unverified uploader

Weekly Downloads

A comprehensive Flutter toolkit with responsive sizing, adaptive widgets, networking, and storage utilities.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

connectivity_plus, dio, encrypt, flutter, fluttertoast, google_fonts, path_provider, shared_preferences

More

Packages that depend on easy_dev_toolkit