import 'package:flutter/material.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../data/app_config.dart'; import '../../state/app_scope.dart'; import '../format.dart'; import '../tokens.dart'; import '../widgets/buttons.dart'; import '../widgets/cards.dart'; import '../widgets/chrome.dart'; import '../widgets/feedback.dart'; import '../widgets/inputs.dart'; import '../widgets/misc.dart'; import 'auth/login_screen.dart'; import 'sheets/place_search_sheet.dart'; /// Account — profile, preferences, and the build's environment line. /// /// The profile folds into the brand header: the avatar takes the slot the other /// tab roots give an action, the customer's name takes the slot the title holds /// elsewhere, and the phone number sits in the recessed track. That removes the /// profile *card* the screen used to open with — a card whose entire content /// was three facts about the person already looking at the screen. class AccountScreen extends StatelessWidget { const AccountScreen({super.key}); @override Widget build(BuildContext context) { final app = AppScope.of(context); final customer = app.customer; // Empty rather than a stand-in name: this screen is only ever built for a // signed-in customer, and a placeholder here would read as somebody's // actual account. final name = customer?.name ?? ''; final phone = customer?.phone ?? ''; return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ DmBrandHeader( eyebrow: 'Account', title: name.isEmpty ? 'Your account' : name, leading: DmAvatar(initials: initialsOf(name), onBrand: true), action: DmIconButton( icon: LucideIcons.circleHelp, tooltip: 'Help', background: DmColors.onBrandRaise, foreground: Colors.white, border: Colors.transparent, radius: DmRadius.lg, size: 42, onPressed: () => DmToast.show(context, 'Support is on the way'), ), child: phone.isEmpty ? null : DmHeaderTrack( trailing: DmTextAction( label: 'Edit', color: Colors.white, minHeight: 24, onPressed: () => DmToast.show(context, 'Editing is coming soon'), ), child: Text( phone, style: DmText.monoLg.copyWith(fontSize: 14.5, color: Colors.white), ), ), ), Expanded( child: ListView( padding: const EdgeInsets.fromLTRB(DmSpace.pad, 4, DmSpace.pad, 28), children: [ const DmMicroHead('Preferences', top: 16, brand: false), DmRowGroup( children: [ DmRow( icon: LucideIcons.mapPin, label: 'Saved addresses', value: app.pickup?.title ?? 'None', showChevron: true, onTap: () async { final place = await showPlaceSearchSheet(context); if (place != null && context.mounted) { app.setPickup(place); DmToast.show(context, 'Pickup location updated'); } }, ), const DmRow( icon: LucideIcons.bell, label: 'Notifications', value: 'SMS and push', showChevron: true, ), const DmRow( icon: LucideIcons.wallet, label: 'Payment methods', value: 'UPI', showChevron: true, ), const DmRow( icon: LucideIcons.circleHelp, label: 'Help and support', showChevron: true, ), ], ), // The environment line is not a control — it is what a bug // report needs in order to be actionable. Always shown when the // session came from a dev token rather than a sign-in. if (!AppConfig.isProd || AppConfig.authBypassed) ...[ const DmMicroHead('Build', brand: false), DmCard( tone: DmCardTone.sunken, children: [ DmCardCell( // Not a DmRow: that lays a short label against a short // value on one line, and this value is a URL plus every // flag the build carries. It overflowed by 59px the // moment a bypass was on — which is exactly when someone // needs to read it. child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('API', style: DmText.eyebrow), const SizedBox(height: 6), Text( AppConfig.describe, style: DmText.mono.copyWith( height: 1.5, color: DmColors.ink2, ), ), ], ), ), ], ), ], const SizedBox(height: 24), DmButton( label: 'Sign out', kind: DmButtonKind.ghost, danger: true, onPressed: () { app.signOut(); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const LoginScreen()), (route) => false, ); }, ), const SizedBox(height: 6), Text.rich( TextSpan( style: DmText.tiny.copyWith(color: DmColors.ink4), children: [ const TextSpan(text: 'Doormile Customer '), TextSpan( text: 'v1.0.0', style: DmText.monoSm.copyWith(color: DmColors.ink4), ), ], ), textAlign: TextAlign.center, ), ], ), ), ], ); } }