2025-08-24 11:02:07 +07:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
|
|
|
|
import 'package:cashumit/services/bluetooth_service.dart';
|
2025-11-08 12:15:38 +07:00
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
|
import 'package:cashumit/providers/receipt_provider.dart';
|
2025-08-24 11:02:07 +07:00
|
|
|
|
|
|
|
|
class ReceiptSpeedDial extends StatelessWidget {
|
|
|
|
|
final BluetoothService bluetoothService;
|
|
|
|
|
final Future<bool> Function() onCheckConnection;
|
|
|
|
|
final Future<void> Function() onPrint;
|
|
|
|
|
final VoidCallback onSettings;
|
|
|
|
|
final bool hasItems;
|
feat: multi-grup sumber, batch send, & perbaikan tip
Multi-Grup Sumber & UI:
- Model ReceiptGroup: satu struk bisa punya banyak grup sumber (
revenue)
- Tombol "Tambah Sumber" dengan dashed border (max 10 grup)
- Hapus label "Dari:" di SourceAccountSelector (chip saja)
- Default 1 grup kosong di ReceiptProvider constructor &
_resetState
Akun Tujuan ke Config:
- Pindah DestinationAccountSelector dari receipt body ke Config
screen
- Persist & load via SharedPreferences (permanen, tidak di-reset)
- Dropdown auto-load dari cache/mirror saat buka Config
- Tombol "Sinkronisasi Manual" sekarang simpan ke mirror &
refresh dropdown
Batch Send via SubmissionTask:
- Model SubmissionTask: konteks per-grup (group/tip +
destination + date)
- TransactionSubmissionDialog refactor: terima
List<SubmissionTask>
- Helper buildTasksFromReceipt &
buildTasksFromAllUnsubmittedReceipts
- LocalReceiptsScreen: tombol "Kirim Semua Nota" + post-process
status
Bug Fix:
- copyWith sentinel pattern: field nullable (tipSourceAccount,
destinationAccount, fireflyUrl, accessToken) kini bisa di-set
ke null
- Tip dapat dibersihkan dengan "Batal Tip" & reset antar
transaksi
- Hapus tombol "Muat Akun" (redundan dgn Sinkronisasi Manual)
Lainnya:
- Date picker untuk tanggal transaksi
- Font courier prime caching via CourierStyles
- Perf: compute() untuk decode image, cancel stream bluetooth,
fix rebuild loop
- External link: <queries> AndroidManifest + skip canLaunchUrl
- Layout cetak: hapus Ke:, sederhanakan separator grup, hapus
TIP: TIDAK
- Hapus TransactionLinksScreen, ganti inline copy/open di popup
2026-06-27 20:18:51 +07:00
|
|
|
final bool allGroupsHaveSource;
|
|
|
|
|
final bool hasDestination;
|
2025-08-24 11:02:07 +07:00
|
|
|
final Future<void> Function() onSendToFirefly;
|
2026-10-24 11:40:07 +07:00
|
|
|
final Future<void> Function()? onViewInvoice;
|
2025-09-05 21:44:38 +07:00
|
|
|
final VoidCallback onPrintingStart;
|
|
|
|
|
final VoidCallback onPrintingEnd;
|
2026-09-04 09:48:34 +07:00
|
|
|
final Future<void> Function()? onSendAndPrint;
|
2025-08-24 11:02:07 +07:00
|
|
|
|
|
|
|
|
const ReceiptSpeedDial({
|
2025-09-05 21:44:38 +07:00
|
|
|
super.key,
|
2025-08-24 11:02:07 +07:00
|
|
|
required this.bluetoothService,
|
|
|
|
|
required this.onCheckConnection,
|
|
|
|
|
required this.onPrint,
|
|
|
|
|
required this.onSettings,
|
|
|
|
|
required this.hasItems,
|
feat: multi-grup sumber, batch send, & perbaikan tip
Multi-Grup Sumber & UI:
- Model ReceiptGroup: satu struk bisa punya banyak grup sumber (
revenue)
- Tombol "Tambah Sumber" dengan dashed border (max 10 grup)
- Hapus label "Dari:" di SourceAccountSelector (chip saja)
- Default 1 grup kosong di ReceiptProvider constructor &
_resetState
Akun Tujuan ke Config:
- Pindah DestinationAccountSelector dari receipt body ke Config
screen
- Persist & load via SharedPreferences (permanen, tidak di-reset)
- Dropdown auto-load dari cache/mirror saat buka Config
- Tombol "Sinkronisasi Manual" sekarang simpan ke mirror &
refresh dropdown
Batch Send via SubmissionTask:
- Model SubmissionTask: konteks per-grup (group/tip +
destination + date)
- TransactionSubmissionDialog refactor: terima
List<SubmissionTask>
- Helper buildTasksFromReceipt &
buildTasksFromAllUnsubmittedReceipts
- LocalReceiptsScreen: tombol "Kirim Semua Nota" + post-process
status
Bug Fix:
- copyWith sentinel pattern: field nullable (tipSourceAccount,
destinationAccount, fireflyUrl, accessToken) kini bisa di-set
ke null
- Tip dapat dibersihkan dengan "Batal Tip" & reset antar
transaksi
- Hapus tombol "Muat Akun" (redundan dgn Sinkronisasi Manual)
Lainnya:
- Date picker untuk tanggal transaksi
- Font courier prime caching via CourierStyles
- Perf: compute() untuk decode image, cancel stream bluetooth,
fix rebuild loop
- External link: <queries> AndroidManifest + skip canLaunchUrl
- Layout cetak: hapus Ke:, sederhanakan separator grup, hapus
TIP: TIDAK
- Hapus TransactionLinksScreen, ganti inline copy/open di popup
2026-06-27 20:18:51 +07:00
|
|
|
required this.allGroupsHaveSource,
|
|
|
|
|
required this.hasDestination,
|
2025-08-24 11:02:07 +07:00
|
|
|
required this.onSendToFirefly,
|
2026-10-24 11:40:07 +07:00
|
|
|
this.onViewInvoice,
|
2025-09-05 21:44:38 +07:00
|
|
|
required this.onPrintingStart,
|
|
|
|
|
required this.onPrintingEnd,
|
2026-09-04 09:48:34 +07:00
|
|
|
this.onSendAndPrint,
|
2025-09-05 21:44:38 +07:00
|
|
|
});
|
2025-08-24 11:02:07 +07:00
|
|
|
|
feat: multi-grup sumber, batch send, & perbaikan tip
Multi-Grup Sumber & UI:
- Model ReceiptGroup: satu struk bisa punya banyak grup sumber (
revenue)
- Tombol "Tambah Sumber" dengan dashed border (max 10 grup)
- Hapus label "Dari:" di SourceAccountSelector (chip saja)
- Default 1 grup kosong di ReceiptProvider constructor &
_resetState
Akun Tujuan ke Config:
- Pindah DestinationAccountSelector dari receipt body ke Config
screen
- Persist & load via SharedPreferences (permanen, tidak di-reset)
- Dropdown auto-load dari cache/mirror saat buka Config
- Tombol "Sinkronisasi Manual" sekarang simpan ke mirror &
refresh dropdown
Batch Send via SubmissionTask:
- Model SubmissionTask: konteks per-grup (group/tip +
destination + date)
- TransactionSubmissionDialog refactor: terima
List<SubmissionTask>
- Helper buildTasksFromReceipt &
buildTasksFromAllUnsubmittedReceipts
- LocalReceiptsScreen: tombol "Kirim Semua Nota" + post-process
status
Bug Fix:
- copyWith sentinel pattern: field nullable (tipSourceAccount,
destinationAccount, fireflyUrl, accessToken) kini bisa di-set
ke null
- Tip dapat dibersihkan dengan "Batal Tip" & reset antar
transaksi
- Hapus tombol "Muat Akun" (redundan dgn Sinkronisasi Manual)
Lainnya:
- Date picker untuk tanggal transaksi
- Font courier prime caching via CourierStyles
- Perf: compute() untuk decode image, cancel stream bluetooth,
fix rebuild loop
- External link: <queries> AndroidManifest + skip canLaunchUrl
- Layout cetak: hapus Ke:, sederhanakan separator grup, hapus
TIP: TIDAK
- Hapus TransactionLinksScreen, ganti inline copy/open di popup
2026-06-27 20:18:51 +07:00
|
|
|
bool get _canSubmit =>
|
|
|
|
|
hasItems && allGroupsHaveSource && hasDestination;
|
|
|
|
|
|
2025-08-24 11:02:07 +07:00
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
2026-09-04 09:48:34 +07:00
|
|
|
final primaryColor = Theme.of(context).colorScheme.primary;
|
|
|
|
|
|
2025-08-24 11:02:07 +07:00
|
|
|
return SpeedDial(
|
|
|
|
|
icon: Icons.menu,
|
|
|
|
|
activeIcon: Icons.close,
|
2026-09-04 09:48:34 +07:00
|
|
|
spacing: 6,
|
|
|
|
|
spaceBetweenChildren: 8,
|
|
|
|
|
backgroundColor: primaryColor,
|
|
|
|
|
foregroundColor: Colors.white,
|
|
|
|
|
activeBackgroundColor: Colors.red.shade600,
|
|
|
|
|
activeForegroundColor: Colors.white,
|
|
|
|
|
elevation: 4,
|
2025-08-24 11:02:07 +07:00
|
|
|
children: [
|
2026-09-04 09:48:34 +07:00
|
|
|
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),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2025-11-08 12:15:38 +07:00
|
|
|
SpeedDialChild(
|
2026-09-04 09:48:34 +07:00
|
|
|
child: const Icon(Icons.send_rounded, color: Colors.white),
|
2025-08-24 11:02:07 +07:00
|
|
|
label: 'Kirim ke Firefly',
|
2026-09-04 09:48:34 +07:00
|
|
|
labelStyle: const TextStyle(
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Color(0xFF0D47A1),
|
|
|
|
|
),
|
|
|
|
|
labelBackgroundColor: const Color(0xFFE3F2FD),
|
|
|
|
|
backgroundColor: const Color(0xFF1E88E5),
|
feat: multi-grup sumber, batch send, & perbaikan tip
Multi-Grup Sumber & UI:
- Model ReceiptGroup: satu struk bisa punya banyak grup sumber (
revenue)
- Tombol "Tambah Sumber" dengan dashed border (max 10 grup)
- Hapus label "Dari:" di SourceAccountSelector (chip saja)
- Default 1 grup kosong di ReceiptProvider constructor &
_resetState
Akun Tujuan ke Config:
- Pindah DestinationAccountSelector dari receipt body ke Config
screen
- Persist & load via SharedPreferences (permanen, tidak di-reset)
- Dropdown auto-load dari cache/mirror saat buka Config
- Tombol "Sinkronisasi Manual" sekarang simpan ke mirror &
refresh dropdown
Batch Send via SubmissionTask:
- Model SubmissionTask: konteks per-grup (group/tip +
destination + date)
- TransactionSubmissionDialog refactor: terima
List<SubmissionTask>
- Helper buildTasksFromReceipt &
buildTasksFromAllUnsubmittedReceipts
- LocalReceiptsScreen: tombol "Kirim Semua Nota" + post-process
status
Bug Fix:
- copyWith sentinel pattern: field nullable (tipSourceAccount,
destinationAccount, fireflyUrl, accessToken) kini bisa di-set
ke null
- Tip dapat dibersihkan dengan "Batal Tip" & reset antar
transaksi
- Hapus tombol "Muat Akun" (redundan dgn Sinkronisasi Manual)
Lainnya:
- Date picker untuk tanggal transaksi
- Font courier prime caching via CourierStyles
- Perf: compute() untuk decode image, cancel stream bluetooth,
fix rebuild loop
- External link: <queries> AndroidManifest + skip canLaunchUrl
- Layout cetak: hapus Ke:, sederhanakan separator grup, hapus
TIP: TIDAK
- Hapus TransactionLinksScreen, ganti inline copy/open di popup
2026-06-27 20:18:51 +07:00
|
|
|
onTap: _canSubmit
|
2025-08-24 11:02:07 +07:00
|
|
|
? onSendToFirefly
|
|
|
|
|
: () {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
feat: multi-grup sumber, batch send, & perbaikan tip
Multi-Grup Sumber & UI:
- Model ReceiptGroup: satu struk bisa punya banyak grup sumber (
revenue)
- Tombol "Tambah Sumber" dengan dashed border (max 10 grup)
- Hapus label "Dari:" di SourceAccountSelector (chip saja)
- Default 1 grup kosong di ReceiptProvider constructor &
_resetState
Akun Tujuan ke Config:
- Pindah DestinationAccountSelector dari receipt body ke Config
screen
- Persist & load via SharedPreferences (permanen, tidak di-reset)
- Dropdown auto-load dari cache/mirror saat buka Config
- Tombol "Sinkronisasi Manual" sekarang simpan ke mirror &
refresh dropdown
Batch Send via SubmissionTask:
- Model SubmissionTask: konteks per-grup (group/tip +
destination + date)
- TransactionSubmissionDialog refactor: terima
List<SubmissionTask>
- Helper buildTasksFromReceipt &
buildTasksFromAllUnsubmittedReceipts
- LocalReceiptsScreen: tombol "Kirim Semua Nota" + post-process
status
Bug Fix:
- copyWith sentinel pattern: field nullable (tipSourceAccount,
destinationAccount, fireflyUrl, accessToken) kini bisa di-set
ke null
- Tip dapat dibersihkan dengan "Batal Tip" & reset antar
transaksi
- Hapus tombol "Muat Akun" (redundan dgn Sinkronisasi Manual)
Lainnya:
- Date picker untuk tanggal transaksi
- Font courier prime caching via CourierStyles
- Perf: compute() untuk decode image, cancel stream bluetooth,
fix rebuild loop
- External link: <queries> AndroidManifest + skip canLaunchUrl
- Layout cetak: hapus Ke:, sederhanakan separator grup, hapus
TIP: TIDAK
- Hapus TransactionLinksScreen, ganti inline copy/open di popup
2026-06-27 20:18:51 +07:00
|
|
|
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),
|
2025-08-24 11:02:07 +07:00
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2026-10-24 11:40:07 +07:00
|
|
|
if (onViewInvoice != null)
|
|
|
|
|
SpeedDialChild(
|
|
|
|
|
child: const Icon(Icons.receipt_long, color: Colors.white),
|
|
|
|
|
label: 'Lihat Invoice',
|
|
|
|
|
labelStyle: const TextStyle(
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Color(0xFF4A148C),
|
|
|
|
|
),
|
|
|
|
|
labelBackgroundColor: const Color(0xFFEDE7F6),
|
|
|
|
|
backgroundColor: const Color(0xFF6A1B9A),
|
|
|
|
|
onTap: hasItems
|
|
|
|
|
? onViewInvoice
|
|
|
|
|
: () {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
const SnackBar(
|
|
|
|
|
content: Text('Tambahkan item terlebih dahulu'),
|
|
|
|
|
duration: Duration(seconds: 2),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2025-08-24 11:02:07 +07:00
|
|
|
SpeedDialChild(
|
|
|
|
|
child: bluetoothService.isPrinting
|
2026-09-04 09:48:34 +07:00
|
|
|
? 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),
|
2025-08-24 11:02:07 +07:00
|
|
|
onTap: bluetoothService.isPrinting
|
|
|
|
|
? null
|
|
|
|
|
: () async {
|
2025-09-05 21:44:38 +07:00
|
|
|
onPrintingStart();
|
2025-09-07 22:29:09 +07:00
|
|
|
|
2025-09-05 21:44:38 +07:00
|
|
|
try {
|
|
|
|
|
final isConnected = await onCheckConnection();
|
|
|
|
|
if (isConnected) {
|
|
|
|
|
await onPrint();
|
|
|
|
|
} else {
|
|
|
|
|
if (bluetoothService.connectedDevice != null) {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
const SnackBar(
|
2025-09-07 22:29:09 +07:00
|
|
|
content:
|
|
|
|
|
Text('Mencoba menyambungkan ke printer...')),
|
2025-09-05 21:44:38 +07:00
|
|
|
);
|
|
|
|
|
try {
|
2025-09-07 22:29:09 +07:00
|
|
|
bool connectResult =
|
|
|
|
|
await bluetoothService.connectToDevice(
|
|
|
|
|
bluetoothService.connectedDevice!);
|
2025-09-05 21:44:38 +07:00
|
|
|
if (!connectResult) {
|
|
|
|
|
throw Exception('Gagal menyambungkan ke printer');
|
|
|
|
|
}
|
2025-09-07 22:29:09 +07:00
|
|
|
await Future.delayed(
|
|
|
|
|
const Duration(milliseconds: 500));
|
|
|
|
|
final isConnectedAfterConnect =
|
|
|
|
|
await onCheckConnection();
|
2025-09-05 21:44:38 +07:00
|
|
|
if (isConnectedAfterConnect) {
|
|
|
|
|
await onPrint();
|
|
|
|
|
} else {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
const SnackBar(
|
2025-09-07 22:29:09 +07:00
|
|
|
content:
|
|
|
|
|
Text('Gagal menyambungkan ke printer')),
|
2025-09-05 21:44:38 +07:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2025-08-24 11:02:07 +07:00
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
2025-09-05 21:44:38 +07:00
|
|
|
SnackBar(
|
2025-09-07 22:29:09 +07:00
|
|
|
content:
|
|
|
|
|
Text('Gagal menyambungkan ke printer: $e')),
|
2025-08-24 11:02:07 +07:00
|
|
|
);
|
|
|
|
|
}
|
2025-09-05 21:44:38 +07:00
|
|
|
} else {
|
2025-08-24 11:02:07 +07:00
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
2025-09-05 21:44:38 +07:00
|
|
|
const SnackBar(
|
2025-09-07 22:29:09 +07:00
|
|
|
content:
|
|
|
|
|
Text('Hubungkan printer terlebih dahulu')),
|
2025-08-24 11:02:07 +07:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-05 21:44:38 +07:00
|
|
|
} catch (e) {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
2025-09-07 22:29:09 +07:00
|
|
|
SnackBar(content: Text('Terjadi kesalahan: $e')),
|
2025-09-05 21:44:38 +07:00
|
|
|
);
|
|
|
|
|
} finally {
|
|
|
|
|
onPrintingEnd();
|
2025-08-24 11:02:07 +07:00
|
|
|
}
|
|
|
|
|
},
|
2026-09-04 09:48:34 +07:00
|
|
|
),
|
|
|
|
|
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),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2026-10-24 11:37:14 +07:00
|
|
|
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');
|
|
|
|
|
},
|
|
|
|
|
),
|
2026-09-04 09:48:34 +07:00
|
|
|
SpeedDialChild(
|
|
|
|
|
child: const Icon(Icons.settings_rounded, color: Colors.white),
|
2026-10-24 11:40:07 +07:00
|
|
|
label: 'Pengaturan',
|
2026-09-04 09:48:34 +07:00
|
|
|
labelStyle: const TextStyle(
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Color(0xFF263238),
|
|
|
|
|
),
|
|
|
|
|
labelBackgroundColor: const Color(0xFFECEFF1),
|
|
|
|
|
backgroundColor: const Color(0xFF546E7A),
|
|
|
|
|
onTap: onSettings,
|
2025-08-24 11:02:07 +07:00
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-09-07 22:29:09 +07:00
|
|
|
}
|