feat(chats,diary): added logic for chosen diet portions and added banner to finish plan to chats

This commit is contained in:
Username1548
2025-04-30 21:25:23 +07:00
parent e572614a8b
commit 3b4ed501fb
28 changed files with 552 additions and 71 deletions

View File

@@ -0,0 +1,102 @@
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/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class CompletePlanBottomSheet extends StatefulWidget {
const CompletePlanBottomSheet({super.key, required this.cubit});
final ChatRoomCubit cubit;
@override
State<CompletePlanBottomSheet> createState() => _CompletePlanBottomSheetState();
}
class _CompletePlanBottomSheetState extends State<CompletePlanBottomSheet> {
bool? isFailure;
@override
Widget build(BuildContext context) {
final s = S.of(context);
if (isFailure == true) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 8,
),
const BottomSheetHandlerBar(),
const SizedBox(
height: 20,
),
Text('Произошла ошибка, попробуйте позже', style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
const SizedBox(
height: 8,
),
CustomOutlinedButton(
text: s.ok,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
onPressed: () async {
context.pop();
},
),
const SizedBox(
height: 40,
),
],
);
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 8,
),
const BottomSheetHandlerBar(),
const SizedBox(
height: 20,
),
Text('Подтверждение плана', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
const SizedBox(
height: 16,
),
Text(
'Вы уверенны что хотите подтвердить прохождения плана?',
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
textAlign: TextAlign.center,
),
const SizedBox(
height: 8,
),
CustomOutlinedButton(
text: s.confirm,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
onPressed: () async {
final result = await widget.cubit.finishChosenPlan();
if (result) {
if (context.mounted) {
context.pop();
return;
}
}
setState(() {
isFailure = true;
});
},
),
const SizedBox(
height: 40,
),
],
),
);
}
}

View File

@@ -1,11 +1,14 @@
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_with_blur.dart';
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/core/widgets/loader.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
import 'package:eatvio_app/features/chat/presentation/pages/payment_screen.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/chose_plan_date_widget.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/complete_plan_bottom_sheet.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/plan_complain_bottom_sheet.dart';
import 'package:eatvio_app/features/my_finance/presentation/pages/card_settings.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
@@ -40,7 +43,7 @@ class _NotificationBannerState extends State<NotificationBanner> {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (widget.bannerType != BannerType.collectCharge)
if (widget.bannerType != BannerType.collectCharge && widget.bannerType != BannerType.finishPlan)
Padding(
padding: const EdgeInsets.only(top: 12, right: 8, left: 12),
child: SvgPicture.asset('assets/icons/reversed_exclamation_mark.svg', height: 68, width: 68),
@@ -139,6 +142,19 @@ class _NotificationBannerState extends State<NotificationBanner> {
),
const SizedBox(height: 8),
],
BannerType.finishPlan => [
SizedBox(
width: size.width * 0.6,
child: Text('${s.congratsYouHaveFinishedPlan} «${widget.planName}». ${s.pleaseConfirmPlan}',
style: TextStyles.textMMediumAuto.copyWith(color: appTheme.black)),
),
const SizedBox(height: 8),
SizedBox(
width: size.width * 0.7,
child: Text(s.planWillBeConfirmedAfterThreeDays, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
),
const SizedBox(height: 8),
],
},
),
),
@@ -156,7 +172,57 @@ class _NotificationBannerState extends State<NotificationBanner> {
GoRouter.of(context).push(CardSettingsScreen.path, extra: widget.chosenPlanId);
},
),
)
),
if (widget.bannerType == BannerType.finishPlan) ...[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: CustomOutlinedButton(
text: s.confirm,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
onPressed: () async {
final cubit = context.read<ChatRoomCubit>();
showBottomSheetWithBlur(
userRootNavigator: true,
context: context,
height: null,
child: CompletePlanBottomSheet(
cubit: cubit,
),
);
},
),
),
const SizedBox(height: 12),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: SizedBox(
child: Text(s.youCanComplain, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
),
),
const SizedBox(height: 8),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: GestureDetector(
onTap: () {
final cubit = context.read<ChatRoomCubit>();
showBottomSheetWithBlur(
userRootNavigator: true,
context: context,
height: null,
child: PlanComplainBottomSheet(
cubit: cubit,
),
);
},
child: Text(s.leaveComplainRequest, style: TextStyles.textSMedium.copyWith(color: appTheme.red))),
),
),
const SizedBox(height: 8),
]
],
),
);
@@ -176,4 +242,4 @@ class _StarIcon extends StatelessWidget {
}
}
enum BannerType { date, card, payment, collectCharge }
enum BannerType { date, card, payment, collectCharge, finishPlan }

View File

@@ -0,0 +1,154 @@
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/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class PlanComplainBottomSheet extends StatefulWidget {
const PlanComplainBottomSheet({super.key, required this.cubit});
final ChatRoomCubit cubit;
@override
State<PlanComplainBottomSheet> createState() => _PlanComplainBottomSheetState();
}
class _PlanComplainBottomSheetState extends State<PlanComplainBottomSheet> {
final controller = TextEditingController();
bool? result;
int? textLength;
@override
Widget build(BuildContext context) {
final s = S.of(context);
if (result == true) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 8,
),
const BottomSheetHandlerBar(),
const SizedBox(
height: 20,
),
Text('Подача жалобы', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
const SizedBox(
height: 16,
),
Text('Жалоба отправлена на рассмотрение. Обычно это занимает до трёх рабочих дней.', style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
const SizedBox(
height: 8,
),
CustomOutlinedButton(
text: s.ok,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
onPressed: () async {
context.pop();
},
),
const SizedBox(
height: 40,
),
],
);
} else if (result == false) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 8,
),
const BottomSheetHandlerBar(),
const SizedBox(
height: 20,
),
Text('Подача жалобы', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
const SizedBox(
height: 16,
),
Text('Произошла ошибка, попробуйте позже', style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
const SizedBox(
height: 8,
),
CustomOutlinedButton(
text: s.ok,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
onPressed: () async {
context.pop();
},
),
const SizedBox(
height: 40,
),
],
);
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 8,
),
const BottomSheetHandlerBar(),
const SizedBox(
height: 20,
),
Text('Подача жалобы', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
const SizedBox(
height: 16,
),
Align(alignment: Alignment.centerLeft, child: Text('Опишите причину жалобы', style: TextStyles.textSMedium.copyWith(color: appTheme.black))),
const SizedBox(
height: 8,
),
CustomTextFormField(
controller: controller,
hasError: textLength != null && textLength! < 3,
onChanged: (p0) {
setState(() {
textLength = p0.length;
});
},
),
if (textLength != null && textLength! < 3) ...[
const SizedBox(
height: 4,
),
ValidationErrorWidget(error: s.atLeast3Symbols),
],
const SizedBox(
height: 8,
),
CustomOutlinedButton(
text: s.confirm,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
onPressed: () async {
if (controller.text.length < 3) {
return;
}
final result = await widget.cubit.complainAboutConsultation(description: controller.text);
setState(() {
this.result = result;
});
},
),
const SizedBox(
height: 40,
),
],
),
);
}
}