forked from eatvio/eatvio_app
feat(consultant_registration): added new consultant registration flow
This commit is contained in:
@@ -4,6 +4,7 @@ import 'package:eatvio_app/core/app_router.dart';
|
||||
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
|
||||
import 'package:eatvio_app/core/utils/toasts.dart';
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_cert_photo_model.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart';
|
||||
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart';
|
||||
@@ -24,13 +25,20 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
try {
|
||||
final profile = await profileRepository.getProfileBySlug(slug);
|
||||
final myProfile = await profileRepository.getMyProfile();
|
||||
final isMyProfile = myProfile.slug == profile.slug;
|
||||
List<ConsultantCertPhotoModel> certPhotos = [];
|
||||
if (isMyProfile) {
|
||||
certPhotos = await consultantRepository.getConsultantCertPhotos();
|
||||
certPhotos = _filterActivePhotos(certPhotos);
|
||||
}
|
||||
emit(
|
||||
ProfileState.loaded(
|
||||
profile: profile,
|
||||
isMyProfile: myProfile.slug == profile.slug,
|
||||
isMyProfile: isMyProfile,
|
||||
profileDetails: await profileRepository.getProfileDetailsBySlug(slug),
|
||||
blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: slug),
|
||||
consultantInfo: profile.roles.contains('consultant') ? await consultantRepository.getConsultantRequestStatus(slug) : null,
|
||||
certPhotos: certPhotos,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
@@ -44,6 +52,8 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
_currentPeriod = period;
|
||||
try {
|
||||
final profile = await profileRepository.getMyProfile();
|
||||
List<ConsultantCertPhotoModel> certPhotos = await consultantRepository.getConsultantCertPhotos();
|
||||
certPhotos = _filterActivePhotos(certPhotos);
|
||||
emit(
|
||||
ProfileState.loaded(
|
||||
profile: profile,
|
||||
@@ -53,6 +63,7 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
weightPoints: await profileRepository.getWeight(period: period),
|
||||
circumferencePoints: await profileRepository.getCircumferences(period: period),
|
||||
consultantInfo: profile.roles.contains('consultant') ? await consultantRepository.getConsultantRequestStatus(profile.slug) : null,
|
||||
certPhotos: certPhotos,
|
||||
),
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
@@ -77,6 +88,7 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
circumferencePoints: (state as ProfileStateLoaded).circumferencePoints,
|
||||
consultantInfo: (state as ProfileStateLoaded).consultantInfo,
|
||||
isMyProfile: (state as ProfileStateLoaded).isMyProfile,
|
||||
certPhotos: (state as ProfileStateLoaded).certPhotos,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -131,4 +143,36 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
await profileRepository.deletePhoto();
|
||||
return await getMyProfile();
|
||||
}
|
||||
|
||||
Future<void> hideCertPhoto(int id) async {
|
||||
try {
|
||||
await consultantRepository.hideConsultantCertPhoto(id);
|
||||
List<ConsultantCertPhotoModel> certPhotos = await consultantRepository.getConsultantCertPhotos();
|
||||
certPhotos = _filterActivePhotos(certPhotos);
|
||||
final currentState = state;
|
||||
if (currentState is ProfileStateLoaded) {
|
||||
emit(currentState.copyWith(certPhotos: certPhotos));
|
||||
}
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unhideCertPhoto(int id) async {
|
||||
try {
|
||||
await consultantRepository.unHideConsultantCertPhoto(id);
|
||||
List<ConsultantCertPhotoModel> certPhotos = await consultantRepository.getConsultantCertPhotos();
|
||||
certPhotos = _filterActivePhotos(certPhotos);
|
||||
final currentState = state;
|
||||
if (currentState is ProfileStateLoaded) {
|
||||
emit(currentState.copyWith(certPhotos: certPhotos));
|
||||
}
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
List<ConsultantCertPhotoModel> _filterActivePhotos(List<ConsultantCertPhotoModel> photos) {
|
||||
return photos.where((photo) => photo.isActive).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_cert_photo_model.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart';
|
||||
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
|
||||
@@ -18,6 +19,7 @@ abstract class ProfileState with _$ProfileState {
|
||||
required ProfileDetailsModel profileDetails,
|
||||
required List<FeedBlogPostModel> blogPosts,
|
||||
required bool isMyProfile,
|
||||
required List<ConsultantCertPhotoModel> certPhotos,
|
||||
List<WeightModel>? weightPoints,
|
||||
List<CircumferenceModel>? circumferencePoints,
|
||||
ConsultationRequestModel? consultantInfo,
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:eatvio_app/core/enums/complained_content.dart';
|
||||
import 'package:eatvio_app/core/permission_handler/permission_handler.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||||
import 'package:eatvio_app/core/widgets/bottom_sheet_with_blur.dart';
|
||||
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart';
|
||||
@@ -26,6 +27,7 @@ import 'package:eatvio_app/features/profile/presentation/pages/subs_screen.dart'
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/circumference_chart_widget.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/imt_chart_widget.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/profile_blog_post_widget.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/toggle_cert_photo_bottom_sheet.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/weight_chart_widget.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
@@ -117,7 +119,6 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return state.isMyProfile ? _myProfileScreen(state) : _profileScreen(state);
|
||||
} else if (state is ProfileStateError) {
|
||||
return Scaffold(
|
||||
@@ -436,9 +437,16 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
}
|
||||
|
||||
SingleChildRenderObjectWidget _diplomasAndCertificates(ProfileStateLoaded state) {
|
||||
if (!state.profile.roles.contains('consultant') || state.consultantInfo!.photos.isEmpty) {
|
||||
if (!state.profile.roles.contains('consultant')) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
if (state.isMyProfile && state.certPhotos.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
if (!state.isMyProfile && state.consultantInfo!.photos.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: Column(
|
||||
@@ -454,7 +462,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug);
|
||||
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: {'slug': state.profile.slug});
|
||||
},
|
||||
child: Text(
|
||||
state.isMyProfile ? 'Редактировать' : '',
|
||||
@@ -477,14 +485,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
if (state.consultantInfo!.photos.isNotEmpty)
|
||||
...List.generate(state.consultantInfo!.photos.length * 2 - 1, (index) {
|
||||
if (index.isEven) {
|
||||
final photo = state.consultantInfo!.photos[index ~/ 2];
|
||||
return _diplomaImage(photo.url);
|
||||
} else {
|
||||
return const SizedBox(width: 8);
|
||||
}
|
||||
if (state.isMyProfile && state.certPhotos.isNotEmpty)
|
||||
...List.generate(state.certPhotos.length, (index) {
|
||||
final photo = state.certPhotos[index];
|
||||
return Row(children: [_diplomaImage(photo.url, state.isMyProfile, photo.isHidden, photo.id), const SizedBox(width: 8)]);
|
||||
})
|
||||
else if (state.consultantInfo!.photos.isNotEmpty)
|
||||
...List.generate(state.consultantInfo!.photos.length, (index) {
|
||||
final photo = state.consultantInfo!.photos[index];
|
||||
return Row(children: [_diplomaImage(photo.url, state.isMyProfile, false, null), const SizedBox(width: 8)]);
|
||||
}),
|
||||
],
|
||||
),
|
||||
@@ -496,16 +505,49 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
GestureDetector _diplomaImage(String url) {
|
||||
GestureDetector _diplomaImage(String url, bool isMyProfile, bool isHidden, int? certPhotoId) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context.pushTransparentRoute(rootNavigator: true, PhotoViewScreen(imageUrls: [url], index: 0));
|
||||
},
|
||||
child: Hero(
|
||||
tag: url,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: CachedNetworkImage(imageUrl: url, fit: BoxFit.fitHeight, width: MediaQuery.of(context).size.width / 3 - (60 / 3), height: 160),
|
||||
child: Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: CachedNetworkImage(imageUrl: url, fit: BoxFit.fill, width: MediaQuery.of(context).size.width / 3 - (60 / 3), height: 160),
|
||||
),
|
||||
if (isMyProfile)
|
||||
Positioned(
|
||||
right: 4,
|
||||
top: 4,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
if (certPhotoId != null) {
|
||||
showBottomSheetWithBlur(
|
||||
userRootNavigator: true,
|
||||
context: context,
|
||||
height: 250,
|
||||
child: ToggleCertPhotoBottomSheet(profileCubit: profileCubit, isPhotoHidden: isHidden, id: certPhotoId),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: appTheme.whiteA700, borderRadius: BorderRadius.circular(4)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 5),
|
||||
child: SvgPicture.asset(
|
||||
isHidden ? 'assets/icons/crossed_eye.svg' : 'assets/icons/eye2.svg',
|
||||
width: 10,
|
||||
height: 8,
|
||||
colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -532,7 +574,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug);
|
||||
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: {'slug': state.profile.slug});
|
||||
},
|
||||
child: Text(
|
||||
state.isMyProfile ? 'Редактировать' : '',
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import 'package:eatvio_app/core/app_router.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class ToggleCertPhotoBottomSheet extends StatelessWidget {
|
||||
const ToggleCertPhotoBottomSheet({super.key, required this.profileCubit, required this.isPhotoHidden, required this.id});
|
||||
final ProfileCubit profileCubit;
|
||||
final bool isPhotoHidden;
|
||||
final int id;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = S.of(context);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
const BottomSheetHandlerBar(),
|
||||
const SizedBox(height: 20),
|
||||
Text(isPhotoHidden ? s.unhide_photo_title : s.hide_photo_title, style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
|
||||
Text(
|
||||
isPhotoHidden ? s.unhide_photo_description : s.hide_photo_description,
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: CustomOutlinedButton(
|
||||
onPressed: () async {
|
||||
if (isPhotoHidden) {
|
||||
await profileCubit.unhideCertPhoto(id);
|
||||
AppRouter.navigatorKey.currentContext?.pop();
|
||||
return;
|
||||
}
|
||||
await profileCubit.hideCertPhoto(id);
|
||||
AppRouter.navigatorKey.currentContext?.pop();
|
||||
return;
|
||||
},
|
||||
text: s.ok,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textSSemibold.copyWith(color: appTheme.whiteA700),
|
||||
buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user