import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:niogu_app/core/components/top_back_bar_app.dart'; import 'package:niogu_app/core/constants/app_color.dart'; import 'package:niogu_app/core/constants/app_font_size.dart'; import 'package:niogu_app/core/widgets/custom_error_screen.dart'; import 'package:niogu_app/core/providers/app_provider.dart'; import 'package:niogu_app/core/router/app_route.dart'; import 'package:niogu_app/core/widgets/custom_empty_screen.dart'; import 'package:niogu_app/features/outlets/domain/entities/outlet.dart'; import 'package:niogu_app/features/outlets/presentation/providers/outlet_provider.dart'; import 'package:niogu_app/features/outlets/presentation/widgets/outlet_shimmer.dart'; import 'package:niogu_app/features/outlets/presentation/widgets/quota_indicator.dart'; import 'package:sizer/sizer.dart'; class OutletScreen extends ConsumerWidget { const OutletScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return LayoutBuilder( builder: (context, constraints) { final bool isTablet = 100.w >= 600; final outletState = ref.watch(displayOutletStreamProvider); int limitOutlet = 5; final limitOutletState = ref.watch(limitOutletStreamProvider); limitOutletState.whenData((limit) => limitOutlet = limit); bool isLimitReached = false; outletState.whenData((outlets) { isLimitReached = outlets.length >= limitOutlet; }); final userDeletedState = ref.watch(userDeletedByOutletStreamProvider); final List userDeleted = []; userDeletedState.whenData((u) => userDeleted.addAll(u)); final outletEmptyState = ref.watch(displayOutletEmptyProvider); final outletIdByOwnerState = ref.watch(outletIdByOwnerProvider); return SafeArea( top: false, bottom: true, right: false, left: false, child: Scaffold( backgroundColor: const Color(0xFFF9FAFB), appBar: TopBackBarApp( title: "Outlet Usaha", onTap: () => context.pop(), ), body: outletState.when( data: (outlets) { switch (outletEmptyState) { case DisplayOutletEmpty.loading: return const SizedBox(); case DisplayOutletEmpty.empty_database: return CustomEmptyScreen( title: "Tidak Ada Outlet", body: "Kamu belum memiliki outlet", ); case DisplayOutletEmpty.has_data: return Column( children: [ QuotaIndicator(current: outlets.length, max: limitOutlet), Expanded( child: ListView.builder( padding: EdgeInsets.symmetric(horizontal: 5.w), itemCount: outlets.length, itemBuilder: (context, index) { final outlet = outlets[index]; final bool imagePathAvailable = outlet.bannerPath != null && outlet.bannerPath!.isNotEmpty; final File imageFile = File( imagePathAvailable ? outlet.bannerPath! : "image not found", ); int userStaffAmount = outlet.userStaffAmount; final bool isOutletOwner = outletIdByOwnerState != null && outlet.id == outletIdByOwnerState; if (userDeleted.isNotEmpty) { for (final user in userDeleted) { if (isOutletOwner && user.outletId == outlet.id) { userStaffAmount = outlet.userStaffAmount - user.amount - 1; } else if (user.outletId == outlet.id) { userStaffAmount = outlet.userStaffAmount - user.amount; } } } else { if (isOutletOwner) { userStaffAmount = outlet.userStaffAmount - 1; } } final bool imageFileExists = imageFile .existsSync(); return Material( color: Colors.transparent, type: MaterialType.transparency, child: InkWell( onTap: () { context.pushNamed( AppRoute.editOutletScreen, pathParameters: {"id": outlet.id}, ); }, child: Container( margin: EdgeInsets.only(bottom: 3.h), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular( 4.w, ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity( 0.06, ), blurRadius: 15, offset: const Offset(0, 8), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ imageFileExists ? Container( height: 22.h, width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.vertical( top: Radius.circular( 4.w, ), ), image: DecorationImage( image: FileImage( imageFile, ), fit: BoxFit .cover, ), ), ) : Container( height: 22.h, width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.vertical( top: Radius.circular( 4.w, ), ), color: Colors .grey .shade200, ), child: Column( mainAxisAlignment: MainAxisAlignment .center, children: [ Icon( Icons .store_outlined, color: Colors.grey, size: 20.w, ), ], ), ), if (imageFileExists) Container( height: 22.h, width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.vertical( top: Radius.circular( 4.w, ), ), gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment .bottomCenter, colors: [ Colors.black .withOpacity(0.4), Colors.transparent, ], ), ), ), ], ), Padding( padding: EdgeInsets.all(4.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( outlet.name, style: TextStyle( color: Colors.black87, fontSize: isTablet ? AppFontSize .medium .sp : AppFontSize .small .sp, fontWeight: FontWeight.bold, ), ), Row( children: [ Container( width: 2.w, height: 2.w, decoration: BoxDecoration( color: outlet .isActive ? Colors.green : Colors.red, shape: BoxShape .circle, ), ), SizedBox( width: 1.5.w, ), Text( outlet.isActive ? 'Aktif / Buka' : 'Non Aktif / Tutup', style: TextStyle( fontSize: isTablet ? (AppFontSize.medium - 2) .sp : (AppFontSize.small - 2) .sp, color: outlet .isActive ? Colors.green : Colors.red, fontWeight: FontWeight .w600, ), ), ], ), ], ), SizedBox(height: 1.h), if (outlet.isMainOutlet) Text( "• Outlet Utama", style: TextStyle( color: Colors .grey .shade700, fontSize: isTablet ? (AppFontSize.medium - 2) .sp : (AppFontSize.small - 2) .sp, fontWeight: FontWeight.bold, ), ), if (outlet.fullAddress != null && outlet .fullAddress! .isNotEmpty) ...[ SizedBox(height: 1.5.h), Row( children: [ Icon( Icons .location_on_outlined, size: 5.w, color: Colors.grey, ), SizedBox(width: 2.w), Expanded( child: Text( outlet.fullAddress!, style: TextStyle( color: Colors .grey .shade700, fontSize: isTablet ? (AppFontSize.medium - 1.25) .sp : (AppFontSize.small - 1.25) .sp, ), maxLines: 1, overflow: TextOverflow .ellipsis, ), ), ], ), ], SizedBox(height: 1.h), Divider( color: Colors.grey[100], ), SizedBox(height: 1.h), Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ _buildInfoMini( Icons.people_outline, "$userStaffAmount Staf", isTablet, ), _buildInfoMini( Icons .shopping_bag_outlined, "${outlet.transactionAmount} Transaksi", isTablet, ), Icon( Icons.arrow_forward_ios, size: 3.5.w, color: Colors.grey[400], ), ], ), ], ), ), ], ), ), ), ); }, ), ), ], ); } }, error: (error, stackTrace) { return CustomErrorScreen( message: "Ups, terjadi kesalahan", onRefresh: () {}, ); }, loading: () => const OutletShimmer(), ), bottomNavigationBar: outletState.isLoading ? null : Container( padding: EdgeInsets.all(5.w), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, -5), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ ElevatedButton( onPressed: isLimitReached ? null : () { final outletState = ref.read( outletStreamProvider, ); bool isLimitReached = false; outletState.whenData((outlets) { isLimitReached = outlets.length >= 5; }); if (isLimitReached) { } else { context.pushNamed( AppRoute.addOutletScreen, ); } }, style: ElevatedButton.styleFrom( backgroundColor: AppColor.primaryColor, minimumSize: Size(double.infinity, 6.5.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(3.w), ), disabledBackgroundColor: !isLimitReached ? null : Colors.grey.shade300, ), child: Text( "Tambah Outlet Baru", style: TextStyle( fontSize: AppFontSize.medium.sp, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ], ), ), ), ); }, ); } Widget _buildInfoMini(IconData icon, String label, bool isTablet) { return Row( children: [ Icon(icon, size: 4.w, color: AppColor.primaryColor), SizedBox(width: 1.5.w), Text( label, style: TextStyle( color: Colors.black54, fontSize: isTablet ? (AppFontSize.medium - 1.25).sp : (AppFontSize.small - 1.25).sp, fontWeight: FontWeight.w500, ), ), ], ); } }