feat: standard error handling, web bug fixes, and mock data setup

This commit is contained in:
2026-06-26 16:06:18 +05:30
parent 401cf600e8
commit 523609796e
18 changed files with 792 additions and 164 deletions

View File

@@ -0,0 +1,100 @@
import 'package:flutter/material.dart';
import 'package:doormile/core/theme/app_colors.dart';
import 'package:doormile/core/theme/app_theme.dart';
class SnackbarUtils {
static void showError(BuildContext context, String rawError) {
String message = _getProfessionalErrorMessage(rawError);
final snackBar = SnackBar(
content: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Icons.error_outline_rounded, color: Colors.white, size: 24),
const SizedBox(width: 12),
Expanded(
child: Text(
message,
style: AppTheme.bodyMd.copyWith(color: Colors.white, fontWeight: FontWeight.w500),
),
),
],
),
backgroundColor: AppColors.error,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
elevation: 4,
duration: const Duration(seconds: 4),
);
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(snackBar);
}
static void showSuccess(BuildContext context, String message) {
final snackBar = SnackBar(
content: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Icons.check_circle_outline_rounded, color: Colors.white, size: 24),
const SizedBox(width: 12),
Expanded(
child: Text(
message,
style: AppTheme.bodyMd.copyWith(color: Colors.white, fontWeight: FontWeight.w500),
),
),
],
),
backgroundColor: const Color(0xFF4CAF50), // Green success color
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
elevation: 4,
duration: const Duration(seconds: 3),
);
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(snackBar);
}
static String _getProfessionalErrorMessage(String raw) {
final lowerRaw = raw.toLowerCase();
// Check for network errors
if (lowerRaw.contains('socketexception') ||
lowerRaw.contains('connection refused') ||
lowerRaw.contains('failed host lookup') ||
lowerRaw.contains('network') ||
lowerRaw.contains('timeout')) {
return 'Please check your internet connection and try again.';
}
// Common auth and business errors
if (lowerRaw.contains('invalid otp') || lowerRaw.contains('incorrect otp')) {
return 'The OTP you entered is incorrect. Please try again.';
}
if (lowerRaw.contains('user not found') || lowerRaw.contains('not registered')) {
return 'Account not found. Please check your details.';
}
if (lowerRaw.contains('already registered') || lowerRaw.contains('exists')) {
return 'This phone number is already registered.';
}
if (lowerRaw.contains('pin')) {
return 'Incorrect PIN. Please try again.';
}
if (lowerRaw.contains('unauthorized') || lowerRaw.contains('expired')) {
return 'Your session has expired. Please log in again.';
}
// Default generic server / unknown error
return 'Something went wrong. Please try again later.';
}
}