forked from eatvio/eatvio_app
feat: Implement glossary moderation, notifications, product modals, social authentication, and internationalization.
This commit is contained in:
@@ -165,6 +165,11 @@ class _AddProductModalState extends State<AddProductModal> {
|
||||
if (widget.portion != null) const SizedBox(width: 8),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
// Автоматически выбираем первый элемент, если текст точно совпадает
|
||||
if (selectedGlossary == null && glossariesList.isNotEmpty && productNameController.text.trim() == glossariesList[0].name) {
|
||||
selectedGlossary = glossariesList[0];
|
||||
}
|
||||
|
||||
if (widget.portion == null) {
|
||||
widget.diaryCubit.addProductToMeal(
|
||||
diaryId: widget.state.diary.id,
|
||||
|
||||
@@ -11,55 +11,53 @@ class ChosenPlanWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DiaryCubit, DiaryState>(builder: (context, state) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
if (state.diary.typeOfDiary.hasChosenPlan) {
|
||||
return ChosenPlanWidgetContent(
|
||||
currentPlanDay: state.chosenPlanCurrentDay ?? 0,
|
||||
planName: state.chosenPlanName ?? '',
|
||||
planDuration: state.chosenPlanDuration ?? 0,
|
||||
);
|
||||
return BlocBuilder<DiaryCubit, DiaryState>(
|
||||
builder: (context, state) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
if (state.diary.typeOfDiary.hasChosenPlan) {
|
||||
return ChosenPlanWidgetContent(
|
||||
currentPlanDay: state.chosenPlanCurrentDay ?? 0,
|
||||
planName: state.chosenPlanName ?? '',
|
||||
planDuration: state.chosenPlanDuration ?? 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
});
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChosenPlanWidgetContent extends StatelessWidget {
|
||||
const ChosenPlanWidgetContent({
|
||||
super.key,
|
||||
required this.currentPlanDay,
|
||||
required this.planName,
|
||||
required this.planDuration,
|
||||
});
|
||||
const ChosenPlanWidgetContent({super.key, required this.currentPlanDay, required this.planName, required this.planDuration});
|
||||
final int currentPlanDay;
|
||||
final String planName;
|
||||
final int planDuration;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
final s = S.of(context);
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: size.width * 0.4,
|
||||
child: Text(planName, style: TextStyles.textLMedium.copyWith(color: appTheme.black)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
planName,
|
||||
style: TextStyles.textLMedium.copyWith(color: appTheme.black),
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.visible,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
decoration: BoxDecoration(color: appTheme.dividerColor, borderRadius: BorderRadius.circular(12)),
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
|
||||
child: Text('${s.day} $currentPlanDay из $planDuration', style: TextStyles.textMSemibold.copyWith(color: appTheme.gray)),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
)
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,19 @@ class _GlossaryModerationRequestModalWidgetState extends State<GlossaryModeratio
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
icon: const Icon(Icons.close, color: Color(0xFF323F4B)),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const Text(
|
||||
'Добавление нового продукта',
|
||||
textAlign: TextAlign.center,
|
||||
@@ -68,10 +81,10 @@ class _GlossaryModerationRequestModalWidgetState extends State<GlossaryModeratio
|
||||
onTap: () async {
|
||||
glossary = (await widget.diaryCubit.sendProductToModeration(
|
||||
name: productNameController.text,
|
||||
energy: 0,
|
||||
proteins: 0,
|
||||
fats: 0,
|
||||
carbohydrates: 0,
|
||||
energy: 1,
|
||||
proteins: 1,
|
||||
fats: 1,
|
||||
carbohydrates: 1,
|
||||
))?.glossary;
|
||||
setState(() {
|
||||
glossaryState = GlossaryState.success;
|
||||
@@ -126,6 +139,19 @@ class _GlossaryModerationRequestModalWidgetState extends State<GlossaryModeratio
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
icon: const Icon(Icons.close, color: Color(0xFF323F4B)),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const Text(
|
||||
'Продукт успешно отправлен\nна модерацию',
|
||||
textAlign: TextAlign.center,
|
||||
@@ -163,6 +189,19 @@ class _GlossaryModerationRequestModalWidgetState extends State<GlossaryModeratio
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
icon: const Icon(Icons.close, color: Color(0xFF323F4B)),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const Text(
|
||||
'Добавление нового продукта',
|
||||
textAlign: TextAlign.center,
|
||||
|
||||
Reference in New Issue
Block a user