feat: Implement glossary moderation, notifications, product modals, social authentication, and internationalization.

This commit is contained in:
mso7nueh
2026-01-19 16:00:30 +03:00
parent eb69b253bc
commit d3c8034b8f
13 changed files with 1557 additions and 1684 deletions

View File

@@ -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,

View File

@@ -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),
],
);
}

View File

@@ -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,