create diet screen

This commit is contained in:
Username1548
2024-11-25 16:01:02 +07:00
parent c3cb55f8a2
commit c78a90b603
42 changed files with 1742 additions and 918 deletions

View File

@@ -1,4 +1,20 @@
import 'package:flutter/widgets.dart';
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/utils/localization_utils.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/core/widgets/main_background_bouble.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/features/create_diet/presentation/widgets/day_widget.dart';
import 'package:eatvio_app/features/create_diet/presentation/widgets/duration_drop_down_widget.dart';
import 'package:eatvio_app/features/create_diet/presentation/widgets/image_picker_widget.dart';
import 'package:eatvio_app/features/create_diet/presentation/widgets/status_drop_down_widget.dart';
import 'package:eatvio_app/features/create_diet/presentation/widgets/type_choice_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CreateDietScreen extends StatelessWidget {
static const name = 'createDietScreen';
@@ -7,6 +23,97 @@ class CreateDietScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const Placeholder();
return BlocProvider(
create: (context) => sl<CreateDietCubit>(),
child: const CreateDietScreenContent(),
);
}
}
}
class CreateDietScreenContent extends StatelessWidget {
const CreateDietScreenContent({super.key});
@override
Widget build(BuildContext context) {
final s = S.of(context);
return Scaffold(
backgroundColor: appTheme.gray100,
appBar: AppBar(
centerTitle: true,
title: Text(
s.create_diet,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
),
body: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 8),
MainBackgroundBouble(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
SizedBox(height: 16),
CustomTextFormField(
hintText: s.enter_diet_name,
onChanged: (value) {
context.read<CreateDietCubit>().setName(value);
},
),
SizedBox(height: 12),
SizedBox(
height: 132,
child: CustomTextFormField(
textAlignVertical: TextAlignVertical.top,
maxLines: null,
minLines: null,
expands: true,
hintText: s.enter_diet_description,
onChanged: (value) {
context.read<CreateDietCubit>().setDetails(value);
},
),
),
SizedBox(height: 12),
DurationDropDownWidget(),
SizedBox(height: 12),
StatusDropDownWidget(),
SizedBox(height: 16),
TypeChoiceWidget(),
SizedBox(height: 16),
ImagePickerWidget(),
SizedBox(height: 16),
],
),
),
SizedBox(height: 16),
BlocBuilder<CreateDietCubit, CreateDietState>(
builder: (context, state) {
return MainBackgroundBouble(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Center(
child: Text(
s.diet_plan + ' (${state.dietData.duration ?? 0} ' + getDayForm(state.dietData.duration ?? 0, s) + ')',
style: TextStyles.headingXLSemibold.copyWith(
color: appTheme.black,
),
),
),
),
);
},
),
SizedBox(height: 8),
DayWidget(
index: 0,
),
],
),
),
);
}
}

View File

