category dictionary finished

null-safety-migration
suvaissov 2021-08-09 15:07:43 +06:00
parent 15e1ffef2e
commit 9241f36813
14 changed files with 603 additions and 161 deletions

View File

@ -59,6 +59,24 @@ class DictionaryService extends BaseService {
return list; return list;
} }
Future<Category?> getCategoryById(int id) async {
Category? result;
try {
final int? appCompanyId = Redux.store?.state.userState?.auth?.companyId;
final List<Map<String, dynamic>> elements = await _db.queryRowsWithWhere(
categoryTableName,
'$categoryColumnAppCompanyId = ? and $categoryColumnId = ?',
[appCompanyId, id]);
for (final Map<String, dynamic> element in elements) {
result = Category.fromMap(element);
}
} catch (e, stack) {
log.e('getCategoryById', e, stack);
}
return result;
}
Future<List<Category>> getCategoriesAll() async { Future<List<Category>> getCategoriesAll() async {
final List<Category> list = []; final List<Category> list = [];
try { try {

View File

@ -10,3 +10,7 @@ const String paymentViewRoute = 'paymentViewRoute';
const String settingPrinterBluetoothViewRoute = 'SettingPrinterBluetoothView'; const String settingPrinterBluetoothViewRoute = 'SettingPrinterBluetoothView';
// Generate the views here // Generate the views here
const String categoryEditRoute = 'categoryEditRoute';
const String categorySelectViewRoute = 'categorySelectViewRoute';

View File

@ -1,4 +1,7 @@
import 'package:satu/views/dictionaries/category/category_edit.dart';
import 'package:satu/views/dictionaries/category/category_select_view.dart';
import 'package:satu/views/dictionaries/category/category_view.dart';
import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart'; import 'package:satu/views/work/views/add_by_barcode/add_by_barcode_view.dart';
import 'package:satu/views/work/views/add_product/add_product_view.dart'; import 'package:satu/views/work/views/add_product/add_product_view.dart';
import 'package:satu/views/login/login_view.dart'; import 'package:satu/views/login/login_view.dart';
@ -54,6 +57,18 @@ Route<dynamic> generateRoute(RouteSettings settings) {
routeName: settings.name!, routeName: settings.name!,
viewToShow: PaymentView(), viewToShow: PaymentView(),
); );
case categoryEditRoute:
final CategoryRowDao category = settings.arguments! as CategoryRowDao;
return _getPageRoute(
routeName: settings.name!,
viewToShow: CategoryEdit(category: category,),
);
case categorySelectViewRoute:
return _getPageRoute(
routeName: settings.name!,
viewToShow: CategorySelectView(),
);
// case ImageShowRoute: // case ImageShowRoute:
// ImageShowModel data = settings.arguments as ImageShowModel; // ImageShowModel data = settings.arguments as ImageShowModel;
// //return SlideRightRoute(widget: ImageShowContainer(data)); // //return SlideRightRoute(widget: ImageShowContainer(data));

View File

@ -1,15 +1,139 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:satu/core/entity/category_entity.dart';
import 'package:satu/core/models/dialog_models.dart';
import 'package:satu/core/services/dialog_service.dart';
import 'package:satu/core/services/dictionary_service.dart';
import 'package:satu/core/services/navigator_service.dart';
import 'package:satu/core/utils/locator.dart';
import 'package:satu/core/utils/logger.dart';
import 'package:satu/routes/route_names.dart';
import 'package:satu/shared/ui_helpers.dart';
import 'package:satu/views/dictionaries/category/category_view.dart';
import 'package:satu/widgets/bar/products_app_bar.dart';
import 'package:satu/widgets/buttons/busy_button.dart';
import 'package:satu/widgets/fields/input_field.dart';
import 'package:satu/widgets/fields/line_tile.dart';
import 'package:satu/widgets/fields/note_text.dart';
class CategoryEdit extends StatefulWidget { class CategoryEdit extends StatefulWidget {
const CategoryEdit({Key? key}) : super(key: key); const CategoryEdit({
required this.category,
Key? key,
}) : super(key: key);
final CategoryRowDao category;
@override @override
_CategoryEditState createState() => _CategoryEditState(); _CategoryEditState createState() => _CategoryEditState();
} }
class _CategoryEditState extends State<CategoryEdit> { class _CategoryEditState extends State<CategoryEdit> {
final NavigatorService _navigatorService = locator<NavigatorService>();
final DictionaryService _dictionaryService = locator<DictionaryService>();
final DialogService _dialogService = locator<DialogService>();
final Logger log = getLogger('_CategoryEditState');
late TextEditingController _controller;
String parentCategoryName = '';
int parentCategoryId = 0;
@override
void initState() {
super.initState();
if (widget.category.parentId != null) {
parentCategoryId = widget.category.parentId!;
}
_controller = TextEditingController(text: widget.category.name);
getAndStateCategoryName(parentCategoryId);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Future<void> getAndStateCategoryName(int id) async {
String name = '';
if (id == 0) {
name = 'Корневая категория';
} else {
log.i('message $id');
final Category? category = await _dictionaryService.getCategoryById(id);
if (category != null) {
name = category.name;
}
log.i('message $name');
}
setState(() {
parentCategoryName = name;
parentCategoryId = id;
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container(); return Scaffold(
appBar: ProductsAppBar(
title: widget.category.id == null
? 'Создание категории'
: 'Редактирование категории',
),
body: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
verticalSpaceSmall,
LineTile(
parentCategoryName,
onTap: selectCategory,
labelText: 'Родительская категория',
),
verticalSpaceSmall,
InputField(
controller: _controller,
labelText: 'Наименование',
placeholder: 'Введите наименование категории',
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 45.0, vertical: 20.0),
child: BusyButton(title: 'СОХРАНИТЬ', onPressed: () {}),
),
if (widget.category.id != null)
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 45.0, vertical: 20.0),
child: BusyButton(
title: 'УДАЛИТЬ',
onPressed: () async {
DialogResponse response =
await _dialogService.showConfirmationDialog(
title: 'Внимание',
description:
'Вы уверены, что хотите удалить категорию?',
confirmationTitle: 'Удалить',
cancelTitle: 'Отмена');
return response.confirmed;
},
isDanger: true,
),
),
],
),
),
);
}
Future<void> selectCategory() async {
final dynamic result =
await _navigatorService.push(categorySelectViewRoute);
if (result != null) {
getAndStateCategoryName(result as int);
}
} }
} }

