fix(my_plans): Issue-189

This commit is contained in:
mso7nueh
2025-09-16 19:09:41 +03:00
parent b146295996
commit c295c06565
5 changed files with 77 additions and 250 deletions

View File

@@ -172,43 +172,43 @@ class _AuthScreenState extends State<AuthScreen> {
children: [
_SocialButton(
onTap: _onVkPressed,
backgroundColor: const Color(0xFF2787F5),
tooltip: 'VK ID',
child: SvgPicture.asset(
'assets/icons/vk.svg',
height: 24,
width: 24,
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
),
backgroundColor: const Color(0xFF2787F5),
tooltip: 'VK ID',
),
_SocialButton(
onTap: _onOkPressed,
backgroundColor: const Color(0xFFF58220),
tooltip: 'Одноклассники',
child: SvgPicture.asset(
'assets/icons/ok.svg',
height: 24,
width: 24,
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
),
backgroundColor: const Color(0xFFF58220),
tooltip: 'Одноклассники',
),
_SocialButton(
const _SocialButton(
onTap: _onMailRuPressed,
child: const Text(
backgroundColor: Color(0xFF005FF9),
tooltip: 'Mail.ru',
child: Text(
'Mail',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700),
),
backgroundColor: const Color(0xFF005FF9),
tooltip: 'Mail.ru',
),
_SocialButton(
const _SocialButton(
onTap: _onYandexPressed,
child: const Text(
backgroundColor: Color(0xFFFFCC00),
tooltip: 'Яндекс ID',
child: Text(
'Yandex',
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w700),
),
backgroundColor: const Color(0xFFFFCC00),
tooltip: 'Яндекс ID',
),
],
),

View File

@@ -12,7 +12,6 @@ import 'package:eatvio_app/features/feed/presentation/widgets/plans_filter_botto
import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_cubit.dart';
import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_state.dart';
import 'package:eatvio_app/features/my_plans/presentation/widgets/my_plan_widget.dart';
import 'package:eatvio_app/features/my_plans/presentation/widgets/my_plans_tab.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -64,9 +63,7 @@ class MyPlansScreenContent extends StatelessWidget {
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)),
),
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))),
backgroundColor: appTheme.gray100,
foregroundColor: appTheme.gray100,
automaticallyImplyLeading: false,
@@ -76,21 +73,12 @@ class MyPlansScreenContent extends StatelessWidget {
snap: true,
scrolledUnderElevation: 0,
bottom: PreferredSize(
preferredSize: Size(
MediaQuery.sizeOf(context).width,
64,
),
preferredSize: Size(MediaQuery.sizeOf(context).width, 32),
child: Padding(
padding: const EdgeInsets.only(bottom: 0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 8),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 4),
child: MyPlansTab(),
),
const SizedBox(height: 8),
Row(
children: [
const SizedBox(width: 4),
@@ -104,20 +92,14 @@ class MyPlansScreenContent extends StatelessWidget {
_ => activePlansSearchController,
},
onChanged: (query) {
EasyDebounce.debounce(
'searchPlans',
const Duration(milliseconds: 500),
() {
context.read<MyPlansCubit>().loadPlans(query: query == '' ? null : query);
},
);
EasyDebounce.debounce('searchPlans', const Duration(milliseconds: 500), () {
context.read<MyPlansCubit>().loadPlans(query: query == '' ? null : query);
});
},
),
),
const SizedBox(width: 12),
AddItemButton(
onTap: () => GoRouter.of(context).pushNamed(CreatePlanScreen.name),
),
AddItemButton(onTap: () => GoRouter.of(context).pushNamed(CreatePlanScreen.name)),
const SizedBox(width: 4),
],
),
@@ -134,10 +116,7 @@ class MyPlansScreenContent extends StatelessWidget {
child: BlocBuilder<MyPlansCubit, MyPlansState>(
builder: (BuildContext context, MyPlansState state) {
if (state.isLoading) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: const Loader(),
);
return Scaffold(backgroundColor: Colors.grey.shade200, body: const Loader());
} else if (state.error != null) {
return DataErrorWidget(onReload: () => context.read<MyPlansCubit>().loadPlans());
} else {
@@ -162,11 +141,7 @@ class MyPlansScreenContent extends StatelessWidget {
Positioned(
right: 0,
bottom: 74,
child: FilterBadge(
filterBottomSheet: PlansFilterBottomSheet(
myPlansCubit: context.read<MyPlansCubit>(),
),
),
child: FilterBadge(filterBottomSheet: PlansFilterBottomSheet(myPlansCubit: context.read<MyPlansCubit>())),
),
],
);

View File

@@ -14,16 +14,13 @@ import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_svg/svg.dart';
// Removed SVG icon usage after switching to text buttons
import 'package:go_router/go_router.dart';
import 'package:share_plus/share_plus.dart';
class MyPlanWidget extends StatefulWidget {
final PlanModel plan;
const MyPlanWidget({
super.key,
required this.plan,
});
const MyPlanWidget({super.key, required this.plan});
@override
State<MyPlanWidget> createState() => _MyPlanWidgetState();
@@ -34,10 +31,7 @@ class _MyPlanWidgetState extends State<MyPlanWidget> {
Widget build(BuildContext context) {
final s = S.of(context);
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.white,
),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -48,23 +42,14 @@ class _MyPlanWidgetState extends State<MyPlanWidget> {
onTap: () => GoRouter.of(context).pushNamed('aboutPlanScreen', extra: {'slug': widget.plan.slug, 'navigateToComments': false}),
child: ClipRRect(
borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
child: CachedNetworkImage(
imageUrl: '$baseUrl/storage/${widget.plan.image}',
fit: BoxFit.fitWidth,
width: MediaQuery.of(context).size.width,
),
child: CachedNetworkImage(imageUrl: '$baseUrl/storage/${widget.plan.image}', fit: BoxFit.fitWidth, width: MediaQuery.of(context).size.width),
),
),
Positioned(
bottom: 16,
child: SizedBox(
width: MediaQuery.sizeOf(context).width,
child: InfoRow(
plan: widget.plan,
itemsBackgroundColor: appTheme.whiteA700,
disableDescriptionOfTypes: true,
type: ProductType.plan,
),
child: InfoRow(plan: widget.plan, itemsBackgroundColor: appTheme.whiteA700, disableDescriptionOfTypes: true, type: ProductType.plan),
),
),
],
@@ -75,19 +60,16 @@ class _MyPlanWidgetState extends State<MyPlanWidget> {
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
widget.plan.name,
style: TextStyles.textMSemibold.copyWith(color: appTheme.black),
),
child: Text(widget.plan.name, style: TextStyles.textMSemibold.copyWith(color: appTheme.black)),
),
if (widget.plan.details.isNotEmpty) ...[
const SizedBox(
height: 12,
),
const SizedBox(height: 12),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Html(
data: widget.plan.details.length > 200 ? '${widget.plan.details.substring(0, 200).replaceAll('\n', '<br>')}...' : widget.plan.details.replaceAll('\n', '<br>'),
data: widget.plan.details.length > 200
? '${widget.plan.details.substring(0, 200).replaceAll('\n', '<br>')}...'
: widget.plan.details.replaceAll('\n', '<br>'),
style: {
"*": Style(
margin: Margins.zero,
@@ -116,26 +98,61 @@ class _MyPlanWidgetState extends State<MyPlanWidget> {
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
// Buttons aligned with MyRecipeWidget: Delete (gray) and Share (blue)
Row(
children: [
Expanded(
child: CustomOutlinedButton(
text: switch (state.selectedStateIndex) {
1 => s.publish,
_ => s.edit,
onPressed: () async {
final result = await context.read<MyPlansCubit>().deletePlan(widget.plan.slug);
if (result) {
Future.delayed(const Duration(seconds: 3), () {
if (!context.mounted) return;
showBottomSheetWithBlur(
context: context,
child: Column(
children: [
const SizedBox(height: 20),
const BottomSheetHandlerBar(),
const SizedBox(height: 20),
Text(widget.plan.name, style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
Text(s.deleted, style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: CustomOutlinedButton(
onPressed: () {
context.pop();
},
text: 'Хорошо',
height: 52,
buttonTextStyle: TextStyles.textSSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(
side: const WidgetStatePropertyAll(BorderSide.none),
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
),
),
),
const SizedBox(height: 20),
],
),
);
});
}
},
text: 'Удалить',
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.black),
buttonStyle: ButtonStyle(
shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(20))),
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
backgroundColor: WidgetStatePropertyAll(appTheme.lightGray0),
side: const WidgetStatePropertyAll(BorderSide.none),
),
),
),
if (state.selectedStateIndex == 0) ...[
const SizedBox(width: 6),
CustomOutlinedButton(
const SizedBox(width: 8),
Expanded(
child: CustomOutlinedButton(
onPressed: () async {
final box = context.findRenderObject() as RenderBox?;
await SharePlus.instance.share(
@@ -146,109 +163,14 @@ class _MyPlanWidgetState extends State<MyPlanWidget> {
);
},
height: 52,
width: 52,
leftIcon: SvgPicture.asset(
'assets/icons/share2.svg',
width: 20,
height: 20,
colorFilter: ColorFilter.mode(appTheme.whiteA700, BlendMode.srcIn),
),
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.red),
buttonStyle: ButtonStyle(
shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(20))),
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
side: const WidgetStatePropertyAll(BorderSide.none),
),
text: '',
text: s.share,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
),
],
],
),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: CustomOutlinedButton(
text: switch (state.selectedStateIndex) {
0 => s.removeFromActive,
_ => s.edit,
},
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.black),
buttonStyle: ButtonStyle(
shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(20))),
backgroundColor: WidgetStatePropertyAll(appTheme.lightGray0),
side: const WidgetStatePropertyAll(BorderSide.none),
),
),
),
const SizedBox(width: 6),
CustomOutlinedButton(
onPressed: () async {
final result = await context.read<MyPlansCubit>().deletePlan(widget.plan.slug);
if (result) {
Future.delayed(const Duration(seconds: 3), () {
if (!context.mounted) return;
showBottomSheetWithBlur(
context: context,
child: Column(
children: [
const SizedBox(
height: 20,
),
const BottomSheetHandlerBar(),
const SizedBox(
height: 20,
),
Text(
widget.plan.name,
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
Text(
s.deleted,
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
const SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: CustomOutlinedButton(
onPressed: () {
context.pop();
},
text: 'Хорошо',
height: 52,
buttonTextStyle: TextStyles.textSSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(
side: const WidgetStatePropertyAll(BorderSide.none),
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
),
),
),
const SizedBox(
height: 20,
),
],
),
);
});
}
},
height: 52,
width: 52,
leftIcon: SvgPicture.asset(
'assets/icons/trash_can.svg',
width: 20,
height: 20,
),
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.red),
buttonStyle: ButtonStyle(
shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(20))),
backgroundColor: WidgetStatePropertyAll(appTheme.lightGray0),
side: const WidgetStatePropertyAll(BorderSide.none),
),
text: '',
),
],
),

