diff --git a/lib/features/profile/models/profile_model.dart b/lib/features/profile/models/profile_model.dart index 075604fc..547f2e8a 100644 --- a/lib/features/profile/models/profile_model.dart +++ b/lib/features/profile/models/profile_model.dart @@ -1,4 +1,3 @@ -import 'package:eatvio_app/features/profile/models/badge_model.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'profile_model.freezed.dart'; @@ -18,7 +17,7 @@ class ProfileModel with _$ProfileModel { @JsonKey(name: "slug") required String slug, @JsonKey(name: "profile_photo_url") required String profilePhotoUrl, @JsonKey(name: "role") required String role, - @JsonKey(name: "badges") required List badges, + // @JsonKey(name: "badges") required List badges, @JsonKey(name: "subscriptions") required List subscriptions, @JsonKey(name: "subscribers") required List subscribers, }) = _ProfileModel; diff --git a/lib/features/profile/models/profile_model.freezed.dart b/lib/features/profile/models/profile_model.freezed.dart index 862e19e6..60d07e27 100644 --- a/lib/features/profile/models/profile_model.freezed.dart +++ b/lib/features/profile/models/profile_model.freezed.dart @@ -39,9 +39,8 @@ mixin _$ProfileModel { @JsonKey(name: "profile_photo_url") String get profilePhotoUrl => throw _privateConstructorUsedError; @JsonKey(name: "role") - String get role => throw _privateConstructorUsedError; - @JsonKey(name: "badges") - List get badges => throw _privateConstructorUsedError; + String get role => + throw _privateConstructorUsedError; // @JsonKey(name: "badges") required List badges, @JsonKey(name: "subscriptions") List get subscriptions => throw _privateConstructorUsedError; @@ -76,7 +75,6 @@ abstract class $ProfileModelCopyWith<$Res> { @JsonKey(name: "slug") String slug, @JsonKey(name: "profile_photo_url") String profilePhotoUrl, @JsonKey(name: "role") String role, - @JsonKey(name: "badges") List badges, @JsonKey(name: "subscriptions") List subscriptions, @JsonKey(name: "subscribers") List subscribers}); } @@ -106,7 +104,6 @@ class _$ProfileModelCopyWithImpl<$Res, $Val extends ProfileModel> Object? slug = null, Object? profilePhotoUrl = null, Object? role = null, - Object? badges = null, Object? subscriptions = null, Object? subscribers = null, }) { @@ -151,10 +148,6 @@ class _$ProfileModelCopyWithImpl<$Res, $Val extends ProfileModel> ? _value.role : role // ignore: cast_nullable_to_non_nullable as String, - badges: null == badges - ? _value.badges - : badges // ignore: cast_nullable_to_non_nullable - as List, subscriptions: null == subscriptions ? _value.subscriptions : subscriptions // ignore: cast_nullable_to_non_nullable @@ -186,7 +179,6 @@ abstract class _$$ProfileModelImplCopyWith<$Res> @JsonKey(name: "slug") String slug, @JsonKey(name: "profile_photo_url") String profilePhotoUrl, @JsonKey(name: "role") String role, - @JsonKey(name: "badges") List badges, @JsonKey(name: "subscriptions") List subscriptions, @JsonKey(name: "subscribers") List subscribers}); } @@ -214,7 +206,6 @@ class __$$ProfileModelImplCopyWithImpl<$Res> Object? slug = null, Object? profilePhotoUrl = null, Object? role = null, - Object? badges = null, Object? subscriptions = null, Object? subscribers = null, }) { @@ -259,10 +250,6 @@ class __$$ProfileModelImplCopyWithImpl<$Res> ? _value.role : role // ignore: cast_nullable_to_non_nullable as String, - badges: null == badges - ? _value._badges - : badges // ignore: cast_nullable_to_non_nullable - as List, subscriptions: null == subscriptions ? _value._subscriptions : subscriptions // ignore: cast_nullable_to_non_nullable @@ -289,13 +276,11 @@ class _$ProfileModelImpl implements _ProfileModel { @JsonKey(name: "slug") required this.slug, @JsonKey(name: "profile_photo_url") required this.profilePhotoUrl, @JsonKey(name: "role") required this.role, - @JsonKey(name: "badges") required final List badges, @JsonKey(name: "subscriptions") required final List subscriptions, @JsonKey(name: "subscribers") required final List subscribers}) - : _badges = badges, - _subscriptions = subscriptions, + : _subscriptions = subscriptions, _subscribers = subscribers; factory _$ProfileModelImpl.fromJson(Map json) => @@ -331,16 +316,9 @@ class _$ProfileModelImpl implements _ProfileModel { @override @JsonKey(name: "role") final String role; - final List _badges; - @override - @JsonKey(name: "badges") - List get badges { - if (_badges is EqualUnmodifiableListView) return _badges; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_badges); - } - +// @JsonKey(name: "badges") required List badges, final List _subscriptions; +// @JsonKey(name: "badges") required List badges, @override @JsonKey(name: "subscriptions") List get subscriptions { @@ -360,7 +338,7 @@ class _$ProfileModelImpl implements _ProfileModel { @override String toString() { - return 'ProfileModel(id: $id, name: $name, email: $email, emailVerifiedAt: $emailVerifiedAt, createdAt: $createdAt, updatedAt: $updatedAt, isPublicProfile: $isPublicProfile, slug: $slug, profilePhotoUrl: $profilePhotoUrl, role: $role, badges: $badges, subscriptions: $subscriptions, subscribers: $subscribers)'; + return 'ProfileModel(id: $id, name: $name, email: $email, emailVerifiedAt: $emailVerifiedAt, createdAt: $createdAt, updatedAt: $updatedAt, isPublicProfile: $isPublicProfile, slug: $slug, profilePhotoUrl: $profilePhotoUrl, role: $role, subscriptions: $subscriptions, subscribers: $subscribers)'; } @override @@ -383,7 +361,6 @@ class _$ProfileModelImpl implements _ProfileModel { (identical(other.profilePhotoUrl, profilePhotoUrl) || other.profilePhotoUrl == profilePhotoUrl) && (identical(other.role, role) || other.role == role) && - const DeepCollectionEquality().equals(other._badges, _badges) && const DeepCollectionEquality() .equals(other._subscriptions, _subscriptions) && const DeepCollectionEquality() @@ -404,7 +381,6 @@ class _$ProfileModelImpl implements _ProfileModel { slug, profilePhotoUrl, role, - const DeepCollectionEquality().hash(_badges), const DeepCollectionEquality().hash(_subscriptions), const DeepCollectionEquality().hash(_subscribers)); @@ -436,7 +412,6 @@ abstract class _ProfileModel implements ProfileModel { @JsonKey(name: "slug") required final String slug, @JsonKey(name: "profile_photo_url") required final String profilePhotoUrl, @JsonKey(name: "role") required final String role, - @JsonKey(name: "badges") required final List badges, @JsonKey(name: "subscriptions") required final List subscriptions, @JsonKey(name: "subscribers") @@ -475,10 +450,7 @@ abstract class _ProfileModel implements ProfileModel { String get profilePhotoUrl; @override @JsonKey(name: "role") - String get role; - @override - @JsonKey(name: "badges") - List get badges; + String get role; // @JsonKey(name: "badges") required List badges, @override @JsonKey(name: "subscriptions") List get subscriptions; diff --git a/lib/features/profile/models/profile_model.g.dart b/lib/features/profile/models/profile_model.g.dart index aa2431ca..041a8bdb 100644 --- a/lib/features/profile/models/profile_model.g.dart +++ b/lib/features/profile/models/profile_model.g.dart @@ -24,9 +24,6 @@ _$ProfileModelImpl _$$ProfileModelImplFromJson(Map json) => slug: json['slug'] as String, profilePhotoUrl: json['profile_photo_url'] as String, role: json['role'] as String, - badges: (json['badges'] as List) - .map((e) => BadgeModel.fromJson(e as Map)) - .toList(), subscriptions: (json['subscriptions'] as List) .map((e) => ProfilePreviewModel.fromJson(e as Map)) .toList(), @@ -47,7 +44,6 @@ Map _$$ProfileModelImplToJson(_$ProfileModelImpl instance) => 'slug': instance.slug, 'profile_photo_url': instance.profilePhotoUrl, 'role': instance.role, - 'badges': instance.badges, 'subscriptions': instance.subscriptions, 'subscribers': instance.subscribers, }; diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart index ebeaa90c..80e49975 100644 --- a/lib/features/profile/presentation/pages/profile_screen.dart +++ b/lib/features/profile/presentation/pages/profile_screen.dart @@ -13,6 +13,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:rive/rive.dart'; +import 'package:flutter_svg/flutter_svg.dart'; class ProfileScreen extends StatefulWidget { final Author? author; @@ -27,14 +28,15 @@ class ProfileScreen extends StatefulWidget { } class _ProfileScreenState extends State { - List circumferencePoints = []; - List weightPoints = []; + final ProfileCubit profileCubit = sl(); final List chipsLabelList = ['Вес', 'Замеры', 'ИМТ']; final List chipsIntervalLabelList = ['1М', '3М', '6М', '1Г', 'ВСЁ ВРЕМЯ']; final List chipsIntervalList = ['1', '3', '6', '12', 'all']; + + List weightPoints = []; + List circumferencePoints = []; int _selectedChipIndex = 0; int _selectedIntervalChipIndex = 0; - final ProfileCubit profileCubit = sl(); @override void initState() { @@ -110,6 +112,10 @@ class _ProfileScreenState extends State { _subscriptionsAndSubscribers(state), _badges(state), if (widget.author == null) SizedBox(height: 16), + _socialLinks(state), + if (widget.author == null) SizedBox(height: 16), + _education(state), + if (widget.author == null) SizedBox(height: 16), if (widget.author == null) _charts(), _blogPosts(state), ], @@ -118,10 +124,140 @@ class _ProfileScreenState extends State { ); } - _badges(ProfileStateLoaded state) { - if (state.profile.badges.isEmpty) { + _education(ProfileStateLoaded state) { + if (state.profile.role != 'consultant') { return const SizedBox.shrink(); } + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Образование', + style: TextStyle( + color: Color(0xFF323F4B), + fontSize: 24, + fontWeight: FontWeight.w600, + ), + ), + Text( + widget.author == null ? 'Редактировать' : 'Показать все', + style: TextStyle( + color: Color(0xFF2F80ED), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Material( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Column( + children: [ + _educationBlock( + 'Наименование диплома или сертификата в 2 строки', + '30.01.2020', + ), + ], + ), + ), + ), + ), + ], + ); + } + + _educationBlock(String title, String date) { + return Material( + color: Color(0xFFF6FAFF), + borderRadius: BorderRadius.circular(12), + child: Padding( + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + height: 1, + color: Color(0xFF323F4B), + fontWeight: FontWeight.w500, + fontSize: 16, + ), + ), + const SizedBox(height: 4), + Text( + date, + style: TextStyle( + height: 1, + color: Color(0xFF6D6F71), + fontWeight: FontWeight.w500, + fontSize: 14, + ), + ), + ], + ), + ), + ); + } + + _socialLinks(ProfileStateLoaded state) { + if (state.profile.role != 'consultant') { + return const SizedBox.shrink(); + } + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Material( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + child: Row( + children: [ + _socialLinkButton(() {}, 'assets/icons/vk.svg'), + const SizedBox(width: 12), + _socialLinkButton(() {}, 'assets/icons/telegram.svg'), + const SizedBox(width: 12), + _socialLinkButton(() {}, 'assets/icons/web.svg'), + ], + ), + ), + ), + ); + } + + _socialLinkButton(Function() onTap, String icon) { + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(20), + child: Ink( + width: MediaQuery.of(context).size.width / 3 - (56 / 3), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Color(0xFFF6F6F6), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 16), + child: SvgPicture.asset( + icon, + width: 24, + ), + ), + ), + ); + } + + _badges(ProfileStateLoaded state) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: InkWell( @@ -141,16 +277,25 @@ class _ProfileScreenState extends State { fontWeight: FontWeight.w600, ), ), + const SizedBox(height: 8), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ - // CircleAvatar( - // backgroundImage: NetworkImage( - // state.profile.badges.first.image, - // ), - // radius: 20, - // ), + CircleAvatar( + radius: 20, + backgroundColor: Colors.grey.shade200, + ), + const SizedBox(width: 8), + CircleAvatar( + radius: 20, + backgroundColor: Colors.grey.shade200, + ), + const SizedBox(width: 8), + CircleAvatar( + radius: 20, + backgroundColor: Colors.grey.shade200, + ), ], ), ),