@@ -1,11 +1,14 @@
import 'dart:io';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/features/create_diet/repositories/create_diet_repository.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
class CreateDietCubit extends Cubit<CreateDietState> {
CreateDietCubit() : super(CreateDietState.initial());
final CreateDietRepository createDietRepository;
static const _dietStateValues = ['active', 'draft', 'personal'];
CreateDietCubit({required this.createDietRepository}) : super(CreateDietState.initial());
void setDetails(String text) {
emit(state.copyWith(dietData: state.dietData.copyWith(details: text)));
@@ -15,11 +18,18 @@ class CreateDietCubit extends Cubit<CreateDietState> {
emit(state.copyWith(dietData: state.dietData.copyWith(name: name)));
}
void setDuration(int duration) {
emit(state.copyWith(dietData: state.dietData.copyWith(duration: duration)));
void setDuration(int index) {
emit(
state.copyWith(
durationIndex: index,
dietData: state.dietData.copyWith(
duration: durationValues[index],
),
),
);
}
void setImage(File image) {
void setImage(XFile? image) {
emit(state.copyWith(dietData: state.dietData.copyWith(image: image)));
}
@@ -27,11 +37,11 @@ class CreateDietCubit extends Cubit<CreateDietState> {
emit(state.copyWith(dietData: state.dietData.copyWith(dailySchedule: dailySchedule)));
}
void setDietState(String dietState) {
emit(state.copyWith(dietData: state.dietData.copyWith(state: dietState)));
void setDietState(int index) {
emit(state.copyWith(dietStateIndex: index, dietData: state.dietData.copyWith(state: _dietStateValues[index])));
}
void setDietType(List<String> type) {
void setDietType(List<bool> type) {
emit(state.copyWith(dietData: state.dietData.copyWith(type: type)));
}
}

View File

@@ -9,7 +9,9 @@ class CreateDietState with _$CreateDietState {
required bool isLoading,
required String? errorMessage,
required CreateDietModel dietData,
int? durationIndex,
int? dietStateIndex,
}) = _CreateDietState;
factory CreateDietState.initial() => CreateDietState(isLoading: false, errorMessage: null, dietData: CreateDietModel());
factory CreateDietState.initial() => CreateDietState(isLoading: false, errorMessage: null, dietData: CreateDietModel(type: [false, false, false, false]));
}

View File

@@ -19,6 +19,8 @@ mixin _$CreateDietState {
bool get isLoading => throw _privateConstructorUsedError;
String? get errorMessage => throw _privateConstructorUsedError;
CreateDietModel get dietData => throw _privateConstructorUsedError;
int? get durationIndex => throw _privateConstructorUsedError;
int? get dietStateIndex => throw _privateConstructorUsedError;
/// Create a copy of CreateDietState
/// with the given fields replaced by the non-null parameter values.
@@ -33,7 +35,12 @@ abstract class $CreateDietStateCopyWith<$Res> {
CreateDietState value, $Res Function(CreateDietState) then) =
_$CreateDietStateCopyWithImpl<$Res, CreateDietState>;
@useResult
$Res call({bool isLoading, String? errorMessage, CreateDietModel dietData});
$Res call(
{bool isLoading,
String? errorMessage,
CreateDietModel dietData,
int? durationIndex,
int? dietStateIndex});
$CreateDietModelCopyWith<$Res> get dietData;
}
@@ -56,6 +63,8 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState>
Object? isLoading = null,
Object? errorMessage = freezed,
Object? dietData = null,
Object? durationIndex = freezed,
Object? dietStateIndex = freezed,
}) {
return _then(_value.copyWith(
isLoading: null == isLoading
@@ -70,6 +79,14 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState>
? _value.dietData
: dietData // ignore: cast_nullable_to_non_nullable
as CreateDietModel,
durationIndex: freezed == durationIndex
? _value.durationIndex
: durationIndex // ignore: cast_nullable_to_non_nullable
as int?,
dietStateIndex: freezed == dietStateIndex
? _value.dietStateIndex
: dietStateIndex // ignore: cast_nullable_to_non_nullable
as int?,
) as $Val);
}
@@ -92,7 +109,12 @@ abstract class _$$CreateDietStateImplCopyWith<$Res>
__$$CreateDietStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({bool isLoading, String? errorMessage, CreateDietModel dietData});
$Res call(
{bool isLoading,
String? errorMessage,
CreateDietModel dietData,
int? durationIndex,
int? dietStateIndex});
@override
$CreateDietModelCopyWith<$Res> get dietData;
@@ -114,6 +136,8 @@ class __$$CreateDietStateImplCopyWithImpl<$Res>
Object? isLoading = null,
Object? errorMessage = freezed,
Object? dietData = null,
Object? durationIndex = freezed,
Object? dietStateIndex = freezed,
}) {
return _then(_$CreateDietStateImpl(
isLoading: null == isLoading
@@ -128,6 +152,14 @@ class __$$CreateDietStateImplCopyWithImpl<$Res>
? _value.dietData
: dietData // ignore: cast_nullable_to_non_nullable
as CreateDietModel,
durationIndex: freezed == durationIndex
? _value.durationIndex
: durationIndex // ignore: cast_nullable_to_non_nullable
as int?,
dietStateIndex: freezed == dietStateIndex
? _value.dietStateIndex
: dietStateIndex // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
@@ -138,7 +170,9 @@ class _$CreateDietStateImpl implements _CreateDietState {
const _$CreateDietStateImpl(
{required this.isLoading,
required this.errorMessage,
required this.dietData});
required this.dietData,
this.durationIndex,
this.dietStateIndex});
@override
final bool isLoading;
@@ -146,10 +180,14 @@ class _$CreateDietStateImpl implements _CreateDietState {
final String? errorMessage;
@override
final CreateDietModel dietData;
@override
final int? durationIndex;
@override
final int? dietStateIndex;
@override
String toString() {
return 'CreateDietState(isLoading: $isLoading, errorMessage: $errorMessage, dietData: $dietData)';
return 'CreateDietState(isLoading: $isLoading, errorMessage: $errorMessage, dietData: $dietData, durationIndex: $durationIndex, dietStateIndex: $dietStateIndex)';
}
@override
@@ -162,12 +200,16 @@ class _$CreateDietStateImpl implements _CreateDietState {
(identical(other.errorMessage, errorMessage) ||
other.errorMessage == errorMessage) &&
(identical(other.dietData, dietData) ||
other.dietData == dietData));
other.dietData == dietData) &&
(identical(other.durationIndex, durationIndex) ||
other.durationIndex == durationIndex) &&
(identical(other.dietStateIndex, dietStateIndex) ||
other.dietStateIndex == dietStateIndex));
}
@override
int get hashCode =>
Object.hash(runtimeType, isLoading, errorMessage, dietData);
int get hashCode => Object.hash(runtimeType, isLoading, errorMessage,
dietData, durationIndex, dietStateIndex);
/// Create a copy of CreateDietState
/// with the given fields replaced by the non-null parameter values.
@@ -183,7 +225,9 @@ abstract class _CreateDietState implements CreateDietState {
const factory _CreateDietState(
{required final bool isLoading,
required final String? errorMessage,
required final CreateDietModel dietData}) = _$CreateDietStateImpl;
required final CreateDietModel dietData,
final int? durationIndex,
final int? dietStateIndex}) = _$CreateDietStateImpl;
@override
bool get isLoading;
@@ -191,6 +235,10 @@ abstract class _CreateDietState implements CreateDietState {
String? get errorMessage;
@override
CreateDietModel get dietData;
@override
int? get durationIndex;
@override
int? get dietStateIndex;
/// Create a copy of CreateDietState
/// with the given fields replaced by the non-null parameter values.

View File

@@ -0,0 +1,178 @@
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/custom_outlined_button.dart';
import 'package:eatvio_app/core/widgets/main_background_bouble.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
class DayWidget extends StatefulWidget {
const DayWidget({
super.key,
required this.index,
});
final int index;
@override
State<DayWidget> createState() => _DayWidgetState();
}
class _DayWidgetState extends State<DayWidget> {
int _selectedDayIndex = 0;
final chipsLabelList = ['1', '2', '3', '4', '5'];
@override
Widget build(BuildContext context) {
final s = S.of(context);
return BlocBuilder<CreateDietCubit, CreateDietState>(
builder: (context, state) {
return MainBackgroundBouble(
child: Padding(
padding: EdgeInsets.only(
left: 16,
right: 16,
top: 16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
s.day + ' ${widget.index + 1}',
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
Spacer(),
SvgPicture.asset(
'assets/icons/copy2.svg',
width: 20,
height: 24,
colorFilter: ColorFilter.mode(appTheme.black, BlendMode.srcIn),
),
],
),
SizedBox(
height: 12,
),
CustomDivider(),
SizedBox(
height: 12,
),
Text(
s.meal,
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
SizedBox(height: 16),
Row(
children: [
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6),
fontSize: TextStyles.textMMedium.fontSize,
fontWeight: TextStyles.textMMedium.fontWeight,
index: 0,
selectedChipIndex: _selectedDayIndex,
onSelected: (selectedValue) {
setState(() {
_selectedDayIndex = 0;
});
},
),
Spacer(),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6),
fontSize: TextStyles.textMMedium.fontSize,
fontWeight: TextStyles.textMMedium.fontWeight,
index: 1,
selectedChipIndex: _selectedDayIndex,
onSelected: (selectedValue) {
setState(() {
_selectedDayIndex = 1;
});
},
),
Spacer(),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6),
fontSize: TextStyles.textMMedium.fontSize,
fontWeight: TextStyles.textMMedium.fontWeight,
index: 2,
selectedChipIndex: _selectedDayIndex,
onSelected: (selectedValue) {
setState(() {
_selectedDayIndex = 2;
});
},
),
Spacer(),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6),
fontSize: TextStyles.textMMedium.fontSize,
fontWeight: TextStyles.textMMedium.fontWeight,
index: 3,
selectedChipIndex: _selectedDayIndex,
onSelected: (selectedValue) {
setState(() {
_selectedDayIndex = 3;
});
},
),
Spacer(),
ChoiceChipWidget(
chipsLabelList: chipsLabelList,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6),
fontSize: TextStyles.textMMedium.fontSize,
fontWeight: TextStyles.textMMedium.fontWeight,
index: 4,
selectedChipIndex: _selectedDayIndex,
onSelected: (selectedValue) {
setState(() {
_selectedDayIndex = 4;
});
},
),
],
),
SizedBox(height: 16),
Row(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 14),
decoration: BoxDecoration(color: appTheme.gray50, borderRadius: BorderRadius.all(Radius.circular(12))),
child: SvgPicture.asset(
'assets/icons/paste2.svg',
width: 28,
height: 24,
),
),
SizedBox(width: 8),
Expanded(
child: CustomOutlinedButton(
text: s.add,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(
color: appTheme.whiteA700,
),
buttonStyle: ButtonStyle(
side: WidgetStatePropertyAll(BorderSide.none),
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
),
),
),
],
),
SizedBox(height: 20),
],
),
),
);
},
);
}
}

