Browse Source

UI qrcode management

phase2
Đại Võ 1 year ago
parent
commit
f1022fc768
15 changed files with 1226 additions and 27 deletions
  1. +12
    -0
      lib/models/item_dropdown.dart
  2. +68
    -0
      lib/presentation/custom_widgets/button/button_2_icon.dart
  3. +68
    -0
      lib/presentation/custom_widgets/button/second_button.dart
  4. +131
    -0
      lib/presentation/custom_widgets/date_picker/date_picker_widget.dart
  5. +184
    -0
      lib/presentation/custom_widgets/dropdown/dropdown_bottom_sheet.dart
  6. +175
    -0
      lib/presentation/screens/codes/code_detail_page.dart
  7. +98
    -0
      lib/presentation/screens/codes/code_page.dart
  8. +145
    -0
      lib/presentation/screens/codes/code_update_timeline_page.dart
  9. +67
    -0
      lib/presentation/screens/codes/cubit/code_update_timeline_cubit.dart
  10. +22
    -0
      lib/presentation/screens/codes/cubit/code_update_timeline_state.dart
  11. +49
    -0
      lib/presentation/screens/codes/widgets/item_code.dart
  12. +155
    -0
      lib/presentation/screens/codes/widgets/item_code_timeline.dart
  13. +29
    -0
      lib/presentation/screens/codes/widgets/item_column.dart
  14. +7
    -6
      lib/presentation/screens/plot/sc_plot.dart
  15. +16
    -21
      lib/presentation/screens/tabbar/tabbar.dart

+ 12
- 0
lib/models/item_dropdown.dart View File

import 'package:equatable/equatable.dart';

class ItemDropDown extends Equatable {
String? key;
String? value;
dynamic data;

ItemDropDown({this.key, this.value, this.data});

@override
List<Object?> get props => [key, value, data];
}

+ 68
- 0
lib/presentation/custom_widgets/button/button_2_icon.dart View File

import 'package:flutter/material.dart';

import '../../../themes/styles_text.dart';

class Button2Icon extends StatelessWidget {
final IconData leftIcon;
final IconData? rightIcon;
final Widget? rightWidget;
final String title;
final Function onPressed;

const Button2Icon({
super.key,
required this.leftIcon,
this.rightIcon,
required this.title,
required this.onPressed,
this.rightWidget,
});

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onPressed();
},
child: Container(
padding: EdgeInsets.all(8),
margin: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.grey.shade200,
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
leftIcon,
size: 16,
color: Colors.grey.shade500,
),
const SizedBox(
width: 4,
),
Text(
title,
style: StylesText.body5,
),
const SizedBox(
width: 4,
),
rightIcon != null
? Icon(
rightIcon,
size: 16,
color: Colors.grey.shade500,
)
: const SizedBox.shrink(),
rightWidget ?? const SizedBox.shrink(),
],
),
),
);
}
}

+ 68
- 0
lib/presentation/custom_widgets/button/second_button.dart View File

import 'package:flutter/material.dart';

import '../../../themes/styles_text.dart';

class SecondButton extends StatelessWidget {
final IconData? leftIcon;
final Function onPressed;
final String title;
final Color? color;
final Color? textColor;
final Color? borderColor;
final double? width;
final double? height;
const SecondButton({
super.key,
required this.onPressed,
this.leftIcon,
required this.title,
this.color,
this.textColor,
this.borderColor,
this.width,
this.height,
});

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onPressed();
},
child: Container(
width: width,
height: height,
padding: EdgeInsets.all(7),
margin: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: borderColor ?? Colors.white,
width: 2,
),
color: color ?? Colors.white,
),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
leftIcon != null
? Icon(
leftIcon,
size: 16,
color: textColor ?? Colors.grey.shade500,
)
: const SizedBox.shrink(),
const SizedBox(
width: 4,
),
Text(
title,
style: StylesText.body5.copyWith(color: textColor ?? Colors.white),
),
],
),
),
);
}
}

+ 131
- 0
lib/presentation/custom_widgets/date_picker/date_picker_widget.dart View File

import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/svg.dart';
import 'package:intl/intl.dart';

import '../../../themes/app_colors.dart';
import '../../../themes/styles_text.dart';
import '../../../utils/app_images.dart';