View File

@ -0,0 +1,141 @@
import 'package:flutter/material.dart';
import 'package:satu/core/entity/category_entity.dart';
import 'package:satu/core/entity/goods_entity.dart';
import 'package:satu/core/redux/actions/sell_actions.dart';
import 'package:satu/core/redux/store.dart';
import 'package:satu/core/services/dictionary_service.dart';
import 'package:satu/core/services/navigator_service.dart';
import 'package:satu/core/utils/locator.dart';
import 'package:satu/routes/route_names.dart';
import 'package:satu/shared/app_colors.dart';
import 'package:satu/shared/ui_helpers.dart';
import 'package:satu/views/dictionaries/component/dictionary_list_tile.dart';
import 'package:satu/widgets/bar/products_app_bar.dart';
import 'package:satu/widgets/bar/products_title_bar.dart';
import 'package:satu/widgets/fields/input_field.dart';
import 'package:satu/widgets/fields/line_checkbox.dart';
import 'category_view.dart';
class CategorySelectView extends StatefulWidget {
@override
_CategorySelectViewState createState() => _CategorySelectViewState();
}
class _CategorySelectViewState extends State<CategorySelectView> {
final DictionaryService _dictionaryService = locator<DictionaryService>();
final NavigatorService _navigatorService = locator<NavigatorService>();
late TextEditingController _searchTextController;
final FocusNode _searchFocusNode = FocusNode();
late List<Category> _categories = [];
late List<CategoryRowDao> items = [];
@override
void initState() {
_searchTextController = TextEditingController();
_searchTextController.addListener(() {
if (_searchTextController.text.isNotEmpty) {
searchByField(_searchTextController.text);
} else {
reset();
}
});
initQuery();
super.initState();
}
Future<void> initQuery() async {
_categories = await _dictionaryService.getCategoriesAll();
searchByField('');
}
@override
void dispose() {
_searchTextController.dispose();
_searchFocusNode.dispose();
super.dispose();
}
Future<void> handlerCategory(int id) async {
_navigatorService.pop(id);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const ProductsAppBar(
title: 'Выбор категории',
),
body: Column(
children: [
InputField(
placeholder: 'Поиск по наименованию категории',
search: true,
controller: _searchTextController,
fieldFocusNode: _searchFocusNode,
),
verticalSpaceMedium,
LineCheckBox(
'Корневая категория',
value: true,
labelText: 'По умолчанию',
onTap: () => handlerCategory(0),
),
const ProductsTitleBarBar(title: 'Выберите категорию'),
Expanded(
child: ListView.separated(
physics: const BouncingScrollPhysics(),
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
final CategoryRowDao category = items[index];
return DictionaryTile(
title: category.name,
subTitle: category.parentName.isEmpty
? 'Корневая категория'
: 'Родитель: ${category.parentName}',
key: Key('category_${category.id}'),
onPress: () => handlerCategory(category.id!),
);
},
separatorBuilder: (BuildContext context, int index) {
return const Divider(
height: 1.0,
color: disableColor,
);
},
),
),
],
),
);
}
void reset() {
_searchTextController.clear();
searchByField('');
}
void searchByField(String query) async {
final List<CategoryRowDao> list = [];
final Iterable<Category> filtered = query == ''
? _categories
: _categories.where((element) =>
element.name.toLowerCase().contains(query.toLowerCase()));
filtered.forEach((element) {
final Category category = _categories
.firstWhere((parent) => parent.id == element.parentId, orElse: () {
return Category();
});
final String parentName = category.name;
final CategoryRowDao rowDao = CategoryRowDao(
element.name, parentName, element.id,
parentId: element.parentId);
list.add(rowDao);
});
setState(() {
items = list;
});
}
}

