560 lines
24 KiB
Dart
560 lines
24 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:esc_pos_utils/esc_pos_utils.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
import 'package:flutter_pos_printer_platform_image_3/flutter_pos_printer_platform_image_3.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:ticket_booth/app/print_ticket.dart';
|
|
import 'package:ticket_booth/app/route.dart';
|
|
import 'package:ticket_booth/model/booth.dart';
|
|
import 'package:ticket_booth/model/branch_model.dart';
|
|
import 'package:ticket_booth/model/cabapility_model.dart';
|
|
import 'package:ticket_booth/model/layanan.dart';
|
|
import 'package:ticket_booth/model/printer_device.dart';
|
|
import 'package:ticket_booth/provider/all_service_provider.dart';
|
|
import 'package:ticket_booth/screen/settings/booth_list_provider.dart';
|
|
import 'package:ticket_booth/screen/settings/branch_list_provider.dart';
|
|
import 'package:ticket_booth/screen/settings/service_list_provider.dart';
|
|
|
|
import '../../app/constant.dart';
|
|
import '../widgets/error_dialog.dart';
|
|
import 'form_input.dart';
|
|
|
|
class SettingScreen extends HookConsumerWidget {
|
|
const SettingScreen({super.key});
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final hostIpController = useTextEditingController(text: '');
|
|
final hostQrController = useTextEditingController(text: '');
|
|
final headerDisplayController = useTextEditingController(text: '');
|
|
final footerDisplayController = useTextEditingController(text: '');
|
|
final footerTicketController = useTextEditingController(text: '');
|
|
final headerTicketController = useTextEditingController(text: '');
|
|
final activeLayanan = useState<List>(List.empty());
|
|
final capabilityProfileList = useState<List<CapabilityProfileModel>>([]);
|
|
final selectedCapabilityProfile = useState<CapabilityProfileModel?>(null);
|
|
final isLoading = useState(false);
|
|
final data = useState('N');
|
|
final PrinterManager pm = PrinterManager.instance;
|
|
final dvcs = useState<List<PrinterDev>>([]);
|
|
var devices3 = <PrinterDev>[];
|
|
final selectedBtnSize = useState<Map<String, dynamic>>({
|
|
'name': '4',
|
|
'message': 'Tombol yang akan ditampilkan berjumlah 4 ',
|
|
'rightLeftWidth': "300",
|
|
'centerWidth': "912",
|
|
'childAspectRatio': '1.559',
|
|
'mainAxisSpacing': "10",
|
|
'crossAxisSpacing': '10',
|
|
'btnHeight': "330",
|
|
'btnWidth': '300',
|
|
'column': '2'
|
|
});
|
|
final List<Map<String, dynamic>> listBtnSize = [
|
|
{
|
|
'name': '10',
|
|
'message': 'Tombol yang akan ditampilkan berjumlah 10',
|
|
'rightLeftWidth': "40",
|
|
'centerWidth': "1432",
|
|
'childAspectRatio': '1',
|
|
'mainAxisSpacing': "20",
|
|
'crossAxisSpacing': '10',
|
|
'btnHeight': "290",
|
|
'btnWidth': '260',
|
|
'column': '5'
|
|
},
|
|
{
|
|
'name': '8',
|
|
'message': 'Tombol yang akan ditampilkan berjumlah 8 ',
|
|
'rightLeftWidth': "100",
|
|
'centerWidth': "1312",
|
|
'childAspectRatio': '1.1',
|
|
'mainAxisSpacing': "40",
|
|
'crossAxisSpacing': '10',
|
|
'btnHeight': "310",
|
|
'btnWidth': '280',
|
|
'column': '4'
|
|
},
|
|
{
|
|
'name': '6',
|
|
'message': 'Tombol yang akan ditampilkan berjumlah 6 ',
|
|
'rightLeftWidth': "200",
|
|
'centerWidth': "1112",
|
|
'childAspectRatio': '1.33',
|
|
'mainAxisSpacing': "40",
|
|
'crossAxisSpacing': '10',
|
|
'btnHeight': "310",
|
|
'btnWidth': '280',
|
|
'column': '3'
|
|
},
|
|
{
|
|
'name': '4',
|
|
'message': 'Tombol yang akan ditampilkan berjumlah 4 ',
|
|
'rightLeftWidth': "300",
|
|
'centerWidth': "912",
|
|
'childAspectRatio': '1.559',
|
|
'mainAxisSpacing': "10",
|
|
'crossAxisSpacing': '10',
|
|
'btnHeight': "330",
|
|
'btnWidth': '300',
|
|
'column': '2'
|
|
}
|
|
];
|
|
getServiceBooth() async {
|
|
activeLayanan.value = List.empty();
|
|
ref.read(BoothListProvider.notifier).list(hostIp: hostIpController.text);
|
|
ref
|
|
.read(ServiceListProvider.notifier)
|
|
.list(hostIp: hostIpController.text);
|
|
ref.read(BranchListProvider.notifier).list(hostIp: hostIpController.text);
|
|
}
|
|
|
|
_scan(PrinterType type) async {
|
|
// Find printers
|
|
pm.discovery(type: PrinterType.usb, isBle: false).listen((device) {
|
|
devices3.add(PrinterDev(
|
|
id: int.parse(device.productId ?? '0'),
|
|
deviceName: device.name,
|
|
address: device.address,
|
|
isBle: false,
|
|
vendorId: device.vendorId,
|
|
productId: device.productId,
|
|
));
|
|
});
|
|
}
|
|
|
|
full() async {
|
|
// await FullScreen.enterFullScreen(FullScreenMode.EMERSIVE_STICKY);
|
|
}
|
|
final lyn = useState<List<Layanan>>(List.empty());
|
|
|
|
final booth = useState<List<Booth>>(List.empty());
|
|
final branch = useState<List<BranchModel>>(List.empty());
|
|
final selected_printer = useState<PrinterDev?>(null);
|
|
final selected_booth =
|
|
useState<Booth>(Booth(name: 'Pilih salah satu', id: 0, code: 'b1'));
|
|
final selected_branch = useState<BranchModel>(
|
|
BranchModel(mBranchID: '0', mBranchName: 'Pilih salah satu cabang'));
|
|
Future delData() async {
|
|
// Obtain shared preferences.
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove('tb-westerindo');
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
}
|
|
|
|
Future getData() async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
var raw_data = prefs.getString('tb-westerindo') ?? 'a';
|
|
data.value = raw_data;
|
|
print(raw_data);
|
|
if (raw_data != 'a') {
|
|
lyn.value = ref.read(allServiceProvider);
|
|
var data = json.decode(raw_data);
|
|
selected_booth.value = Booth.fromJson(data['selectedBooth']);
|
|
selected_branch.value = BranchModel.fromJson(data['selectedBranch']);
|
|
selected_printer.value = PrinterDev.fromJson(data['selectedPrinter']);
|
|
hostIpController.text = data['hostIp'];
|
|
hostQrController.text = data['hostQrIp'];
|
|
headerDisplayController.text = data['headerDisplay'];
|
|
footerDisplayController.text = data['footerDisplay'];
|
|
footerTicketController.text = data['footerTicket'];
|
|
headerTicketController.text = data['headerTicket'];
|
|
activeLayanan.value = data['activeLayanan'] ?? List.empty();
|
|
selectedBtnSize.value = data['buttonSize'];
|
|
selectedCapabilityProfile.value =
|
|
CapabilityProfileModel.fromJson(data['selectedCapability']);
|
|
|
|
if (activeLayanan.value.isNotEmpty) {
|
|
activeLayanan.value.forEach((e) {
|
|
lyn.value.forEach((f) {
|
|
if (e == f.id) {
|
|
f.value = true;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print(e);
|
|
ErrorDialog(context, e.toString(), 'ERROR');
|
|
}
|
|
}
|
|
|
|
useEffect(() {
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
await getData();
|
|
var capabilityList = await CapabilityProfile.getAvailableProfiles();
|
|
List<CapabilityProfileModel> cl = List.empty(growable: true);
|
|
for (var i = 0; i < capabilityList.length; i++) {
|
|
var data = capabilityList[i];
|
|
final model = CapabilityProfileModel.fromJson(data);
|
|
cl.add(model);
|
|
}
|
|
capabilityProfileList.value = cl;
|
|
|
|
var stb = capabilityProfileList.value.firstWhere(
|
|
(element) => element.key == selectedCapabilityProfile.value?.key,
|
|
orElse: () => CapabilityProfileModel());
|
|
if (stb.key != null) {
|
|
selectedCapabilityProfile.value = stb;
|
|
}
|
|
|
|
_scan(PrinterType.usb);
|
|
dvcs.value = devices3;
|
|
if (data.value != 'a') {
|
|
ref
|
|
.read(BoothListProvider.notifier)
|
|
.list(hostIp: hostIpController.text);
|
|
ref
|
|
.read(BranchListProvider.notifier)
|
|
.list(hostIp: hostIpController.text);
|
|
}
|
|
});
|
|
full();
|
|
return () {};
|
|
}, []);
|
|
ref.listen(BoothListProvider, (previous, next) {
|
|
if (next is BoothListStateLoading) {
|
|
isLoading.value = true;
|
|
} else if (next is BoothListStateError) {
|
|
ErrorDialog(context, next.message, 'ERROR');
|
|
isLoading.value = false;
|
|
} else if (next is BoothListStateDone) {
|
|
booth.value = next.model;
|
|
isLoading.value = false;
|
|
}
|
|
});
|
|
ref.listen(ServiceListProvider, (previous, next) {
|
|
if (next is ServiceListStateLoading) {
|
|
isLoading.value = true;
|
|
} else if (next is ServiceListStateError) {
|
|
ErrorDialog(context, next.message, 'ERROR');
|
|
isLoading.value = false;
|
|
} else if (next is ServiceListStateDone) {
|
|
// ref.read(allServiceProvider.notifier).state = next.model;
|
|
// print(ref.read(allServiceProvider));
|
|
lyn.value = next.model;
|
|
isLoading.value = false;
|
|
}
|
|
});
|
|
ref.listen(BranchListProvider, (previous, next) {
|
|
if (next is BranchListStateLoading) {
|
|
isLoading.value = true;
|
|
} else if (next is BranchListStateError) {
|
|
ErrorDialog(context, next.message, 'ERROR');
|
|
isLoading.value = false;
|
|
} else if (next is BranchListStateDone) {
|
|
// ref.read(allServiceProvider.notifier).state = next.model;
|
|
// print(ref.read(allServiceProvider));
|
|
branch.value = next.model;
|
|
isLoading.value = false;
|
|
}
|
|
});
|
|
Future<bool> saveData() async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final Map<String, dynamic> data = {
|
|
"headerDisplay": headerDisplayController.text != ''
|
|
? headerDisplayController.text
|
|
: 'Selamat Datang Di Pramita',
|
|
"footerDisplay": footerDisplayController.text != ''
|
|
? footerDisplayController.text
|
|
: 'Sentuh Salah Satu Layanan',
|
|
"footerTicket": footerTicketController.text != ''
|
|
? footerTicketController.text
|
|
: 'SCAN QR CODE UNTUK MELIHAT STATUS ANTRIAN',
|
|
"headerTicket": headerTicketController.text != ''
|
|
? headerTicketController.text
|
|
: 'Labratorium Medis & Klinik PRAMITA',
|
|
"hostQrIp": hostQrController.text,
|
|
"hostIp": hostIpController.text,
|
|
"selectedPrinter": selected_printer.value,
|
|
"selectedBooth": selected_booth.value,
|
|
"selectedBranch": selected_branch.value,
|
|
"activeLayanan": activeLayanan.value,
|
|
'buttonSize': selectedBtnSize.value,
|
|
"selectedCapability": selectedCapabilityProfile.value
|
|
};
|
|
json.encode(data);
|
|
await prefs.setString('tb-westerindo', json.encode(data));
|
|
return true;
|
|
} catch (e) {
|
|
ErrorDialog(context, e.toString(), 'ERROR');
|
|
print(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Color getColor(Set<MaterialState> states) {
|
|
const Set<MaterialState> interactiveStates = <MaterialState>{
|
|
MaterialState.pressed,
|
|
MaterialState.hovered,
|
|
MaterialState.focused,
|
|
};
|
|
|
|
if (states.any(interactiveStates.contains)) {
|
|
return Colors.blue;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.green;
|
|
}
|
|
return Colors.white;
|
|
}
|
|
|
|
return Material(
|
|
child: Container(
|
|
height: Constant.getActualY(context: context, y: 982),
|
|
width: Constant.getActualX(context: context, x: 1512),
|
|
decoration: const BoxDecoration(
|
|
image: DecorationImage(
|
|
fit: BoxFit.cover,
|
|
image: AssetImage("assets/images/new-bg-icon.png"))),
|
|
child: Center(
|
|
child: Card(
|
|
color: Colors.white,
|
|
shadowColor: Colors.white,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.all(Radius.circular(10))),
|
|
elevation: 5,
|
|
child: SizedBox(
|
|
height: Constant.getActualY(context: context, y: 880),
|
|
width: Constant.getActualX(context: context, x: 1360),
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: Constant.getActualX(context: context, x: 30),
|
|
vertical: Constant.getActualY(context: context, y: 30)),
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
// TextButton(
|
|
// onPressed: () {
|
|
// Navigator.of(context)
|
|
// .popAndPushNamed(displayRoute);
|
|
// // print(pm.currentStatusUSB);
|
|
// // print(pm.currentStatusUSB);
|
|
// },
|
|
// child: const Text('back')),
|
|
Text(
|
|
'Setting',
|
|
style: Constant.subTitle(context: context),
|
|
),
|
|
// TextButton(
|
|
// onPressed: () {
|
|
// delData();
|
|
// },
|
|
// child: const Text('Delete All')),
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: Constant.getActualY(context: context, y: 30),
|
|
),
|
|
FormInput(
|
|
pm: pm,
|
|
selected_booth: selected_booth,
|
|
booth: booth,
|
|
selected_printer: selected_printer,
|
|
prnt: dvcs,
|
|
branch: branch,
|
|
selected_branch: selected_branch,
|
|
hostIpController: hostIpController,
|
|
hostQrController: hostQrController,
|
|
headerDisplayController: headerDisplayController,
|
|
footerDisplayController: footerDisplayController,
|
|
headerTicketController: headerTicketController,
|
|
getServiceBooth: getServiceBooth,
|
|
isLoading: isLoading.value,
|
|
selectedCapability: selectedCapabilityProfile,
|
|
capabilityList: capabilityProfileList,
|
|
footerTicketController: footerTicketController),
|
|
SizedBox(
|
|
height: Constant.getActualY(context: context, y: 20),
|
|
),
|
|
Container(
|
|
// color: Colors.red,
|
|
height: Constant.getActualY(context: context, y: 40),
|
|
child: Row(
|
|
children: [
|
|
Tooltip(
|
|
message: "Jumlah tombol pada display",
|
|
child: Text('Button display',
|
|
style: Constant.label(context: context)),
|
|
),
|
|
SizedBox(
|
|
width: Constant.getActualX(context: context, x: 10),
|
|
),
|
|
Row(
|
|
children: [
|
|
SizedBox(
|
|
width: Constant.getActualX(
|
|
context: context, x: 10),
|
|
),
|
|
Row(
|
|
children: listBtnSize
|
|
.map(
|
|
(e) => Row(
|
|
children: [
|
|
Checkbox(
|
|
fillColor: MaterialStateProperty
|
|
.resolveWith(getColor),
|
|
value: e['name'].toString() ==
|
|
selectedBtnSize
|
|
.value['name']
|
|
? true
|
|
: false,
|
|
onChanged: ((value) {
|
|
selectedBtnSize.value = e;
|
|
})),
|
|
SizedBox(
|
|
width: Constant.getActualX(
|
|
context: context, x: 3),
|
|
),
|
|
Tooltip(
|
|
message: e['message'].toString(),
|
|
child: Text(
|
|
e['name'].toString(),
|
|
style: Constant.normal(
|
|
context: context),
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: Constant.getActualX(
|
|
context: context, x: 15),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
.toList(),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: Constant.getActualY(context: context, y: 190),
|
|
child: GridView.count(
|
|
childAspectRatio:
|
|
Constant.getActualY(context: context, y: 150) /
|
|
Constant.getActualX(context: context, x: 15),
|
|
crossAxisCount: 3,
|
|
children: lyn.value
|
|
.map((e) => Row(
|
|
children: [
|
|
Transform.scale(
|
|
scale: 0.8,
|
|
child: CupertinoSwitch(
|
|
value: e.value,
|
|
onChanged: (val) {
|
|
if (val) {
|
|
var rw_data = json.encode(
|
|
activeLayanan.value);
|
|
List data =
|
|
json.decode(rw_data);
|
|
List actlyn = data;
|
|
actlyn.add(e.id);
|
|
activeLayanan.value = actlyn;
|
|
}
|
|
if (!val) {
|
|
var rw_data = json.encode(
|
|
activeLayanan.value);
|
|
List data =
|
|
json.decode(rw_data);
|
|
List actlyn = data;
|
|
actlyn.remove(e.id);
|
|
activeLayanan.value = actlyn;
|
|
}
|
|
|
|
e.value = val;
|
|
}),
|
|
),
|
|
Expanded(
|
|
child: e.isConsultDoctor == 'N'
|
|
? Text(
|
|
e.name,
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: Constant.normal(
|
|
context: context),
|
|
)
|
|
: Text(
|
|
"${e.name} ${e.doctorName}",
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: Constant.normal(
|
|
context: context),
|
|
),
|
|
)
|
|
],
|
|
))
|
|
.toList()),
|
|
),
|
|
SizedBox(
|
|
height: Constant.getActualY(context: context, y: 20),
|
|
),
|
|
Center(
|
|
child: SizedBox(
|
|
height: Constant.getActualY(context: context, y: 60),
|
|
width: Constant.getActualX(context: context, x: 200),
|
|
child: ElevatedButton(
|
|
onPressed: () {
|
|
if (selected_booth.value != null &&
|
|
selected_booth.value.id > 0 &&
|
|
selected_printer.value != null &&
|
|
selectedCapabilityProfile.value?.key !=
|
|
null &&
|
|
selected_branch.value != null &&
|
|
selected_branch.value.mBranchID != '0' &&
|
|
hostIpController.text.isNotEmpty &&
|
|
activeLayanan.value.isNotEmpty) {
|
|
saveData();
|
|
ref.read(allServiceProvider.notifier).state =
|
|
lyn.value;
|
|
Navigator.of(context).pushNamed(queueRoute);
|
|
} else {
|
|
if (selected_booth.value == null ||
|
|
selected_printer.value == null ||
|
|
selectedCapabilityProfile.value == null ||
|
|
hostIpController.text.isEmpty) {
|
|
ErrorDialog(
|
|
context,
|
|
'Input bertanda * tidak boleh kosong',
|
|
'PERINGATAN');
|
|
} else if (activeLayanan.value.isEmpty) {
|
|
ErrorDialog(
|
|
context,
|
|
'Layanan belum ada yang aktif',
|
|
'PERINGATAN');
|
|
}
|
|
}
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
elevation: 5, backgroundColor: Colors.blue),
|
|
child: Text(
|
|
'Save',
|
|
style: Constant.subTitle(context: context)
|
|
.copyWith(color: Colors.white),
|
|
),
|
|
)),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
));
|
|
}
|
|
}
|