class DatePickerWidget extends StatefulWidget {
final bool isEnable;
final DateTime initDateTime;
final DateTime? minDate;
final bool isMinDate;
SvgPicture? icon;
final bool isAcceptSelectPassDate;
final bool isShowTime;
final Function(DateTime? selectedDateTimeLocal) onUpdateDateTime;
DatePickerWidget({
required this.initDateTime,
required this.onUpdateDateTime,
this.minDate,
this.isMinDate = false,
this.isEnable = true,
this.icon,
this.isAcceptSelectPassDate = true,
this.isShowTime = false,
});
@override
_DatePickerWidgetState createState() => _DatePickerWidgetState();
}

class _DatePickerWidgetState extends State<DatePickerWidget> {
late DateTime selectedDate;
@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
selectedDate = widget.initDateTime;
print('--- min date ----');
print(widget.isMinDate ? DateTime.parse(widget.minDate.toString()) : DateTime(DateTime.now().year - 5));
return InkWell(
onTap: widget.isEnable
? () {
widget.isShowTime
? DatePicker.showDateTimePicker(
context,
showTitleActions: true,
minTime: DateTime(DateTime.now().year - 5),
maxTime: DateTime(DateTime.now().year + 5),
onChanged: (date) {},
onConfirm: (date) {
if (date != null) {
if (widget.isAcceptSelectPassDate) {
} else {
var now = DateTime.now();
if (date.isBefore(
DateTime(now.year, now.month, now.day, 00, 00, 00),
)) {
return;
}
}
widget.onUpdateDateTime(date);
setState(() {
selectedDate = date;
});
}
},
currentTime: selectedDate,
locale: LocaleType.vi,
)
: showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(DateTime.now().year - 5),
lastDate: DateTime(DateTime.now().year + 5),
).then((date) {
if (date != null) {
if (widget.isAcceptSelectPassDate) {
} else {
var now = DateTime.now();
if (date.isBefore(
DateTime(now.year, now.month, now.day, 00, 00, 00),
)) {
return;
}
}
widget.onUpdateDateTime(date);
setState(() {
selectedDate = date;
});
}
});
}
: null,
child: Container(
height: 48.h,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: AppColors.neutral4,
width: 1,
),
color: widget.isEnable ? Colors.white : Colors.transparent,
),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: Row(
children: [
Expanded(
child: Text(
widget.isShowTime ? DateFormat('dd/MM/yyyy HH:mm').format(selectedDate) : DateFormat('dd/MM/yyyy').format(selectedDate),
style: StylesText.body6,
textAlign: TextAlign.start,
),
),
SizedBox(
child: widget.icon ??
SvgPicture.asset(
AssetSVG.icCalendar,
),
)
],
),
),
);
}
}

+ 184
- 0
lib/presentation/custom_widgets/dropdown/dropdown_bottom_sheet.dart View File

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import '../../../themes/app_dimension.dart';

import '../../../models/item_dropdown.dart';
import '../../../themes/app_colors.dart';
import '../../../themes/styles_text.dart';
import '../../../utils/app_images.dart';
import '../../../utils/validators.dart';

class DropdownBottomSheet extends StatefulWidget {
final String? initValue;
final List<ItemDropDown> dataSources;
final Function(ItemDropDown) onSelected;
final Color? borderColor;
final String hint;
final double? height;
final String? errorText;
final bool isDisable;
final EdgeInsetsGeometry? contentPadding;
final Color? disabledColor;

const DropdownBottomSheet({
Key? key,
required this.dataSources,
required this.onSelected,
required this.hint,
this.initValue,
this.borderColor,
this.height,
this.errorText,
this.isDisable = false,
this.contentPadding,
this.disabledColor,
}) : super(key: key);

@override
_DropdownBottomSheetState createState() => _DropdownBottomSheetState();
}

