import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import 'package:tm_app/core/theme/colors.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import 'package:tm_app/view_models/tenders_view_model.dart'; import '../../../core/constants/assets.dart'; import '../../../core/utils/size_config.dart'; import 'tender_card.dart'; class MainTendersSlider extends StatefulWidget { const MainTendersSlider({ required this.tenders, super.key, this.isDesktop = false, }); final bool isDesktop; final List tenders; @override State createState() => _MainTendersSliderState(); } class _MainTendersSliderState extends State { final PageController pageController = PageController(initialPage: 0); int currentPage = 1; void _goToPreviousPage() { if (currentPage == 1) { return; } pageController.previousPage( duration: Duration(milliseconds: 300), curve: Curves.easeInOutCubic, ); setState(() { currentPage = currentPage - 1; }); // Fetch feedback and approvals for the previous tender if not already loaded final viewModel = context.read(); final previousTenderId = widget.tenders[currentPage - 2].id!; if (!viewModel.hasFeedbackForTender(previousTenderId)) { viewModel.getTenderFeedback(previousTenderId); } if (!viewModel.hasTenderApprovalForTender(previousTenderId)) { viewModel.getTenderApprovals(previousTenderId); } } void _goToNextPage() { if (currentPage == widget.tenders.length) { return; } pageController.nextPage( duration: Duration(milliseconds: 300), curve: Curves.easeInOutCubic, ); setState(() { currentPage = currentPage + 1; }); // Fetch feedback and approvals for the next tender if not already loaded final viewModel = context.read(); final nextTenderId = widget.tenders[currentPage].id!; if (!viewModel.hasFeedbackForTender(nextTenderId)) { viewModel.getTenderFeedback(nextTenderId); } if (!viewModel.hasTenderApprovalForTender(nextTenderId)) { viewModel.getTenderApprovals(nextTenderId); } } @override void dispose() { pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return SingleChildScrollView( child: Stack(children: [_tendersPageView(), _nextPreviousArrows()]), ); } Widget _tendersPageView() { return SizedBox( width: double.infinity, height: 722.0.h(), child: PageView.builder( controller: pageController, scrollDirection: Axis.horizontal, itemCount: widget.tenders.length, onPageChanged: (index) { setState(() { currentPage = index + 1; }); // Fetch feedback and approvals for the new tender if not already loaded final viewModel = context.read(); if (!viewModel.hasFeedbackForTender(widget.tenders[index].id!)) { viewModel.getTenderFeedback(widget.tenders[index].id!); } if (!viewModel.hasTenderApprovalForTender( widget.tenders[index].id!, )) { viewModel.getTenderApprovals(widget.tenders[index].id!); } // Check if we need to load more tenders (when user reaches near the end) if (index >= widget.tenders.length - 1 && viewModel.hasMoreData && !viewModel.isLoadingMore) { viewModel.loadMoreTenders(); } }, itemBuilder: (context, index) { final tender = widget.tenders[index]; return TenderCard(tender: tender, isDesktop: widget.isDesktop); }, ), ); } Widget _nextPreviousArrows() { return Positioned( top: 607.0.h(), bottom: 52.0.h(), left: 9.0.w(), right: 9.0.w(), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [_leftArrowButton(), _pageNumberText(), _rightArrowButton()], ), ); } Widget _leftArrowButton() { return Visibility( visible: currentPage != 1, child: InkWell( borderRadius: BorderRadius.circular(100), onTap: _goToPreviousPage, child: Container( width: 32.0.h(), height: 32.0.h(), decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: AppColors.iconColor, width: 1.5), ), alignment: Alignment.center, child: SvgPicture.asset( AssetsManager.arrowLeftSmall, colorFilter: ColorFilter.mode( AppColors.iconColor, BlendMode.srcATop, ), ), ), ), ); } Widget _pageNumberText() { final viewModel = context.watch(); return Column( mainAxisSize: MainAxisSize.min, children: [ viewModel.isLoadingMore ? Padding( padding: EdgeInsets.only(top: 4.0.h()), child: SizedBox( width: 16.0.w(), height: 16.0.w(), child: CircularProgressIndicator( strokeWidth: 2.0, color: AppColors.jellyBean, ), ), ) : Text( '$currentPage/${widget.tenders.length}', style: TextStyle( fontSize: 14.0.sp(), fontWeight: FontWeight.w500, color: AppColors.grey, ), ), ], ); } Widget _rightArrowButton() { return Visibility( visible: currentPage != widget.tenders.length, child: InkWell( borderRadius: BorderRadius.circular(100), onTap: _goToNextPage, child: Container( width: 32.0.h(), height: 32.0.h(), decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: AppColors.iconColor, width: 1.5), ), alignment: Alignment.center, child: SvgPicture.asset( AssetsManager.arrowRightSmall, colorFilter: ColorFilter.mode( AppColors.iconColor, BlendMode.srcATop, ), ), ), ), ); } }