import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/format.dart'; import '../../core/models.dart'; import '../../core/providers.dart'; import '../../core/theme.dart'; import '../../widgets/ui.dart'; import 'shop_sheet.dart'; class ShopsScreen extends ConsumerStatefulWidget { const ShopsScreen({super.key}); @override ConsumerState createState() => _ShopsScreenState(); } class _ShopsScreenState extends ConsumerState { String _q = ''; @override Widget build(BuildContext context) { final date = ref.watch(selectedDateProvider); final isAdmin = ref.watch(sessionProvider)?.isAdmin ?? false; final shops = ref.watch(shopsProvider(date)); final count = shops.value?.where((s) => s.shop.active).length; Future refresh() => refreshData(context, ref, shopsProvider(date)); return Column( children: [ ScreenHeader( title: 'Shops', subtitle: count == null ? null : '${plural(count, 'shop')} · ${dateShort(date)}', subtitleLoading: shops.isLoading, trailing: isAdmin ? SmallButton('Add shop', onTap: () => showShopSheet(context)) : null, ), PagePad( top: S.s4, bottom: S.s6, child: _Toolbar( search: SearchField( hint: 'Search shops', onChanged: (v) => setState(() => _q = v.trim().toLowerCase()), ), ), ), Expanded( child: RefreshableView( value: shops, onRefresh: refresh, skeleton: const SkeletonList( top: S.s8, children: [TileGridBone(figure: false)], ), builder: (list) { final f = list .where( (s) => _q.isEmpty || s.shop.name.toLowerCase().contains(_q) || s.shop.code.toLowerCase().contains(_q), ) .toList(); if (f.isEmpty) { return ListView( physics: const AlwaysScrollableScrollPhysics(), children: [ EmptyState( icon: Icons.storefront_outlined, title: list.isEmpty ? 'No shops yet' : 'No results for “$_q”', body: list.isEmpty ? (isAdmin ? 'Add a shop to get started.' : 'No shops are assigned to your account. Contact your administrator.') : null, ), ], ); } return PageList( top: S.s8, children: [ CardGrid(children: [for (final s in f) _ShopTile(s: s)]), ], ); }, ), ), ], ); } } class _Toolbar extends StatelessWidget { const _Toolbar({required this.search}); final Widget search; @override Widget build(BuildContext context) => LayoutBuilder( builder: (context, c) { if (c.maxWidth < 760) { return Column( children: [ const DateStrip(), const SizedBox(height: S.s12), search, ], ); } return Row( children: [ const SizedBox(width: 380, child: DateStrip()), const SizedBox(width: S.s16), Expanded(child: search), ], ); }, ); } class _ShopTile extends StatelessWidget { const _ShopTile({required this.s}); final ShopDay s; @override Widget build(BuildContext context) => Opacity(opacity: s.shop.active ? 1 : 0.62, child: _card(context)); Widget _card(BuildContext context) => SrsCard( onTap: () => s.shop.active ? context.push('/shops/${s.shop.id}') : showShopSheet(context, shop: s.shop), padding: const EdgeInsets.all(S.s14), child: Row( children: [ CodeTile(s.shop.code), const SizedBox(width: S.s14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( s.shop.name, maxLines: 1, overflow: TextOverflow.ellipsis, style: ts(15, w: w6), ), const SizedBox(height: S.s4), Text( !s.shop.active ? 'Inactive' : s.orders == 0 ? 'No orders' : '${plural(s.tickets, 'ticket')} · ${plural(s.orders, 'order')}', style: ts(12, c: C.muted), ), ], ), ), if (s.shop.active) const Icon(Icons.chevron_right_rounded, color: C.placeholder) else const Pill('Inactive', bg: C.redTint, fg: C.red), ], ), ); }