class _DropdownBottomSheetState extends State<DropdownBottomSheet> {
var dataSources = ValueNotifier(<ItemDropDown>[]);
var selectValue = ValueNotifier(ItemDropDown());
int _selectedIndex = 0;
FixedExtentScrollController? scrollController;
final _searchCtl = TextEditingController();

@override
void initState() {
super.initState();
}

@override
void dispose() {
_searchCtl.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
_selectedIndex = widget.dataSources.indexWhere((element) {
return element.key == widget.initValue;
});
if (_selectedIndex >= 0) {
selectValue.value = widget.dataSources[_selectedIndex];
} else {
selectValue.value = ItemDropDown(key: '', value: '');
}
return InkWell(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
widget.isDisable ? null : _modalBottomSheetMenu();
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: widget.contentPadding ??
EdgeInsets.symmetric(
horizontal: 12.w,
vertical: 16.h,
),
decoration: BoxDecoration(
color: widget.isDisable ? (widget.disabledColor ?? AppColors.background1) : AppColors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: AppColors.neutral4,
width: 1,
),
),
child: Row(
children: [
Expanded(
child: ValueListenableBuilder<ItemDropDown>(
valueListenable: selectValue,
builder: (context, selected, _) {
if (Validators.stringNotNullOrEmpty(selected.key)) {
return Text(
selected.value ?? '',
style: StylesText.body6,
maxLines: 1,
);
} else {
return Text(
widget.hint,
style: StylesText.body6.copyWith(
color: AppColors.neutral3,
),
);
}
},
),
),
SvgPicture.asset(AssetSVG.icArrowDown),
],
),
),
if (widget.errorText != null) ...[
SizedBox(
height: 4.h,
),
Text(
widget.errorText ?? '',
style: StylesText.caption1.copyWith(
color: AppColors.semantic2,
),
)
],
],
),
);
}

void _modalBottomSheetMenu() {
_searchCtl.clear();
dataSources.value = List.of(widget.dataSources);
showDialog(
context: context,
builder: (context) {
return AlertDialog(
contentPadding: const EdgeInsets.all(8),
content: Container(
width: double.maxFinite,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: ValueListenableBuilder<List<ItemDropDown>>(
valueListenable: dataSources,
builder: (context, sources, _) {
return ListView.builder(
shrinkWrap: true,
itemBuilder: ((context, index) {
var item = sources[index];
return InkWell(
onTap: () {},
child: RadioListTile<ItemDropDown>(
value: item,
title: Text(
item.value ?? '',
style: StylesText.body6,
),
groupValue: item.key == selectValue.value.key ? item : null,
onChanged: (val) {
Get.back();
widget.onSelected(val!);
},
),
);
}),
itemCount: sources.length,
);
},
),
)
],
),
),
);
},
);
}
}

+ 175
- 0
lib/presentation/screens/codes/code_detail_page.dart View File

import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/button/second_button.dart';
import 'package:farm_tpf/presentation/screens/codes/code_update_timeline_page.dart';
import 'package:farm_tpf/presentation/screens/codes/widgets/item_code_timeline.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../themes/styles_text.dart';

class CodeDetailPage extends StatefulWidget {
const CodeDetailPage({super.key});

@override
State<CodeDetailPage> createState() => _CodeDetailPageState();
}

class _CodeDetailPageState extends State<CodeDetailPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarWidget(
action: IconButton(
onPressed: () {
Get.to(() => CodeUpdateTimelinePage());
},
icon: Icon(
Icons.edit,
color: Colors.blue,
),
),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
_itemCodeDetail(
title: 'Tên sản phẩm',
detail: 'Cà rốt',
titleStyle: StylesText.body4,
detailStyle: StylesText.body4.copyWith(
color: Colors.blue,
),
),
_itemCodeDetail(title: 'Mô tả', detail: 'detail'),
_itemCodeDetail(title: 'Số lượng tem', detail: 'detail'),
_itemCodeDetail(title: 'Trạng thái', detail: 'detail'),
_itemCodeDetail(title: 'Hạn sử dụng', detail: 'detail'),
_itemCodeDetail(title: 'Mẫu tem', detail: 'detail'),
Text(
'Timeline hoạt động',
style: StylesText.body1,
),
_timelineWidget(),
],
),
),
),
const SizedBox(
height: 8,
),
// Container(
// width: 100,
// height: 100,
// color: Colors.red,
// ),
_actionButtonWidget(),
],
),
),
);
}

Widget _timelineWidget() {
return ListView.builder(
itemBuilder: (context, index) {
return ItemCodeTimeline(
onPressed: () {},
);
},
itemCount: 20,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
);
}

