forked from eatvio/eatvio_app
feat(insights): first isights impemetation
This commit is contained in:
@@ -14,23 +14,10 @@ class UserDetailsCubit extends Cubit<UserDetailsState> {
|
||||
try {
|
||||
final profileDetails = await profileRepository.getProfileDetailsBySlug(slug);
|
||||
emit(state.copyWith(profileDetails: profileDetails, isLoading: false));
|
||||
getChartData(slug: slug);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
}
|
||||
|
||||
void getChartData({String period = '1', required String slug}) async {
|
||||
try {
|
||||
final weightPoints = await profileRepository.getWeight(period: period, slug: slug);
|
||||
final circumferencePoints = await profileRepository.getCircumferences(period: period, slug: slug);
|
||||
emit(state.copyWith(weightPoints: weightPoints, circumferencePoints: circumferencePoints));
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/weight_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'user_details_state.freezed.dart';
|
||||
@@ -11,7 +9,5 @@ abstract class UserDetailsState with _$UserDetailsState {
|
||||
@Default(false) bool isLoading,
|
||||
String? error,
|
||||
ProfileDetailsModel? profileDetails,
|
||||
List<WeightModel>? weightPoints,
|
||||
List<CircumferenceModel>? circumferencePoints,
|
||||
}) = _UserDetailsState;
|
||||
}
|
||||
@@ -8,11 +8,7 @@ import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
|
||||
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart';
|
||||
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/weight_model.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/weight_chart_widget.dart';
|
||||
import 'package:eatvio_app/features/insights/presentation/widgets/insights_card.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_cubit.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_state.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/widgets/expandable_bouble.dart';
|
||||
@@ -44,13 +40,6 @@ class UserDetailsContent extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _UserDetailsContentState extends State<UserDetailsContent> {
|
||||
final List<String> chipsLabelList = ['Вес', 'Замеры', 'ИМТ'];
|
||||
final List<String> chipsIntervalLabelList = ['1М', '3М', '6М', '1Г', 'ВСЁ ВРЕМЯ'];
|
||||
final List<String> chipsIntervalList = ['1', '3', '6', '12', 'all'];
|
||||
|
||||
List<WeightModel> weightPoints = [];
|
||||
List<CircumferenceModel> circumferencePoints = []; int _selectedChipIndex = 0;
|
||||
int _selectedIntervalChipIndex = 0;
|
||||
bool isMoreOptionsVisible = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -59,8 +48,6 @@ class _UserDetailsContentState extends State<UserDetailsContent> {
|
||||
builder: (context, state) {
|
||||
final profileDetails = state.profileDetails;
|
||||
if (profileDetails != null && state.isLoading == false) {
|
||||
weightPoints = state.weightPoints ?? [];
|
||||
circumferencePoints = state.circumferencePoints ?? [];
|
||||
return Scaffold(
|
||||
backgroundColor: appTheme.gray100,
|
||||
appBar: AppBar(
|
||||
@@ -104,7 +91,7 @@ class _UserDetailsContentState extends State<UserDetailsContent> {
|
||||
spacing: 12,
|
||||
children: [
|
||||
const SizedBox.shrink(),
|
||||
_charts(),
|
||||
InsightsCard(slug: widget.slug),
|
||||
ExpandableBouble(
|
||||
initiallyExpanded: true,
|
||||
title: s.general_info,
|
||||
@@ -309,92 +296,4 @@ class _UserDetailsContentState extends State<UserDetailsContent> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Material _charts() {
|
||||
return Material(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(children: [_choiceChipWidget(0), const SizedBox(width: 8), _choiceChipWidget(1), const SizedBox(width: 8), _choiceChipWidget(2)]),
|
||||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
return WeightChartWidget(weightPoints: weightPoints);
|
||||
case 1:
|
||||
return CircumferenceChartWidget(circumferencePoints: circumferencePoints);
|
||||
case 2:
|
||||
return ImtChartWidget(weightPoints: weightPoints);
|
||||
default:
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(width: 16),
|
||||
_choiceIntervalChipWidget(0),
|
||||
const SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(1),
|
||||
const SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(2),
|
||||
const SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(3),
|
||||
const SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(4),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ChoiceChip _choiceIntervalChipWidget(int index) {
|
||||
return ChoiceChip(
|
||||
selectedColor: Colors.grey.withValues(alpha: 0.1),
|
||||
pressElevation: 0,
|
||||
showCheckmark: false,
|
||||
side: BorderSide.none,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
label: Text(chipsIntervalLabelList[index]),
|
||||
labelStyle: TextStyle(color: appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12),
|
||||
selected: _selectedIntervalChipIndex == index,
|
||||
onSelected: (bool selected) {
|
||||
context.read<UserDetailsCubit>().getChartData(period: chipsIntervalList[index], slug: widget.slug);
|
||||
setState(() {
|
||||
_selectedIntervalChipIndex = index;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
ChoiceChip _choiceChipWidget(int index) {
|
||||
return ChoiceChip(
|
||||
selectedColor: appTheme.blueA400,
|
||||
pressElevation: 0,
|
||||
showCheckmark: false,
|
||||
side: BorderSide.none,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
label: Text(chipsLabelList[index]),
|
||||
labelStyle: TextStyle(color: index == _selectedChipIndex ? Colors.white : appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12),
|
||||
selected: _selectedChipIndex == index,
|
||||
backgroundColor: appTheme.gray100,
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = index;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user