View File

@ -6,6 +6,7 @@ import 'package:satu/core/redux/store.dart';
import 'package:satu/core/services/dictionary_service.dart'; import 'package:satu/core/services/dictionary_service.dart';
import 'package:satu/core/services/navigator_service.dart'; import 'package:satu/core/services/navigator_service.dart';
import 'package:satu/core/utils/locator.dart'; import 'package:satu/core/utils/locator.dart';
import 'package:satu/routes/route_names.dart';
import 'package:satu/shared/app_colors.dart'; import 'package:satu/shared/app_colors.dart';
import 'package:satu/shared/ui_helpers.dart'; import 'package:satu/shared/ui_helpers.dart';
import 'package:satu/views/dictionaries/component/dictionary_list_tile.dart'; import 'package:satu/views/dictionaries/component/dictionary_list_tile.dart';
@ -79,9 +80,10 @@ class _CategoryDictionaryViewState extends State<CategoryDictionaryView> {
title: category.name, title: category.name,
subTitle: category.parentName.isEmpty subTitle: category.parentName.isEmpty
? 'Корневая категория' ? 'Корневая категория'
: 'Родитель: ${category.parentName}' : 'Родитель: ${category.parentName}',
// key: Key('category_${category.id}'), key: Key('category_${category.id}'),
//onPress: () => () {}, onPress: () => _navigatorService.push(categoryEditRoute,
arguments: category),
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
@ -94,6 +96,16 @@ class _CategoryDictionaryViewState extends State<CategoryDictionaryView> {
), ),
], ],
), ),
floatingActionButton: FloatingActionButton(
elevation: 2,
onPressed: () => locator<NavigatorService>()
.push(categoryEditRoute, arguments: CategoryRowDao('', '', null)),
child: const Icon(
Icons.add_rounded,
size: 34.0,
color: whiteColor,
),
),
); );
} }
@ -114,9 +126,10 @@ class _CategoryDictionaryViewState extends State<CategoryDictionaryView> {
.firstWhere((parent) => parent.id == element.parentId, orElse: () { .firstWhere((parent) => parent.id == element.parentId, orElse: () {
return Category(); return Category();
}); });
String parentName = category.name; final String parentName = category.name;
final CategoryRowDao rowDao = final CategoryRowDao rowDao = CategoryRowDao(
CategoryRowDao(element.name, parentName, element.id); element.name, parentName, element.id,
parentId: element.parentId);
list.add(rowDao); list.add(rowDao);
}); });
setState(() { setState(() {
@ -126,9 +139,10 @@ class _CategoryDictionaryViewState extends State<CategoryDictionaryView> {
} }
class CategoryRowDao { class CategoryRowDao {
CategoryRowDao(this.name, this.parentName, this.id); CategoryRowDao(this.name, this.parentName, this.id, { this.parentId = 0});
final String name; final String name;
final String parentName; final String parentName;
final int? id; final int? id;
final int? parentId;
} }

View File

@ -2,32 +2,44 @@ import 'package:flutter/material.dart';
import 'package:satu/shared/app_colors.dart'; import 'package:satu/shared/app_colors.dart';
class DictionaryTile extends StatelessWidget { class DictionaryTile extends StatelessWidget {
const DictionaryTile({required this.title, this.subTitle, Key? key}) const DictionaryTile({
: super(key: key); required this.title,
Key? key,
this.subTitle,
this.onPress,
}) : super(key: key);
final String title; final String title;
final String? subTitle; final String? subTitle;
final Function()? onPress;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
decoration: const BoxDecoration(color: whiteColor), decoration: const BoxDecoration(color: whiteColor),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onPress,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( horizontal: 15.0 , vertical: 10.0), padding:
const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
title, title,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12, color: textColor),
), ),
if (subTitle != null && subTitle!.isNotEmpty) if (subTitle != null && subTitle!.isNotEmpty)
Text(subTitle!, Text(subTitle!,
style: style: const TextStyle(
const TextStyle(fontSize: 10, color: placeholderColor)), fontSize: 10, color: placeholderColor)),
], ],
), ),
), ),
),
),
); );
} }
} }