Widget _actionButtonWidget() {
return Wrap(
spacing: 8,
children: [
Row(
children: [
Expanded(
child: SecondButton(
onPressed: () {},
title: 'Kích hoạt toàn bộ',
borderColor: Colors.blue,
textColor: Colors.blue,
width: double.infinity,
height: 40,
),
),
Expanded(
child: SecondButton(
onPressed: () {},
title: 'Huỷ toàn bộ',
borderColor: Colors.red,
textColor: Colors.white,
color: Colors.red,
width: double.infinity,
height: 40,
),
),
],
),
const SizedBox(
height: 8,
),
Row(
children: [
Expanded(
child: SecondButton(
onPressed: () {},
title: 'Cập nhật hoạt động',
borderColor: Colors.green,
textColor: Colors.green,
width: double.infinity,
height: 40,
),
),
Expanded(
child: SecondButton(
onPressed: () {},
title: 'In / Xuất file',
borderColor: Colors.cyan,
textColor: Colors.white,
color: Colors.cyan,
width: double.infinity,
height: 40,
),
),
],
),
],
);
}

Widget _itemCodeDetail({
required String title,
required String detail,
TextStyle? titleStyle,
TextStyle? detailStyle,
}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: Row(
children: [
Expanded(
child: Text(
title,
style: titleStyle ?? StylesText.body6,
),
),
Text(
detail,
style: detailStyle ?? StylesText.body6,
)
],
),
);
}
}

+ 98
- 0
lib/presentation/screens/codes/code_page.dart View File

import 'package:farm_tpf/presentation/custom_widgets/button/button_2_icon.dart';
import 'package:farm_tpf/presentation/custom_widgets/button/second_button.dart';
import 'package:farm_tpf/presentation/screens/codes/code_detail_page.dart';
import 'package:farm_tpf/presentation/screens/codes/widgets/item_code.dart';
import 'package:farm_tpf/themes/app_colors.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../themes/styles_text.dart';
import '../plot/widget_search.dart';

class CodePage extends StatefulWidget {
const CodePage({super.key});

@override
State<CodePage> createState() => _CodePageState();
}

class _CodePageState extends State<CodePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
key: _scaffoldKey,
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 8,
),
Container(
padding: EdgeInsets.all(8),
color: Colors.white,
child: Text(
'Danh sách tem',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
),
WidgetSearch(),
Row(
children: [
Button2Icon(
leftIcon: CupertinoIcons.arrow_up_arrow_down,
rightIcon: CupertinoIcons.chevron_down,
title: 'Sort',
onPressed: () {},
),
Button2Icon(
leftIcon: CupertinoIcons.slider_horizontal_3,
title: 'Filter',
rightWidget: Container(
width: 16,
height: 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.blue,
),
child: Center(
child: Text(
'1',
style: StylesText.caption6.copyWith(color: Colors.white),
),
),
),
onPressed: () {},
),
const Spacer(),
SecondButton(
onPressed: () {},
title: 'Tạo tem',
leftIcon: CupertinoIcons.add,
color: AppColors.primary1,
textColor: Colors.white,
borderColor: AppColors.primary1,
),
],
),
Expanded(
child: ListView.builder(
itemBuilder: ((context, index) {
return ItemCode(
onPressed: () {
Get.to(() => CodeDetailPage());
},
);
}),
itemCount: 100,
),
),
],
),
),
);
}
}

+ 145
- 0
lib/presentation/screens/codes/code_update_timeline_page.dart View File

import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
import 'package:farm_tpf/presentation/screens/codes/cubit/code_update_timeline_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart';

import '../../../utils/utils.dart';
import '../../custom_widgets/date_picker/date_picker_widget.dart';
import '../../custom_widgets/dropdown/dropdown_bottom_sheet.dart';
import '../../custom_widgets/textfield/text_field_normal.dart';
import 'widgets/item_column.dart';

class CodeUpdateTimelinePage extends StatefulWidget {
const CodeUpdateTimelinePage({super.key});

@override
State<CodeUpdateTimelinePage> createState() => _CodeUpdateTimelinePageState();
}

