pos changes
This commit is contained in:
@@ -6,6 +6,9 @@ import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/theme/app_layout.dart';
|
||||
import '../../../core/utils/formatters.dart';
|
||||
import '../../../core/widgets/brand_mark.dart';
|
||||
import '../../auth/providers/auth_controller.dart';
|
||||
import '../../shift/widgets/session_end_sheet.dart';
|
||||
import '../providers/cart_controller.dart';
|
||||
import '../providers/navigation_provider.dart';
|
||||
|
||||
@@ -32,7 +35,10 @@ class PageHeader extends ConsumerWidget {
|
||||
return LayoutBuilder(
|
||||
builder: (context, box) {
|
||||
final showStatus = box.maxWidth >= 720;
|
||||
return _bar(context, ref, compact, showStatus);
|
||||
// The brand block only earns its space once the bar is genuinely wide;
|
||||
// below that it would push the actions off the end.
|
||||
final showBrand = box.maxWidth >= 1000;
|
||||
return _bar(context, ref, compact, showStatus, showBrand);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -42,10 +48,14 @@ class PageHeader extends ConsumerWidget {
|
||||
WidgetRef ref,
|
||||
bool compact,
|
||||
bool showStatus,
|
||||
bool showBrand,
|
||||
) {
|
||||
final module = ref.watch(activeModuleProvider);
|
||||
final now = ref.watch(clockProvider).value ?? DateTime.now();
|
||||
|
||||
// With no sidebar there is nothing else on screen carrying the brand, the
|
||||
// sync log or the way out — so all three are promoted into this bar.
|
||||
final cashierMode = ref.watch(isCashierModeProvider);
|
||||
|
||||
return Container(
|
||||
constraints: const BoxConstraints(minHeight: AppSizes.headerHeight),
|
||||
padding: EdgeInsets.symmetric(
|
||||
@@ -58,7 +68,7 @@ class PageHeader extends ConsumerWidget {
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
if (compact) ...[
|
||||
if (compact && onMenuTap != null) ...[
|
||||
IconButton(
|
||||
onPressed: onMenuTap,
|
||||
icon: const Icon(Icons.menu_rounded),
|
||||
@@ -68,7 +78,12 @@ class PageHeader extends ConsumerWidget {
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
],
|
||||
|
||||
|
||||
// Dropped first when the bar gets tight: the actions are what the
|
||||
// counter actually presses.
|
||||
if (cashierMode && showBrand) ...[
|
||||
const _CashierBrand(),
|
||||
const SizedBox(width: AppSpacing.lg),
|
||||
],
|
||||
|
||||
if (showStatus) ...[
|
||||
_LivePill(offline: ref.watch(simulateOfflineProvider)),
|
||||
@@ -82,14 +97,26 @@ class PageHeader extends ConsumerWidget {
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppSpacing.lg),
|
||||
Container(width: 1, height: 26, color: AppColors.border),
|
||||
const SizedBox(width: AppSpacing.lg),
|
||||
],
|
||||
|
||||
// The bar is always the same shape: status on the left, actions
|
||||
// pinned to the right, for admin and cashier alike. Packed left with
|
||||
// a divider between them, the actions landed in a different place on
|
||||
// every screen — mid-bar on a wide admin window, hard left on a
|
||||
// narrow one — and the two roles never agreed with each other.
|
||||
const Spacer(),
|
||||
|
||||
_ParkedBillsButton(compact: compact),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
_NewSaleButton(compact: compact),
|
||||
|
||||
// Every role signs out from here. It used to sit at the foot of the
|
||||
// sidebar for admins and up here for cashiers, which meant the same
|
||||
// action lived in two places depending on who was holding the till.
|
||||
const SizedBox(width: AppSpacing.md),
|
||||
Container(width: 1, height: 26, color: AppColors.border),
|
||||
const SizedBox(width: AppSpacing.md),
|
||||
const _LogoutButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -366,3 +393,77 @@ class _NewSaleButton extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Brand and outlet name, shown only in cashier mode.
|
||||
///
|
||||
/// The sidebar normally carries these; without it the bar reads as a fragment
|
||||
/// of an app rather than the top of one.
|
||||
class _CashierBrand extends ConsumerWidget {
|
||||
const _CashierBrand();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final store = ref.watch(currentStoreProvider);
|
||||
final user = ref.watch(currentUserProvider);
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const BrandMark(size: 32),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 170),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
store?.name ?? 'Nearle POS',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: -0.2,
|
||||
color: AppColors.textPrimary,
|
||||
height: 1.15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
user == null ? 'Cashier' : '${user.name} · Cashier',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 11.5,
|
||||
color: AppColors.textTertiary,
|
||||
height: 1.25,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Signing out, for both roles.
|
||||
///
|
||||
/// Opens the session-end chooser rather than signing out directly: a cashier
|
||||
/// stepping away for ten minutes and a cashier finishing for the day want two
|
||||
/// very different things to happen to the drawer and the catalogue.
|
||||
class _LogoutButton extends ConsumerWidget {
|
||||
const _LogoutButton();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return IconButton(
|
||||
tooltip: 'Sign out',
|
||||
onPressed: () => showSessionEndSheet(context, ref),
|
||||
style: IconButton.styleFrom(
|
||||
foregroundColor: AppColors.danger,
|
||||
backgroundColor: AppColors.dangerSurface,
|
||||
),
|
||||
icon: const Icon(Icons.logout_rounded),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user