View File

@ -66,26 +66,40 @@ class _ProductListItemState extends State<ProductListItem> {
), ),
direction: DismissDirection.endToStart, direction: DismissDirection.endToStart,
confirmDismiss: (DismissDirection direction) async { confirmDismiss: (DismissDirection direction) async {
return await showDialog( DialogResponse response = await _dialogService.showConfirmationDialog(
context: context, title: 'Внимание',
builder: (BuildContext context) { description: 'Удалить товар'
return AlertDialog(
title: const Text('Внимание'),
content: Text('Удалить товар '
'"${widget.name}"' '"${widget.name}"'
' - ${widget.count} ед. ?'), ' - ${widget.count} ед. ?',
actions: <Widget>[ confirmationTitle: 'Удалить',
TextButton( cancelTitle: 'Отмена'
onPressed: () => Navigator.of(context).pop(true),
child: const Text('Удалить')),
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: const Text('Отмена'),
),
],
);
},
); );
return response.confirmed;
// return await showDialog(
// context: context,
// builder: (BuildContext context) {
//
//
//
// return AlertDialog(
// title: const Text('Внимание'),
// content: Text('Удалить товар '
// '"${widget.name}"'
// ' - ${widget.count} ед. ?'),
// actions: <Widget>[
// TextButton(
// onPressed: () => Navigator.of(context).pop(true),
// child: const Text('Удалить')),
// TextButton(
// onPressed: () => Navigator.of(context).pop(false),
// child: const Text('Отмена'),
// ),
// ],
// );
// },
// );
}, },
onDismissed: (direction) { onDismissed: (direction) {
Redux.store! Redux.store!

View File

@ -5,6 +5,7 @@ import 'package:satu/core/redux/state/sell_state.dart';
import 'package:satu/core/redux/store.dart'; import 'package:satu/core/redux/store.dart';
import 'package:satu/core/utils/utils_parse.dart'; import 'package:satu/core/utils/utils_parse.dart';
import 'package:satu/shared/app_colors.dart'; import 'package:satu/shared/app_colors.dart';
import 'package:satu/views/dictionaries/category/category_view.dart';
import 'package:satu/views/work/views/payment/component/combine_dock.dart'; import 'package:satu/views/work/views/payment/component/combine_dock.dart';
import 'package:satu/widgets/bar/products_app_bar.dart'; import 'package:satu/widgets/bar/products_app_bar.dart';
import 'package:satu/widgets/bar/products_header_bar.dart'; import 'package:satu/widgets/bar/products_header_bar.dart';
@ -14,6 +15,7 @@ import 'package:satu/widgets/fields/input_field.dart';
import 'package:satu/widgets/fields/line_checkbox.dart'; import 'package:satu/widgets/fields/line_checkbox.dart';
class PaymentView extends StatefulWidget { class PaymentView extends StatefulWidget {
const PaymentView();
@override @override
_PaymentViewState createState() => _PaymentViewState(); _PaymentViewState createState() => _PaymentViewState();
} }

View File

@ -3,30 +3,28 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:satu/core/redux/actions/sell_actions.dart'; import 'package:satu/core/redux/actions/sell_actions.dart';
import 'package:satu/core/redux/store.dart'; import 'package:satu/core/redux/store.dart';
import 'package:satu/shared/app_colors.dart'; import 'package:satu/shared/app_colors.dart';
import 'package:satu/shared/shared_styles.dart';
import 'package:satu/widgets/dialog/modal_select_dialog.dart';
class ProductsTitleBarBar extends StatelessWidget { class ProductsTitleBarBar extends StatelessWidget {
const ProductsTitleBarBar(
{required this.title , Key? key, this.itemsExist = false})
: super(key: key);
final bool itemsExist; final bool itemsExist;
final String title; final String title;
const ProductsTitleBarBar(
{Key? key, this.itemsExist = false, required this.title})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Padding(
child: Padding( padding: const EdgeInsets.only(left: 15, right: 5, top: 15),
padding: EdgeInsets.only(left: 15.w, right: 5.w, top: 30.w),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.w), padding: const EdgeInsets.symmetric(vertical: 10),
child: Text( child: Text(
title, title,
style: TextStyle(fontSize: 16.sp, color: placeholderColor), style: const TextStyle(fontSize: 12, color: placeholderColor),
), ),
)), )),
if (itemsExist) if (itemsExist)
@ -61,7 +59,6 @@ class ProductsTitleBarBar extends StatelessWidget {
)) ))
], ],
), ),
),
); );
} }
} }