class _CodeUpdateTimelinePageState extends State<CodeUpdateTimelinePage> {
final bloc = CodeUpdateTimelineCubit();

@override
void initState() {
super.initState();
bloc.preparedData();
}

@override
void dispose() {
bloc.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarWidget(),
body: BlocListener<CodeUpdateTimelineCubit, CodeUpdateTimelineState>(
bloc: bloc,
listener: ((context, state) {
if (state is CodeUpdateTimelineLoading) {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
UtilWidget.showLoading();
});
} else if (state is CodeUpdateTimelineFailure) {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
UtilWidget.hideLoading();
// UtilWidget.showToastError(state.errorMessage);
});
} else if (state is CodeUpdateTimelinePrepareDataSuccessful) {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
UtilWidget.hideLoading();
});
}
}),
child: KeyboardDismisser(
child: Container(
child: Form(
key: bloc.formKey,
child: Column(
children: [
Expanded(
child: _widgetBody(),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ButtonWidget(
title: 'Cập nhật',
onPressed: () {},
),
),
],
),
),
),
),
),
);
}

Widget _widgetBody() {
return Container(
padding: const EdgeInsets.all(16),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ValueListenableBuilder<DateTime>(
valueListenable: bloc.actionDate,
builder: (context, actionDate, _) {
return ItemColumnWidget(
title: 'Ngày nhập',
child: DatePickerWidget(
initDateTime: actionDate,
onUpdateDateTime: (selectedDate) {
if (selectedDate != null) {
bloc.actionDate.value = selectedDate;
}
},
),
);
},
),
SizedBox(
height: 8,
),
ItemColumnWidget(
title: 'Hoạt động',
child: ValueListenableBuilder<String>(
valueListenable: bloc.selectedActionType,
builder: (context, selected, _) {
return DropdownBottomSheet(
dataSources: bloc.actionTypes,
initValue: selected,
onSelected: (val) {
bloc.selectedActionType.value = val.key ?? '';
},
hint: 'Hoạt động',
);
},
),
),
const SizedBox(
height: 8,
),
ItemColumnWidget(
title: 'Mô tả',
child: TextFieldNormal(
controller: bloc.descriptionCtl,
maxLines: 2,
hint: 'Mô tả',
),
),
const SizedBox(
height: 16,
),
],
),
),
);
}
}

+ 67
- 0
lib/presentation/screens/codes/cubit/code_update_timeline_cubit.dart View File

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';

import '../../../../data/api/app_exception.dart';
import '../../../../data/repository/repository.dart';
import '../../../../models/item_dropdown.dart';

part 'code_update_timeline_state.dart';

class CodeUpdateTimelineCubit extends Cubit<CodeUpdateTimelineState> {
CodeUpdateTimelineCubit() : super(CodeUpdateTimelineInitial());

final repository = Repository();
final formKey = GlobalKey<FormState>();
var actionDate = ValueNotifier(DateTime.now());
final descriptionCtl = TextEditingController();
var actionTypes = [
ItemDropDown(key: 'hoat dong 1', value: 'hoat dong 1'),
ItemDropDown(key: 'hoat dong 2', value: 'hoat dong 2'),
];
var selectedActionType = ValueNotifier('');
// var existedCodeUpdateTimeline = UpdateCodeUpdateTimeline();

void dispose() {
descriptionCtl.dispose();
}

Future<void> preparedData() async {
try {
await Future.delayed(const Duration(seconds: 0));
emit(CodeUpdateTimelineLoading());

emit(CodeUpdateTimelinePrepareDataSuccessful());
} catch (e) {
emit(CodeUpdateTimelineFailure(AppException.handleError(e)));
}
}

Future<void> onSubmit() async {
if (formKey.currentState!.validate()) {
// var gioiTinh = gioiTinhs.firstWhere(
// (element) => selectedGioiTinh.value == element.key,
// orElse: () => ItemDropDown(),
// );

// existedCodeUpdateTimeline
// ..gioiTinhBe = gioiTinh.value
// ..ghiChu = noteCtl.text
// ..ngayTiemUngKhiThan = ungKhiThanDate.value.convertLocalDateTimeToServer();

// UtilWidget.showLoading();
// await repository.updateCodeUpdateTimeline(
// (success) {
// UtilWidget.hideDialog();
// UtilWidget.showToastSuccess('Thêm thành công');
// Get.back();
// },
// (errorMessage) {
// UtilWidget.hideDialog();
// UtilWidget.showToastError(errorMessage);
// },
// item: existedCodeUpdateTimeline,
// );
}
}
}

