cashumit/lib/widgets/receipt_speed_dial.dart

267 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:cashumit/services/bluetooth_service.dart';
import 'package:provider/provider.dart';
import 'package:cashumit/providers/receipt_provider.dart';
class ReceiptSpeedDial extends StatelessWidget {
final BluetoothService bluetoothService;
final Future<bool> Function() onCheckConnection;
final Future<void> Function() onPrint;
final VoidCallback onSettings;
final bool hasItems;
final bool allGroupsHaveSource;
final bool hasDestination;
final Future<void> Function() onSendToFirefly;
final VoidCallback onPrintingStart;
final VoidCallback onPrintingEnd;
final Future<void> Function()? onSendAndPrint;
const ReceiptSpeedDial({
super.key,
required this.bluetoothService,
required this.onCheckConnection,
required this.onPrint,
required this.onSettings,
required this.hasItems,
required this.allGroupsHaveSource,
required this.hasDestination,
required this.onSendToFirefly,
required this.onPrintingStart,
required this.onPrintingEnd,
this.onSendAndPrint,
});
bool get _canSubmit =>
hasItems && allGroupsHaveSource && hasDestination;
@override
Widget build(BuildContext context) {
final primaryColor = Theme.of(context).colorScheme.primary;
return SpeedDial(
icon: Icons.menu,
activeIcon: Icons.close,
spacing: 6,
spaceBetweenChildren: 8,
backgroundColor: primaryColor,
foregroundColor: Colors.white,
activeBackgroundColor: Colors.red.shade600,
activeForegroundColor: Colors.white,
elevation: 4,
children: [
if (onSendAndPrint != null)
SpeedDialChild(
child: const Icon(Icons.done_all, color: Colors.white),
label: 'Kirim & Cetak Sekaligus',
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF004D40),
),
labelBackgroundColor: const Color(0xFFE0F2F1),
backgroundColor: const Color(0xFF00897B),
onTap: _canSubmit
? onSendAndPrint
: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(!hasDestination
? 'Pilih akun tujuan terlebih dahulu'
: !allGroupsHaveSource
? 'Setiap grup harus punya akun sumber'
: 'Tambahkan item terlebih dahulu'),
duration: const Duration(seconds: 2),
),
);
},
),
SpeedDialChild(
child: const Icon(Icons.send_rounded, color: Colors.white),
label: 'Kirim ke Firefly',
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF0D47A1),
),
labelBackgroundColor: const Color(0xFFE3F2FD),
backgroundColor: const Color(0xFF1E88E5),
onTap: _canSubmit
? onSendToFirefly
: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(!hasDestination
? 'Pilih akun tujuan terlebih dahulu'
: !allGroupsHaveSource
? 'Setiap grup harus punya akun sumber'
: 'Tambahkan item terlebih dahulu'),
duration: const Duration(seconds: 2),
),
);
},
),
SpeedDialChild(
child: bluetoothService.isPrinting
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Colors.white, strokeWidth: 2),
)
: const Icon(Icons.print_rounded, color: Colors.white),
label: 'Cetak Struk Saja',
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF4A148C),
),
labelBackgroundColor: const Color(0xFFEDE7F6),
backgroundColor: const Color(0xFF7E57C2),
onTap: bluetoothService.isPrinting
? null
: () async {
onPrintingStart();
try {
final isConnected = await onCheckConnection();
if (isConnected) {
await onPrint();
} else {
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');
}
await Future.delayed(
const Duration(milliseconds: 500));
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) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Terjadi kesalahan: $e')),
);
} finally {
onPrintingEnd();
}
},
),
SpeedDialChild(
child: const Icon(Icons.bookmark_added_rounded, color: Colors.white),
label: 'Simpan Nanti (Offline)',
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFFE65100),
),
labelBackgroundColor: const Color(0xFFFFF3E0),
backgroundColor: const Color(0xFFEF6C00),
onTap: _canSubmit
? () async {
final receiptProvider = context.read<ReceiptProvider>();
try {
final receiptId =
await receiptProvider.saveTransactionLocally();
if (receiptId != null) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Nota berhasil disimpan untuk dikirim nanti'),
),
);
}
}
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Gagal menyimpan nota: $e'),
),
);
}
}
}
: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(!hasDestination
? 'Pilih akun tujuan terlebih dahulu'
: !allGroupsHaveSource
? 'Setiap grup harus punya akun sumber'
: 'Tambahkan item terlebih dahulu'),
duration: const Duration(seconds: 2),
),
);
},
),
SpeedDialChild(
child: const Icon(Icons.assessment_outlined, color: Colors.white),
label: 'Laporan Keuangan',
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF14532D),
),
labelBackgroundColor: const Color(0xFFDCFCE7),
backgroundColor: const Color(0xFF16A34A),
onTap: () {
Navigator.pushNamed(context, '/report');
},
),
SpeedDialChild(
child: const Icon(Icons.folder_copy_outlined, color: Colors.white),
label: 'Laporan Tersimpan',
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF065F46),
),
labelBackgroundColor: const Color(0xFFD1FAE5),
backgroundColor: const Color(0xFF059669),
onTap: () {
Navigator.pushNamed(context, '/saved-reports');
},
),
SpeedDialChild(
child: const Icon(Icons.settings_rounded, color: Colors.white),
label: 'Pengaturan Server',
labelStyle: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF263238),
),
labelBackgroundColor: const Color(0xFFECEFF1),
backgroundColor: const Color(0xFF546E7A),
onTap: onSettings,
),
],
);
}
}