View File

@ -10,14 +10,16 @@ class BusyButton extends StatefulWidget {
final String title; final String title;
final Function onPressed; final Function onPressed;
final bool enabled; final bool enabled;
final Color? mainColor; final bool isCancel;
final bool isDanger;
const BusyButton({ const BusyButton({
required this.title, required this.title,
this.busy = false, this.busy = false,
required this.onPressed, required this.onPressed,
this.enabled = true, this.enabled = true,
this.mainColor, this.isCancel = false,
this.isDanger = false,
}); });
@override @override
@ -30,7 +32,8 @@ class _BusyButtonState extends State<BusyButton> {
return AnimatedContainer( return AnimatedContainer(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: primaryGradient, gradient: widget.isCancel || widget.isDanger ? null : primaryGradient,
color: widget.isCancel || widget.isDanger ? whiteColor : null,
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
boxShadow: [buttonShadowBox]), boxShadow: [buttonShadowBox]),
child: Material( child: Material(
@ -47,9 +50,9 @@ class _BusyButtonState extends State<BusyButton> {
? Text( ? Text(
widget.title, widget.title,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: const TextStyle( style: TextStyle(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: blackColor, color: widget.isDanger ? dangerColor : blackColor,
fontSize: 12), fontSize: 12),
//minFontSize: 2, //minFontSize: 2,
maxLines: 1, maxLines: 1,

View File

@ -50,38 +50,59 @@ class _DialogManagerState extends State<DialogManager> {
showDialog<String>( showDialog<String>(
context: context, context: context,
builder: (BuildContext context) => AlertDialog( builder: (BuildContext context) => AlertDialog(
backgroundColor: backgroundColor,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0), borderRadius: BorderRadius.circular(5.0),
), ),
actionsPadding: const EdgeInsets.only(right: 15, bottom: 5), actionsPadding: const EdgeInsets.only(right: 15, bottom: 5),
title: Column( content: SizedBox(
crossAxisAlignment: CrossAxisAlignment.start, width: ScreenUtil().setWidth(ScreenUtil().screenWidth * 0.9),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
verticalSpaceSmall,
Text( Text(
request.title, request.description,
style: const TextStyle(fontWeight: FontWeight.bold), style: const TextStyle(fontSize: 12),
), ),
//Divider(), verticalSpaceSmall,
], const Divider(),
verticalSpaceSmall,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: BusyButton(
isDanger: true,
title: request.buttonTitle.toUpperCase(),
onPressed: () {
final String _price = _controllerPrice.text;
final String _count = _controllerCount.text;
_dialogService.dialogComplete(DialogResponse(
confirmed: true,
responsePrice: _price.replaceAll(',', '.'),
responseCount: _count.replaceAll(',', '.')));
},
), ),
content: Text(request.description), ),
actions: <Widget>[ horizontalSpaceMedium,
if (isConfirmationDialog) if (isConfirmationDialog)
TextButton( Expanded(
child: BusyButton(
isCancel: true,
onPressed: () { onPressed: () {
_dialogService _dialogService.dialogComplete(
.dialogComplete(DialogResponse(confirmed: false)); DialogResponse(confirmed: false));
}, },
child: Text(request.cancelTitle!), //color: redColor,
title: request.cancelTitle!.toUpperCase(),
), ),
TextButton(
onPressed: () {
_dialogService
.dialogComplete(DialogResponse(confirmed: true));
},
child: Text(request.buttonTitle),
), ),
], ],
)
],
),
),
)); ));
} }

