import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:proxibuy/core/config/app_colors.dart'; import 'package:proxibuy/core/gen/assets.gen.dart'; import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_bloc.dart'; import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_event.dart'; import 'package:proxibuy/presentation/notification_preferences/bloc/notification_preferences_state.dart'; import 'package:proxibuy/presentation/pages/offers_page.dart'; import 'package:proxibuy/presentation/pages/reserved_list_page.dart'; import 'package:proxibuy/presentation/reservation/cubit/reservation_cubit.dart'; import 'package:proxibuy/presentation/widgets/category_selection_card.dart'; import 'package:shared_preferences/shared_preferences.dart'; class NotificationPreferencesPage extends StatefulWidget { // This parameter is used to decide whether to fetch favorite categories on start final bool loadFavoritesOnStart; // The constructor now accepts the 'loadFavoritesOnStart' parameter const NotificationPreferencesPage({super.key, this.loadFavoritesOnStart = false}); static Route route({bool loadFavorites = false}) { return MaterialPageRoute( builder: (_) => BlocProvider( create: (context) => NotificationPreferencesBloc(), // The widget is created here, passing the parameter correctly child: NotificationPreferencesPage(loadFavoritesOnStart: loadFavorites), ), ); } @override State createState() => _NotificationPreferencesPageState(); } class _NotificationPreferencesPageState extends State { @override void initState() { super.initState(); // If the flag is true, dispatch the event to load favorites from the API if (widget.loadFavoritesOnStart) { context.read().add(LoadFavoriteCategories()); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.white, automaticallyImplyLeading: false, title: Padding( padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 0.0), child: Assets.icons.logoWithName.svg(height: 40, width: 200), ), actions: [ IconButton(onPressed: () {}, icon: Assets.icons.notification.svg()), BlocBuilder( builder: (context, state) { final reservedCount = state.reservedProductIds.length; return Stack( alignment: Alignment.center, children: [ IconButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (_) => const ReservedListPage(), ), ); }, icon: Assets.icons.scanBarcode.svg(), ), if (reservedCount > 0) Positioned( top: 0, right: 2, child: GestureDetector( onTap: () { Navigator.of(context).push( MaterialPageRoute( builder: (_) => const ReservedListPage(), ), ); }, child: Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: Colors.green, shape: BoxShape.circle, border: Border.all(color: Colors.white, width: 1.5), ), constraints: const BoxConstraints( minWidth: 18, minHeight: 18, ), child: Padding( padding: const EdgeInsets.fromLTRB(2, 4, 2, 2), child: Text( '$reservedCount', style: const TextStyle( color: Colors.white, fontSize: 11, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), ), ), ), ), ], ); }, ), const SizedBox(width: 8), ], ), body: BlocListener( listener: (context, state) { if (state.submissionSuccess) { // Pop the page and return 'true' to signal a successful update if (Navigator.canPop(context)) { Navigator.of(context).pop(true); } else { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const OffersPage(showDialogsOnLoad: true), ), ); } } if (state.errorMessage != null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(state.errorMessage!), backgroundColor: Colors.red, ), ); } }, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'دریافت اعلان', style: TextStyle( fontFamily: 'Dana', fontSize: 20, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), const Divider(), RichText( text: TextSpan( style: TextStyle( fontFamily: 'Dana', fontSize: 14, color: AppColors.hint, height: 1.5, ), children: const [ TextSpan( text: 'ترجیح می‌دی از کدام دسته‌بندی‌ها اعلان تخفیف دریافت کنی؟ ', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14), ), TextSpan(text: '(حداقل یک مورد رو انتخاب کن).'), ], ), ), const SizedBox(height: 24), Expanded( child: BlocBuilder( builder: (context, state) { if (state.categories.isEmpty && state.isLoading) { return const Center(child: CircularProgressIndicator()); } final double horizontalPadding = 24.0; final double crossAxisSpacing = 16.0; final int crossAxisCount = 3; final screenWidth = MediaQuery.of(context).size.width; final itemWidth = (screenWidth - (horizontalPadding * 2) - (crossAxisSpacing * (crossAxisCount - 1))) / crossAxisCount; final itemHeight = itemWidth / 0.9; return SingleChildScrollView( child: Wrap( spacing: crossAxisSpacing, runSpacing: 24.0, alignment: WrapAlignment.center, children: state.categories.map((category) { final isSelected = state.selectedCategoryIds.contains(category.id); return SizedBox( width: itemWidth, height: itemHeight, child: CategorySelectionCard( name: category.name, icon: category.icon, isSelected: isSelected, showSelectableIndicator: state.selectedCategoryIds.isNotEmpty, onTap: () { context .read() .add(ToggleCategorySelection(category.id)); }, ), ); }).toList(), ), ); }, ), ), BlocBuilder( builder: (context, state) { final areCategoriesSelected = state.selectedCategoryIds.isNotEmpty; if (areCategoriesSelected) { return SizedBox( width: double.infinity, child: ElevatedButton( onPressed: !state.isLoading ? () async { final bloc = context.read(); final selectedCategoryNames = bloc.state.categories .where((cat) => bloc.state.selectedCategoryIds.contains(cat.id)) .map((cat) => cat.name) .toList(); final prefs = await SharedPreferences.getInstance(); await prefs.setStringList('user_selected_categories', selectedCategoryNames); bloc.add(SubmitPreferences()); } : null, style: ElevatedButton.styleFrom( backgroundColor: AppColors.confirm, foregroundColor: Colors.white, disabledBackgroundColor: Colors.grey, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(50), ), ), child: state.isLoading ? const CircularProgressIndicator(color: Colors.white) : const Text( 'اعمال', style: TextStyle( fontFamily: 'Dana', fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ); } else { return const SizedBox.shrink(); } }, ), const SizedBox(height: 20), ], ), ), ), ); } }