View File

@@ -1,71 +1,3 @@
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/animated_option_button.dart';
import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_cubit.dart';
import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_state.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// File intentionally left minimal after removing tabs for My Plans
class MyPlansTab extends StatefulWidget {
const MyPlansTab({super.key, this.additionalOnTap});
final void Function()? additionalOnTap;
@override
State<MyPlansTab> createState() => _MyPlansTabState();
}
class _MyPlansTabState extends State<MyPlansTab> {
final List<String> tabTitles = [];
@override
void didChangeDependencies() {
final s = S.of(context);
if (tabTitles.isEmpty) {
tabTitles.add(s.published);
tabTitles.add(s.drafted);
}
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<MyPlansCubit, MyPlansState>(
builder: (context, state) {
return Align(
alignment: Alignment.centerLeft,
child: Row(
children: [
Expanded(
child: Container(
height: 48,
decoration: BoxDecoration(
color: appTheme.whiteA700,
borderRadius: BorderRadius.circular(100),
),
padding: const EdgeInsets.all(4),
child: Row(
children: [
...List.generate(
2,
(index) => Expanded(
child: AnimatedOptionButton(
textStyle: TextStyles.textSMedium,
isSelected: state.selectedStateIndex == index,
text: tabTitles[index],
onTap: () {
widget.additionalOnTap?.call();
context.read<MyPlansCubit>().changeSelectedStateIndex(index);
},
),
),
),
],
),
),
),
],
),
);
},
);
}
}
// Drafts/published tab UI removed per requirements

View File

@@ -1,6 +1,4 @@
import 'dart:developer';
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dismissible_page/dismissible_page.dart';
import 'package:eatvio_app/core/app_router.dart';