+ 22
- 0
lib/presentation/screens/codes/cubit/code_update_timeline_state.dart View File

part of 'code_update_timeline_cubit.dart';

abstract class CodeUpdateTimelineState extends Equatable {
const CodeUpdateTimelineState();

@override
List<Object> get props => [];
}

class CodeUpdateTimelineInitial extends CodeUpdateTimelineState {}

class CodeUpdateTimelineLoading extends CodeUpdateTimelineState {}

class CodeUpdateTimelineFailure extends CodeUpdateTimelineState {
final String errorMessage;

CodeUpdateTimelineFailure(this.errorMessage);
}

class CodeUpdateTimelinePrepareDataSuccessful extends CodeUpdateTimelineState {
CodeUpdateTimelinePrepareDataSuccessful();
}

+ 49
- 0
lib/presentation/screens/codes/widgets/item_code.dart View File

import 'package:flutter/material.dart';

import '../../../../themes/app_colors.dart';
import '../../../../themes/styles_text.dart';

class ItemCode extends StatelessWidget {
final Function onPressed;
const ItemCode({
super.key,
required this.onPressed,
});

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onPressed();
},
child: Container(
padding: EdgeInsets.all(8),
margin: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.grey.shade200,
width: 1,
),
color: AppColors.primary1.withOpacity(0.3),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Cà chua đợt 1 5/2023',
style: StylesText.body1,
),
const SizedBox(
height: 8,
),
Text(
'06/05/2023 - 1500 tem - mới',
style: StylesText.body6,
),
],
),
),
);
}
}

+ 155
- 0
lib/presentation/screens/codes/widgets/item_code_timeline.dart View File

import 'package:flutter/material.dart';

import '../../../../themes/app_colors.dart';
import '../../../../themes/styles_text.dart';

class ItemCodeTimeline extends StatelessWidget {
final Function onPressed;
const ItemCodeTimeline({
super.key,
required this.onPressed,
});

@override
Widget build(BuildContext context) {
return Container(
child: Stack(
children: [
Row(
children: [
const SizedBox(
width: 16,
height: 20,
),
Expanded(child: _widgetTimeLine()),
],
),
Positioned(
top: 0,
left: 8,
child: Container(
color: Colors.white,
width: 16,
height: 24,
child: Column(
children: [
Container(
width: 16,
height: 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
16,
),
color: Colors.green,
),
),
],
),
),
),
],
),
);
}

Widget _widgetTimeLine() {
return Container(
width: double.infinity,
padding: const EdgeInsets.only(
left: 12,
right: 8,
),
margin: const EdgeInsets.only(
bottom: 8,
),
decoration: BoxDecoration(
border: Border(
left: BorderSide(color: Colors.blue),
),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'ss - ',
style: StylesText.body5,
),
Text(
'20/22/2202',
style: StylesText.caption3.copyWith(),
)
],
),
const SizedBox(
height: 8,
),
_widgetItemInfoCompleted(
title: 'title',
actionDate: '2/2/2023',
nguoiThucHiens: 'nguoi thuc hien',
),
],
),
);
}

Widget _widgetItemInfoCompleted({
required String title,
required String actionDate,
String? nguoiThucHiens,
}) {
return Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: AppColors.background1,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
title,
style: StylesText.caption2.copyWith(
color: AppColors.neutral1,
),
),
),
Text(
actionDate,
style: StylesText.caption3.copyWith(
color: AppColors.neutral1,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
Expanded(
child: Text(
'Người thực hiện',
style: StylesText.caption2.copyWith(
color: AppColors.neutral1,
),
),
),
Text(
nguoiThucHiens ?? '',
style: StylesText.caption3.copyWith(
color: AppColors.neutral1,
),
),
],
),
),
],
),
);
}
}

+ 29
- 0
lib/presentation/screens/codes/widgets/item_column.dart View File

import 'package:flutter/material.dart';

import '../../../../themes/styles_text.dart';

class ItemColumnWidget extends StatelessWidget {
final String title;
double? textSize12;
final Widget child;
ItemColumnWidget({Key? key, required this.title, required this.child, this.textSize12}) : super(key: key);

@override
Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: textSize12 != null ? StylesText.body6.copyWith(fontSize: textSize12) : StylesText.body6,
),
const SizedBox(
height: 5,
),
child,
],
),
);
}
}

