payment combine dock
parent
8d162bf19b
commit
fe99db18b4
|
|
@ -50,9 +50,9 @@ class AppState {
|
||||||
|
|
||||||
//stable work
|
//stable work
|
||||||
AppState copyWith({
|
AppState copyWith({
|
||||||
@required UserState? userState,
|
UserState? userState,
|
||||||
@required NavState? navState,
|
NavState? navState,
|
||||||
@required SellState? sellState,
|
SellState? sellState,
|
||||||
}) {
|
}) {
|
||||||
return AppState(
|
return AppState(
|
||||||
userState: userState ?? this.userState,
|
userState: userState ?? this.userState,
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ class _AddProductViewState extends State<AddProductView> {
|
||||||
ean: good.ean,
|
ean: good.ean,
|
||||||
name: good.name,
|
name: good.name,
|
||||||
price: good.price,
|
price: good.price,
|
||||||
categoryName: _history?.last?.name,
|
categoryName: _history?.last.name,
|
||||||
onPress: () {
|
onPress: () {
|
||||||
onGoodPress(good);
|
onGoodPress(good);
|
||||||
} ,
|
} ,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:satu/shared/app_colors.dart';
|
||||||
|
import 'package:satu/shared/ui_helpers.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class CombineDock extends StatelessWidget {
|
||||||
|
const CombineDock({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
verticalSpaceSmall,
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8.0),
|
||||||
|
child: Text(
|
||||||
|
'Расчет',
|
||||||
|
style: TextStyle(fontSize: 12, color: placeholderColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: whiteColor,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(15.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: const [
|
||||||
|
Text(
|
||||||
|
'К оплате',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'1200 ₸',
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
height: 1,
|
||||||
|
color: disableColor,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: const [
|
||||||
|
Text(
|
||||||
|
'Банковская карта',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12, color: placeholderColor),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'1200 ₸',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12, color: placeholderColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
verticalSpaceSmall,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: const [
|
||||||
|
Text(
|
||||||
|
'Наличными',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12, color: placeholderColor),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'0 ₸',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12, color: placeholderColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
verticalSpaceSmall,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: const [
|
||||||
|
Text(
|
||||||
|
'Сдача',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12, color: placeholderColor),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'0 ₸',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 12, color: placeholderColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:satu/core/redux/state/sell_state.dart';
|
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/shared/app_colors.dart';
|
import 'package:satu/shared/app_colors.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';
|
||||||
import 'package:satu/widgets/bar/products_title_bar.dart';
|
|
||||||
import 'package:satu/views/work/tabs/utils/product_utils.dart';
|
import 'package:satu/views/work/tabs/utils/product_utils.dart';
|
||||||
import 'package:satu/widgets/buttons/busy_button.dart';
|
import 'package:satu/widgets/buttons/busy_button.dart';
|
||||||
|
import 'package:satu/widgets/fields/input_field.dart';
|
||||||
|
import 'package:satu/widgets/fields/line_checkbox.dart';
|
||||||
|
|
||||||
class PaymentView extends StatefulWidget {
|
class PaymentView extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
|
@ -17,7 +19,26 @@ class PaymentView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PaymentViewState extends State<PaymentView> {
|
class _PaymentViewState extends State<PaymentView> {
|
||||||
bool combine = false;
|
bool combine = true;
|
||||||
|
late num _sum;
|
||||||
|
|
||||||
|
late TextEditingController _bankSumCtrl;
|
||||||
|
late TextEditingController _cashSumCtrl;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_sum = sumProducts(Redux.store!.state.sellState!.items!);
|
||||||
|
_bankSumCtrl = TextEditingController(text: formatDecimal(_sum.toDouble()));
|
||||||
|
_cashSumCtrl = TextEditingController(text: '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_bankSumCtrl.dispose();
|
||||||
|
_cashSumCtrl.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -31,43 +52,49 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
childHeight: 60,
|
childHeight: 60,
|
||||||
child: ProductHeaderBar(
|
child: ProductHeaderBar(
|
||||||
count: state.items!.length,
|
count: state.items!.length,
|
||||||
sum: sumProducts(state.items!),
|
sum: _sum,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: ListView(
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 15.w),
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Visibility(
|
||||||
'Способ оплаты',
|
visible: combine == false,
|
||||||
style: TextStyle(
|
child: const Text(
|
||||||
fontSize: 16.sp, color: placeholderColor),
|
'Способ оплаты',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 14, color: placeholderColor),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
const Text(
|
||||||
'Комбинированный',
|
'комбинированный',
|
||||||
style: TextStyle(fontSize: 14.sp, color: placeholderColor),
|
style: TextStyle(
|
||||||
),
|
fontSize: 12, color: placeholderColor),
|
||||||
Switch(
|
),
|
||||||
value: combine,
|
Switch(
|
||||||
onChanged: (vl) {
|
value: combine,
|
||||||
setState(() {
|
onChanged: (vl) {
|
||||||
combine = !combine;
|
setState(() {
|
||||||
});
|
combine = !combine;
|
||||||
},
|
});
|
||||||
),
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
buildPaymentSelect(),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 45.0),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 45, vertical: 30),
|
||||||
child: BusyButton(title: 'ОПЛАТА', onPressed: () {}),
|
child: BusyButton(title: 'ОПЛАТА', onPressed: () {}),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -75,4 +102,44 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Column buildPaymentSelect() {
|
||||||
|
if (combine) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
InputField(
|
||||||
|
controller: _bankSumCtrl,
|
||||||
|
labelText: 'Банковская карта',
|
||||||
|
placeholder: 'Укажите сумму',
|
||||||
|
suffixText: '₸',
|
||||||
|
textInputType: const TextInputType.numberWithOptions(decimal: true),
|
||||||
|
),
|
||||||
|
InputField(
|
||||||
|
controller: _cashSumCtrl,
|
||||||
|
labelText: 'Наличные',
|
||||||
|
placeholder: 'Укажите сумму наличных',
|
||||||
|
suffixText: '₸',
|
||||||
|
textInputType: const TextInputType.numberWithOptions(decimal: true),
|
||||||
|
),
|
||||||
|
const CombineDock()
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Column(
|
||||||
|
children: const [
|
||||||
|
LineCheckBox(
|
||||||
|
'Банковская карта',
|
||||||
|
value: true,
|
||||||
|
),
|
||||||
|
Divider(
|
||||||
|
height: 1,
|
||||||
|
color: disableColor,
|
||||||
|
),
|
||||||
|
LineCheckBox(
|
||||||
|
'Оплата наличными',
|
||||||
|
value: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ class ProductsTitleBarBar extends StatelessWidget {
|
||||||
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);
|
const ProductsTitleBarBar(
|
||||||
|
{Key? key, this.itemsExist = false, required this.title})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -21,38 +23,42 @@ class ProductsTitleBarBar extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric( vertical: 10.w ),
|
padding: EdgeInsets.symmetric(vertical: 10.w),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(fontSize: 16.sp, color: placeholderColor),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
if (itemsExist)
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final bool? result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Внимание'),
|
||||||
|
content: const Text('Удалить все товары из списка'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () =>
|
||||||
|
Navigator.of(context).pop(true),
|
||||||
|
child: const Text('Удалить')),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(false),
|
||||||
|
child: const Text('Отмена'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result == true) {
|
||||||
|
Redux.store!.dispatch(removeAllSellData);
|
||||||
|
}
|
||||||
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
'Удалить все',
|
||||||
style: TextStyle(fontSize: 16.sp, color: placeholderColor),
|
style: TextStyle(fontSize: 16.sp, color: dangerColor),
|
||||||
),
|
))
|
||||||
)),
|
|
||||||
if(itemsExist)
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async {
|
|
||||||
bool? result = await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text("Внимание"),
|
|
||||||
content: Text("Удалить все товары из списка"),
|
|
||||||
actions: <Widget>[
|
|
||||||
TextButton(onPressed: () => Navigator.of(context).pop(true), child: const Text("Удалить")),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(context).pop(false),
|
|
||||||
child: const Text("Отмена"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if(result == true)
|
|
||||||
Redux.store!.dispatch(removeAllSellData);
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
'Удалить все',
|
|
||||||
style: TextStyle(fontSize: 16.sp, color: dangerColor),
|
|
||||||
))
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,21 @@ import 'package:satu/shared/shared_styles.dart';
|
||||||
|
|
||||||
/// A button that shows a busy indicator in place of title
|
/// A button that shows a busy indicator in place of title
|
||||||
class AmanIconButton extends StatefulWidget {
|
class AmanIconButton extends StatefulWidget {
|
||||||
|
const AmanIconButton({
|
||||||
|
required this.title,
|
||||||
|
required this.onPressed,
|
||||||
|
required this.mainColor,
|
||||||
|
required this.icon,
|
||||||
|
this.busy = false,
|
||||||
|
this.enabled = true,
|
||||||
|
});
|
||||||
|
|
||||||
final bool busy;
|
final bool busy;
|
||||||
final String title;
|
final String title;
|
||||||
final Function onPressed;
|
final Function onPressed;
|
||||||
final bool? enabled;
|
final bool? enabled;
|
||||||
final Color mainColor;
|
final Color mainColor;
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
const AmanIconButton(
|
|
||||||
{
|
|
||||||
required this.title,
|
|
||||||
this.busy = false,
|
|
||||||
required this.onPressed,
|
|
||||||
this.enabled = true,
|
|
||||||
required this.mainColor,
|
|
||||||
required this.icon
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_AmanIconButtonState createState() => _AmanIconButtonState();
|
_AmanIconButtonState createState() => _AmanIconButtonState();
|
||||||
|
|
@ -32,7 +32,7 @@ class _AmanIconButtonState extends State<AmanIconButton> {
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: BorderRadius.circular(6),
|
borderRadius: BorderRadius.circular(6),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if(!widget.busy) {
|
if (!widget.busy) {
|
||||||
widget.onPressed();
|
widget.onPressed();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -40,27 +40,35 @@ class _AmanIconButtonState extends State<AmanIconButton> {
|
||||||
//height: 75,
|
//height: 75,
|
||||||
width: 120,
|
width: 120,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
padding: EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||||
//horizontal: 25,
|
|
||||||
vertical: 15),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(6),
|
borderRadius: BorderRadius.circular(6),
|
||||||
border: Border.all( width: 1.0, color: widget.mainColor )
|
border: Border.all(width: 1.0, color: widget.mainColor)),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
(!widget.busy
|
||||||
|
? Icon(
|
||||||
|
widget.icon,
|
||||||
|
color: widget.mainColor,
|
||||||
|
size: 36,
|
||||||
|
)
|
||||||
|
: CircularProgressIndicator(
|
||||||
|
strokeWidth: 3,
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(widget.mainColor))),
|
||||||
|
AutoSizeText(
|
||||||
|
widget.title,
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
|
maxLines: 2,
|
||||||
|
style: TextStyle(
|
||||||
|
color: widget.mainColor,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
(!widget.busy
|
|
||||||
? Icon(
|
|
||||||
widget.icon,
|
|
||||||
color: widget.mainColor,
|
|
||||||
size: 36,
|
|
||||||
)
|
|
||||||
: CircularProgressIndicator(
|
|
||||||
strokeWidth: 3,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(widget.mainColor))),
|
|
||||||
AutoSizeText(widget.title, overflow: TextOverflow.fade, maxLines: 2, style: TextStyle(color: widget.mainColor, fontSize: 14, fontWeight: FontWeight.w800, ), textAlign: TextAlign.center,)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -47,17 +47,17 @@ class _BusyButtonState extends State<BusyButton> {
|
||||||
? Text(
|
? Text(
|
||||||
widget.title,
|
widget.title,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: blackColor,
|
color: blackColor,
|
||||||
fontSize: 14.sp),
|
fontSize: 12),
|
||||||
//minFontSize: 2,
|
//minFontSize: 2,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
)
|
)
|
||||||
: SizedBox(
|
: SizedBox(
|
||||||
width: 20.h,
|
width: 20.h,
|
||||||
height: 20.h,
|
height: 20.h,
|
||||||
child: CircularProgressIndicator(
|
child: const CircularProgressIndicator(
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
valueColor:
|
valueColor:
|
||||||
AlwaysStoppedAnimation<Color>(Colors.white)),
|
AlwaysStoppedAnimation<Color>(Colors.white)),
|
||||||
|
|
|
||||||
|
|
@ -23,23 +23,23 @@ class AppDrawer extends StatelessWidget {
|
||||||
}),
|
}),
|
||||||
Divider(),
|
Divider(),
|
||||||
ExpansionTile(
|
ExpansionTile(
|
||||||
title: Text("Справочники"),
|
title: Text('Справочники'), // ignore: prefer_const_constructors
|
||||||
childrenPadding: EdgeInsets.only(left: 18.0),
|
childrenPadding: const EdgeInsets.only(left: 18.0),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('Категории'),
|
title: const Text('Категории'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('Товары'),
|
title: const Text('Товары'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('Контрагенты'),
|
title: const Text('Контрагенты'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
|
|
@ -79,7 +79,7 @@ class AppDrawer extends StatelessWidget {
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 12.0,
|
bottom: 12.0,
|
||||||
left: 16.0,
|
left: 16.0,
|
||||||
child: Text("Сату - онлайн касса",
|
child: Text('Сату - онлайн касса',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 20.0,
|
fontSize: 20.0,
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,21 @@ import 'package:satu/shared/app_colors.dart';
|
||||||
import 'package:satu/shared/shared_styles.dart';
|
import 'package:satu/shared/shared_styles.dart';
|
||||||
import 'package:satu/shared/ui_helpers.dart';
|
import 'package:satu/shared/ui_helpers.dart';
|
||||||
|
|
||||||
|
|
||||||
import 'note_text.dart';
|
import 'note_text.dart';
|
||||||
|
|
||||||
class DropDownField extends StatefulWidget {
|
class DropDownField extends StatefulWidget {
|
||||||
|
const DropDownField(
|
||||||
|
{required this.placeholder,
|
||||||
|
this.fieldFocusNode,
|
||||||
|
this.nextFocusNode,
|
||||||
|
this.additionalNote,
|
||||||
|
this.onChanged,
|
||||||
|
this.initialValue,
|
||||||
|
this.validationMessage,
|
||||||
|
this.isReadOnly = false,
|
||||||
|
this.smallVersion = false,
|
||||||
|
this.labelText});
|
||||||
|
|
||||||
final bool isReadOnly;
|
final bool isReadOnly;
|
||||||
final String placeholder;
|
final String placeholder;
|
||||||
final String? validationMessage;
|
final String? validationMessage;
|
||||||
|
|
@ -19,17 +30,7 @@ class DropDownField extends StatefulWidget {
|
||||||
final String? initialValue;
|
final String? initialValue;
|
||||||
final String? labelText;
|
final String? labelText;
|
||||||
|
|
||||||
DropDownField(
|
|
||||||
{
|
|
||||||
required this.placeholder,
|
|
||||||
this.fieldFocusNode,
|
|
||||||
this.nextFocusNode,
|
|
||||||
this.additionalNote,
|
|
||||||
this.onChanged,
|
|
||||||
this.initialValue,
|
|
||||||
this.validationMessage,
|
|
||||||
this.isReadOnly = false,
|
|
||||||
this.smallVersion = false, this.labelText});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_DropDownFieldState createState() => _DropDownFieldState();
|
_DropDownFieldState createState() => _DropDownFieldState();
|
||||||
|
|
@ -51,14 +52,16 @@ class _DropDownFieldState extends State<DropDownField> {
|
||||||
if (widget.labelText != null) NoteText(widget.labelText ?? ''),
|
if (widget.labelText != null) NoteText(widget.labelText ?? ''),
|
||||||
Container(
|
Container(
|
||||||
//height: widget.smallVersion ? 40 : fieldHeight,
|
//height: widget.smallVersion ? 40 : fieldHeight,
|
||||||
constraints: BoxConstraints(minHeight: widget.smallVersion ? 40 : fieldHeight),
|
constraints:
|
||||||
|
BoxConstraints(minHeight: widget.smallVersion ? 40 : fieldHeight),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
padding: fieldPadding,
|
padding: fieldPadding,
|
||||||
decoration: widget.isReadOnly ? disabledFieldDecoration : fieldDecoration,
|
decoration:
|
||||||
child: Expanded(
|
widget.isReadOnly ? disabledFieldDecoration : fieldDecoration,
|
||||||
child: Container()
|
child: Expanded(child: Container()
|
||||||
// SearchableDropdown.single(
|
// SearchableDropdown.single(
|
||||||
// items: <String>['Частное лицо', 'ИП Иванов', 'ТО "Рога и копыта"', 'Network Energy']
|
// items: <String>['Частное лицо', 'ИП Иванов',
|
||||||
|
// 'ТО "Рога и копыта"', 'Network Energy']
|
||||||
// .map<DropdownMenuItem<String>>((String value) {
|
// .map<DropdownMenuItem<String>>((String value) {
|
||||||
// return DropdownMenuItem<String>(
|
// return DropdownMenuItem<String>(
|
||||||
// value: value,
|
// value: value,
|
||||||
|
|
@ -72,7 +75,8 @@ class _DropDownFieldState extends State<DropDownField> {
|
||||||
// underline: Container(
|
// underline: Container(
|
||||||
// height: 1.0,
|
// height: 1.0,
|
||||||
// decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
// border: Border(bottom: BorderSide(color: yellowColor, width: 3.0))
|
// border: Border(bottom:
|
||||||
|
// BorderSide(color: yellowColor, width: 3.0))
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// onChanged: (value) {
|
// onChanged: (value) {
|
||||||
|
|
@ -80,7 +84,7 @@ class _DropDownFieldState extends State<DropDownField> {
|
||||||
// },
|
// },
|
||||||
// isExpanded: true,
|
// isExpanded: true,
|
||||||
// ),
|
// ),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.validationMessage != null)
|
if (widget.validationMessage != null)
|
||||||
NoteText(
|
NoteText(
|
||||||
|
|
@ -88,7 +92,8 @@ class _DropDownFieldState extends State<DropDownField> {
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
),
|
),
|
||||||
if (widget.additionalNote != null) verticalSpace(5),
|
if (widget.additionalNote != null) verticalSpace(5),
|
||||||
if (widget.additionalNote != null) NoteText(widget.additionalNote ?? ''),
|
if (widget.additionalNote != null)
|
||||||
|
NoteText(widget.additionalNote ?? ''),
|
||||||
verticalSpaceSmall
|
verticalSpaceSmall
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class InputField extends StatefulWidget {
|
||||||
final bool password;
|
final bool password;
|
||||||
final bool search;
|
final bool search;
|
||||||
final bool isReadOnly;
|
final bool isReadOnly;
|
||||||
final String placeholder;
|
final String? placeholder;
|
||||||
final String? validationMessage;
|
final String? validationMessage;
|
||||||
final Function? enterPressed;
|
final Function? enterPressed;
|
||||||
final bool smallVersion;
|
final bool smallVersion;
|
||||||
|
|
@ -26,16 +26,17 @@ class InputField extends StatefulWidget {
|
||||||
final TextInputFormatter? formatter;
|
final TextInputFormatter? formatter;
|
||||||
final String? initialValue;
|
final String? initialValue;
|
||||||
final String? labelText;
|
final String? labelText;
|
||||||
|
final String? suffixText;
|
||||||
|
|
||||||
InputField(
|
InputField(
|
||||||
{
|
{required this.controller,
|
||||||
required this.controller,
|
this.placeholder,
|
||||||
required this.placeholder,
|
|
||||||
this.enterPressed,
|
this.enterPressed,
|
||||||
this.fieldFocusNode,
|
this.fieldFocusNode,
|
||||||
this.nextFocusNode,
|
this.nextFocusNode,
|
||||||
this.additionalNote,
|
this.additionalNote,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
|
this.suffixText,
|
||||||
this.formatter,
|
this.formatter,
|
||||||
this.initialValue,
|
this.initialValue,
|
||||||
this.validationMessage,
|
this.validationMessage,
|
||||||
|
|
@ -45,7 +46,8 @@ class InputField extends StatefulWidget {
|
||||||
this.search = false,
|
this.search = false,
|
||||||
this.isReadOnly = false,
|
this.isReadOnly = false,
|
||||||
this.multiline = false,
|
this.multiline = false,
|
||||||
this.smallVersion = false, this.labelText});
|
this.smallVersion = false,
|
||||||
|
this.labelText});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_InputFieldState createState() => _InputFieldState();
|
_InputFieldState createState() => _InputFieldState();
|
||||||
|
|
@ -61,9 +63,9 @@ class _InputFieldState extends State<InputField> {
|
||||||
super.initState();
|
super.initState();
|
||||||
isPassword = widget.password;
|
isPassword = widget.password;
|
||||||
isSearch = widget.search;
|
isSearch = widget.search;
|
||||||
if(widget.search == true) {
|
if (widget.search == true) {
|
||||||
widget.fieldFocusNode!.addListener(() {
|
widget.fieldFocusNode!.addListener(() {
|
||||||
if(widget.fieldFocusNode!.hasFocus){
|
if (widget.fieldFocusNode!.hasFocus) {
|
||||||
setState(() {
|
setState(() {
|
||||||
isSearch = !isSearch;
|
isSearch = !isSearch;
|
||||||
});
|
});
|
||||||
|
|
@ -77,10 +79,16 @@ class _InputFieldState extends State<InputField> {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (widget.labelText != null) NoteText(widget.labelText ?? ''),
|
if (widget.labelText != null)
|
||||||
Container(
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 14.0, vertical: 5.0),
|
||||||
|
child: NoteText(widget.labelText ?? ''),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
//height: widget.smallVersion ? 40 : fieldHeight,
|
//height: widget.smallVersion ? 40 : fieldHeight,
|
||||||
constraints: BoxConstraints(minHeight: widget.smallVersion ? 40.h : fieldHeight),
|
constraints: BoxConstraints(
|
||||||
|
minHeight: widget.smallVersion ? 40.h : fieldHeight),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
padding: fieldPadding,
|
padding: fieldPadding,
|
||||||
decoration:
|
decoration:
|
||||||
|
|
@ -89,35 +97,39 @@ class _InputFieldState extends State<InputField> {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if(isSearch) {
|
if (isSearch) {
|
||||||
widget.fieldFocusNode!.requestFocus();
|
widget.fieldFocusNode!.requestFocus();
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
isSearch = !isSearch;
|
isSearch = !isSearch;
|
||||||
});
|
});
|
||||||
FocusScope.of(context).requestFocus(new FocusNode()); //remove focus
|
FocusScope.of(context)
|
||||||
WidgetsBinding.instance!.addPostFrameCallback((_) => widget.controller.clear()); // clear content
|
.requestFocus(FocusNode()); //remove focus
|
||||||
|
WidgetsBinding.instance!.addPostFrameCallback(
|
||||||
|
(_) => widget.controller.clear()); // clear content
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
child: widget.search
|
child: widget.search
|
||||||
? Container(
|
? Container(
|
||||||
width: fieldHeight,
|
width: fieldHeight,
|
||||||
height: fieldHeight,
|
height: fieldHeight,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Icon(isSearch
|
child: Icon(isSearch ? Icons.search : Icons.search_off,
|
||||||
? Icons.search
|
color: placeholderColor))
|
||||||
: Icons.search_off, color: placeholderColor))
|
|
||||||
: Container(),
|
: Container(),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
style: TextStyle( color: textColor, fontSize: widget.smallVersion ? ScreenUtil().setSp(12) : ScreenUtil().setSp(15) ),
|
style: TextStyle(
|
||||||
|
color: textColor,
|
||||||
|
fontSize: widget.smallVersion
|
||||||
|
? 12
|
||||||
|
: 14),
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
keyboardType: widget.textInputType,
|
keyboardType: widget.textInputType,
|
||||||
focusNode: widget.fieldFocusNode,
|
focusNode: widget.fieldFocusNode,
|
||||||
textInputAction: widget.textInputAction,
|
textInputAction: widget.textInputAction,
|
||||||
maxLines: widget.multiline ? null : 1,
|
maxLines: widget.multiline ? null : 1,
|
||||||
onChanged: widget.onChanged,
|
onChanged: widget.onChanged,
|
||||||
initialValue: widget.initialValue,
|
initialValue: widget.initialValue,
|
||||||
inputFormatters:
|
inputFormatters:
|
||||||
|
|
@ -138,10 +150,15 @@ class _InputFieldState extends State<InputField> {
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: widget.placeholder,
|
hintText: widget.placeholder,
|
||||||
filled: true,
|
filled: true,
|
||||||
|
suffixText: widget.suffixText,
|
||||||
|
suffixStyle: const TextStyle(color: textColor),
|
||||||
fillColor: whiteColor,
|
fillColor: whiteColor,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
hintStyle:
|
hintStyle: TextStyle(
|
||||||
TextStyle(fontSize: widget.smallVersion ? ScreenUtil().setSp(12) : ScreenUtil().setSp(15), color: placeholderColor)),
|
fontSize: widget.smallVersion
|
||||||
|
? ScreenUtil().setSp(12)
|
||||||
|
: ScreenUtil().setSp(14),
|
||||||
|
color: placeholderColor)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
|
|
@ -153,9 +170,11 @@ class _InputFieldState extends State<InputField> {
|
||||||
width: fieldHeight,
|
width: fieldHeight,
|
||||||
height: fieldHeight,
|
height: fieldHeight,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Icon(isPassword
|
child: Icon(
|
||||||
? Icons.visibility
|
isPassword
|
||||||
: Icons.visibility_off, color: textColor))
|
? Icons.visibility
|
||||||
|
: Icons.visibility_off,
|
||||||
|
color: textColor))
|
||||||
: Container(),
|
: Container(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -167,7 +186,8 @@ class _InputFieldState extends State<InputField> {
|
||||||
color: dangerColor,
|
color: dangerColor,
|
||||||
),
|
),
|
||||||
if (widget.additionalNote != null) verticalSpace(5),
|
if (widget.additionalNote != null) verticalSpace(5),
|
||||||
if (widget.additionalNote != null) NoteText(widget.additionalNote ?? ''),
|
if (widget.additionalNote != null)
|
||||||
|
NoteText(widget.additionalNote ?? ''),
|
||||||
verticalSpaceSmall
|
verticalSpaceSmall
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,8 @@ class _InputFieldRoundedState extends State<InputFieldRounded> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: textColor,
|
color: textColor,
|
||||||
fontSize: widget.smallVersion
|
fontSize: widget.smallVersion
|
||||||
? ScreenUtil().setSp(12)
|
? 12
|
||||||
: ScreenUtil().setSp(15)),
|
: 14),
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
keyboardType: widget.textInputType,
|
keyboardType: widget.textInputType,
|
||||||
focusNode: widget.fieldFocusNode,
|
focusNode: widget.fieldFocusNode,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:satu/shared/app_colors.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
|
class LineCheckBox extends StatelessWidget {
|
||||||
|
const LineCheckBox(this.text, { required this.value });
|
||||||
|
final String text;
|
||||||
|
final bool value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: whiteColor
|
||||||
|
),
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 12.w),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 20.w,
|
||||||
|
child: Visibility(
|
||||||
|
visible: value,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.check,
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
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';
|
||||||
|
|
||||||
class NoteText extends StatelessWidget {
|
class NoteText extends StatelessWidget {
|
||||||
const NoteText(this.text, {this.textAlign, this.color, this.fontSize});
|
const NoteText(this.text, {this.textAlign, this.color, this.fontSize});
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ class _BarcodePermissionWidgetState extends State<_BarcodePermissionWidget> {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_requestMobilePermission();
|
_requestMobilePermission();
|
||||||
},
|
},
|
||||||
child: Text("Запроса на разрешения"),
|
child: const Text('Запроса на разрешения'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@ class LogoSatu extends StatelessWidget {
|
||||||
height: 75.h,
|
height: 75.h,
|
||||||
child: Image.asset('assets/images/logo.png'),
|
child: Image.asset('assets/images/logo.png'),
|
||||||
),
|
),
|
||||||
AutoSizeText('Товароучетная система', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w400 ), )
|
AutoSizeText(
|
||||||
|
'Товароучетная система',
|
||||||
|
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w400),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ import 'package:satu/shared/ui_helpers.dart';
|
||||||
import 'package:satu/views/work/tabs/component/product_list_item.dart';
|
import 'package:satu/views/work/tabs/component/product_list_item.dart';
|
||||||
|
|
||||||
class ProductTitleWidget extends StatelessWidget {
|
class ProductTitleWidget extends StatelessWidget {
|
||||||
const ProductTitleWidget({Key? key, required this.name, this.ean, this.categoryName}) : super(key: key);
|
const ProductTitleWidget(
|
||||||
|
{required this.name, Key? key, this.ean, this.categoryName})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
final String? ean;
|
final String? ean;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue