diff --git a/lib/core/app_router.dart b/lib/core/app_router.dart index fec9b100..d29fea2d 100644 --- a/lib/core/app_router.dart +++ b/lib/core/app_router.dart @@ -293,7 +293,12 @@ class AppRouter { ), GoRoute(path: '/become-consultant-screen', name: 'becomeConsultantScreen', builder: (context, state) => const BecomeConsultantScreen()), GoRoute( - path: '/stepper-become-consultant-screen', name: 'stepperBecomeConsultantScreen', builder: (context, state) => const StepperBecomeConsultantScreen()), + path: '/stepper-become-consultant-screen', + name: 'stepperBecomeConsultantScreen', + builder: (context, state) => StepperBecomeConsultantScreen( + slug: state.extra == null ? null : state.extra as String, + ), + ), GoRoute(path: '/calendar-screen', name: 'calendarScreen', builder: (context, state) => const CalendarScreen()), GoRoute(path: '/support-screen', name: 'supportScreen', builder: (context, state) => const SupportScreen()), GoRoute( diff --git a/lib/core/const.dart b/lib/core/const.dart index 31c47e9c..73e7ecfd 100644 --- a/lib/core/const.dart +++ b/lib/core/const.dart @@ -1,4 +1,4 @@ -String baseUrl = 'https://eatvio.ru'; + String baseUrl = 'https://eatvio.ru'; // String baseUrl = 'https://dev2.eatvio.com'; const List durationValues = [7, 14, 21]; diff --git a/lib/features/consultant/become_consultant/models/consultation_request_model.dart b/lib/features/consultant/become_consultant/models/consultation_request_model.dart index 1579fab5..547ff856 100644 --- a/lib/features/consultant/become_consultant/models/consultation_request_model.dart +++ b/lib/features/consultant/become_consultant/models/consultation_request_model.dart @@ -8,7 +8,7 @@ part 'consultation_request_model.g.dart'; @freezed abstract class ConsultationRequestModel with _$ConsultationRequestModel { const factory ConsultationRequestModel({ - @JsonKey(name: 'rating_place') required int ratingPlace, + @JsonKey(name: 'rating_place') int? ratingPlace, @JsonKey(name: 'education_resource') required EducationModel educationModel, @JsonKey(name: 'cert_photos') required List photos, }) = _ConsultationRequestModel; diff --git a/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_cubit.dart b/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_cubit.dart index a7171f89..7ca3ac48 100644 --- a/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_cubit.dart +++ b/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_cubit.dart @@ -1,13 +1,15 @@ import 'dart:io'; - import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart'; import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_profile_model.dart'; import 'package:eatvio_app/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart'; import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:http/http.dart' as http; +import 'package:path_provider/path_provider.dart'; class RegisterConsultantCubit extends Cubit { final ConsultantRepository consultantRepository; + bool _update = false; RegisterConsultantCubit({ required this.consultantRepository, @@ -17,12 +19,73 @@ class RegisterConsultantCubit extends Cubit { socialLinks: SocialLinksModel(), hasMedicalEducation: true, ), + loading: true, acceptOffer: false, ), ); + Future downloadImageAsFile(String imageUrl) async { + final response = await http.get(Uri.parse(imageUrl)); + + if (response.statusCode == 200) { + final tempDir = await getTemporaryDirectory(); + final filePath = '${tempDir.path}/${imageUrl.split('/').last}'; + final file = File(filePath); + return await file.writeAsBytes(response.bodyBytes); + } else { + throw Exception('Не удалось загрузить изображение'); + } + } + + getMyRequestStatus(String slug) async { + _update = true; + final myRequestStatus = await consultantRepository.getMyRequestStatus(slug); + + final List photos = await Future.wait( + myRequestStatus.photos.map( + (e) async => (await downloadImageAsFile(e.url)).path, + ), + ); + + List? certificates = myRequestStatus.educationModel.completedCourses?.map((courseMap) { + final course = courseMap.values.first; + + return CertificatesModel( + title: course.title, + date: course.date, + ); + }).toList(); + + String? sanitizeLink(String? link) { + return (link != null && link.isNotEmpty) ? link : null; + } + + emit( + RegisterConsultantState( + consultant: ConsultantProfileModel( + photos: photos, + certificates: certificates, + socialLinks: SocialLinksModel( + vkLink: sanitizeLink(myRequestStatus.educationModel.vkLink), + tgLink: sanitizeLink(myRequestStatus.educationModel.tgLink), + fbLink: sanitizeLink(myRequestStatus.educationModel.fbLink), + instaLink: sanitizeLink(myRequestStatus.educationModel.instaLink), + personalSiteLink: sanitizeLink(myRequestStatus.educationModel.personalSiteLink), + ), + hasMedicalEducation: myRequestStatus.educationModel.hasMedicalEducation == 1, + ), + acceptOffer: false, + loading: false, + ), + ); + } + + disableLoading() { + emit(state.copyWith(loading: false)); + } + updateConsultantProfileModel(ConsultantProfileModel consultant, [bool acceptOffer = false]) { - emit(RegisterConsultantState(consultant: consultant, acceptOffer: acceptOffer)); + emit(RegisterConsultantState(consultant: consultant, acceptOffer: acceptOffer, loading: false)); } registerConsultant() async { @@ -35,7 +98,7 @@ class RegisterConsultantCubit extends Cubit { ), ); } - await consultantRepository.registerConsultant(consultant: state.consultant); + await consultantRepository.registerConsultant(consultant: state.consultant, update: _update); } Future> uploadPhotos(List files) async { diff --git a/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart b/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart index 5f318efe..32f495d9 100644 --- a/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart +++ b/lib/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart @@ -8,5 +8,6 @@ abstract class RegisterConsultantState with _$RegisterConsultantState { const factory RegisterConsultantState({ required ConsultantProfileModel consultant, required bool acceptOffer, + required bool loading, }) = _RegisterConsultantState; } diff --git a/lib/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen.dart b/lib/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen.dart index 6e49d3b3..3b877c4d 100644 --- a/lib/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen.dart +++ b/lib/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen.dart @@ -30,19 +30,20 @@ class _CertificatesAndDiplomasScreenState extends State().state.consultant.certificates != null) { - diplomasList = context - .read() - .state - .consultant - .certificates! - .map( - (e) => DiplomaEntity( - date: DateTime.tryParse(e.date), - textEditingController: TextEditingController(text: e.title), - enableDeleteButton: true, + diplomasList = [ + ...context.read().state.consultant.certificates!.map( + (e) => DiplomaEntity( + date: DateTime.tryParse(e.date), + textEditingController: TextEditingController(text: e.title), + enableDeleteButton: true, + ), ), - ) - .toList(); + DiplomaEntity( + textEditingController: TextEditingController(), + enableDeleteButton: false, + date: null, + ), + ]; diplomasList.last.enableDeleteButton = false; } } diff --git a/lib/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen.dart b/lib/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen.dart index 28692a4c..b49610fc 100644 --- a/lib/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen.dart +++ b/lib/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen.dart @@ -1,5 +1,7 @@ import 'package:eatvio_app/core/utils/image_constant.dart'; +import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_cubit.dart'; +import 'package:eatvio_app/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart'; import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/additional_settings_screen.dart'; import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen.dart'; import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/last_step_screen.dart'; @@ -15,7 +17,9 @@ import 'package:go_router/go_router.dart'; import 'package:lottie/lottie.dart'; class StepperBecomeConsultantScreen extends StatefulWidget { - const StepperBecomeConsultantScreen({super.key}); + final String? slug; + + const StepperBecomeConsultantScreen({super.key, this.slug}); @override State createState() => _StepperBecomeConsultantScreenState(); @@ -25,249 +29,271 @@ class _StepperBecomeConsultantScreenState extends State(); + late final RegisterConsultantCubit registrationConsultantCubit; bool isLoading = false; + @override + void initState() { + super.initState(); + if (widget.slug == null) { + registrationConsultantCubit = sl()..disableLoading(); + } else { + registrationConsultantCubit = sl()..getMyRequestStatus(widget.slug!); + } + } + @override Widget build(BuildContext context) { return BlocProvider( create: (context) => registrationConsultantCubit, - child: Scaffold( - floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, - floatingActionButton: Row( - children: [ - Container( - height: 48, - width: MediaQuery.of(context).size.width * 0.2, - padding: const EdgeInsets.only(left: 16, right: 4), - child: FloatingActionButton.extended( - heroTag: 'backButtonRegistration', - highlightElevation: 0, - focusElevation: 0, - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), - ), - backgroundColor: const Color(0xFFEAF2FD), - onPressed: () async { - setState(() { - pageController.previousPage( - duration: const Duration(milliseconds: 350), - curve: Curves.easeInOut, - ); - }); - }, - label: Icon( - Icons.arrow_back_ios_new_rounded, - color: appTheme.blueA400, - ), - ), - ), - Container( - height: 48, - width: MediaQuery.of(context).size.width * 0.8, - padding: const EdgeInsets.only(left: 4, right: 16), - child: FloatingActionButton.extended( - heroTag: 'nextButtonRegistration', - highlightElevation: 0, - elevation: 0, - focusElevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), - ), - backgroundColor: isLoading ? Colors.grey : appTheme.blueA400, - onPressed: isLoading - ? null - : () async { - if (step == 6) { - if (registrationConsultantCubit.state.acceptOffer) { - setState(() { - isLoading = true; - }); - try { - await registrationConsultantCubit.registerConsultant(); - if (!context.mounted) return; - await showModalBottomSheet( - useRootNavigator: true, - showDragHandle: true, - context: context, - builder: (context) => Container( - padding: const EdgeInsets.all(16), - width: MediaQuery.of(context).size.width, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text( - 'Спасибо!\nВаши данные отправлены на модерацию', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20, - height: 1, - fontWeight: FontWeight.w600, - ), - ), - const SizedBox(height: 16), - Lottie.asset( - 'assets/lottie_animations/success.json', - width: 160, - height: 160, - ), - const SizedBox(height: 16), - const Text( - 'В течении трех рабочих дней Вам придет уведомление о смене статуса', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - height: 1, - fontWeight: FontWeight.w500, - ), - ), - const SizedBox(height: 16), - InkWell( - onTap: () { - Navigator.of(context).pop(); - GoRouter.of(context).pop(); - }, - child: Ink( - width: MediaQuery.of(context).size.width - 32, - height: 52, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: appTheme.blueA400, - ), - child: const Center( - child: Text( - 'Закрыть', + child: BlocBuilder( + builder: (context, state) { + if (state.loading == false) { + return Scaffold( + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: Row( + children: [ + Container( + height: 48, + width: MediaQuery.of(context).size.width * 0.2, + padding: const EdgeInsets.only(left: 16, right: 4), + child: FloatingActionButton.extended( + heroTag: 'backButtonRegistration', + highlightElevation: 0, + focusElevation: 0, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + backgroundColor: const Color(0xFFEAF2FD), + onPressed: () async { + setState(() { + pageController.previousPage( + duration: const Duration(milliseconds: 350), + curve: Curves.easeInOut, + ); + }); + }, + label: Icon( + Icons.arrow_back_ios_new_rounded, + color: appTheme.blueA400, + ), + ), + ), + Container( + height: 48, + width: MediaQuery.of(context).size.width * 0.8, + padding: const EdgeInsets.only(left: 4, right: 16), + child: FloatingActionButton.extended( + heroTag: 'nextButtonRegistration', + highlightElevation: 0, + elevation: 0, + focusElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + backgroundColor: isLoading ? Colors.grey : appTheme.blueA400, + onPressed: isLoading + ? null + : () async { + if (step == 6) { + if (registrationConsultantCubit.state.acceptOffer) { + setState(() { + isLoading = true; + }); + try { + await registrationConsultantCubit.registerConsultant(); + if (!context.mounted) return; + await showModalBottomSheet( + useRootNavigator: true, + showDragHandle: true, + context: context, + builder: (context) => Container( + padding: const EdgeInsets.all(16), + width: MediaQuery.of(context).size.width, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + 'Спасибо!\nВаши данные отправлены на модерацию', + textAlign: TextAlign.center, style: TextStyle( - color: Colors.white, - fontSize: 18, + fontSize: 20, + height: 1, fontWeight: FontWeight.w600, ), ), - ), + const SizedBox(height: 16), + Lottie.asset( + 'assets/lottie_animations/success.json', + width: 160, + height: 160, + ), + const SizedBox(height: 16), + const Text( + 'В течении трех рабочих дней Вам придет уведомление о смене статуса', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + height: 1, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(height: 16), + InkWell( + onTap: () { + Navigator.of(context).pop(); + GoRouter.of(context).pop(); + }, + child: Ink( + width: MediaQuery.of(context).size.width - 32, + height: 52, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: appTheme.blueA400, + ), + child: const Center( + child: Text( + 'Закрыть', + style: TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ), + ], ), ), - ], - ), - ), - ); - } catch (e) { - if (!context.mounted) return; - showDialog( - context: context, - builder: (context) => AlertDialog( - actionsPadding: const EdgeInsets.symmetric(horizontal: 4), - content: Text(e.toString()), - actions: [ - TextButton( - child: const Text('Ок'), - onPressed: () { - Navigator.of(context).pop(); - }, + ); + } catch (e) { + if (!context.mounted) return; + showDialog( + context: context, + builder: (context) => AlertDialog( + actionsPadding: const EdgeInsets.symmetric(horizontal: 4), + content: Text(e.toString()), + actions: [ + TextButton( + child: const Text('Ок'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ), + ); + } finally { + setState(() { + isLoading = false; + }); + } + } else { + showDialog( + context: context, + builder: (context) => AlertDialog( + actionsPadding: const EdgeInsets.symmetric(horizontal: 4), + content: const Text('Примите договор публичной офёрты'), + actions: [ + TextButton( + child: const Text('Ок'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], ), - ], - ), - ); - } finally { - setState(() { - isLoading = false; - }); - } - } else { - showDialog( - context: context, - builder: (context) => AlertDialog( - actionsPadding: const EdgeInsets.symmetric(horizontal: 4), - content: const Text('Примите договор публичной офёрты'), - actions: [ - TextButton( - child: const Text('Ок'), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - } - } else { - FocusManager.instance.primaryFocus?.unfocus(); - setState(() { - pageController.nextPage( - duration: const Duration(milliseconds: 350), - curve: Curves.easeInOut, - ); - }); - } - }, - label: isLoading ? const CircularProgressIndicator() : Text( - 'Продолжить', - style: theme.textTheme.titleSmall!.copyWith(color: Colors.white), + ); + } + } else { + FocusManager.instance.primaryFocus?.unfocus(); + setState(() { + pageController.nextPage( + duration: const Duration(milliseconds: 350), + curve: Curves.easeInOut, + ); + }); + } + }, + label: isLoading + ? const CircularProgressIndicator() + : Text( + 'Продолжить', + style: theme.textTheme.titleSmall!.copyWith(color: Colors.white), + ), + ), + ), + ], + ), + appBar: AppBar( + automaticallyImplyLeading: false, + leading: Builder( + builder: (context) => IconButton( + icon: const Icon(Icons.close_rounded), + onPressed: () => GoRouter.of(context).pop(), + ), + ), + centerTitle: true, + title: SvgPicture.asset( + ImageConstant.imgLogoEatvio, + height: 48, + fit: BoxFit.contain, + ), + actions: [ + Padding( + padding: const EdgeInsets.only(right: 16), + child: Text('шаг $step из 6'), + ), + ], + bottom: PreferredSize( + preferredSize: Size(MediaQuery.of(context).size.width, 32), + child: Padding( + padding: const EdgeInsets.all(16), + child: TweenAnimationBuilder( + duration: const Duration(milliseconds: 350), + curve: Curves.easeInOut, + tween: Tween( + begin: 1 / 6, + end: progressValue, + ), + builder: (context, value, _) => LinearProgressIndicator( + value: value, + borderRadius: BorderRadius.circular(16), + minHeight: 8, + backgroundColor: Colors.grey.shade100, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), ), ), - ), - ], - ), - appBar: AppBar( - automaticallyImplyLeading: false, - leading: Builder( - builder: (context) => IconButton( - icon: const Icon(Icons.close_rounded), - onPressed: () => GoRouter.of(context).pop(), - ), - ), - centerTitle: true, - title: SvgPicture.asset( - ImageConstant.imgLogoEatvio, - height: 48, - fit: BoxFit.contain, - ), - actions: [ - Padding( - padding: const EdgeInsets.only(right: 16), - child: Text('шаг $step из 6'), - ), - ], - bottom: PreferredSize( - preferredSize: Size(MediaQuery.of(context).size.width, 32), - child: Padding( - padding: const EdgeInsets.all(16), - child: TweenAnimationBuilder( - duration: const Duration(milliseconds: 350), - curve: Curves.easeInOut, - tween: Tween( - begin: 1 / 6, - end: progressValue, - ), - builder: (context, value, _) => LinearProgressIndicator( - value: value, - borderRadius: BorderRadius.circular(16), - minHeight: 8, - backgroundColor: Colors.grey.shade100, - valueColor: AlwaysStoppedAnimation(appTheme.blueA400), - ), + body: PageView( + physics: const NeverScrollableScrollPhysics(), + controller: pageController, + onPageChanged: (index) { + setState(() { + step = index + 1; + progressValue = step / 6; + }); + }, + children: const [ + CertificatesAndDiplomasScreen(), + PhotoOrScansScreen(), + AdditionalSettingsScreen(), + SocialNetworksScreen(), + RegistrationAsScreen(), + LastStepScreen(), + ], ), - ), - ), - ), - body: PageView( - physics: const NeverScrollableScrollPhysics(), - controller: pageController, - onPageChanged: (index) { - setState(() { - step = index + 1; - progressValue = step / 6; - }); - }, - children: const [ - CertificatesAndDiplomasScreen(), - PhotoOrScansScreen(), - AdditionalSettingsScreen(), - SocialNetworksScreen(), - RegistrationAsScreen(), - LastStepScreen(), - ], - ), + ); + } else { + return const Scaffold( + body: Loader(), + ); + } + }, ), ); } diff --git a/lib/features/consultant/become_consultant/repositories/consultant_repository.dart b/lib/features/consultant/become_consultant/repositories/consultant_repository.dart index 6af88cb5..89eef1c8 100644 --- a/lib/features/consultant/become_consultant/repositories/consultant_repository.dart +++ b/lib/features/consultant/become_consultant/repositories/consultant_repository.dart @@ -14,11 +14,18 @@ class ConsultantRepository { Future registerConsultant({ required ConsultantProfileModel consultant, + bool update = false, }) async { try { - return await consultantService.consultantRegistration( - consultantModel: consultant, - ); + if (update) { + return await consultantService.consultantUpdate( + consultantModel: consultant, + ); + } else { + return await consultantService.consultantRegistration( + consultantModel: consultant, + ); + } } catch (e) { rethrow; } @@ -57,4 +64,12 @@ class ConsultantRepository { rethrow; } } + + Future getMyRequestStatus(String slug) async { + try { + return await consultantService.getMyRequestStatus(slug: slug); + } catch (e) { + rethrow; + } + } } diff --git a/lib/features/consultant/become_consultant/services/consultant_service.dart b/lib/features/consultant/become_consultant/services/consultant_service.dart index fbf7541d..bfde5a92 100644 --- a/lib/features/consultant/become_consultant/services/consultant_service.dart +++ b/lib/features/consultant/become_consultant/services/consultant_service.dart @@ -24,4 +24,14 @@ abstract class ConsultantService { Future getConsultantRequestStatus({ @Path() required String slug, }); + + @GET('/api/consultant_request/{slug}/status') + Future getMyRequestStatus({ + @Path() required String slug, + }); + + @PUT('/api/consultant_request/update') + Future consultantUpdate({ + @Body() required ConsultantProfileModel consultantModel, + }); } diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart index 174500c1..6c91bbff 100644 --- a/lib/features/profile/presentation/pages/profile_screen.dart +++ b/lib/features/profile/presentation/pages/profile_screen.dart @@ -449,12 +449,17 @@ class _ProfileScreenState extends State { fontWeight: FontWeight.w600, ), ), - Text( - widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', - style: const TextStyle( - color: Color(0xFF2F80ED), - fontSize: 16, - fontWeight: FontWeight.w500, + GestureDetector( + onTap: () { + GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug); + }, + child: Text( + widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', + style: const TextStyle( + color: Color(0xFF2F80ED), + fontSize: 16, + fontWeight: FontWeight.w500, + ), ), ), ], @@ -544,12 +549,17 @@ class _ProfileScreenState extends State { fontWeight: FontWeight.w600, ), ), - Text( - widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', - style: const TextStyle( - color: Color(0xFF2F80ED), - fontSize: 16, - fontWeight: FontWeight.w500, + GestureDetector( + onTap: () { + GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug); + }, + child: Text( + widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', + style: const TextStyle( + color: Color(0xFF2F80ED), + fontSize: 16, + fontWeight: FontWeight.w500, + ), ), ), ],