import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; class DashboardScreenForDependet extends StatefulWidget { const DashboardScreenForDependet({Key? key}) : super(key: key); @override State createState() => _DashboardScreenForDependetState(); } class _DashboardScreenForDependetState extends State { List offersList = []; List _filteredOffersList = []; bool isLoading = false; String searchQuery = ""; @override void initState() { super.initState(); fetchOffers(); } /// Offers API placeholder - will be connected when the endpoint is provided Future fetchOffers() async { setState(() { isLoading = true; }); try { // TODO: Call Dependent Offers API here once provided // Example: // offersList = await OffersApiClient().getDependentOffers(); await Future.delayed(const Duration(milliseconds: 300)); _filteredOffersList = offersList; } catch (e) { print("Error fetching dependent offers: $e"); } finally { if (mounted) { setState(() { isLoading = false; }); } } } void _runFilter(String query) { searchQuery = query; if (query.isEmpty) { _filteredOffersList = offersList; } else { bool isAr = AppState().isArabic(context); _filteredOffersList = offersList.where((offer) { String title = isAr ? (offer.titleAr ?? "") : (offer.titleEn ?? ""); return title.toLowerCase().contains(query.toLowerCase()); }).toList(); } setState(() {}); } void _performLogout() { Utils.confirmDialog( context, AppState().isArabic(context) ? "هل أنت متأكد من تسجيل الخروج؟" : "Are you sure you want to log out?", onTap: () { ApiConsts.selectedMemberType = MemberType.employee; ApiConsts.ISDependetLogin = false; Navigator.pushNamedAndRemoveUntil(context, AppRoutes.login, (Route route) => false); }, ); } @override Widget build(BuildContext context) { bool isAr = AppState().isArabic(context); return Scaffold( backgroundColor: MyColors.backgroundColor, appBar: AppBar( backgroundColor: Colors.white, elevation: 0, surfaceTintColor: Colors.transparent, automaticallyImplyLeading: false, title: Row(children: [(isAr ? "عروض التابعين" : "Offers & Discounts").toText20(color: MyColors.darkTextColor, isBold: true)]), actions: [ // Logout button Container( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration(color: MyColors.redColor.withOpacity(0.08), borderRadius: BorderRadius.circular(8)), child: InkWell( borderRadius: BorderRadius.circular(8), onTap: _performLogout, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), child: Row( mainAxisSize: MainAxisSize.min, children: [const Icon(Icons.logout_rounded, size: 18, color: MyColors.redColor), 6.width, (isAr ? "خروج" : "Logout").toText13(color: MyColors.redColor)], ), ), ), ), ], ), body: RefreshIndicator( onRefresh: fetchOffers, color: MyColors.textMixColor, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysics()), padding: const EdgeInsets.all(21), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Search input DynamicTextFieldWidget( LocaleKeys.search.tr(), LocaleKeys.searchItems.tr(), isEnable: true, suffixIconData: Icons.search, isPopup: false, lines: 1, isInputTypeNum: false, isReadOnly: false, onChange: (String value) { _runFilter(value); }, ), 20.height, // Header Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ (isAr ? "العروض المتاحة" : "Available Offers").toText18(isBold: true, color: MyColors.darkTextColor), if (offersList.isNotEmpty) "${_filteredOffersList.length} ${isAr ? "عرض" : "offers"}".toText12(color: MyColors.grey70Color), ], ), 16.height, // Content Area if (isLoading) const Center(child: Padding(padding: EdgeInsets.symmetric(vertical: 60), child: CircularProgressIndicator(color: MyColors.textMixColor))) else if (_filteredOffersList.isEmpty) _buildEmptyOffersWidget(isAr) else GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 162 / 266, crossAxisSpacing: 12, mainAxisSpacing: 12), itemCount: _filteredOffersList.length, itemBuilder: (context, index) { return _buildOfferCard(_filteredOffersList[index], isAr); }, ), ], ), ), ), ); } Widget _buildEmptyOffersWidget(bool isAr) { return Center( child: Padding( padding: const EdgeInsets.symmetric(vertical: 60, horizontal: 24), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 80, height: 80, decoration: BoxDecoration(color: MyColors.textMixColor.withOpacity(0.1), shape: BoxShape.circle), child: const Icon(Icons.local_offer_outlined, size: 40, color: MyColors.textMixColor), ), 16.height, (isAr ? "لا توجد عروض متاحة حالياً" : "No Offers Available Currently").toText16(isBold: true, color: MyColors.darkTextColor), 8.height, (isAr ? "سيتم إتاحة العروض الخاصة بك قريباً" : "Exclusive offers for dependents will be available soon.").toText13(color: MyColors.grey70Color), 24.height, DefaultButton(isAr ? "تحديث" : "Refresh", fetchOffers, colors: const [MyColors.gradiantStartColor, MyColors.gradiantEndColor]), ], ), ), ); } Widget _buildOfferCard(OffersListModel item, bool isAr) { return Container( padding: const EdgeInsets.all(10.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [BoxShadow(color: const Color(0xff000000).withOpacity(.05), blurRadius: 26, offset: const Offset(0, -3))], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ AspectRatio( aspectRatio: 118 / 127, child: ClipRRect( borderRadius: BorderRadius.circular(6), child: (item.bannerImage != null && item.bannerImage!.isNotEmpty) ? Image.network( item.bannerImage!, fit: BoxFit.contain, errorBuilder: (_, __, ___) => Container(color: MyColors.greyF7Color, child: const Icon(Icons.broken_image, color: MyColors.grey70Color)), ) : Container(color: MyColors.greyF7Color, child: const Icon(Icons.image_outlined, color: MyColors.grey70Color)), ), ), 8.height, (isAr ? (item.titleAr ?? "") : (item.titleEn ?? "")).toText16(isBold: true, color: MyColors.darkTextColor, maxlines: 1), if (item.discountDescription != null && item.discountDescription!.isNotEmpty) ...[4.height, item.discountDescription!.toText14(isBold: true, maxlines: 1)], ], ), ); } }