cashumit/lib/widgets/receipt_speed_dial.dart

150 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:cashumit/services/bluetooth_service.dart';
class ReceiptSpeedDial extends StatelessWidget {
final BluetoothService bluetoothService;
final Future<bool> Function() onCheckConnection;
final Future<void> Function() onPrint;
final VoidCallback onSettings;
final Future<void> Function() onReloadAccounts;
final bool hasItems;
final bool hasSourceAccount;
final bool hasDestinationAccount;
final Future<void> Function() onSendToFirefly;
final VoidCallback onPrintingStart;
final VoidCallback onPrintingEnd;
const ReceiptSpeedDial({
super.key,
required this.bluetoothService,
required this.onCheckConnection,
required this.onPrint,
required this.onSettings,
required this.onReloadAccounts,
required this.hasItems,
required this.hasSourceAccount,
required this.hasDestinationAccount,
required this.onSendToFirefly,
required this.onPrintingStart,
required this.onPrintingEnd,
});
@override
Widget build(BuildContext context) {
return SpeedDial(
icon: Icons.menu,
activeIcon: Icons.close,
spacing: 3,
spaceBetweenChildren: 4,
children: [
SpeedDialChild(
child: const Icon(Icons.send),
label: 'Kirim ke Firefly',
onTap: hasItems && hasSourceAccount && hasDestinationAccount
? onSendToFirefly
: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text('Pilih akun sumber dan tujuan terlebih dahulu'),
duration: Duration(seconds: 2),
),
);
},
backgroundColor: hasItems && hasSourceAccount && hasDestinationAccount
? Colors.blue
: Colors.grey,
),
SpeedDialChild(
child: const Icon(Icons.refresh),
label: 'Muat Ulang Akun',
onTap: onReloadAccounts,
backgroundColor: Colors.orange,
),
SpeedDialChild(
child: const Icon(Icons.settings),
label: 'Pengaturan',
onTap: onSettings,
backgroundColor: Colors.green,
),
SpeedDialChild(
child: bluetoothService.isPrinting
? const CircularProgressIndicator(
color: Colors.white, strokeWidth: 2)
: const Icon(Icons.receipt),
label: 'Cetak Struk',
onTap: bluetoothService.isPrinting
? null
: () async {
// Panggil callback untuk memulai printing status
onPrintingStart();
try {
// Periksa koneksi secara real-time
final isConnected = await onCheckConnection();
if (isConnected) {
await onPrint();
} else {
// Coba sambungkan kembali jika ada device yang tersimpan
if (bluetoothService.connectedDevice != null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text('Mencoba menyambungkan ke printer...')),
);
try {
bool connectResult =
await bluetoothService.connectToDevice(
bluetoothService.connectedDevice!);
if (!connectResult) {
throw Exception('Gagal menyambungkan ke printer');
}
// Tunggu sebentar untuk memastikan koneksi stabil
await Future.delayed(
const Duration(milliseconds: 500));
// Periksa koneksi lagi
final isConnectedAfterConnect =
await onCheckConnection();
if (isConnectedAfterConnect) {
await onPrint();
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text('Gagal menyambungkan ke printer')),
);
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text('Gagal menyambungkan ke printer: $e')),
);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text('Hubungkan printer terlebih dahulu')),
);
}
}
} catch (e) {
// Tangani error secara umum
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Terjadi kesalahan: $e')),
);
} finally {
// Pastikan printing status selalu diakhiri
onPrintingEnd();
}
},
backgroundColor: Colors.purple,
),
],
);
}
}