diff --git a/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/hub_details_page.dart b/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/hub_details_page.dart index d6d41786..2713d4ae 100644 --- a/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/hub_details_page.dart +++ b/apps/mobile/packages/features/client/hubs/lib/src/presentation/pages/hub_details_page.dart @@ -42,81 +42,146 @@ class HubDetailsPage extends StatelessWidget { ); } }, - child: Scaffold( - appBar: UiAppBar( - title: hub.name, - subtitle: t.client_hubs.hub_details.title, - onLeadingPressed: () => Modular.to.pop(), - actions: [ - IconButton( - onPressed: () => _confirmDeleteHub(context), - icon: const Icon(UiIcons.delete, color: UiColors.iconSecondary), + child: BlocBuilder( + builder: (BuildContext context, HubDetailsState state) { + final bool isLoading = state.status == HubDetailsStatus.loading; + + return Scaffold( + appBar: UiAppBar( + title: t.client_hubs.hub_details.title, + onLeadingPressed: () => Modular.to.pop(), ), - UiIconButton( - icon: UiIcons.edit, - onTap: () => _navigateToEditPage(context), - backgroundColor: UiColors.transparent, - iconColor: UiColors.iconSecondary, + bottomNavigationBar: SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Divider(height: 1, thickness: 0.5), + Padding( + padding: const EdgeInsets.all(UiConstants.space5), + child: Row( + children: [ + Expanded( + child: UiButton.secondary( + onPressed: isLoading + ? null + : () => _confirmDeleteHub(context), + text: t.common.delete, + leadingIcon: UiIcons.delete, + style: OutlinedButton.styleFrom( + foregroundColor: UiColors.destructive, + side: const BorderSide( + color: UiColors.destructive, + ), + ), + ), + ), + const SizedBox(width: UiConstants.space4), + Expanded( + child: UiButton.secondary( + onPressed: isLoading + ? null + : () => _navigateToEditPage(context), + text: t.client_hubs.hub_details.edit_button, + leadingIcon: UiIcons.edit, + ), + ), + ], + ), + ), + ], + ), ), - ], - ), - backgroundColor: UiColors.bgMenu, - body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - // ── Header ────────────────────────────────────────── - Padding( - padding: const EdgeInsets.all(UiConstants.space5), - child: IntrinsicHeight( - child: Row( + backgroundColor: UiColors.bgMenu, + body: Stack( + children: [ + SingleChildScrollView( + child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Container( - width: 114, - decoration: BoxDecoration( - color: UiColors.primary.withValues(alpha: 0.08), - borderRadius: BorderRadius.circular( - UiConstants.radiusBase, - ), - border: Border.all(color: UiColors.primary), - ), - child: const Center( - child: Icon( - UiIcons.nfc, - color: UiColors.primary, - size: 32, + // ── Header ────────────────────────────────────────── + Padding( + padding: const EdgeInsets.all(UiConstants.space5), + child: IntrinsicHeight( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Container( + width: 114, + decoration: BoxDecoration( + color: UiColors.primary.withValues( + alpha: 0.08, + ), + borderRadius: BorderRadius.circular( + UiConstants.radiusBase, + ), + border: Border.all(color: UiColors.primary), + ), + child: const Center( + child: Icon( + UiIcons.nfc, + color: UiColors.primary, + size: 32, + ), + ), + ), + const SizedBox(width: UiConstants.space4), + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + hub.name, + style: + UiTypography.headline1b.textPrimary, + ), + const SizedBox( + height: UiConstants.space1, + ), + Row( + children: [ + const Icon( + UiIcons.mapPin, + size: 16, + color: UiColors.textSecondary, + ), + const SizedBox( + width: UiConstants.space1, + ), + Expanded( + child: Text( + hub.address, + style: UiTypography + .body2r + .textSecondary, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ], + ), + ), + ], ), ), ), - const SizedBox(width: UiConstants.space4), - Expanded( + const Divider(height: 1, thickness: 0.5), + + Padding( + padding: const EdgeInsets.all(UiConstants.space5), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Text( - hub.name, - style: UiTypography.headline1b.textPrimary, - ), - const SizedBox(height: UiConstants.space1), - Row( - children: [ - const Icon( - UiIcons.mapPin, - size: 16, - color: UiColors.textSecondary, - ), - const SizedBox(width: UiConstants.space1), - Expanded( - child: Text( - hub.address, - style: UiTypography.body2r.textSecondary, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - ), - ], + _buildDetailItem( + label: t.client_hubs.hub_details.nfc_label, + value: + hub.nfcTagId ?? + t.client_hubs.hub_details.nfc_not_assigned, + icon: UiIcons.nfc, + isHighlight: hub.nfcTagId != null, ), ], ), @@ -124,28 +189,15 @@ class HubDetailsPage extends StatelessWidget { ], ), ), - ), - const Divider(height: 1, thickness: 0.5), - - Padding( - padding: const EdgeInsets.all(UiConstants.space5), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _buildDetailItem( - label: t.client_hubs.hub_details.nfc_label, - value: - hub.nfcTagId ?? - t.client_hubs.hub_details.nfc_not_assigned, - icon: UiIcons.nfc, - isHighlight: hub.nfcTagId != null, - ), - ], - ), - ), - ], - ), - ), + if (isLoading) + Container( + color: UiColors.black.withValues(alpha: 0.1), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + }, ), ), ); @@ -210,11 +262,11 @@ class HubDetailsPage extends StatelessWidget { title: Text(t.client_hubs.delete_dialog.title), content: Text(t.client_hubs.delete_dialog.message(hubName: hub.name)), actions: [ - TextButton( + UiButton.text( onPressed: () => Navigator.of(context).pop(false), child: Text(t.client_hubs.delete_dialog.cancel), ), - TextButton( + UiButton.text( onPressed: () => Navigator.of(context).pop(true), style: TextButton.styleFrom(foregroundColor: UiColors.destructive), child: Text(t.client_hubs.delete_dialog.delete),