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

@@ -5,6 +5,7 @@ import 'package:geocoding/geocoding.dart';
import 'package:doormile/main.dart';
import 'package:doormile/shared/state/app_state.dart';
import 'package:doormile/core/utils/snackbar_utils.dart';
import 'package:doormile/core/theme/app_colors.dart';
import 'package:doormile/core/theme/app_theme.dart';
import 'package:doormile/core/widgets/common.dart';
@@ -123,6 +124,12 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
draft.parcelType = _category;
draft.service = _serviceType;
// Extract pincode from typed address if GPS/saved address didn't set it.
if (draft.pickupPincode.isEmpty) {
final match = RegExp(r'\b\d{6}\b').firstMatch(_pickup.text);
if (match != null) draft.pickupPincode = match.group(0)!;
}
setState(() => _loading = true);
await appState.fetchPriceEstimate();
setState(() => _loading = false);
@@ -229,16 +236,14 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
final area = '${place.subLocality ?? place.locality}, ${place.administrativeArea}';
final pincode = place.postalCode ?? '';
final fullAddress = '${place.street}, $area, $pincode';
_showLocationConfirmationSheet(context, state, area, pincode, fullAddress);
_showLocationConfirmationSheet(context, state, area, pincode, fullAddress, position.latitude, position.longitude);
} else {
throw Exception('Could not determine address from coordinates.');
}
} catch (e) {
if (!mounted) return;
setState(() => _loading = false);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(e.toString().replaceAll('Exception: ', ''))),
);
SnackbarUtils.showError(context, e.toString());
}
},
child: Row(
@@ -268,9 +273,11 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
icon: Icons.home_rounded,
label: 'Home',
address: '12th Main, Indiranagar, Bengaluru, Karnataka 560038',
onSelect: (addr) => setState(() {
pincode: '560038',
onSelect: (addr, pin) => setState(() {
_pickup.text = addr;
final state = context.read<AppState>();
state.draft.pickupPincode = pin;
_name.text = state.firstName;
_mobile.text = state.phone;
}),
@@ -280,9 +287,11 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
icon: Icons.business_rounded,
label: 'Office',
address: 'Sector 4, HSR Layout, Bengaluru, Karnataka 560102',
onSelect: (addr) => setState(() {
pincode: '560102',
onSelect: (addr, pin) => setState(() {
_pickup.text = addr;
final state = context.read<AppState>();
state.draft.pickupPincode = pin;
_name.text = state.firstName;
_mobile.text = state.phone;
}),
@@ -292,9 +301,11 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
icon: Icons.favorite_rounded,
label: "Mom's House",
address: 'Jayanagar 4th Block, Bengaluru, Karnataka 560011',
onSelect: (addr) => setState(() {
pincode: '560011',
onSelect: (addr, pin) => setState(() {
_pickup.text = addr;
final state = context.read<AppState>();
state.draft.pickupPincode = pin;
_name.text = state.firstName;
_mobile.text = state.phone;
}),
@@ -516,7 +527,13 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
...state.savedAddresses.map((a) => Padding(
padding: const EdgeInsets.only(bottom: 12),
child: AppCard(
onTap: () => setState(() => _pickup.text = '${a.label}, ${a.line}'),
onTap: () {
final draft = context.read<AppState>().draft;
draft.pickupPincode = a.pincode;
draft.pickupLatitude = a.latitude;
draft.pickupLongitude = a.longitude;
setState(() => _pickup.text = '${a.label}, ${a.line}');
},
child: Row(
children: [
IconBadge(
@@ -543,7 +560,7 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
);
}
void _showLocationConfirmationSheet(BuildContext context, AppState state, String area, String pincode, String fullAddress) {
void _showLocationConfirmationSheet(BuildContext context, AppState state, String area, String pincode, String fullAddress, double latitude, double longitude) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
@@ -597,6 +614,9 @@ class _BookingPickupScreenState extends State<BookingPickupScreen> {
child: PrimaryButton(
label: 'Confirm',
onPressed: () {
state.draft.pickupPincode = pincode;
state.draft.pickupLatitude = latitude;
state.draft.pickupLongitude = longitude;
setState(() {
_pickup.text = fullAddress;
_name.text = state.firstName;
@@ -679,19 +699,21 @@ class _SavedAddressChip extends StatelessWidget {
final IconData icon;
final String label;
final String address;
final Function(String) onSelect;
final String pincode;
final Function(String address, String pincode) onSelect;
const _SavedAddressChip({
required this.icon,
required this.label,
required this.address,
required this.pincode,
required this.onSelect,
});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => onSelect(address),
onTap: () => onSelect(address, pincode),
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),

View File

@@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
import 'package:doormile/main.dart';
import 'package:doormile/shared/state/app_state.dart';
import 'package:doormile/core/utils/snackbar_utils.dart';
import 'package:doormile/core/theme/app_colors.dart';
import 'package:doormile/core/theme/app_theme.dart';
import 'package:doormile/core/widgets/common.dart';
@@ -29,7 +30,7 @@ class _BookingPreviewScreenState extends State<BookingPreviewScreen> {
} catch (e) {
if (!mounted) return;
setState(() => _loading = false);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.toString().replaceAll('Exception: ', ''))));
SnackbarUtils.showError(context, e.toString());
}
}