chitfund/luckychit/QUICK_REFERENCE_NEW_COMPONE...

8.6 KiB

Quick Reference Guide - New UX Components

🎯 Quick Start Guide for Developers

1. Skeleton Loaders

When to use: Show during data loading to indicate progress

// 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:

import '../../core/utils/snackbar_util.dart';

Usage:

// 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:

import '../../shared/widgets/empty_state_widget.dart';

Usage:

// 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:

import '../../shared/widgets/interactive_card.dart';

Usage:

Basic Interactive Card

InteractiveCard(
  onTap: () => navigateToDetails(),
  child: Column(
    children: [
      Text('Card Title'),
      Text('Card Description'),
    ],
  ),
)

Stats Card

InteractiveStatsCard(
  title: 'Active Groups',
  value: '12',
  icon: Icons.group,
  color: Colors.blue.shade600,
  onTap: () => navigateToGroups(),
  subtitle: 'Last updated today', // Optional
)

Quick Action Card

QuickActionCard(
  title: 'Create New Group',
  subtitle: 'Start a new chit fund',
  icon: Icons.group_add,
  color: Colors.green.shade600,
  onTap: () => showCreateDialog(),
)

Activity Card

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

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:

// 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:

// 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

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

try {
  await someOperation();
  SnackbarUtil.showSuccess('Operation completed!');
} catch (e) {
  SnackbarUtil.showError(
    'Something went wrong. Please try again.',
    title: 'Error',
  );
}

Confirmation Pattern

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

    const SkeletonDashboard()  // Good
    SkeletonDashboard()        // Less optimal
    
  2. Avoid rebuilding expensive widgets

    Obx(() {
      if (isLoading.value) return const SkeletonDashboard();
      return const YourContent(); // const helps
    })
    
  3. Reuse card instances when building lists

    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

// 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

// 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

// 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

    onPressed: () async {
      SnackbarUtil.showLoading('Saving...');
      await save();
      SnackbarUtil.dismiss();
      SnackbarUtil.showSuccess('Saved!');
    }
    
  2. Provide clear empty states

    // 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

    // Success actions
    SnackbarUtil.showSuccess(...)
    
    // Destructive actions
    SnackbarUtil.showWarning('This will delete all data')
    
    // Errors
    SnackbarUtil.showError('Failed to connect')
    
  4. Keep interactions consistent

    // All cards should use InteractiveCard
    // All notifications should use SnackbarUtil
    // All empty states should use EmptyStateWidget
    

📚 More Resources


Happy Coding! 🚀