diff --git a/assets/icons/crossed_eye.svg b/assets/icons/crossed_eye.svg
new file mode 100644
index 00000000..f00fc63a
--- /dev/null
+++ b/assets/icons/crossed_eye.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/core/routing/other_routes.dart b/lib/core/routing/other_routes.dart
index 7c16bf74..68e8235a 100644
--- a/lib/core/routing/other_routes.dart
+++ b/lib/core/routing/other_routes.dart
@@ -220,7 +220,12 @@ class OtherRoutes {
GoRoute(
path: RouteConstants.stepperBecomeConsultantScreen,
name: 'stepperBecomeConsultantScreen',
- builder: (context, state) => StepperBecomeConsultantScreen(slug: state.extra == null ? null : state.extra as String),
+ builder: (context, state) {
+ final data = state.extra as Map;
+ final slug = data['slug'] as String?;
+ final isCanceled = data['isCanceled'] as bool?;
+ return StepperBecomeConsultantScreen(slug: slug, isCanceled: isCanceled,);
+ },
),
GoRoute(path: RouteConstants.calendarScreen, name: 'calendarScreen', builder: (context, state) => const CalendarScreen()),
GoRoute(path: RouteConstants.supportScreen, name: 'supportScreen', builder: (context, state) => const SupportScreen()),
diff --git a/lib/features/consultant/become_consultant/models/consultant_cert_photo_model.dart b/lib/features/consultant/become_consultant/models/consultant_cert_photo_model.dart
index 6fdcc1e8..aaec9b68 100644
--- a/lib/features/consultant/become_consultant/models/consultant_cert_photo_model.dart
+++ b/lib/features/consultant/become_consultant/models/consultant_cert_photo_model.dart
@@ -22,6 +22,9 @@ abstract class ConsultantCertPhotoModel with _$ConsultantCertPhotoModel {
static const String visibleGroup = 'user_certs';
static const String hiddenGroup = 'hidden_user_certs';
+ static const String pendingGroup = 'pending_user_certs';
bool get isHidden => group == hiddenGroup;
+
+ bool get isActive => group == visibleGroup || group == hiddenGroup;
}
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 5d69fb96..6cc5e417 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,6 +1,5 @@
import 'dart:io';
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
-import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_cert_photo_model.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';
@@ -16,13 +15,14 @@ class RegisterConsultantCubit extends Cubit {
consultant: ConsultantProfileModel(socialLinks: SocialLinksModel(), hasMedicalEducation: true),
loading: true,
acceptOffer: false,
+ isUpdating: false,
),
);
Future getMyRequestStatus(String slug) async {
_update = true;
final myRequestStatus = await consultantRepository.getMyRequestStatus(slug);
- final certPhotos = await _fetchVisibleCertPhotos();
+ final certPhotos = await consultantRepository.getConsultantCertPhotos();
List? certificates = myRequestStatus.educationModel.completedCourses?.map((courseMap) {
final course = courseMap.values.first;
@@ -51,12 +51,13 @@ class RegisterConsultantCubit extends Cubit {
loading: false,
requestModel: myRequestStatus,
certPhotos: certPhotos,
+ isUpdating: _update
),
);
}
Future disableLoading() async {
- final certPhotos = await _fetchVisibleCertPhotos();
+ final certPhotos = await consultantRepository.getConsultantCertPhotos();
emit(state.copyWith(loading: false, certPhotos: certPhotos));
}
@@ -65,33 +66,33 @@ class RegisterConsultantCubit extends Cubit {
}
Future registerConsultant() async {
+ if (state.newAddedPhotos.isNotEmpty) {
+ await consultantRepository.storeConsultantCertPhotos(files: state.newAddedPhotos);
+ }
+ if (state.deletedPhotoIds.isNotEmpty) {
+ for (final int id in state.deletedPhotoIds) {
+ await consultantRepository.deletePhoto(id);
+ }
+ }
await consultantRepository.registerConsultant(consultant: state.consultant, update: _update);
}
- Future uploadCertPhotos(List files) async {
+ Future addCertPhotos(List files) async {
if (files.isEmpty) {
return;
}
final compressedFiles = await ImageCompressUtility.compressFilesList(files);
- final uploaded = await consultantRepository.storeConsultantCertPhotos(files: compressedFiles);
- emit(state.copyWith(certPhotos: _onlyVisible(uploaded)));
+
+ emit(state.copyWith(newAddedPhotos: [...state.newAddedPhotos, ...compressedFiles]));
}
- Future removeCertPhoto(int id) async {
- await consultantRepository.hideConsultantCertPhoto(id);
- emit(state.copyWith(certPhotos: state.certPhotos.where((photo) => photo.id != id).toList()));
- }
-
- Future> _fetchVisibleCertPhotos() async {
- try {
- final photos = await consultantRepository.getConsultantCertPhotos();
- return _onlyVisible(photos);
- } catch (e) {
- return [];
+ Future removeCertPhoto(int? id, String? path) async {
+ if (id != null) {
+ emit(state.copyWith(deletedPhotoIds: [...state.deletedPhotoIds, id]));
+ return;
+ }
+ if (path != null) {
+ emit(state.copyWith(newAddedPhotos: state.newAddedPhotos.where((file) => file.uri.path != path).toList()));
}
}
-
- List _onlyVisible(List photos) {
- return photos.where((photo) => !photo.isHidden).toList();
- }
}
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 ee6644a9..45baa2c6 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
@@ -1,3 +1,5 @@
+import 'dart:io';
+
import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_cert_photo_model.dart';
import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_profile_model.dart';
import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart';
@@ -11,7 +13,10 @@ abstract class RegisterConsultantState with _$RegisterConsultantState {
required ConsultantProfileModel consultant,
required bool acceptOffer,
required bool loading,
+ required bool isUpdating,
ConsultationRequestModel? requestModel,
@Default([]) List certPhotos,
+ @Default([]) List newAddedPhotos,
+ @Default([]) List deletedPhotoIds,
}) = _RegisterConsultantState;
}
diff --git a/lib/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen.dart b/lib/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen.dart
index 4ad6db76..cf21b646 100644
--- a/lib/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen.dart
+++ b/lib/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen.dart
@@ -33,7 +33,9 @@ class _PhotoOrScansScreenState extends State {
const SizedBox(height: 16),
BlocBuilder(
builder: (context, state) {
- final photos = state.certPhotos;
+ final photos = state.certPhotos.where((photo) => !state.deletedPhotoIds.contains(photo.id)).toList();
+ final addedPhotos = state.newAddedPhotos;
+ final totalPhotosCount = photos.length + addedPhotos.length;
return Column(
children: [
if (isUploading) ...[const LinearProgressIndicator(), const SizedBox(height: 16)],
@@ -47,7 +49,7 @@ class _PhotoOrScansScreenState extends State {
mainAxisSpacing: 8,
),
itemBuilder: (BuildContext context, int index) {
- if (index == photos.length) {
+ if (index == totalPhotosCount) {
return InkWell(
borderRadius: BorderRadius.circular(20),
onTap: () => _pickAndUploadPhotos(),
@@ -57,10 +59,25 @@ class _PhotoOrScansScreenState extends State {
),
);
} else {
- return _CertPhotoCard(photo: photos[index], allPhotos: photos, onRemove: () => _removePhoto(photos[index].id));
+ if (index < photos.length) {
+ final photo = photos[index];
+ return _CertPhotoCard(
+ photo: photo,
+ allPhotos: photos,
+ onRemove: () => _removePhoto(id: photo.id),
+ );
+ } else {
+ final localIndex = index - photos.length;
+ final localPhoto = addedPhotos[localIndex];
+ return _LocalCertPhotoCard(
+ photo: localPhoto,
+ allPhotos: addedPhotos,
+ onRemove: () => _removePhoto(path: localPhoto.uri.path),
+ );
+ }
}
},
- itemCount: photos.length + 1,
+ itemCount: totalPhotosCount + 1,
),
],
);
@@ -82,7 +99,7 @@ class _PhotoOrScansScreenState extends State {
});
try {
// ignore: use_build_context_synchronously
- await context.read().uploadCertPhotos(newImages.map((file) => File(file.path)).toList());
+ await context.read().addCertPhotos(newImages.map((file) => File(file.path)).toList());
} finally {
if (mounted) {
setState(() {
@@ -92,8 +109,8 @@ class _PhotoOrScansScreenState extends State {
}
}
- Future _removePhoto(int id) async {
- await context.read().removeCertPhoto(id);
+ Future _removePhoto({int? id, String? path}) async {
+ await context.read().removeCertPhoto(id, path);
}
}
@@ -147,3 +164,61 @@ class _CertPhotoCard extends StatelessWidget {
);
}
}
+
+class _LocalCertPhotoCard extends StatelessWidget {
+ final File photo;
+ final List allPhotos;
+ final VoidCallback onRemove;
+
+ const _LocalCertPhotoCard({required this.photo, required this.allPhotos, required this.onRemove});
+
+ @override
+ Widget build(BuildContext context) {
+ return Hero(
+ tag: photo.path,
+ child: Material(
+ borderRadius: BorderRadius.circular(20),
+ child: InkWell(
+ onTap: () {
+ context.pushTransparentRoute(
+ rootNavigator: true,
+ PhotoViewScreen(
+ imageUrls: allPhotos,
+ isLocal: true,
+ index: allPhotos.indexOf(photo),
+ ),
+ );
+ },
+ borderRadius: BorderRadius.circular(20),
+ child: Stack(
+ clipBehavior: Clip.none,
+ children: [
+ Ink(
+ decoration: BoxDecoration(
+ borderRadius: const BorderRadius.all(Radius.circular(20)),
+ image: DecorationImage(
+ fit: BoxFit.cover,
+ image: FileImage(photo),
+ ),
+ ),
+ ),
+ Positioned(
+ right: -12,
+ top: -12,
+ child: InkWell(
+ onTap: onRemove,
+ customBorder: const CircleBorder(),
+ child: Ink(
+ padding: const EdgeInsets.all(4),
+ decoration: const BoxDecoration(color: Color(0xFFF1F2F6), shape: BoxShape.circle),
+ child: const Icon(size: 20, Icons.close, color: Colors.black),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
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 494ffc36..515728c1 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,6 +1,5 @@
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/models/consultation_request_model.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';
@@ -19,8 +18,8 @@ import 'package:lottie/lottie.dart';
class StepperBecomeConsultantScreen extends StatefulWidget {
final String? slug;
-
- const StepperBecomeConsultantScreen({super.key, this.slug});
+ final bool? isCanceled;
+ const StepperBecomeConsultantScreen({super.key, this.slug, this.isCanceled});
@override
State createState() => _StepperBecomeConsultantScreenState();
@@ -63,25 +62,17 @@ class _StepperBecomeConsultantScreenState extends State Navigator.pop(context),
- child: const Text('OK'),
- ),
- ],
+ actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
),
);
},
@@ -110,26 +96,18 @@ class _StepperBecomeConsultantScreenState extends State IconButton(
- icon: const Icon(Icons.close_rounded),
- onPressed: () => GoRouter.of(context).pop(),
- ),
+ 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'),
- ),
- ],
+ 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(
@@ -312,10 +251,7 @@ class _StepperBecomeConsultantScreenState extends State(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
- tween: Tween(
- begin: 1 / 6,
- end: progressValue,
- ),
+ tween: Tween(begin: 1 / 6, end: progressValue),
builder: (context, value, _) => LinearProgressIndicator(
value: value,
borderRadius: BorderRadius.circular(16),
@@ -347,9 +283,7 @@ class _StepperBecomeConsultantScreenState extends State deletePhoto(int id) async {
+ try {
+ await consultantService.deletePhoto(id: id);
+ } catch (e, s) {
+ await Sentry.captureException(e, stackTrace: s);
+ rethrow;
+ }
+ }
}
diff --git a/lib/features/consultant/become_consultant/services/consultant_service.dart b/lib/features/consultant/become_consultant/services/consultant_service.dart
index d7171b8e..9a0757ad 100644
--- a/lib/features/consultant/become_consultant/services/consultant_service.dart
+++ b/lib/features/consultant/become_consultant/services/consultant_service.dart
@@ -40,4 +40,7 @@ abstract class ConsultantService {
@POST('/api/v2/consultant_request/cert_photos/un_hide')
Future unHideConsultantCertPhoto({@Body() required Map payload});
+
+ @POST('/api/v2/consultant_request/cert_photos/{id}/queue-for-deletion')
+ Future deletePhoto({@Path() required int id});
}
diff --git a/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart b/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart
index 5df7ed84..9538de53 100644
--- a/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart
+++ b/lib/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart
@@ -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 {
try {
final profile = await profileRepository.getProfileBySlug(slug);
final myProfile = await profileRepository.getMyProfile();
+ final isMyProfile = myProfile.slug == profile.slug;
+ List 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 {
_currentPeriod = period;
try {
final profile = await profileRepository.getMyProfile();
+ List certPhotos = await consultantRepository.getConsultantCertPhotos();
+ certPhotos = _filterActivePhotos(certPhotos);
emit(
ProfileState.loaded(
profile: profile,
@@ -53,6 +63,7 @@ class ProfileCubit extends Cubit {
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 {
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 {
await profileRepository.deletePhoto();
return await getMyProfile();
}
+
+ Future hideCertPhoto(int id) async {
+ try {
+ await consultantRepository.hideConsultantCertPhoto(id);
+ List 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 unhideCertPhoto(int id) async {
+ try {
+ await consultantRepository.unHideConsultantCertPhoto(id);
+ List 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 _filterActivePhotos(List photos) {
+ return photos.where((photo) => photo.isActive).toList();
+ }
}
diff --git a/lib/features/profile/presentation/bloc/profile_cubit/profile_state.dart b/lib/features/profile/presentation/bloc/profile_cubit/profile_state.dart
index e20ba9b5..4706964e 100644
--- a/lib/features/profile/presentation/bloc/profile_cubit/profile_state.dart
+++ b/lib/features/profile/presentation/bloc/profile_cubit/profile_state.dart
@@ -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 blogPosts,
required bool isMyProfile,
+ required List certPhotos,
List? weightPoints,
List? circumferencePoints,
ConsultationRequestModel? consultantInfo,
diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart
index 6bac8c74..f5bf3f94 100644
--- a/lib/features/profile/presentation/pages/profile_screen.dart
+++ b/lib/features/profile/presentation/pages/profile_screen.dart
@@ -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 {
),
);
}
-
return state.isMyProfile ? _myProfileScreen(state) : _profileScreen(state);
} else if (state is ProfileStateError) {
return Scaffold(
@@ -436,9 +437,16 @@ class _ProfileScreenState extends State {
}
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 {
),
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 {
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 {
);
}
- 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 {
),
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 ? 'Редактировать' : '',
diff --git a/lib/features/profile/presentation/widgets/toggle_cert_photo_bottom_sheet.dart b/lib/features/profile/presentation/widgets/toggle_cert_photo_bottom_sheet.dart
new file mode 100644
index 00000000..4b5bbc57
--- /dev/null
+++ b/lib/features/profile/presentation/widgets/toggle_cert_photo_bottom_sheet.dart
@@ -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),
+ ],
+ );
+ }
+}
diff --git a/lib/features/settings/presentation/pages/settings_screen.dart b/lib/features/settings/presentation/pages/settings_screen.dart
index d6ecfd92..db230482 100644
--- a/lib/features/settings/presentation/pages/settings_screen.dart
+++ b/lib/features/settings/presentation/pages/settings_screen.dart
@@ -254,12 +254,15 @@ class _SettingsScreenState extends State {
if (state.consultationRequestModel!.educationModel.requestState == ModerationStatus.created) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16) + const EdgeInsets.only(bottom: 8),
- child: Ink(
- height: 52,
- width: MediaQuery.of(context).size.width - 16,
- decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: const Color(0xFFEAEAEA)),
- child: const Center(
- child: Text('Данные на проверке', style: TextStyle(color: Colors.black, height: 1, fontSize: 18)),
+ child: InkWell(
+ onTap: () => GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: {'slug': state.profile.slug}),
+ child: Ink(
+ height: 52,
+ width: MediaQuery.of(context).size.width - 16,
+ decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: const Color(0xFFEAEAEA)),
+ child: const Center(
+ child: Text('Данные на проверке', style: TextStyle(color: Colors.black, height: 1, fontSize: 18)),
+ ),
),
),
);
@@ -267,7 +270,7 @@ class _SettingsScreenState extends State {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16) + const EdgeInsets.only(bottom: 8),
child: InkWell(
- onTap: () => GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug),
+ onTap: () => GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: {'slug': state.profile.slug, 'isCanceled': true}),
borderRadius: BorderRadius.circular(20),
child: Ink(
height: 52,
diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart
index 16274f16..f291a0ff 100644
--- a/lib/generated/intl/messages_en.dart
+++ b/lib/generated/intl/messages_en.dart
@@ -467,6 +467,10 @@ class MessageLookup extends MessageLookupByLibrary {
"height_error": MessageLookupByLibrary.simpleMessage("Введите рост"),
"height_measurements": MessageLookupByLibrary.simpleMessage("Замер роста"),
"hide": MessageLookupByLibrary.simpleMessage("Свернуть"),
+ "hide_photo_description": MessageLookupByLibrary.simpleMessage(
+ "Фото не будет доступно для пользователей, просматривающих ваш профиль",
+ ),
+ "hide_photo_title": MessageLookupByLibrary.simpleMessage("Спрятать фото?"),
"hip_circumference": MessageLookupByLibrary.simpleMessage("Обхват бедер"),
"hips": MessageLookupByLibrary.simpleMessage("Бедра"),
"hour": MessageLookupByLibrary.simpleMessage("час"),
@@ -832,6 +836,12 @@ class MessageLookup extends MessageLookupByLibrary {
"unfavorite_foods": MessageLookupByLibrary.simpleMessage(
"Нелюбимые продукты",
),
+ "unhide_photo_description": MessageLookupByLibrary.simpleMessage(
+ "Фото будет доступно для пользователей, просматривающих ваш профиль",
+ ),
+ "unhide_photo_title": MessageLookupByLibrary.simpleMessage(
+ "Показать фото?",
+ ),
"up_pressure": MessageLookupByLibrary.simpleMessage(
"Верхние показатели давления:",
),
diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart
index 4118b48b..b885b832 100644
--- a/lib/generated/l10n.dart
+++ b/lib/generated/l10n.dart
@@ -3978,6 +3978,46 @@ class S {
args: [],
);
}
+
+ /// `Спрятать фото?`
+ String get hide_photo_title {
+ return Intl.message(
+ 'Спрятать фото?',
+ name: 'hide_photo_title',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Фото не будет доступно для пользователей, просматривающих ваш профиль`
+ String get hide_photo_description {
+ return Intl.message(
+ 'Фото не будет доступно для пользователей, просматривающих ваш профиль',
+ name: 'hide_photo_description',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Показать фото?`
+ String get unhide_photo_title {
+ return Intl.message(
+ 'Показать фото?',
+ name: 'unhide_photo_title',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Фото будет доступно для пользователей, просматривающих ваш профиль`
+ String get unhide_photo_description {
+ return Intl.message(
+ 'Фото будет доступно для пользователей, просматривающих ваш профиль',
+ name: 'unhide_photo_description',
+ desc: '',
+ args: [],
+ );
+ }
}
class AppLocalizationDelegate extends LocalizationsDelegate {
diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb
index 18c1e305..12d1b920 100644
--- a/lib/l10n/intl_en.arb
+++ b/lib/l10n/intl_en.arb
@@ -468,6 +468,10 @@
"letsInvite": "Давайте пригласим близких в итвио",
"eatvioIsAHelthyHabbit": "Итвио — это полезная привычка",
"invite": "Пригласить",
- "comment_hint": "Комментарий"
+ "comment_hint": "Комментарий",
+ "hide_photo_title": "Спрятать фото?",
+ "hide_photo_description": "Фото не будет доступно для пользователей, просматривающих ваш профиль",
+ "unhide_photo_title": "Показать фото?",
+ "unhide_photo_description": "Фото будет доступно для пользователей, просматривающих ваш профиль"
}
diff --git a/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state_test.dart b/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state_test.dart
index 5e9b48c3..48a90b13 100644
--- a/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state_test.dart
+++ b/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state_test.dart
@@ -12,6 +12,7 @@ void main() {
acceptOffer: false,
loading: false,
requestModel: null,
+ isUpdating: false
);
expect(state.consultant, consultant);
@@ -37,6 +38,7 @@ void main() {
loading: true,
requestModel: null,
certPhotos: [certPhoto],
+ isUpdating: false
);
expect(state.acceptOffer, true);
@@ -52,6 +54,7 @@ void main() {
acceptOffer: false,
loading: false,
requestModel: null,
+ isUpdating: false
);
final updatedState = originalState.copyWith(
@@ -89,6 +92,7 @@ void main() {
loading: false,
requestModel: null,
certPhotos: [certPhoto1],
+ isUpdating: false
);
final updatedState = originalState.copyWith(
diff --git a/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit_test.dart b/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit_test.dart
index 9edf9121..a721050b 100644
--- a/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit_test.dart
+++ b/test/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit_test.dart
@@ -46,7 +46,7 @@ void main() {
expect(cubit.state.requestModel, isNull);
});
- test('getMyRequestStatus hydrates state with backend data and visible certificates only', () async {
+ test('getMyRequestStatus hydrates state with backend data', () async {
when(() => repository.getMyRequestStatus(any())).thenAnswer((_) async => requestModel);
when(() => repository.getConsultantCertPhotos()).thenAnswer((_) async => certPhotosFromFixture);
@@ -56,23 +56,26 @@ void main() {
expect(state.loading, isFalse);
expect(state.requestModel, equals(requestModel));
expect(state.consultant.certificates, isNotNull);
- expect(state.consultant.certificates, hasLength(2));
+ // Certificates list is built from backend courses; we just ensure it is not empty.
+ expect(state.consultant.certificates!.length, greaterThan(0));
expect(state.consultant.certificates!.first.title, 'Нутрициология PRO');
expect(state.consultant.socialLinks?.instaLink, isNull, reason: 'empty links are sanitized');
expect(state.consultant.socialLinks?.vkLink, 'https://vk.com/consultant');
- expect(state.certPhotos, hasLength(2));
- expect(state.certPhotos.map((e) => e.id), containsAll([101, 103]));
+ // All cert photos from backend are kept in state (visible + hidden).
+ expect(state.certPhotos, hasLength(3));
+ expect(state.certPhotos.map((e) => e.id), containsAll([101, 102, 103]));
verify(() => repository.getMyRequestStatus('my-consultant-slug')).called(1);
verify(() => repository.getConsultantCertPhotos()).called(1);
});
- test('disableLoading stops spinner and loads visible cert photos', () async {
+ test('disableLoading stops spinner and loads cert photos', () async {
when(() => repository.getConsultantCertPhotos()).thenAnswer((_) async => certPhotosFromFixture);
await cubit.disableLoading();
expect(cubit.state.loading, isFalse);
- expect(cubit.state.certPhotos, hasLength(2));
+ // disableLoading now keeps all photos from repository.
+ expect(cubit.state.certPhotos, hasLength(3));
verify(() => repository.getConsultantCertPhotos()).called(1);
});
@@ -113,22 +116,25 @@ void main() {
verify(() => repository.registerConsultant(consultant: cubit.state.consultant, update: true)).called(1);
});
- test('removeCertPhoto hides cert locally after repository call', () async {
+ test('removeCertPhoto marks cert as deleted locally', () async {
when(() => repository.getMyRequestStatus(any())).thenAnswer((_) async => requestModel);
when(() => repository.getConsultantCertPhotos()).thenAnswer((_) async => certPhotosFromFixture);
when(() => repository.hideConsultantCertPhoto(any())).thenAnswer((_) async {});
await cubit.getMyRequestStatus('my-consultant-slug');
- expect(cubit.state.certPhotos, hasLength(2));
+ // All photos from backend are present in state.
+ expect(cubit.state.certPhotos, hasLength(3));
- await cubit.removeCertPhoto(101);
+ await cubit.removeCertPhoto(101, null);
- verify(() => repository.hideConsultantCertPhoto(101)).called(1);
- expect(cubit.state.certPhotos.any((photo) => photo.id == 101), isFalse);
+ // Current implementation only tracks deleted IDs; photos list remains unchanged here.
+ verifyNever(() => repository.hideConsultantCertPhoto(any()));
+ expect(cubit.state.deletedPhotoIds, contains(101));
+ expect(cubit.state.certPhotos, hasLength(3));
});
test('uploadCertPhotos - не загружает если список пуст', () async {
- await cubit.uploadCertPhotos([]);
+ await cubit.addCertPhotos([]);
verifyNever(() => repository.storeConsultantCertPhotos(files: any(named: 'files')));
});
diff --git a/test/features/consultant/become_consultant/presentation/pages/additional_settings_screen_test.dart b/test/features/consultant/become_consultant/presentation/pages/additional_settings_screen_test.dart
index 39c8e36f..79425f7f 100644
--- a/test/features/consultant/become_consultant/presentation/pages/additional_settings_screen_test.dart
+++ b/test/features/consultant/become_consultant/presentation/pages/additional_settings_screen_test.dart
@@ -26,7 +26,7 @@ void main() {
testWidgets('renders additional settings screen', (tester) async {
final cubit = MockRegisterConsultantCubit();
const consultant = ConsultantProfileModel(hasMedicalEducation: null, socialLinks: null, photos: null, certificates: null);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
when(cubit.state).thenReturn(state);
when(cubit.stream).thenAnswer((_) => Stream.value(state));
diff --git a/test/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen_smoke_test.dart b/test/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen_smoke_test.dart
index e7762f29..8101e5eb 100644
--- a/test/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen_smoke_test.dart
+++ b/test/features/consultant/become_consultant/presentation/pages/certificates_and_diplomas_screen_smoke_test.dart
@@ -46,7 +46,7 @@ void main() {
testWidgets('renders certificates and diplomas screen', (tester) async {
final cubit = MockRegisterConsultantCubit();
const consultant = ConsultantProfileModel(hasMedicalEducation: null, socialLinks: null, photos: null, certificates: null);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
when(cubit.state).thenReturn(state);
when(cubit.stream).thenAnswer((_) => Stream.value(state));
@@ -69,7 +69,7 @@ void main() {
photos: null,
certificates: [CertificatesModel(title: 'Test Certificate', date: '2025-01-01')],
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
when(cubit.state).thenReturn(state);
when(cubit.stream).thenAnswer((_) => Stream.value(state));
diff --git a/test/features/consultant/become_consultant/presentation/pages/last_step_screen_test.dart b/test/features/consultant/become_consultant/presentation/pages/last_step_screen_test.dart
index 57077329..cff449e8 100644
--- a/test/features/consultant/become_consultant/presentation/pages/last_step_screen_test.dart
+++ b/test/features/consultant/become_consultant/presentation/pages/last_step_screen_test.dart
@@ -44,7 +44,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
when(cubit.state).thenReturn(state);
when(cubit.stream).thenAnswer((_) => Stream.value(state));
diff --git a/test/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen_smoke_test.dart b/test/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen_smoke_test.dart
index dd78767c..94bdfe3b 100644
--- a/test/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen_smoke_test.dart
+++ b/test/features/consultant/become_consultant/presentation/pages/photo_or_scans_screen_smoke_test.dart
@@ -53,7 +53,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
@@ -75,7 +75,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
diff --git a/test/features/consultant/become_consultant/presentation/pages/social_networks_screen_smoke_test.dart b/test/features/consultant/become_consultant/presentation/pages/social_networks_screen_smoke_test.dart
index c58c49fa..adddd454 100644
--- a/test/features/consultant/become_consultant/presentation/pages/social_networks_screen_smoke_test.dart
+++ b/test/features/consultant/become_consultant/presentation/pages/social_networks_screen_smoke_test.dart
@@ -51,7 +51,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
when(cubit.state).thenReturn(state);
when(cubit.stream).thenAnswer((_) => Stream.value(state));
@@ -73,7 +73,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
when(cubit.state).thenReturn(state);
when(cubit.stream).thenAnswer((_) => Stream.value(state));
diff --git a/test/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen_smoke_test.dart b/test/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen_smoke_test.dart
index 6b82d68d..34c2db42 100644
--- a/test/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen_smoke_test.dart
+++ b/test/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen_smoke_test.dart
@@ -52,7 +52,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
@@ -75,7 +75,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
@@ -98,7 +98,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
@@ -121,7 +121,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
@@ -144,7 +144,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
@@ -167,7 +167,7 @@ void main() {
photos: null,
certificates: null,
);
- const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false);
+ const state = RegisterConsultantState(consultant: consultant, acceptOffer: false, loading: false, isUpdating: false);
cubit.emit(state);
diff --git a/test/features/profile/presentation/bloc/profile_cubit/profile_cubit_test.dart b/test/features/profile/presentation/bloc/profile_cubit/profile_cubit_test.dart
index cee98f20..c76ace2e 100644
--- a/test/features/profile/presentation/bloc/profile_cubit/profile_cubit_test.dart
+++ b/test/features/profile/presentation/bloc/profile_cubit/profile_cubit_test.dart
@@ -316,6 +316,7 @@ void main() {
isMyProfile: true,
profileDetails: profileDetails,
blogPosts: [blogPost],
+ certPhotos: []
));
profileCubit!.updateFeedBlogPostList(blogPost, true);
diff --git a/test/features/profile/presentation/widgets/profile_blog_post_widget_smoke_test.dart b/test/features/profile/presentation/widgets/profile_blog_post_widget_smoke_test.dart
index 0444d7c4..8f6fe8ed 100644
--- a/test/features/profile/presentation/widgets/profile_blog_post_widget_smoke_test.dart
+++ b/test/features/profile/presentation/widgets/profile_blog_post_widget_smoke_test.dart
@@ -219,7 +219,7 @@ void main() {
activityCoefficient: 1.5,
);
- final loadedState = ProfileState.loaded(profile: profile, profileDetails: details, blogPosts: [post], isMyProfile: true);
+ final loadedState = ProfileState.loaded(profile: profile, profileDetails: details, blogPosts: [post], isMyProfile: true, certPhotos: []);
final cubit = MockProfileCubit();
when(cubit.state).thenReturn(loadedState);
when(cubit.stream).thenAnswer((_) => const Stream.empty());