forked from eatvio/eatvio_app
feat(order info): added order info screen
This commit is contained in:
@@ -61,7 +61,7 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
|
||||
EasyDebounce.debounce(
|
||||
'like_plan_$slug',
|
||||
Duration(seconds: 1),
|
||||
const Duration(seconds: 1),
|
||||
() async {
|
||||
try {
|
||||
await planRepository.likePlan(slug);
|
||||
@@ -86,7 +86,7 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
}
|
||||
EasyDebounce.debounce(
|
||||
'add_or_remove_plan_to_favorites',
|
||||
Duration(seconds: 1),
|
||||
const Duration(seconds: 1),
|
||||
() async {
|
||||
try {
|
||||
await planRepository.addToFavorite(slug);
|
||||
@@ -112,7 +112,7 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
}
|
||||
EasyDebounce.debounce(
|
||||
'add_or_remove_plan_to_favorites',
|
||||
Duration(seconds: 1),
|
||||
const Duration(seconds: 1),
|
||||
() async {
|
||||
try {
|
||||
await planRepository.removeFromFavorite(slug);
|
||||
|
||||
@@ -12,8 +12,7 @@ part of 'about_plan_state.dart';
|
||||
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',
|
||||
);
|
||||
'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 _$AboutPlanState {
|
||||
@@ -32,16 +31,14 @@ mixin _$AboutPlanState {
|
||||
/// @nodoc
|
||||
abstract class $AboutPlanStateCopyWith<$Res> {
|
||||
factory $AboutPlanStateCopyWith(
|
||||
AboutPlanState value,
|
||||
$Res Function(AboutPlanState) then,
|
||||
) = _$AboutPlanStateCopyWithImpl<$Res, AboutPlanState>;
|
||||
AboutPlanState value, $Res Function(AboutPlanState) then) =
|
||||
_$AboutPlanStateCopyWithImpl<$Res, AboutPlanState>;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isLoading,
|
||||
String? error,
|
||||
PlanModel? planModel,
|
||||
int chosenOptionIndex,
|
||||
});
|
||||
$Res call(
|
||||
{bool isLoading,
|
||||
String? error,
|
||||
PlanModel? planModel,
|
||||
int chosenOptionIndex});
|
||||
|
||||
$PlanModelCopyWith<$Res>? get planModel;
|
||||
}
|
||||
@@ -66,31 +63,24 @@ class _$AboutPlanStateCopyWithImpl<$Res, $Val extends AboutPlanState>
|
||||
Object? planModel = freezed,
|
||||
Object? chosenOptionIndex = null,
|
||||
}) {
|
||||
return _then(
|
||||
_value.copyWith(
|
||||
isLoading:
|
||||
null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
error:
|
||||
freezed == error
|
||||
? _value.error
|
||||
: error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
planModel:
|
||||
freezed == planModel
|
||||
? _value.planModel
|
||||
: planModel // ignore: cast_nullable_to_non_nullable
|
||||
as PlanModel?,
|
||||
chosenOptionIndex:
|
||||
null == chosenOptionIndex
|
||||
? _value.chosenOptionIndex
|
||||
: chosenOptionIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
)
|
||||
as $Val,
|
||||
);
|
||||
return _then(_value.copyWith(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
error: freezed == error
|
||||
? _value.error
|
||||
: error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
planModel: freezed == planModel
|
||||
? _value.planModel
|
||||
: planModel // ignore: cast_nullable_to_non_nullable
|
||||
as PlanModel?,
|
||||
chosenOptionIndex: null == chosenOptionIndex
|
||||
? _value.chosenOptionIndex
|
||||
: chosenOptionIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
/// Create a copy of AboutPlanState
|
||||
@@ -111,18 +101,16 @@ class _$AboutPlanStateCopyWithImpl<$Res, $Val extends AboutPlanState>
|
||||
/// @nodoc
|
||||
abstract class _$$AboutPlanStateImplCopyWith<$Res>
|
||||
implements $AboutPlanStateCopyWith<$Res> {
|
||||
factory _$$AboutPlanStateImplCopyWith(
|
||||
_$AboutPlanStateImpl value,
|
||||
$Res Function(_$AboutPlanStateImpl) then,
|
||||
) = __$$AboutPlanStateImplCopyWithImpl<$Res>;
|
||||
factory _$$AboutPlanStateImplCopyWith(_$AboutPlanStateImpl value,
|
||||
$Res Function(_$AboutPlanStateImpl) then) =
|
||||
__$$AboutPlanStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isLoading,
|
||||
String? error,
|
||||
PlanModel? planModel,
|
||||
int chosenOptionIndex,
|
||||
});
|
||||
$Res call(
|
||||
{bool isLoading,
|
||||
String? error,
|
||||
PlanModel? planModel,
|
||||
int chosenOptionIndex});
|
||||
|
||||
@override
|
||||
$PlanModelCopyWith<$Res>? get planModel;
|
||||
@@ -133,9 +121,8 @@ class __$$AboutPlanStateImplCopyWithImpl<$Res>
|
||||
extends _$AboutPlanStateCopyWithImpl<$Res, _$AboutPlanStateImpl>
|
||||
implements _$$AboutPlanStateImplCopyWith<$Res> {
|
||||
__$$AboutPlanStateImplCopyWithImpl(
|
||||
_$AboutPlanStateImpl _value,
|
||||
$Res Function(_$AboutPlanStateImpl) _then,
|
||||
) : super(_value, _then);
|
||||
_$AboutPlanStateImpl _value, $Res Function(_$AboutPlanStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of AboutPlanState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -147,42 +134,35 @@ class __$$AboutPlanStateImplCopyWithImpl<$Res>
|
||||
Object? planModel = freezed,
|
||||
Object? chosenOptionIndex = null,
|
||||
}) {
|
||||
return _then(
|
||||
_$AboutPlanStateImpl(
|
||||
isLoading:
|
||||
null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
error:
|
||||
freezed == error
|
||||
? _value.error
|
||||
: error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
planModel:
|
||||
freezed == planModel
|
||||
? _value.planModel
|
||||
: planModel // ignore: cast_nullable_to_non_nullable
|
||||
as PlanModel?,
|
||||
chosenOptionIndex:
|
||||
null == chosenOptionIndex
|
||||
? _value.chosenOptionIndex
|
||||
: chosenOptionIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
),
|
||||
);
|
||||
return _then(_$AboutPlanStateImpl(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
error: freezed == error
|
||||
? _value.error
|
||||
: error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
planModel: freezed == planModel
|
||||
? _value.planModel
|
||||
: planModel // ignore: cast_nullable_to_non_nullable
|
||||
as PlanModel?,
|
||||
chosenOptionIndex: null == chosenOptionIndex
|
||||
? _value.chosenOptionIndex
|
||||
: chosenOptionIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$AboutPlanStateImpl implements _AboutPlanState {
|
||||
const _$AboutPlanStateImpl({
|
||||
required this.isLoading,
|
||||
required this.error,
|
||||
required this.planModel,
|
||||
required this.chosenOptionIndex,
|
||||
});
|
||||
const _$AboutPlanStateImpl(
|
||||
{required this.isLoading,
|
||||
required this.error,
|
||||
required this.planModel,
|
||||
required this.chosenOptionIndex});
|
||||
|
||||
@override
|
||||
final bool isLoading;
|
||||
@@ -223,18 +203,15 @@ class _$AboutPlanStateImpl implements _AboutPlanState {
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$AboutPlanStateImplCopyWith<_$AboutPlanStateImpl> get copyWith =>
|
||||
__$$AboutPlanStateImplCopyWithImpl<_$AboutPlanStateImpl>(
|
||||
this,
|
||||
_$identity,
|
||||
);
|
||||
this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _AboutPlanState implements AboutPlanState {
|
||||
const factory _AboutPlanState({
|
||||
required final bool isLoading,
|
||||
required final String? error,
|
||||
required final PlanModel? planModel,
|
||||
required final int chosenOptionIndex,
|
||||
}) = _$AboutPlanStateImpl;
|
||||
const factory _AboutPlanState(
|
||||
{required final bool isLoading,
|
||||
required final String? error,
|
||||
required final PlanModel? planModel,
|
||||
required final int chosenOptionIndex}) = _$AboutPlanStateImpl;
|
||||
|
||||
@override
|
||||
bool get isLoading;
|
||||
|
||||
@@ -32,10 +32,10 @@ import 'package:flutter_portal/flutter_portal.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../widgets/option_widget.dart';
|
||||
import '../../../../core/widgets/option_widget.dart';
|
||||
|
||||
class AboutPlanScreen extends StatefulWidget {
|
||||
AboutPlanScreen({super.key, required this.plan, required this.navigateToComments, required this.index});
|
||||
const AboutPlanScreen({super.key, required this.plan, required this.navigateToComments, required this.index});
|
||||
final PlanModel plan;
|
||||
final bool navigateToComments;
|
||||
final int? index;
|
||||
@@ -97,7 +97,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
builder: (BuildContext context, CommentsState commentsState) {
|
||||
return BlocBuilder<AboutPlanCubit, AboutPlanState>(
|
||||
builder: (context, state) {
|
||||
if (state.isLoading)
|
||||
if (state.isLoading) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
@@ -117,7 +117,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
path: 'plan/${widget.plan.id}',
|
||||
slug: widget.plan.slug,
|
||||
),
|
||||
anchor: Aligned(
|
||||
anchor: const Aligned(
|
||||
shiftToWithinBound: AxisFlag(x: true, y: true),
|
||||
follower: Alignment.topRight,
|
||||
target: Alignment.bottomRight,
|
||||
@@ -137,8 +137,9 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Loader(),
|
||||
body: const Loader(),
|
||||
);
|
||||
}
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (widget.navigateToComments && !_jumped) {
|
||||
_scrollToBottom();
|
||||
@@ -164,7 +165,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
path: 'plan/${widget.plan.id}',
|
||||
slug: widget.plan.slug,
|
||||
),
|
||||
anchor: Aligned(
|
||||
anchor: const Aligned(
|
||||
shiftToWithinBound: AxisFlag(x: true, y: true),
|
||||
follower: Alignment.topRight,
|
||||
target: Alignment.bottomRight,
|
||||
@@ -191,7 +192,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
backgroundColor: appTheme.gray100,
|
||||
resizeToAvoidBottomInset: true,
|
||||
bottomSheet: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
@@ -221,9 +222,11 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
onPressed: () async {
|
||||
final chosenPlan = await context.read<AboutPlanCubit>().chosePlan();
|
||||
if (chosenPlan == null) {
|
||||
if (!context.mounted) return;
|
||||
showErrorDialog(context, title: 'Не удалось заказать план');
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
GoRouter.of(context).pushReplacementNamed(
|
||||
'chatScreen',
|
||||
extra: {
|
||||
@@ -238,7 +241,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
BookmarkButton(
|
||||
isFavorite: state.planModel?.isFavorite ?? false,
|
||||
onTap: () {
|
||||
@@ -258,7 +261,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@@ -279,17 +282,17 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
),
|
||||
height: 32,
|
||||
width: 32,
|
||||
child: Icon(
|
||||
child: const Icon(
|
||||
Icons.close_rounded,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (replyId != null) SizedBox(width: 8),
|
||||
if (replyId != null) const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(minHeight: 52),
|
||||
constraints: const BoxConstraints(minHeight: 52),
|
||||
child: TextFormField(
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
onChanged: (_) {
|
||||
@@ -299,7 +302,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
maxLines: 5,
|
||||
minLines: 1,
|
||||
keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black,
|
||||
@@ -307,9 +310,9 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
isDense: false, // убираем true, чтобы padding учитывался корректно
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), // вертикальный паддинг увеличен
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), // вертикальный паддинг увеличен
|
||||
hintText: 'Комментарий',
|
||||
hintStyle: TextStyle(
|
||||
hintStyle: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1.2,
|
||||
@@ -318,21 +321,21 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
filled: true,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(color: Color(0xFFD1D1D6), width: 1),
|
||||
borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(color: Color(0xFFD1D1D6), width: 1),
|
||||
borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(color: Color(0xFFD1D1D6), width: 1),
|
||||
borderSide: const BorderSide(color: Color(0xFFD1D1D6), width: 1),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (textEditingController.text.length > 2) {
|
||||
@@ -348,8 +351,10 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
replyId = null;
|
||||
});
|
||||
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
context.read<AboutPlanCubit>().getPlan(widget.plan.slug);
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (context.mounted) {
|
||||
context.read<AboutPlanCubit>().getPlan(widget.plan.slug);
|
||||
}
|
||||
});
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
@@ -392,7 +397,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
path: 'plan/${widget.plan.id}',
|
||||
slug: widget.plan.slug,
|
||||
),
|
||||
anchor: Aligned(
|
||||
anchor: const Aligned(
|
||||
shiftToWithinBound: AxisFlag(x: true, y: true),
|
||||
follower: Alignment.topRight,
|
||||
target: Alignment.bottomRight,
|
||||
@@ -414,11 +419,11 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
padding: EdgeInsets.only(bottom: 160),
|
||||
padding: const EdgeInsets.only(bottom: 160),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
MainBackgroundBouble(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -426,7 +431,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
Stack(
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: baseUrl + '/storage/' + widget.plan.image,
|
||||
imageUrl: '$baseUrl/storage/${widget.plan.image}',
|
||||
height: 300,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
fit: BoxFit.fill,
|
||||
@@ -439,22 +444,23 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
InfoBouble(
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
children: [
|
||||
SvgPicture.asset('assets/icons/eye.svg', width: 18, height: 12),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
widget.plan.totalViews.toString(),
|
||||
style: TextStyles.textXSSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
],
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
const SizedBox(width: 12),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
context.read<AboutPlanCubit>().likePlan(slug: widget.plan.slug, index: widget.index);
|
||||
},
|
||||
child: InfoBouble(
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/icons/heart.svg',
|
||||
@@ -462,33 +468,32 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
height: 12,
|
||||
colorFilter: state.planModel?.wasLikedByMe == true ? ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn) : null,
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
state.planModel?.totalLikes.toString() ?? '0',
|
||||
style: TextStyles.textXSSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
],
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
const SizedBox(width: 12),
|
||||
InfoBouble(
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
children: [
|
||||
SvgPicture.asset('assets/icons/comment2.svg', width: 13, height: 12),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
widget.plan.totalComments.toString(),
|
||||
style: TextStyles.textXSSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
],
|
||||
backgroundColor: appTheme.whiteA700,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
@@ -496,12 +501,12 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
const SizedBox(height: 12),
|
||||
InfoRow(plan: state.planModel, type: ProductType.plan),
|
||||
ExpandableText(
|
||||
text: widget.plan.details,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: AuthorCard(
|
||||
@@ -509,11 +514,11 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
title: s.plan_author,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
if (state.planModel?.packetsCount == 3) ...[
|
||||
OptionsTab(
|
||||
cost: [
|
||||
@@ -522,7 +527,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
state.planModel?.packet3Options?.price ?? 0,
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
switch (state.chosenOptionIndex) {
|
||||
1 => OptionWidget(
|
||||
@@ -535,15 +540,15 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
option: state.planModel?.packet1Options,
|
||||
),
|
||||
},
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
MainBackgroundBouble(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'${state.planModel?.totalComments ?? 0} ${getCommentForm(state.planModel?.totalComments ?? 0, s)}',
|
||||
@@ -552,7 +557,7 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
if (commentsState is CommentsStateLoading) const Loader(),
|
||||
if (commentsState is CommentsStateLoaded)
|
||||
CommentsWidget(
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/utils/localization_utils.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OptionDurationWidget extends StatelessWidget {
|
||||
const OptionDurationWidget({super.key, required this.duration});
|
||||
final int duration;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = S.of(context);
|
||||
return Container(
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), color: appTheme.cardBackground),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Container(
|
||||
width: 4,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(100),
|
||||
bottomRight: Radius.circular(100),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Text(
|
||||
'${s.option_duration} $duration ${getDayForm(duration, s)}',
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
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_divider.dart';
|
||||
import 'package:eatvio_app/core/widgets/main_background_bouble.dart';
|
||||
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
|
||||
import 'package:eatvio_app/core/widgets/item_widget.dart';
|
||||
import 'package:eatvio_app/features/plans/presentation/widgets/option_duration_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OptionWidget extends StatelessWidget {
|
||||
const OptionWidget({super.key, required this.option});
|
||||
final PacketOptions? option;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (option == null) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return MainBackgroundBouble(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
option?.short ?? '',
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Text(
|
||||
option?.description ?? '',
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
OptionDurationWidget(duration: 7),
|
||||
SizedBox(height: 16),
|
||||
CustomDivider(),
|
||||
SizedBox(height: 16),
|
||||
ListView.separated(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
separatorBuilder: (context, index) => SizedBox(height: 12),
|
||||
itemBuilder: (context, index) => ItemWidget(text: option?.items[index] ?? ''),
|
||||
itemCount: option?.items.length ?? 0,
|
||||
shrinkWrap: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ class OptionsTab extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
final selectedOption = state.chosenOptionIndex;
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 4),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.whiteA700,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
|
||||
Reference in New Issue
Block a user