View File

@ -1,22 +1,36 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:satu/shared/app_colors.dart'; import 'package:satu/shared/app_colors.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'note_text.dart';
class LineCheckBox extends StatelessWidget { class LineCheckBox extends StatelessWidget {
const LineCheckBox(this.text, { required this.value }); const LineCheckBox(this.text,
{required this.value, this.labelText, this.onTap});
final String text; final String text;
final bool value; final bool value;
final String? labelText;
final Function()? onTap;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Column(
decoration: const BoxDecoration( crossAxisAlignment: CrossAxisAlignment.start,
color: whiteColor children: [
if (labelText != null)
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 14.0, vertical: 5.0),
child: NoteText(labelText ?? ''),
), ),
Container(
decoration: const BoxDecoration(color: whiteColor),
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: () {}, onTap: onTap,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 12.w), padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 12.w),
child: Row( child: Row(
@ -44,6 +58,8 @@ class LineCheckBox extends StatelessWidget {
), ),
), ),
), ),
),
],
); );
} }
} }

View File

@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
import 'package:satu/shared/app_colors.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'note_text.dart';
class LineTile extends StatelessWidget {
const LineTile(this.text, { required this.onTap, this.labelText });
final String text;
final String? labelText;
final Function() onTap;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (labelText != null)
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 14.0, vertical: 5.0),
child: NoteText(labelText ?? ''),
),
Container(
decoration: const BoxDecoration(
color: whiteColor
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 12.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
text,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: textColor
),
),
SizedBox(
width: 20,
child: const Icon(
Icons.chevron_right,
color: textColor,
),
)
],
),
),
),
),
),
],
);
}
}