View File

@@ -0,0 +1,65 @@
import 'package:eatvio_app/core/const.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/utils/localization_utils.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/core/widgets/custom_drop_down_button.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class DurationDropDownWidget extends StatefulWidget {
const DurationDropDownWidget({super.key});
@override
State<DurationDropDownWidget> createState() => _DurationDropDownWidgetState();
}
class _DurationDropDownWidgetState extends State<DurationDropDownWidget> {
final List<String> durationDropDownTitles = [];
@override
void didChangeDependencies() {
super.didChangeDependencies();
final s = S.of(context);
if (durationDropDownTitles.isEmpty) {
durationValues.forEach((element) {
durationDropDownTitles.add('$element ${getDayForm(element, s)}');
});
}
}
@override
Widget build(BuildContext context) {
final s = S.of(context);
return BlocBuilder<CreateDietCubit, CreateDietState>(
builder: (context, state) {
return CustomDropDownButton(
hint: Text(
s.choose_diet_duration,
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
onChanged: (value) {
if (value != null) {
context.read<CreateDietCubit>().setDuration(durationDropDownTitles.indexOf(value));
}
},
items: durationDropDownTitles
.mapIndexed(
(index, value) => DropdownMenuItem(
child: Text(
durationDropDownTitles[index],
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
value: durationDropDownTitles[index],
),
)
.toList(),
value: state.durationIndex == null ? null : durationDropDownTitles[state.durationIndex ?? 0],
);
},
);
}
}

View File

@@ -0,0 +1,122 @@
import 'dart:io';
import 'package:dotted_border/dotted_border.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.dart';
class ImagePickerWidget extends StatefulWidget {
const ImagePickerWidget({super.key});
@override
State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
}
class _ImagePickerWidgetState extends State<ImagePickerWidget> {
void _showImagePickerOptions(S s, CreateDietCubit cubit) {
showCupertinoModalPopup<void>(
context: context,
builder: (context) => CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
final image = await picker.pickImage(source: ImageSource.camera);
cubit.setImage(image);
Navigator.of(context).pop();
},
child: Row(
children: [
Icon(Icons.photo_camera),
SizedBox(width: 8),
Text(s.photo),
],
),
),
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
final image = await picker.pickImage(source: ImageSource.gallery);
cubit.setImage(image);
Navigator.of(context).pop();
},
child: Row(
children: [
Icon(Icons.photo),
SizedBox(width: 8),
Text(s.gallery),
],
),
),
],
cancelButton: CupertinoActionSheetAction(
onPressed: () => Navigator.of(context).pop(),
isDestructiveAction: true,
child: const Text('Отмена'),
),
),
);
}
@override
Widget build(BuildContext context) {
final s = S.of(context);
return BlocBuilder<CreateDietCubit, CreateDietState>(
builder: (context, state) {
return GestureDetector(
onTap: () {
_showImagePickerOptions(s, context.read<CreateDietCubit>());
},
child: Container(
height: 240,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
image: state.dietData.image != null ? DecorationImage(fit: BoxFit.cover, image: FileImage(File(state.dietData.image?.path ?? ''))) : null,
color: appTheme.gray50,
),
width: MediaQuery.sizeOf(context).width,
padding: state.dietData.image != null ? null : EdgeInsets.all(8),
child: state.dietData.image != null
? null
: Stack(
children: [
DottedBorder(
stackFit: StackFit.expand,
dashPattern: [14, 14],
color: appTheme.dottedBorder,
borderType: BorderType.RRect,
radius: Radius.circular(12),
child: SizedBox.expand(),
),
Center(
child: Column(
children: [
SizedBox(
height: 48,
),
SvgPicture.asset('assets/icons/eatvio_logo.svg'),
SizedBox(
height: 24,
),
Text(
s.add_cover,
style: TextStyles.textMMedium.copyWith(color: appTheme.gray),
),
],
),
),
],
),
),
);
},
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/core/widgets/custom_drop_down_button.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:collection/collection.dart';
class StatusDropDownWidget extends StatefulWidget {
const StatusDropDownWidget({super.key});
@override
State<StatusDropDownWidget> createState() => _StatusDropDownWidgetState();
}
class _StatusDropDownWidgetState extends State<StatusDropDownWidget> {
final List<String> dietStateTitles = [];
@override
void didChangeDependencies() {
super.didChangeDependencies();
final s = S.of(context);
if (dietStateTitles.isEmpty) {
dietStateTitles.add(s.active_diet_state);
dietStateTitles.add(s.inactive_diet_state);
dietStateTitles.add(s.personal_diet_state);
}
}
@override
Widget build(BuildContext context) {
final s = S.of(context);
return BlocBuilder<CreateDietCubit, CreateDietState>(
builder: (context, state) {
return CustomDropDownButton(
hint: Text(
s.diet_state,
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
onChanged: (value) {
if (value != null) {
context.read<CreateDietCubit>().setDietState(dietStateTitles.indexOf(value));
}
},
items: dietStateTitles
.mapIndexed(
(index, value) => DropdownMenuItem(
child: Text(
dietStateTitles[index],
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
value: dietStateTitles[index],
),
)
.toList(),
value: state.dietStateIndex == null ? null : dietStateTitles[state.dietStateIndex ?? 0],
);
},
);
}
}

View File

@@ -0,0 +1,100 @@
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
class TypeChoiceWidget extends StatefulWidget {
TypeChoiceWidget({super.key});
@override
State<TypeChoiceWidget> createState() => _TypeChoiceWidgetState();
}
class _TypeChoiceWidgetState extends State<TypeChoiceWidget> {
final List<(String, String)> choiceContent = [];
@override
void didChangeDependencies() {
super.didChangeDependencies();
final s = S.of(context);
if (choiceContent.isEmpty) {
choiceContent.add(
(
'assets/icons/meat2.svg',
s.meat,
),
);
choiceContent.add(
(
'assets/icons/broccoli.svg',
s.vegan,
),
);
choiceContent.add(
(
'assets/icons/bread.svg',
s.carb_type,
),
);
choiceContent.add(
(
'assets/icons/cocktail.svg',
s.light_type,
),
);
}
}
@override
Widget build(BuildContext context) {
return BlocBuilder<CreateDietCubit, CreateDietState>(
builder: (context, state) {
return Row(
children: [
...List.generate(4, (index) {
return Expanded(
child: GestureDetector(
onTap: () {
final dietTypes = [...state.dietData.type];
dietTypes[index] = !dietTypes[index];
context.read<CreateDietCubit>().setDietType(dietTypes);
},
child: Container(
margin: EdgeInsets.only(right: index == 3 ? 0 : 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: state.dietData.type[index] ? appTheme.cardBackground : appTheme.whiteA700,
border: Border.all(
width: 1,
color: state.dietData.type[index] ? appTheme.blueA400 : appTheme.lightGray00,
),
),
height: 80,
child: Column(
children: [
SizedBox(height: 16),
SvgPicture.asset(
choiceContent[index].$1,
height: 30,
),
SizedBox(height: 8),
Text(
choiceContent[index].$2,
overflow: TextOverflow.clip,
style: TextStyles.textXSSemibold.copyWith(color: appTheme.black),
),
],
),
),
),
);
}),
],
);
},
);
}
}