+ 7
- 6
lib/presentation/screens/plot/sc_plot.dart View File

height: 8, height: 8,
), ),
Container( Container(
padding: EdgeInsets.all(8),
color: Colors.white,
child: Text(
'Danh sách lô trồng',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
)),
padding: EdgeInsets.all(8),
color: Colors.white,
child: Text(
'Danh sách lô trồng',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
),
WidgetSearch(), WidgetSearch(),
Expanded(child: BlocBuilder<PlotBloc, PlotState>( Expanded(child: BlocBuilder<PlotBloc, PlotState>(
builder: (context, state) { builder: (context, state) {

+ 16
- 21
lib/presentation/screens/tabbar/tabbar.dart View File

import 'dart:io';

import 'package:badges/badges.dart' as badge;
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:farm_tpf/custom_model/NotificationObjectDTO.dart'; import 'package:farm_tpf/custom_model/NotificationObjectDTO.dart';
import 'package:farm_tpf/data/repository/repository.dart'; import 'package:farm_tpf/data/repository/repository.dart';
import 'package:farm_tpf/data/repository/user_repository.dart'; import 'package:farm_tpf/data/repository/user_repository.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
import 'package:farm_tpf/presentation/screens/account/sc_account.dart'; import 'package:farm_tpf/presentation/screens/account/sc_account.dart';
import 'package:farm_tpf/presentation/screens/codes/code_page.dart';
import 'package:farm_tpf/presentation/screens/control_device/sc_control_device.dart'; import 'package:farm_tpf/presentation/screens/control_device/sc_control_device.dart';
import 'package:farm_tpf/presentation/screens/notification/sc_notification.dart'; import 'package:farm_tpf/presentation/screens/notification/sc_notification.dart';
import 'package:farm_tpf/presentation/screens/notification/update_count_noti_bloc.dart'; import 'package:farm_tpf/presentation/screens/notification/update_count_noti_bloc.dart';
import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart'; import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart'; import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
import 'package:farm_tpf/presentation/screens/qr_scan/qr_scan_page.dart';
import 'package:farm_tpf/utils/NotificationsBloc.dart'; import 'package:farm_tpf/utils/NotificationsBloc.dart';
import 'package:farm_tpf/utils/const_color.dart'; import 'package:farm_tpf/utils/const_color.dart';
import 'package:farm_tpf/utils/const_common.dart'; import 'package:farm_tpf/utils/const_common.dart';
import 'package:farm_tpf/utils/const_icons.dart'; import 'package:farm_tpf/utils/const_icons.dart';
import 'package:farm_tpf/utils/pref.dart'; import 'package:farm_tpf/utils/pref.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';


import '../../../main.dart';

class TabbarScreen extends StatefulWidget { class TabbarScreen extends StatefulWidget {
static Route route() { static Route route() {
return MaterialPageRoute<void>(builder: (_) => TabbarScreen()); return MaterialPageRoute<void>(builder: (_) => TabbarScreen());
return ControlDeviceScreen(); return ControlDeviceScreen();
break; break;
case TabBarIndex.qr: case TabBarIndex.qr:
return Container();
return CodePage();
break; break;
case TabBarIndex.notification: case TabBarIndex.notification:
return NotificationScreen(); return NotificationScreen();
)), )),
onTap: () { onTap: () {
//Open scan qr code when tap icon in tabbar //Open scan qr code when tap icon in tabbar
if (index == 2) {
changeTabbar.changeIndex(changeTabbar.index ?? TabBarIndex.plot);
// scan(context);
Get.to(
QrCodeScannerScreen(),
).then((value) {
if (value != null) {
_showAlertCheckCropCode(value);
}
});
} else {
changeTabbar.changeIndex(itemsTabbar[index].index);
}
// if (index == 2) {
// changeTabbar.changeIndex(changeTabbar.index ?? TabBarIndex.plot);
// // scan(context);
// Get.to(
// QrCodeScannerScreen(),
// ).then((value) {
// if (value != null) {
// _showAlertCheckCropCode(value);
// }
// });
// } else {
// changeTabbar.changeIndex(itemsTabbar[index].index);
// }
changeTabbar.changeIndex(itemsTabbar[index].index);
}, },
); );
}), }),

Loading…
Cancel
Save