import 'dart:async'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/utils/date_helper.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/branch_details_card.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; import 'package:sizer/sizer.dart'; class ProviderProfileView extends StatefulWidget { final int providerId; ProviderProfileView({required this.providerId}); @override State createState() => _ProviderProfileViewState(); } class _ProviderProfileViewState extends State { @override void initState() { super.initState(); scheduleMicrotask(() async => context.read().getProviderProfileWithBranchesAndServices(widget.providerId)); } @override Widget build(BuildContext context) { return Consumer( builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { if (appointmentsVM.state == ViewState.busy || appointmentsVM.providerProfileModel == null) { return Scaffold( backgroundColor: MyColors.white, appBar: CustomAppBar( title: LocaleKeys.providerDetails.tr(), ), body: Center(child: CircularProgressIndicator()), ); } return Scaffold( appBar: CustomAppBar( title: LocaleKeys.providerDetails.tr(), ), body: Container( width: double.infinity, height: double.infinity, padding: EdgeInsets.symmetric(horizontal: 21), child: SingleChildScrollView( child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ Center( child: appointmentsVM.providerProfileModel!.profileImage.buildNetworkImage( height: 250, width: double.infinity, fit: BoxFit.cover, ), ), Positioned( top: 10, right: 10, child: FavoriteProviderButton( isFavorite: appointmentsVM.providerProfileModel!.isFavorite!, serviceProviderID: appointmentsVM.providerProfileModel!.id!, onToggle: () { setState(() {}); }, ), ), ], ), 12.height, if (appointmentsVM.providerProfileModel!.memberSince!.isNotEmpty) ...[ Row( children: [ ("${LocaleKeys.companyName.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12), 4.width, (appointmentsVM.providerProfileModel!.companyName ?? appointmentsVM.providerProfileModel!.name).toString().toText( fontSize: 16, isBold: true, ), ], ), ], if (appointmentsVM.providerProfileModel!.memberSince!.isNotEmpty) ...[ Row( children: [ ("${LocaleKeys.memberSince.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12), 4.width, // "${DateHelper.formatAsMonthYear( // DateHelper.parseStringToDate( // DateHelper.formatDateT( // appointmentsVM.providerProfileModel!.memberSince ?? "", // ), // ), // )}" "${DateFormat('MMMM yyyy', context.locale.languageCode).format( DateHelper.parseStringToDate( DateHelper.formatDateT( appointmentsVM.providerProfileModel!.memberSince ?? "", ), ), )}" .toText(fontSize: 12, isBold: true), ], ), ], 4.height, appointmentsVM.providerProfileModel!.companyDescription!.toText(color: MyColors.lightTextColor, fontSize: 12), ], ).toWhiteContainer(width: double.infinity, allPading: 12), 12.height, appointmentsVM.providerProfileModel!.serviceProviderBranch == null ? Center( child: (LocaleKeys.noBranchFound.tr()).toText( fontSize: 16, color: MyColors.lightTextColor, ), ) : appointmentsVM.providerProfileModel!.serviceProviderBranch!.isEmpty ? Center(child: Text(LocaleKeys.no_branch.tr())) : ListView.separated( itemBuilder: (context, index) { BranchDetailModel branchModel = appointmentsVM.providerProfileModel!.serviceProviderBranch![index]; return BranchDetailCard( onCardTapped: () { navigateWithName(context, AppRoutes.branchDetailView, arguments: branchModel); }, providerImageUrl: (branchModel.branchImages != null && branchModel.branchImages!.isNotEmpty) ? (branchModel.branchImages!.first.imageUrl ?? "") : "", title: branchModel.branchName ?? "", providerLocation: branchModel.distanceKm.toString() + LocaleKeys.km.tr(), providerName: branchModel.serviceProviderName ?? "", providerRatings: (branchModel.branchRateAvg ?? 0.0), services: branchModel.branchServices, ); }, separatorBuilder: (context, index) { return 12.height; }, itemCount: appointmentsVM.providerProfileModel!.serviceProviderBranch!.length, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, ) ], ), ), ), ); }, ); } } class FavoriteProviderButton extends StatefulWidget { final bool isFavorite; final int serviceProviderID; final VoidCallback onToggle; const FavoriteProviderButton({ super.key, required this.isFavorite, required this.serviceProviderID, required this.onToggle, }); @override State createState() => _FavoriteProviderButtonState(); } class _FavoriteProviderButtonState extends State with SingleTickerProviderStateMixin { bool isLoading = false; late bool isFavorite; late AnimationController _animationController; late Animation _scaleAnimation; @override void initState() { super.initState(); isFavorite = widget.isFavorite; _animationController = AnimationController( duration: const Duration(milliseconds: 300), vsync: this, ); _scaleAnimation = Tween(begin: 1.0, end: 1.3).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), ); } @override void dispose() { _animationController.dispose(); super.dispose(); } Future toggleFavorite() async { if (isLoading) return; setState(() { isLoading = true; }); _animationController.forward().then((_) => _animationController.reverse()); bool success; if (isFavorite) { success = await context.read().removeProviderFromFavorite(serviceProviderID: widget.serviceProviderID); } else { success = await context.read().addProviderToFavorite(serviceProviderID: widget.serviceProviderID); } if (success) { setState(() { isFavorite = !isFavorite; isLoading = false; }); context.read().providerProfileModel!.isFavorite = isFavorite; if (isFavorite == false) { context.read().getMyFavoriteProviders(); } widget.onToggle(); } else { setState(() { isLoading = false; }); } } @override Widget build(BuildContext context) { return GestureDetector( onTap: toggleFavorite, child: Container( width: 8.6.w, height: 8.6.w, decoration: BoxDecoration( color: Colors.white, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: const Color(0xff000000).withOpacity(.07), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Center( child: isLoading ? SizedBox( width: 4.4.w, height: 4.4.w, child: const CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(MyColors.darkPrimaryColor), ), ) : ScaleTransition( scale: _scaleAnimation, child: Icon( isFavorite ? Icons.favorite : Icons.favorite_border, color: isFavorite ? Colors.red : MyColors.darkIconColor, size: 5.5.w, ), ), ), ), ); } }