forked from eatvio/eatvio_app
fix(diary): added proccesing of future dates and fixed deleted portions
This commit is contained in:
@@ -350,7 +350,8 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
hintText: 'Сообщение',
|
||||
hintStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400, height: 1, color: Color(0xFFAEAEB2)),
|
||||
filled: true,
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(100), borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1)),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100), borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1),
|
||||
@@ -394,7 +395,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
left: 16,
|
||||
child: AboutOrderButton(
|
||||
onTap: () {
|
||||
GoRouter.of(context).push(InfoByOrderScreen.path, extra: state.chatRoom.chosenPlan);
|
||||
GoRouter.of(context).push(InfoByOrderScreen.path, extra: {'planId': state.chatRoom.chosenPlan?.id});
|
||||
},
|
||||
)),
|
||||
],
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class PaymentScreen extends StatefulWidget {
|
||||
static const name = 'paymentScreen';
|
||||
static const path = '/payment-screen';
|
||||
final String url;
|
||||
const PaymentScreen({super.key, required this.url});
|
||||
final int planId;
|
||||
const PaymentScreen({super.key, required this.url, required this.planId});
|
||||
|
||||
@override
|
||||
State<PaymentScreen> createState() => _PaymentScreenState();
|
||||
@@ -23,13 +24,14 @@ class _PaymentScreenState extends State<PaymentScreen> {
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onProgress: (int progress) {},
|
||||
onPageStarted: (String url) {},
|
||||
onPageFinished: (String url) {},
|
||||
onHttpError: (HttpResponseError error) {},
|
||||
onWebResourceError: (WebResourceError error) {},
|
||||
onNavigationRequest: (NavigationRequest request) {
|
||||
log(request.url);
|
||||
if (request.url.contains('tbank/checkout-success')) {
|
||||
if (request.url.contains('Success=true')) {
|
||||
GoRouter.of(context).pushReplacement(InfoByOrderScreen.path, extra: {'planId': widget.planId, 'successfulPayment': true});
|
||||
} else {
|
||||
GoRouter.of(context).pushReplacement(InfoByOrderScreen.path, extra: {'planId': widget.planId, 'successfulPayment': false});
|
||||
}
|
||||
}
|
||||
return NavigationDecision.navigate;
|
||||
},
|
||||
),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
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/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/generated/l10n.dart';
|
||||
@@ -9,9 +11,16 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class NotificationBanner extends StatelessWidget {
|
||||
class NotificationBanner extends StatefulWidget {
|
||||
const NotificationBanner({super.key, required this.bannerType});
|
||||
final BannerType bannerType;
|
||||
|
||||
@override
|
||||
State<NotificationBanner> createState() => _NotificationBannerState();
|
||||
}
|
||||
|
||||
class _NotificationBannerState extends State<NotificationBanner> {
|
||||
bool isLoading = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
@@ -28,65 +37,81 @@ class NotificationBanner extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 12, right: 8, left: 12),
|
||||
child: SvgPicture.asset('assets/icons/reversed_exclamation_mark.svg', height: 68, width: 68),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: switch (bannerType) {
|
||||
BannerType.date => [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(s.choose_plan_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
final cubit = context.read<ChatRoomCubit>();
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => ChosePlanDateWidget(
|
||||
chatCubit: cubit,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(s.choose_date, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
BannerType.card => [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(s.can_not_choose_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Text(s.add_card, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
BannerType.payment => [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(s.tap_on_link_to_pay, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
final paymentLink = await context.read<ChatRoomCubit>().getPaymentLink();
|
||||
if (paymentLink != null) {
|
||||
if (!context.mounted) return;
|
||||
GoRouter.of(context).push(PaymentScreen.path, extra: paymentLink);
|
||||
}
|
||||
},
|
||||
child: Text(s.pay, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
},
|
||||
if (isLoading)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 40, top: 24),
|
||||
child: Loader(),
|
||||
)
|
||||
else
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: switch (widget.bannerType) {
|
||||
BannerType.date => [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(s.choose_plan_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
final cubit = context.read<ChatRoomCubit>();
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => ChosePlanDateWidget(
|
||||
chatCubit: cubit,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(s.choose_date, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
BannerType.card => [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(s.can_not_choose_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Text(s.add_card, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
BannerType.payment => [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(s.tap_on_link_to_pay, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
final planId = (context.read<ChatRoomCubit>().state as ChatRoomStateLoaded).chatRoom.chosenPlan?.id;
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
final paymentLink = await context.read<ChatRoomCubit>().getPaymentLink();
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
if (paymentLink != null && planId != null) {
|
||||
if (!context.mounted) return;
|
||||
GoRouter.of(context).pushReplacement(
|
||||
PaymentScreen.path,
|
||||
extra: {'url': paymentLink, 'planId': planId},
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Text(s.pay, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -5,14 +5,18 @@ part 'diary_day_model.freezed.dart';
|
||||
part 'diary_day_model.g.dart';
|
||||
|
||||
enum PortionState {
|
||||
active,
|
||||
@JsonValue('filled_diet')
|
||||
filledDiet,
|
||||
@JsonValue('eaten_from_diet')
|
||||
eatenFromDiet,
|
||||
eaten,
|
||||
@JsonValue('eaten_deleted')
|
||||
eatenDeleted,
|
||||
@JsonValue('eaten_edited')
|
||||
eatenEdited,
|
||||
commented,
|
||||
revieweByUser,
|
||||
@JsonValue('reviewed_by_user')
|
||||
reviewedByUser,
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
||||
@@ -113,14 +113,13 @@ Map<String, dynamic> _$$PortionModelImplToJson(_$PortionModelImpl instance) =>
|
||||
};
|
||||
|
||||
const _$PortionStateEnumMap = {
|
||||
PortionState.active: 'active',
|
||||
PortionState.filledDiet: 'filledDiet',
|
||||
PortionState.eatenFromDiet: 'eatenFromDiet',
|
||||
PortionState.filledDiet: 'filled_diet',
|
||||
PortionState.eatenFromDiet: 'eaten_from_diet',
|
||||
PortionState.eaten: 'eaten',
|
||||
PortionState.eatenDeleted: 'eatenDeleted',
|
||||
PortionState.eatenEdited: 'eatenEdited',
|
||||
PortionState.eatenDeleted: 'eaten_deleted',
|
||||
PortionState.eatenEdited: 'eaten_edited',
|
||||
PortionState.commented: 'commented',
|
||||
PortionState.revieweByUser: 'revieweByUser',
|
||||
PortionState.reviewedByUser: 'reviewed_by_user',
|
||||
};
|
||||
|
||||
_$TypeOfDiaryModelImpl _$$TypeOfDiaryModelImplFromJson(
|
||||
|
||||
@@ -39,17 +39,19 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
}
|
||||
try {
|
||||
final diaryDay = await diaryRepository.getDiaryByDate('$selectedDay');
|
||||
|
||||
final nutrition = await getNutrition(diaryDay.id);
|
||||
emit(
|
||||
DiaryState.loaded(
|
||||
diary: diaryDay,
|
||||
nutrition: await getNutrition((await diaryRepository.getDiaryByDate('$selectedDay')).id),
|
||||
nutrition: nutrition,
|
||||
selectedDay: selectedDay,
|
||||
selectedMeal: selectedMeal,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,10 +183,12 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
|
||||
fillSatiety({required int diaryId, required int satiety}) async {
|
||||
await diaryRepository.fillSatiety(diaryId: diaryId, mealId: selectedMeal, satiety: satiety);
|
||||
await fetchDiary();
|
||||
}
|
||||
|
||||
fillMood({required int diaryId, required int mood}) async {
|
||||
await diaryRepository.fillMood(diaryId: diaryId, mealId: selectedMeal, mood: mood);
|
||||
await fetchDiary();
|
||||
}
|
||||
|
||||
fillComment(String comment) {
|
||||
|
||||
@@ -19,5 +19,6 @@ class DiaryState with _$DiaryState {
|
||||
required NutritionDataModel nutrition,
|
||||
required DateTime selectedDay,
|
||||
required int selectedMeal,
|
||||
|
||||
}) = DiaryStateLoaded;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
}
|
||||
if (state is DiaryStateError) {
|
||||
return Scaffold(
|
||||
body: DataErrorWidget(onReload: context.read<DiaryCubit>().fetchDiary()),
|
||||
body: DataErrorWidget(onReload: () => context.read<DiaryCubit>().fetchDiary()),
|
||||
);
|
||||
}
|
||||
return Scaffold(
|
||||
@@ -48,12 +48,15 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
children: [
|
||||
const CalendarWidget(),
|
||||
if (state is DiaryStateLoading) const Loader(),
|
||||
if (state is DiaryStateLoaded) const WakeupAndRetireWidget(),
|
||||
if (state is DiaryStateLoaded) WakeupAndRetireWidget(showRetire: state.diary.typeOfDiary.hasChosenPlan),
|
||||
const SizedBox(height: 12),
|
||||
if (state is DiaryStateLoaded) const MealWidget(),
|
||||
if (state is DiaryStateLoaded)
|
||||
MealWidget(
|
||||
showMood: state.diary.typeOfDiary.hasChosenPlan,
|
||||
),
|
||||
if (state is DiaryStateLoaded) const CaloriesChartWidget(),
|
||||
const SizedBox(height: 12),
|
||||
if (state is DiaryStateLoaded) const CommentForConsultantWidget(),
|
||||
if (state is DiaryStateLoaded && state.diary.typeOfDiary.hasChosenPlan) const CommentForConsultantWidget(),
|
||||
if (state is DiaryStateLoaded && state.diary.closed == 0)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 12),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/widgets/show_error_dialog.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:table_calendar/table_calendar.dart';
|
||||
@@ -19,6 +21,7 @@ class _CalendarWidgetState extends State<CalendarWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = S.of(context);
|
||||
return BlocConsumer<DiaryCubit, DiaryState>(
|
||||
listener: (BuildContext context, DiaryState state) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
@@ -48,6 +51,11 @@ class _CalendarWidgetState extends State<CalendarWidget> {
|
||||
),
|
||||
onDaySelected: (selectedDay, focusedDay) {
|
||||
if (!isSameDay(_selectedDay, selectedDay)) {
|
||||
final today = DateTime.now();
|
||||
if (selectedDay.isAfter(today)) {
|
||||
showErrorDialog(context, title: s.want_to_see_tomorrow, description: s.can_not_see_next_day);
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_selectedDay = selectedDay;
|
||||
_focusedDay = focusedDay;
|
||||
|
||||
@@ -8,8 +8,8 @@ import 'package:eatvio_app/features/diary/presentation/widgets/time_of_meal_pick
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MealWidget extends StatefulWidget {
|
||||
const MealWidget({super.key});
|
||||
|
||||
const MealWidget({super.key, required this.showMood});
|
||||
final bool showMood;
|
||||
@override
|
||||
State<MealWidget> createState() => _MealWidgetState();
|
||||
}
|
||||
@@ -20,12 +20,12 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
return Material(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: Colors.white,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
const Text(
|
||||
'Прием пищи',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
@@ -33,8 +33,8 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Row(
|
||||
const SizedBox(height: 16),
|
||||
const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
MealButtonWidget(mealNumber: 1),
|
||||
@@ -44,18 +44,20 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
MealButtonWidget(mealNumber: 5),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
TimeOfMealPickerWidget(),
|
||||
SizedBox(height: 12),
|
||||
ProductsListWidget(),
|
||||
SizedBox(height: 12),
|
||||
AddProductButtonWidget(),
|
||||
SizedBox(height: 12),
|
||||
PhotoGalleryWidget(),
|
||||
SizedBox(height: 12),
|
||||
SatietyRatingWidget(),
|
||||
SizedBox(height: 12),
|
||||
MoodRatingWidget(),
|
||||
const SizedBox(height: 12),
|
||||
const TimeOfMealPickerWidget(),
|
||||
const SizedBox(height: 12),
|
||||
const ProductsListWidget(),
|
||||
const SizedBox(height: 12),
|
||||
const AddProductButtonWidget(),
|
||||
const SizedBox(height: 12),
|
||||
const PhotoGalleryWidget(),
|
||||
const SizedBox(height: 12),
|
||||
const SatietyRatingWidget(),
|
||||
if (widget.showMood) ...[
|
||||
const SizedBox(height: 12),
|
||||
const MoodRatingWidget(),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -14,17 +14,18 @@ class MoodRatingWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MoodRatingWidgetState extends State<MoodRatingWidget> {
|
||||
late double currentSelectedRating;
|
||||
bool isFirstFetch = true;
|
||||
List<double> currentSelectedRating = [0, 0, 0, 0, 0];
|
||||
List<bool> isFirstFetch = [true, true, true, true, true];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DiaryCubit, DiaryState>(
|
||||
builder: (BuildContext context, DiaryState state) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
if (isFirstFetch) {
|
||||
currentSelectedRating = state.diary.meals[state.selectedMeal - 1].mood.toDouble() + 1;
|
||||
isFirstFetch = false;
|
||||
final selectedIndex = state.selectedMeal - 1;
|
||||
if (isFirstFetch[selectedIndex]) {
|
||||
currentSelectedRating[selectedIndex] = state.diary.meals[selectedIndex].mood.toDouble() + 1;
|
||||
isFirstFetch[selectedIndex] = false;
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
@@ -46,7 +47,7 @@ class _MoodRatingWidgetState extends State<MoodRatingWidget> {
|
||||
width: 32,
|
||||
),
|
||||
RatingBar.builder(
|
||||
initialRating: state.diary.meals[state.selectedMeal - 1].mood.toDouble() + 1,
|
||||
initialRating: state.diary.meals[selectedIndex].mood.toDouble() + 1,
|
||||
itemCount: 6,
|
||||
itemSize: MediaQuery.of(context).size.width / 6 - (124 / 6),
|
||||
updateOnDrag: true,
|
||||
@@ -56,129 +57,129 @@ class _MoodRatingWidgetState extends State<MoodRatingWidget> {
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 1 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 1 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFC82222),
|
||||
border: currentSelectedRating == 1
|
||||
border: currentSelectedRating[selectedIndex] == 1
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFFAA3333),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
width: 2,
|
||||
color: const Color(0xFFAA3333),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 1
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 1
|
||||
? const BorderRadius.horizontal(
|
||||
left: Radius.circular(8),
|
||||
right: Radius.circular(2),
|
||||
)
|
||||
left: Radius.circular(8),
|
||||
right: Radius.circular(2),
|
||||
)
|
||||
: const BorderRadius.horizontal(
|
||||
left: Radius.circular(8),
|
||||
),
|
||||
left: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
);
|
||||
case 1:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 2 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 2 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFF3E3E),
|
||||
border: currentSelectedRating == 2
|
||||
border: currentSelectedRating[selectedIndex] == 2
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF550000),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
width: 2,
|
||||
color: const Color(0xFF550000),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 2 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 2 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 2:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 3 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 3 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF8C926),
|
||||
border: currentSelectedRating == 3
|
||||
border: currentSelectedRating[selectedIndex] == 3
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF8C5D00),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
width: 2,
|
||||
color: const Color(0xFF8C5D00),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 3 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 3 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 3:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 4 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 4 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFF3BF),
|
||||
border: currentSelectedRating == 4
|
||||
border: currentSelectedRating[selectedIndex] == 4
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFFB5911B),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
width: 2,
|
||||
color: const Color(0xFFB5911B),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 4 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 4 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 4:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 5 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 5 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF62E833),
|
||||
border: currentSelectedRating == 5
|
||||
border: currentSelectedRating[selectedIndex] == 5
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF276918),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
width: 2,
|
||||
color: const Color(0xFF276918),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 5 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 5 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
default:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 6 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 6 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF4DCE20),
|
||||
border: currentSelectedRating == 6
|
||||
border: currentSelectedRating[selectedIndex] == 6
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF184D12),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
width: 2,
|
||||
color: const Color(0xFF184D12),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 6
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 6
|
||||
? const BorderRadius.horizontal(
|
||||
left: Radius.circular(2),
|
||||
right: Radius.circular(8),
|
||||
)
|
||||
left: Radius.circular(2),
|
||||
right: Radius.circular(8),
|
||||
)
|
||||
: const BorderRadius.horizontal(
|
||||
right: Radius.circular(8),
|
||||
),
|
||||
right: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onRatingUpdate: (value) {
|
||||
setState(() {
|
||||
currentSelectedRating = value;
|
||||
currentSelectedRating[selectedIndex] = value;
|
||||
});
|
||||
EasyDebounce.debounce(
|
||||
'change-satiety',
|
||||
const Duration(milliseconds: 250),
|
||||
() {
|
||||
context.read<DiaryCubit>().fillMood(diaryId: state.diary.id, mood: currentSelectedRating.toInt() - 1);
|
||||
() {
|
||||
context.read<DiaryCubit>().fillMood(diaryId: state.diary.id, mood: currentSelectedRating[selectedIndex].toInt() - 1);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
@@ -14,17 +14,18 @@ class SatietyRatingWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
|
||||
late double currentSelectedRating;
|
||||
bool isFirstFetch = true;
|
||||
List<double> currentSelectedRating = [0, 0, 0, 0, 0];
|
||||
List<bool> isFirstFetch = [true, true, true, true, true];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DiaryCubit, DiaryState>(
|
||||
builder: (BuildContext context, DiaryState state) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
if (isFirstFetch) {
|
||||
currentSelectedRating = state.diary.meals[state.selectedMeal - 1].satiety.toDouble() + 1;
|
||||
isFirstFetch = false;
|
||||
final selectedIndex = state.selectedMeal - 1;
|
||||
if (isFirstFetch[selectedIndex]) {
|
||||
currentSelectedRating[selectedIndex] = state.diary.meals[selectedIndex].satiety.toDouble() + 1;
|
||||
isFirstFetch[selectedIndex] = false;
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
@@ -46,7 +47,7 @@ class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
|
||||
width: 32,
|
||||
),
|
||||
RatingBar.builder(
|
||||
initialRating: state.diary.meals[state.selectedMeal - 1].satiety.toDouble() + 1,
|
||||
initialRating: state.diary.meals[selectedIndex].satiety.toDouble() + 1,
|
||||
itemCount: 6,
|
||||
itemSize: MediaQuery.of(context).size.width / 6 - (124 / 6),
|
||||
updateOnDrag: true,
|
||||
@@ -56,17 +57,17 @@ class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 1 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 1 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFC82222),
|
||||
border: currentSelectedRating == 1
|
||||
border: currentSelectedRating[selectedIndex] == 1
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFFAA3333),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 1
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 1
|
||||
? const BorderRadius.horizontal(
|
||||
left: Radius.circular(8),
|
||||
right: Radius.circular(2),
|
||||
@@ -80,85 +81,85 @@ class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 2 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 2 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFF3E3E),
|
||||
border: currentSelectedRating == 2
|
||||
border: currentSelectedRating[selectedIndex] == 2
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF550000),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 2 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 2 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 2:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 3 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 3 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF8C926),
|
||||
border: currentSelectedRating == 3
|
||||
border: currentSelectedRating[selectedIndex] == 3
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF8C5D00),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 3 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 3 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 3:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 4 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 4 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFF3BF),
|
||||
border: currentSelectedRating == 4
|
||||
border: currentSelectedRating[selectedIndex] == 4
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFFB5911B),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 4 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 4 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 4:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 5 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 5 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF62E833),
|
||||
border: currentSelectedRating == 5
|
||||
border: currentSelectedRating[selectedIndex] == 5
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF276918),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 5 ? BorderRadius.circular(2) : null,
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 5 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
default:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: currentSelectedRating == 6 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
margin: currentSelectedRating[selectedIndex] == 6 ? const EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF4DCE20),
|
||||
border: currentSelectedRating == 6
|
||||
border: currentSelectedRating[selectedIndex] == 6
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: const Color(0xFF184D12),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: currentSelectedRating == 6
|
||||
borderRadius: currentSelectedRating[selectedIndex] == 6
|
||||
? const BorderRadius.horizontal(
|
||||
left: Radius.circular(2),
|
||||
right: Radius.circular(8),
|
||||
@@ -172,13 +173,13 @@ class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
|
||||
},
|
||||
onRatingUpdate: (value) {
|
||||
setState(() {
|
||||
currentSelectedRating = value;
|
||||
currentSelectedRating[selectedIndex] = value;
|
||||
});
|
||||
EasyDebounce.debounce(
|
||||
'change-satiety',
|
||||
const Duration(milliseconds: 250),
|
||||
() {
|
||||
context.read<DiaryCubit>().fillSatiety(diaryId: state.diary.id, satiety: currentSelectedRating.toInt() - 1);
|
||||
context.read<DiaryCubit>().fillSatiety(diaryId: state.diary.id, satiety: currentSelectedRating[selectedIndex].toInt() - 1);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
@@ -8,8 +8,8 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import '../../../../core/theme/theme_helper.dart';
|
||||
|
||||
class WakeupAndRetireWidget extends StatefulWidget {
|
||||
const WakeupAndRetireWidget({super.key});
|
||||
|
||||
const WakeupAndRetireWidget({super.key, required this.showRetire});
|
||||
final bool showRetire;
|
||||
@override
|
||||
State<WakeupAndRetireWidget> createState() => _WakeupAndRetireWidgetState();
|
||||
}
|
||||
@@ -29,65 +29,62 @@ class _WakeupAndRetireWidgetState extends State<WakeupAndRetireWidget> {
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
useRootNavigator: true,
|
||||
builder:
|
||||
(context) => SizedBox(
|
||||
height: MediaQuery.of(context).copyWith().size.height / 3,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
use24hFormat: true,
|
||||
initialDateTime: DateTime.now(),
|
||||
onDateTimeChanged: (newTime) {
|
||||
if (isWakeup) {
|
||||
wakeup = newTime;
|
||||
} else {
|
||||
retire = newTime;
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
if (isWakeup) {
|
||||
diaryCubit.fillWakeup(
|
||||
diaryId: diaryId,
|
||||
time:
|
||||
'${wakeup.hour.toString().padLeft(2, '0')}:${wakeup.minute.toString().padLeft(2, '0')}:00',
|
||||
);
|
||||
} else {
|
||||
diaryCubit.fillRetire(
|
||||
diaryId: diaryId,
|
||||
time:
|
||||
'${retire.hour.toString().padLeft(2, '0')}:${retire.minute.toString().padLeft(2, '0')}:00',
|
||||
);
|
||||
}
|
||||
},
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 16,
|
||||
height: 52,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
child: const Center(
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
builder: (context) => SizedBox(
|
||||
height: MediaQuery.of(context).copyWith().size.height / 3,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
use24hFormat: true,
|
||||
initialDateTime: DateTime.now(),
|
||||
onDateTimeChanged: (newTime) {
|
||||
if (isWakeup) {
|
||||
wakeup = newTime;
|
||||
} else {
|
||||
retire = newTime;
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
if (isWakeup) {
|
||||
diaryCubit.fillWakeup(
|
||||
diaryId: diaryId,
|
||||
time: '${wakeup.hour.toString().padLeft(2, '0')}:${wakeup.minute.toString().padLeft(2, '0')}:00',
|
||||
);
|
||||
} else {
|
||||
diaryCubit.fillRetire(
|
||||
diaryId: diaryId,
|
||||
time: '${retire.hour.toString().padLeft(2, '0')}:${retire.minute.toString().padLeft(2, '0')}:00',
|
||||
);
|
||||
}
|
||||
},
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 16,
|
||||
height: 52,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
child: const Center(
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,9 +138,9 @@ class _WakeupAndRetireWidgetState extends State<WakeupAndRetireWidget> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
state.diary.wakeup.toString().substring(
|
||||
0,
|
||||
state.diary.wakeup.toString().length - 3,
|
||||
),
|
||||
0,
|
||||
state.diary.wakeup.toString().length - 3,
|
||||
),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 17,
|
||||
@@ -158,65 +155,67 @@ class _WakeupAndRetireWidgetState extends State<WakeupAndRetireWidget> {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 12,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset('assets/icons/retire.svg'),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Уход ко сну',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
InkWell(
|
||||
onTap: () => showTimePicker(state.diary.id, false),
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: Ink(
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
color: const Color(0xFFF1F2F6),
|
||||
),
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
state.diary.retire.toString().substring(
|
||||
0,
|
||||
state.diary.retire.toString().length - 3,
|
||||
),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 17,
|
||||
if (widget.showRetire) ...[
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 12,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset('assets/icons/retire.svg'),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Уход ко сну',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
InkWell(
|
||||
onTap: () => showTimePicker(state.diary.id, false),
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: Ink(
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
color: const Color(0xFFF1F2F6),
|
||||
),
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
state.diary.retire.toString().substring(
|
||||
0,
|
||||
state.diary.retire.toString().length - 3,
|
||||
),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
32
lib/features/order_info/cubit/order_info_cubit.dart
Normal file
32
lib/features/order_info/cubit/order_info_cubit.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/features/order_info/cubit/order_info_state.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class OrderInfoCubit extends Cubit<OrderInfoState> {
|
||||
OrderInfoCubit({required this.chatRepository}) : super(OrderInfoState());
|
||||
final ChatRepository chatRepository;
|
||||
|
||||
Future<String?> getPaymentLink() async {
|
||||
try {
|
||||
final plan = state.chosenPlan;
|
||||
if (plan == null) return null;
|
||||
final paymentModel = await chatRepository.getPaymentLink(id: plan.id);
|
||||
return paymentModel.paymentUrl;
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getChosenPlan(int id) async{
|
||||
try {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
emit(state.copyWith(isLoading: false));
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
emit(state.copyWith(isLoading: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
14
lib/features/order_info/cubit/order_info_state.dart
Normal file
14
lib/features/order_info/cubit/order_info_state.dart
Normal file
@@ -0,0 +1,14 @@
|
||||
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'order_info_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class OrderInfoState with _$OrderInfoState {
|
||||
|
||||
factory OrderInfoState({
|
||||
@Default(false) bool isLoading,
|
||||
@Default(null) ChosenPlanModel? chosenPlan,
|
||||
}) = _OrderInfoState;
|
||||
|
||||
}
|
||||
185
lib/features/order_info/cubit/order_info_state.freezed.dart
Normal file
185
lib/features/order_info/cubit/order_info_state.freezed.dart
Normal file
@@ -0,0 +1,185 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'order_info_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$OrderInfoState {
|
||||
bool get isLoading => throw _privateConstructorUsedError;
|
||||
ChosenPlanModel? get chosenPlan => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of OrderInfoState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$OrderInfoStateCopyWith<OrderInfoState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $OrderInfoStateCopyWith<$Res> {
|
||||
factory $OrderInfoStateCopyWith(
|
||||
OrderInfoState value, $Res Function(OrderInfoState) then) =
|
||||
_$OrderInfoStateCopyWithImpl<$Res, OrderInfoState>;
|
||||
@useResult
|
||||
$Res call({bool isLoading, ChosenPlanModel? chosenPlan});
|
||||
|
||||
$ChosenPlanModelCopyWith<$Res>? get chosenPlan;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$OrderInfoStateCopyWithImpl<$Res, $Val extends OrderInfoState>
|
||||
implements $OrderInfoStateCopyWith<$Res> {
|
||||
_$OrderInfoStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of OrderInfoState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? isLoading = null,
|
||||
Object? chosenPlan = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
chosenPlan: freezed == chosenPlan
|
||||
? _value.chosenPlan
|
||||
: chosenPlan // ignore: cast_nullable_to_non_nullable
|
||||
as ChosenPlanModel?,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
/// Create a copy of OrderInfoState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ChosenPlanModelCopyWith<$Res>? get chosenPlan {
|
||||
if (_value.chosenPlan == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $ChosenPlanModelCopyWith<$Res>(_value.chosenPlan!, (value) {
|
||||
return _then(_value.copyWith(chosenPlan: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$OrderInfoStateImplCopyWith<$Res>
|
||||
implements $OrderInfoStateCopyWith<$Res> {
|
||||
factory _$$OrderInfoStateImplCopyWith(_$OrderInfoStateImpl value,
|
||||
$Res Function(_$OrderInfoStateImpl) then) =
|
||||
__$$OrderInfoStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({bool isLoading, ChosenPlanModel? chosenPlan});
|
||||
|
||||
@override
|
||||
$ChosenPlanModelCopyWith<$Res>? get chosenPlan;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$OrderInfoStateImplCopyWithImpl<$Res>
|
||||
extends _$OrderInfoStateCopyWithImpl<$Res, _$OrderInfoStateImpl>
|
||||
implements _$$OrderInfoStateImplCopyWith<$Res> {
|
||||
__$$OrderInfoStateImplCopyWithImpl(
|
||||
_$OrderInfoStateImpl _value, $Res Function(_$OrderInfoStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of OrderInfoState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? isLoading = null,
|
||||
Object? chosenPlan = freezed,
|
||||
}) {
|
||||
return _then(_$OrderInfoStateImpl(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
chosenPlan: freezed == chosenPlan
|
||||
? _value.chosenPlan
|
||||
: chosenPlan // ignore: cast_nullable_to_non_nullable
|
||||
as ChosenPlanModel?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$OrderInfoStateImpl implements _OrderInfoState {
|
||||
_$OrderInfoStateImpl({this.isLoading = false, this.chosenPlan = null});
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isLoading;
|
||||
@override
|
||||
@JsonKey()
|
||||
final ChosenPlanModel? chosenPlan;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'OrderInfoState(isLoading: $isLoading, chosenPlan: $chosenPlan)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$OrderInfoStateImpl &&
|
||||
(identical(other.isLoading, isLoading) ||
|
||||
other.isLoading == isLoading) &&
|
||||
(identical(other.chosenPlan, chosenPlan) ||
|
||||
other.chosenPlan == chosenPlan));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, isLoading, chosenPlan);
|
||||
|
||||
/// Create a copy of OrderInfoState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$OrderInfoStateImplCopyWith<_$OrderInfoStateImpl> get copyWith =>
|
||||
__$$OrderInfoStateImplCopyWithImpl<_$OrderInfoStateImpl>(
|
||||
this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _OrderInfoState implements OrderInfoState {
|
||||
factory _OrderInfoState(
|
||||
{final bool isLoading,
|
||||
final ChosenPlanModel? chosenPlan}) = _$OrderInfoStateImpl;
|
||||
|
||||
@override
|
||||
bool get isLoading;
|
||||
@override
|
||||
ChosenPlanModel? get chosenPlan;
|
||||
|
||||
/// Create a copy of OrderInfoState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$OrderInfoStateImplCopyWith<_$OrderInfoStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -1,80 +1,172 @@
|
||||
import 'package:eatvio_app/core/locator_service.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/loader.dart';
|
||||
import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart';
|
||||
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/order_info/cubit/order_info_cubit.dart';
|
||||
import 'package:eatvio_app/features/order_info/cubit/order_info_state.dart';
|
||||
import 'package:eatvio_app/features/order_info/presentation/widgets/payment_banner.dart';
|
||||
import 'package:eatvio_app/features/order_info/presentation/widgets/plan_info.dart';
|
||||
import 'package:eatvio_app/features/order_info/presentation/widgets/plan_props.dart';
|
||||
import 'package:eatvio_app/features/order_info/presentation/widgets/plan_state.dart';
|
||||
import 'package:eatvio_app/features/order_info/presentation/widgets/plan_status_box.dart';
|
||||
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
|
||||
import 'package:eatvio_app/core/widgets/option_widget.dart';
|
||||
import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class InfoByOrderScreen extends StatefulWidget {
|
||||
class InfoByOrderScreen extends StatelessWidget {
|
||||
static const name = 'infoByOrderScreen';
|
||||
static const path = '/info-by-order-screen';
|
||||
final ChosenPlanModel plan;
|
||||
const InfoByOrderScreen({
|
||||
super.key,
|
||||
required this.plan,
|
||||
});
|
||||
|
||||
const InfoByOrderScreen({super.key, this.successfulPayment, required this.planId});
|
||||
final bool? successfulPayment;
|
||||
final int planId;
|
||||
@override
|
||||
State<InfoByOrderScreen> createState() => _InfoByOrderScreenState();
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => sl<OrderInfoCubit>()..getChosenPlan(planId),
|
||||
child: InfoByOrderScreenContent(
|
||||
successfulPayment: successfulPayment,
|
||||
planId: planId,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _InfoByOrderScreenState extends State<InfoByOrderScreen> {
|
||||
class InfoByOrderScreenContent extends StatefulWidget {
|
||||
static const name = 'infoByOrderScreen';
|
||||
static const path = '/info-by-order-screen';
|
||||
const InfoByOrderScreenContent({
|
||||
super.key,
|
||||
required this.planId,
|
||||
required this.successfulPayment,
|
||||
});
|
||||
final int planId;
|
||||
final bool? successfulPayment;
|
||||
@override
|
||||
State<InfoByOrderScreenContent> createState() => _InfoByOrderScreenContentState();
|
||||
}
|
||||
|
||||
class _InfoByOrderScreenContentState extends State<InfoByOrderScreenContent> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = S.of(context);
|
||||
PacketOptions? chosenOption;
|
||||
if (widget.plan.optionType == 'options1') {
|
||||
chosenOption = widget.plan.plan.packet1Options;
|
||||
} else if (widget.plan.optionType == 'options2') {
|
||||
chosenOption = widget.plan.plan.packet2Options;
|
||||
} else {
|
||||
chosenOption = widget.plan.plan.packet3Options;
|
||||
}
|
||||
return Scaffold(
|
||||
backgroundColor: appTheme.gray100,
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
s.infoAboutOrder,
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
leading: IconButton(icon: const Icon(Icons.arrow_back), onPressed: () {}),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
AuthorCard(
|
||||
author: widget.plan.plan.author,
|
||||
title: s.plan_seller,
|
||||
titleStyle: TextStyles.textSSemibold.copyWith(color: appTheme.gray),
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
|
||||
return BlocBuilder<OrderInfoCubit, OrderInfoState>(
|
||||
builder: (context, state) {
|
||||
final plan = state.chosenPlan;
|
||||
if (state.isLoading) {
|
||||
Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
s.infoAboutOrder,
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
PlanProps(planDuration: widget.plan.plan.duration, planPrice: chosenOption?.price.toDouble() ?? 0, planStatus: PlanStatusValues.paymentFailed),
|
||||
const SizedBox(height: 8),
|
||||
PlanInfo(
|
||||
title: widget.plan.plan.name,
|
||||
description: widget.plan.plan.details,
|
||||
imagePath: widget.plan.plan.image,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pop();
|
||||
}),
|
||||
),
|
||||
body: const Center(
|
||||
child: Loader(),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (plan == null) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
s.infoAboutOrder,
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
OptionWidget(
|
||||
option: chosenOption,
|
||||
disableDuration: true,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pop();
|
||||
}),
|
||||
),
|
||||
body: Center(
|
||||
child: Text(
|
||||
s.sorry_we_did_not_find_the_plan,
|
||||
style: TextStyles.textSSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
PlanState(
|
||||
state: widget.plan.chosenPlanState,
|
||||
),
|
||||
);
|
||||
}
|
||||
PacketOptions? chosenOption;
|
||||
if (plan.optionType == 'options1') {
|
||||
chosenOption = plan.plan.packet1Options;
|
||||
} else if (plan.optionType == 'options2') {
|
||||
chosenOption = plan.plan.packet2Options;
|
||||
} else {
|
||||
chosenOption = plan.plan.packet3Options;
|
||||
}
|
||||
|
||||
PlanStatusValues planStatus;
|
||||
if (widget.successfulPayment == true) {
|
||||
planStatus = PlanStatusValues.paid;
|
||||
} else if (widget.successfulPayment == false) {
|
||||
planStatus = PlanStatusValues.paymentFailed;
|
||||
} else if (plan.chosenPlanState == ChosenPlanStateEnum.statePaid) {
|
||||
planStatus = PlanStatusValues.paid;
|
||||
} else {
|
||||
planStatus = PlanStatusValues.pendingPayment;
|
||||
}
|
||||
return Scaffold(
|
||||
backgroundColor: appTheme.gray100,
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
s.infoAboutOrder,
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
));
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pop();
|
||||
}),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
if (widget.successfulPayment != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
PaymentBanner(
|
||||
successfulPayment: widget.successfulPayment ?? false,
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 8),
|
||||
AuthorCard(
|
||||
author: plan.plan.author,
|
||||
title: s.plan_seller,
|
||||
titleStyle: TextStyles.textSSemibold.copyWith(color: appTheme.gray),
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
PlanProps(planDuration: plan.plan.duration, planPrice: chosenOption?.price.toDouble() ?? 0, planStatus: planStatus),
|
||||
const SizedBox(height: 8),
|
||||
PlanInfo(
|
||||
title: plan.plan.name,
|
||||
description: plan.plan.details,
|
||||
imagePath: plan.plan.image,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
OptionWidget(
|
||||
option: chosenOption,
|
||||
disableDuration: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
PlanState(
|
||||
state: plan.chosenPlanState,
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
161
lib/features/order_info/presentation/widgets/payment_banner.dart
Normal file
161
lib/features/order_info/presentation/widgets/payment_banner.dart
Normal file
@@ -0,0 +1,161 @@
|
||||
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/custom_outlined_button.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/core/widgets/main_background_bouble.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/pages/payment_screen.dart';
|
||||
import 'package:eatvio_app/features/order_info/cubit/order_info_cubit.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class PaymentBanner extends StatefulWidget {
|
||||
const PaymentBanner({
|
||||
super.key,
|
||||
required this.successfulPayment,
|
||||
});
|
||||
final bool successfulPayment;
|
||||
|
||||
@override
|
||||
State<PaymentBanner> createState() => _PaymentBannerState();
|
||||
}
|
||||
|
||||
class _PaymentBannerState extends State<PaymentBanner> {
|
||||
bool isLoading = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = S.of(context);
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
return MainBackgroundBouble(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Stack(children: [
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
width: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.successfulPayment ? appTheme.blueA400 : appTheme.strongRed,
|
||||
borderRadius: const BorderRadius.only(topRight: Radius.circular(20), bottomRight: Radius.circular(20))),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: widget.successfulPayment
|
||||
? [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(
|
||||
s.cunsutation_was_paid_successfully,
|
||||
style: TextStyles.textLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(
|
||||
s.wait_for_start_day,
|
||||
style: TextStyles.textMMediumAuto.copyWith(color: appTheme.black),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
isLoading
|
||||
? const Center(child: Loader())
|
||||
: CustomOutlinedButton(
|
||||
text: s.go_to_diary,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
|
||||
buttonStyle:
|
||||
ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
|
||||
onPressed: () async {
|
||||
GoRouter.of(context).pushReplacement('/diary-screen');
|
||||
},
|
||||
),
|
||||
isLoading
|
||||
? const Center(child: Loader())
|
||||
: CustomOutlinedButton(
|
||||
text: s.back_to_chat,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
|
||||
buttonStyle:
|
||||
ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pop();
|
||||
},
|
||||
)
|
||||
]
|
||||
: [
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(
|
||||
s.smth_went_wrong_payment_failed,
|
||||
style: TextStyles.textLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width * 0.6,
|
||||
child: Text(
|
||||
s.try_again_2,
|
||||
style: TextStyles.textMMediumAuto.copyWith(color: appTheme.black),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
isLoading
|
||||
? const Center(child: Loader())
|
||||
: CustomOutlinedButton(
|
||||
text: s.pay,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
|
||||
buttonStyle:
|
||||
ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
|
||||
onPressed: () async {
|
||||
final planId = context.read<OrderInfoCubit>().state.chosenPlan?.id;
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
final paymentLink = await context.read<OrderInfoCubit>().getPaymentLink();
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
if (paymentLink != null && planId != null) {
|
||||
if (!context.mounted) return;
|
||||
GoRouter.of(context).pushReplacement(
|
||||
PaymentScreen.path,
|
||||
extra: {'url': paymentLink, 'planId': planId},
|
||||
);
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
])
|
||||
// ? Column(children: [
|
||||
// SizedBox(
|
||||
// width: size.width * 0.6,
|
||||
// child: Text(
|
||||
// s.smth_went_wrong_payment_failed,
|
||||
// style: TextStyles.textLSemibold.copyWith(color: appTheme.black),
|
||||
// ),
|
||||
// ),
|
||||
// ])
|
||||
// : Padding(
|
||||
// padding: const EdgeInsets.only(right: 16),
|
||||
// child: ,
|
||||
// ),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user