printer receipt
This commit is contained in:
+206
-41
@@ -1,58 +1,223 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../../../../../application/printer/printer_form/printer_form_bloc.dart';
|
||||
import '../../../../../../../common/data/printer_data.dart';
|
||||
import '../../../../../../../common/extension/extension.dart';
|
||||
import '../../../../../../../common/theme/theme.dart';
|
||||
import '../../../../../../../domain/printer/printer.dart';
|
||||
import '../../../../../../components/button/button.dart';
|
||||
import '../../../../../../components/dialog/dialog.dart';
|
||||
import '../../../../../../components/field/field.dart';
|
||||
import '../../../../../../components/spaces/space.dart';
|
||||
import '../../../../../../components/toast/flushbar.dart';
|
||||
|
||||
class SettingPrinterForm extends StatelessWidget {
|
||||
class SettingPrinterForm extends StatefulWidget {
|
||||
final String code;
|
||||
const SettingPrinterForm({super.key, required this.code});
|
||||
final Printer? printer;
|
||||
final Function()? onCancel;
|
||||
final Function()? onSuccess;
|
||||
|
||||
const SettingPrinterForm({
|
||||
super.key,
|
||||
required this.code,
|
||||
this.printer,
|
||||
this.onCancel,
|
||||
this.onSuccess,
|
||||
});
|
||||
|
||||
@override
|
||||
State<SettingPrinterForm> createState() => _SettingPrinterFormState();
|
||||
}
|
||||
|
||||
class _SettingPrinterFormState extends State<SettingPrinterForm> {
|
||||
final TextEditingController _nameController = TextEditingController();
|
||||
void setup() {
|
||||
if (widget.printer != null) {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.typeChanged(widget.printer!.type),
|
||||
);
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.addressChanged(widget.printer!.address),
|
||||
);
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.codeChanged(widget.printer!.code),
|
||||
);
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.nameChanged(widget.printer!.name),
|
||||
);
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.paperChanged(widget.printer!.paper),
|
||||
);
|
||||
_nameController.text = widget.printer!.name;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
setup();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
AppDropdownSearch<String>(
|
||||
label: 'Tipe',
|
||||
hintText: 'Printer Tipe',
|
||||
items: printerTypes,
|
||||
itemAsString: (value) => value,
|
||||
),
|
||||
SpaceHeight(12),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: AppElevatedButton.outlined(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
PrinterBluetoothDialog(onSelected: (value) {}),
|
||||
);
|
||||
},
|
||||
label: 'Cari',
|
||||
return MultiBlocListener(
|
||||
listeners: [
|
||||
BlocListener<PrinterFormBloc, PrinterFormState>(
|
||||
listenWhen: (p, c) =>
|
||||
p.failureOrCreateSuccess != c.failureOrCreateSuccess,
|
||||
listener: (context, state) {
|
||||
state.failureOrCreateSuccess.fold(
|
||||
() => null,
|
||||
(either) => either.fold(
|
||||
(f) => AppFlushbar.showPrinterFailureToast(context, f),
|
||||
(either) {
|
||||
widget.onSuccess?.call();
|
||||
AppFlushbar.showSuccess(
|
||||
context,
|
||||
'Printer ${widget.code.toTitleCase()} berhasil ditambahkan',
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
BlocListener<PrinterFormBloc, PrinterFormState>(
|
||||
listenWhen: (p, c) =>
|
||||
p.failureOrUpdateSuccess != c.failureOrUpdateSuccess,
|
||||
listener: (context, state) {
|
||||
state.failureOrUpdateSuccess.fold(
|
||||
() => null,
|
||||
(either) => either.fold(
|
||||
(f) => AppFlushbar.showPrinterFailureToast(context, f),
|
||||
(either) {
|
||||
widget.onSuccess?.call();
|
||||
AppFlushbar.showSuccess(
|
||||
context,
|
||||
'Printer ${widget.code.toTitleCase()} berhasil diubah',
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
child: BlocBuilder<PrinterFormBloc, PrinterFormState>(
|
||||
builder: (context, state) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
),
|
||||
),
|
||||
SpaceHeight(12),
|
||||
AppTextFormField(label: 'Nama Printer'),
|
||||
SpaceHeight(12),
|
||||
AppDropdownSearch<String>(
|
||||
label: 'Kertas',
|
||||
hintText: 'Kertas Tipe',
|
||||
items: paperTypes,
|
||||
itemAsString: (value) => "$value mm",
|
||||
),
|
||||
SpaceHeight(20),
|
||||
AppElevatedButton.filled(onPressed: () {}, label: 'Simpan'),
|
||||
],
|
||||
child: Column(
|
||||
children: [
|
||||
AppDropdownSearch<String>(
|
||||
label: 'Tipe',
|
||||
hintText: 'Printer Tipe',
|
||||
items: printerTypes,
|
||||
itemAsString: (value) => value,
|
||||
selectedItem: state.type,
|
||||
onChanged: (value) {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.typeChanged(value!),
|
||||
);
|
||||
},
|
||||
),
|
||||
SpaceHeight(12),
|
||||
state.type == 'Bluetooth'
|
||||
? SizedBox(
|
||||
width: double.infinity,
|
||||
child: AppElevatedButton.outlined(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => PrinterBluetoothDialog(
|
||||
onSelected: (value) {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.addressChanged(value),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
label: state.address != '' ? state.address : 'Cari',
|
||||
),
|
||||
)
|
||||
: AppTextFormField(
|
||||
label: 'Network',
|
||||
onChanged: (value) {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.addressChanged(value),
|
||||
);
|
||||
},
|
||||
),
|
||||
SpaceHeight(12),
|
||||
AppTextFormField(
|
||||
label: 'Nama Printer',
|
||||
controller: _nameController,
|
||||
onChanged: (value) {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.nameChanged(value),
|
||||
);
|
||||
},
|
||||
),
|
||||
SpaceHeight(12),
|
||||
AppDropdownSearch<String>(
|
||||
label: 'Kertas',
|
||||
hintText: 'Kertas Tipe',
|
||||
items: paperTypes,
|
||||
itemAsString: (value) => "$value mm",
|
||||
selectedItem: state.paper,
|
||||
onChanged: (value) {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.paperChanged(value!),
|
||||
);
|
||||
},
|
||||
),
|
||||
SpaceHeight(20),
|
||||
Row(
|
||||
children: [
|
||||
if (widget.printer != null) ...[
|
||||
Expanded(
|
||||
child: AppElevatedButton.outlined(
|
||||
onPressed: widget.onCancel,
|
||||
label: 'Batal',
|
||||
),
|
||||
),
|
||||
SpaceWidth(12),
|
||||
],
|
||||
Expanded(
|
||||
child: AppElevatedButton.filled(
|
||||
onPressed: () {
|
||||
if (widget.printer == null) {
|
||||
if (!state.isCreating) {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.codeChanged(widget.code),
|
||||
);
|
||||
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.created(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
context.read<PrinterFormBloc>().add(
|
||||
PrinterFormEvent.updated(widget.printer!.id),
|
||||
);
|
||||
}
|
||||
},
|
||||
label: widget.printer == null ? 'Simpan' : 'Ubah',
|
||||
isLoading: widget.printer == null
|
||||
? state.isCreating
|
||||
: state.isUpdate,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
+69
-3
@@ -1,18 +1,84 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../../../../../application/printer/printer_loader/printer_loader_bloc.dart';
|
||||
import '../../../../../../../common/theme/theme.dart';
|
||||
import '../../../../../../components/loader/loader_with_text.dart';
|
||||
import '../../widgets/printer_card.dart';
|
||||
import 'setting_printer_form.dart';
|
||||
|
||||
class SettingPrinterReceipt extends StatelessWidget {
|
||||
class SettingPrinterReceipt extends StatefulWidget {
|
||||
const SettingPrinterReceipt({super.key});
|
||||
|
||||
@override
|
||||
State<SettingPrinterReceipt> createState() => _SettingPrinterReceiptState();
|
||||
}
|
||||
|
||||
class _SettingPrinterReceiptState extends State<SettingPrinterReceipt> {
|
||||
bool isEdit = false;
|
||||
@override
|
||||
initState() {
|
||||
context.read<PrinterLoaderBloc>().add(
|
||||
const PrinterLoaderEvent.getByCode('receipt'),
|
||||
);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: AppColor.background,
|
||||
child: Padding(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(children: [SettingPrinterForm(code: 'receipt')]),
|
||||
child: Column(
|
||||
children: [
|
||||
BlocBuilder<PrinterLoaderBloc, PrinterLoaderState>(
|
||||
builder: (context, state) {
|
||||
if (state.isFetching) {
|
||||
return const Center(child: LoaderWithText());
|
||||
}
|
||||
|
||||
if (state.printer.code == '') {
|
||||
return SettingPrinterForm(
|
||||
code: 'receipt',
|
||||
onSuccess: () {
|
||||
context.read<PrinterLoaderBloc>().add(
|
||||
PrinterLoaderEvent.getByCode('receipt'),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return isEdit
|
||||
? SettingPrinterForm(
|
||||
code: 'receipt',
|
||||
printer: state.printer,
|
||||
onCancel: () {
|
||||
setState(() {
|
||||
isEdit = false;
|
||||
});
|
||||
},
|
||||
onSuccess: () {
|
||||
context.read<PrinterLoaderBloc>().add(
|
||||
PrinterLoaderEvent.getByCode('receipt'),
|
||||
);
|
||||
setState(() {
|
||||
isEdit = false;
|
||||
});
|
||||
},
|
||||
)
|
||||
: PrinterCard(
|
||||
printer: state.printer,
|
||||
onEdit: () {
|
||||
setState(() {
|
||||
isEdit = true;
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../../../common/theme/theme.dart';
|
||||
import '../../../../../../domain/printer/printer.dart';
|
||||
import '../../../../../components/spaces/space.dart';
|
||||
|
||||
class PrinterCard extends StatelessWidget {
|
||||
final Printer printer;
|
||||
final VoidCallback? onEdit;
|
||||
final VoidCallback? onDelete;
|
||||
final VoidCallback? onTestPrint;
|
||||
|
||||
const PrinterCard({
|
||||
super.key,
|
||||
required this.printer,
|
||||
this.onEdit,
|
||||
this.onDelete,
|
||||
this.onTestPrint,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Printer icon
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.disabled.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: const Icon(Icons.print_outlined),
|
||||
),
|
||||
const SpaceWidth(12),
|
||||
// Printer info
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
printer.name,
|
||||
style: AppStyle.lg.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColor.primary,
|
||||
),
|
||||
),
|
||||
const SpaceHeight(4),
|
||||
Text(
|
||||
"${printer.paper} mm | ${printer.type}",
|
||||
style: AppStyle.sm,
|
||||
),
|
||||
const SpaceHeight(2),
|
||||
Text(
|
||||
printer.address,
|
||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Popup menu
|
||||
PopupMenuButton<String>(
|
||||
color: AppColor.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
onSelected: (value) {
|
||||
switch (value) {
|
||||
case 'edit':
|
||||
onEdit?.call();
|
||||
break;
|
||||
case 'delete':
|
||||
onDelete?.call();
|
||||
break;
|
||||
case 'test':
|
||||
onTestPrint?.call();
|
||||
break;
|
||||
}
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
value: 'edit',
|
||||
child: Text('Edit', style: AppStyle.md),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 'delete',
|
||||
child: Text('Hapus', style: AppStyle.md),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 'test',
|
||||
child: Text('Test Print', style: AppStyle.md),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user