# Quick Reference Guide - New UX Components ## 🎯 Quick Start Guide for Developers ### 1. Skeleton Loaders **When to use:** Show during data loading to indicate progress ```dart // Full dashboard skeleton if (isLoading) { return const SkeletonDashboard(); } // Individual skeleton cards SkeletonCard() SkeletonStatsCard() SkeletonListItem() // Custom skeleton SkeletonLoader( width: 200.w, height: 40.h, borderRadius: BorderRadius.circular(12.r), ) ``` --- ### 2. Enhanced Notifications **Import:** ```dart import '../../core/utils/snackbar_util.dart'; ``` **Usage:** ```dart // Success (Green) SnackbarUtil.showSuccess('Group created successfully!'); // Error (Red) SnackbarUtil.showError('Failed to save payment'); // Warning (Orange) SnackbarUtil.showWarning('Payment deadline approaching'); // Info (Blue) SnackbarUtil.showInfo('Feature coming soon', title: 'Coming Soon'); // With custom title SnackbarUtil.showError( 'Please check your internet connection', title: 'Connection Error', ); // Loading (can be dismissed programmatically) SnackbarUtil.showLoading('Processing payment...'); // Later... SnackbarUtil.dismiss(); // With action button SnackbarUtil.showWithAction( title: 'Payment Due', message: 'You have a pending payment of ₹5,000', actionLabel: 'Pay Now', onAction: () => navigateToPayment(), type: SnackbarType.warning, ); ``` --- ### 3. Empty States **Import:** ```dart import '../../shared/widgets/empty_state_widget.dart'; ``` **Usage:** ```dart // Pre-configured empty states EmptyStateWidget( type: EmptyStateType.noGroups, actionLabel: 'Create Group', onActionPressed: () => showCreateDialog(), ) // Available types: // - EmptyStateType.noGroups // - EmptyStateType.noMembers // - EmptyStateType.noPayments // - EmptyStateType.noActivities // - EmptyStateType.noResults // - EmptyStateType.error // - EmptyStateType.noInternet // Custom empty state EmptyStateWidget( type: EmptyStateType.noGroups, customTitle: 'Your Custom Title', customMessage: 'Your custom message here', actionLabel: 'Custom Action', onActionPressed: () => doSomething(), ) // Compact version for smaller spaces CompactEmptyState( icon: Icons.inbox_rounded, message: 'No items found', color: Colors.grey.shade600, ) ``` --- ### 4. Interactive Cards **Import:** ```dart import '../../shared/widgets/interactive_card.dart'; ``` **Usage:** #### Basic Interactive Card ```dart InteractiveCard( onTap: () => navigateToDetails(), child: Column( children: [ Text('Card Title'), Text('Card Description'), ], ), ) ``` #### Stats Card ```dart InteractiveStatsCard( title: 'Active Groups', value: '12', icon: Icons.group, color: Colors.blue.shade600, onTap: () => navigateToGroups(), subtitle: 'Last updated today', // Optional ) ``` #### Quick Action Card ```dart QuickActionCard( title: 'Create New Group', subtitle: 'Start a new chit fund', icon: Icons.group_add, color: Colors.green.shade600, onTap: () => showCreateDialog(), ) ``` #### Activity Card ```dart ActivityCard( title: 'Payment Received', description: 'John Doe paid ₹5,000', time: '2h ago', icon: Icons.payment, color: Colors.green.shade600, onTap: () => viewPaymentDetails(), // Optional ) ``` #### Advanced InteractiveCard Options ```dart InteractiveCard( onTap: () => doSomething(), onLongPress: () => showOptions(), padding: EdgeInsets.all(20.w), margin: EdgeInsets.all(8.w), backgroundColor: Colors.white, elevation: 4.0, borderRadius: BorderRadius.circular(16.r), enableHoverEffect: true, enableRipple: true, splashColor: Colors.blue.withOpacity(0.2), child: YourContent(), ) ``` --- ## 🎨 Color Guidelines Use these consistent colors across the app: ```dart // Success / Positive Colors.green.shade600 // #43A047 // Error / Negative Colors.red.shade600 // #E53935 // Warning / Caution Colors.orange.shade600 // #FB8C00 // Info / Neutral Colors.blue.shade600 // #1E88E5 // Action / Primary Colors.purple.shade600 // #8E24AA ``` --- ## 📐 Spacing Guidelines Use consistent spacing throughout: ```dart // Small spacing SizedBox(height: 8.h) // Between related items SizedBox(width: 8.w) // Medium spacing SizedBox(height: 16.h) // Between sections SizedBox(width: 16.w) // Large spacing SizedBox(height: 24.h) // Between major sections SizedBox(width: 24.w) ``` --- ## 🔧 Common Patterns ### Loading Pattern ```dart Obx(() { if (controller.isLoading.value) { return const SkeletonDashboard(); } if (controller.items.isEmpty) { return EmptyStateWidget( type: EmptyStateType.noGroups, onActionPressed: () => controller.createItem(), ); } return YourContentWidget(); }) ``` ### Error Handling Pattern ```dart try { await someOperation(); SnackbarUtil.showSuccess('Operation completed!'); } catch (e) { SnackbarUtil.showError( 'Something went wrong. Please try again.', title: 'Error', ); } ``` ### Confirmation Pattern ```dart QuickActionCard( title: 'Delete Group', icon: Icons.delete, color: Colors.red.shade600, onTap: () { showDialog( context: context, builder: (context) => AlertDialog( title: Text('Confirm Delete'), content: Text('Are you sure?'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('Cancel'), ), ElevatedButton( onPressed: () { Navigator.pop(context); deleteGroup(); SnackbarUtil.showSuccess('Group deleted'); }, child: Text('Delete'), ), ], ), ); }, ) ``` --- ## ⚡ Performance Tips 1. **Use const constructors** when possible ```dart const SkeletonDashboard() // Good SkeletonDashboard() // Less optimal ``` 2. **Avoid rebuilding expensive widgets** ```dart Obx(() { if (isLoading.value) return const SkeletonDashboard(); return const YourContent(); // const helps }) ``` 3. **Reuse card instances** when building lists ```dart ListView.builder( itemBuilder: (context, index) { return ActivityCard( key: ValueKey(items[index].id), // Add key for better performance title: items[index].title, // ... ); }, ) ``` --- ## 🐛 Troubleshooting ### Issue: Snackbar not showing **Solution:** Make sure you're using `Get.context` or have a valid `BuildContext` ```dart // If outside widget tree SnackbarUtil.showError('Error message'); // Still need GetX initialized void main() { runApp(GetMaterialApp(home: App())); } ``` ### Issue: Skeleton loader not animating **Solution:** Ensure parent widget has proper size constraints ```dart // Bad Container(child: SkeletonLoader()) // Good Container( width: 200.w, height: 40.h, child: SkeletonLoader(), ) ``` ### Issue: Interactive card not responding **Solution:** Check if there's a conflicting GestureDetector in parent ```dart // Remove or set behavior GestureDetector( behavior: HitTestBehavior.translucent, // Add this onTap: () {}, child: InteractiveCard(...), ) ``` --- ## 📱 Testing Checklist When adding new features, test: - ✅ Loading state (skeleton loader appears) - ✅ Empty state (shows when no data) - ✅ Success state (content displays correctly) - ✅ Error state (error message shows) - ✅ Tap interactions (cards respond to touch) - ✅ Pull-to-refresh (works on mobile) - ✅ Notifications (appear and dismiss correctly) --- ## 🎓 Best Practices 1. **Always show feedback for user actions** ```dart onPressed: () async { SnackbarUtil.showLoading('Saving...'); await save(); SnackbarUtil.dismiss(); SnackbarUtil.showSuccess('Saved!'); } ``` 2. **Provide clear empty states** ```dart // Bad: Just showing nothing if (items.isEmpty) return SizedBox(); // Good: Show helpful empty state if (items.isEmpty) { return EmptyStateWidget( type: EmptyStateType.noItems, onActionPressed: () => createItem(), ); } ``` 3. **Use appropriate colors for context** ```dart // Success actions SnackbarUtil.showSuccess(...) // Destructive actions SnackbarUtil.showWarning('This will delete all data') // Errors SnackbarUtil.showError('Failed to connect') ``` 4. **Keep interactions consistent** ```dart // All cards should use InteractiveCard // All notifications should use SnackbarUtil // All empty states should use EmptyStateWidget ``` --- ## 📚 More Resources - Flutter Documentation: https://flutter.dev/docs - GetX Documentation: https://pub.dev/packages/get - Material Design: https://material.io/design --- **Happy Coding! 🚀**