From a52e0ea9b1611527cad9b688122891c882de72ba Mon Sep 17 00:00:00 2001 From: Onie Date: Sun, 18 Oct 2026 15:16:14 +0700 Subject: [PATCH] Bersihkan semua 20 analyzer issue: hapus _initAuth/_ProductCard/dead code, rename underscore var, print->debugPrint, perbaiki BuildContext async guard (analyze 0 issue) --- lib/screens/kasir_screen.dart | 132 +----------------------- lib/screens/produk_screen.dart | 24 ++--- lib/screens/riwayat_screen.dart | 28 ++--- lib/services/offline_queue_service.dart | 3 +- lib/state/app_state.dart | 8 -- 5 files changed, 27 insertions(+), 168 deletions(-) diff --git a/lib/screens/kasir_screen.dart b/lib/screens/kasir_screen.dart index f2dc7da..fc901db 100644 --- a/lib/screens/kasir_screen.dart +++ b/lib/screens/kasir_screen.dart @@ -155,7 +155,6 @@ class _KasirScreenState extends State { final result = await showDialog>( context: context, builder: (ctx) { - bool submitting = false; return StatefulBuilder( builder: (context, setDialog) { return AlertDialog( @@ -201,7 +200,7 @@ class _KasirScreenState extends State { children: [ Expanded( child: OutlinedButton( - onPressed: submitting ? null : () => Navigator.pop(ctx), + onPressed: () => Navigator.pop(ctx), style: OutlinedButton.styleFrom( foregroundColor: kMuted, side: const BorderSide(color: kBorder), @@ -212,9 +211,7 @@ class _KasirScreenState extends State { const SizedBox(width: 10), Expanded( child: FilledButton( - onPressed: submitting - ? null - : () { + onPressed: () { final name = nameCtrl.text.trim(); final price = (RupiahInputFormatter.getRawValue(priceCtrl.text) ?? 0).toDouble(); final qty = int.tryParse(qtyCtrl.text.trim()) ?? 1; @@ -226,9 +223,7 @@ class _KasirScreenState extends State { }); }, style: FilledButton.styleFrom(backgroundColor: kAccent, foregroundColor: const Color(0xFF06210F)), - child: submitting - ? const SizedBox(height: 18, width: 18, child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF06210F))) - : const Text('Tambah'), + child: const Text('Tambah'), ), ), ], @@ -247,7 +242,7 @@ class _KasirScreenState extends State { for (int i = 0; i < (result['qty'] as int); i++) { state.addToCart(manualProduct); } - if (mounted) { + if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Pesanan manual ditambahkan: ${result['name']}'), @@ -1748,125 +1743,6 @@ class _KasirListTile extends StatelessWidget { } } -class _ProductCard extends StatelessWidget { - final Product product; - final double displayPrice; - final bool isReseller; - final VoidCallback onTap; - const _ProductCard({ - required this.product, - required this.displayPrice, - required this.isReseller, - required this.onTap, - }); - - @override - Widget build(BuildContext context) { - final out = product.stock <= 0; - - return AbsorbPointer( - absorbing: out, - child: Opacity( - opacity: out ? 0.5 : 1, - child: InkWell( - onTap: out ? null : onTap, - borderRadius: BorderRadius.circular(kRadius), - child: Container( - padding: const EdgeInsets.all(14), - decoration: BoxDecoration( - color: kSurface2, - borderRadius: BorderRadius.circular(kRadius), - border: Border.all(color: kBorder), - boxShadow: const [ - BoxShadow( - color: Colors.black26, - blurRadius: 8, - offset: Offset(0, 4), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - _KasirAvatar(product: product, size: 36, radius: 18), - const Spacer(), - Container( - padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 3), - decoration: BoxDecoration( - color: out - ? kDanger.withValues(alpha: 0.15) - : kSuccess.withValues(alpha: 0.12), - borderRadius: BorderRadius.circular(20), - ), - child: Text( - out ? 'Habis' : 'Stok ${product.stock}', - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.w600, - color: out ? kDanger : kSuccess, - ), - ), - ), - ], - ), - const Spacer(), - Text( - product.name, - style: const TextStyle( - fontWeight: FontWeight.w600, fontSize: 14), - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 8), - Wrap( - spacing: 6, - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 5), - decoration: BoxDecoration( - color: kAccent.withValues(alpha: 0.12), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - formatRupiah(displayPrice), - style: TextStyle( - color: kAccent, - fontWeight: FontWeight.w800, - fontSize: 13, - ), - ), - ), - if (isReseller) ...[ - const SizedBox(width: 6), - Container( - padding: const EdgeInsets.symmetric( - horizontal: 6, vertical: 2), - decoration: BoxDecoration( - color: kAccent.withValues(alpha: 0.15), - borderRadius: BorderRadius.circular(6), - ), - child: const Text('Reseller', - style: TextStyle( - fontSize: 9, - fontWeight: FontWeight.w700, - color: kAccent)), - ), - ], - ], - ), - ], - ), - ), - ), - ), - ); - } -} - class _QtyButton extends StatelessWidget { final IconData icon; diff --git a/lib/screens/produk_screen.dart b/lib/screens/produk_screen.dart index c1fc0ce..d126fc8 100644 --- a/lib/screens/produk_screen.dart +++ b/lib/screens/produk_screen.dart @@ -338,25 +338,25 @@ void _showAddForm(BuildContext context, AppState state) { FocusNode(), FocusNode(), ]; - bool _listenersAdded = false; - final _sheetController = DraggableScrollableController(); + bool listenersAdded = false; + final sheetController = DraggableScrollableController(); showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (sheetContext) => DraggableScrollableSheet( - controller: _sheetController, + controller: sheetController, initialChildSize: 0.65, minChildSize: 0.5, maxChildSize: 0.92, builder: (_, scrollController) { - if (!_listenersAdded) { - _listenersAdded = true; + if (!listenersAdded) { + listenersAdded = true; for (final node in focusNodes) { node.addListener(() { if (node.hasFocus && context.mounted) { - _sheetController.animateTo( + sheetController.animateTo( 0.92, duration: const Duration(milliseconds: 300), curve: Curves.easeOut, @@ -606,8 +606,8 @@ void _showEditDialog(BuildContext context, AppState state, Product product) { FocusNode(), FocusNode(), ]; - bool _listenersAdded = false; - final _sheetController = DraggableScrollableController(); + bool listenersAdded = false; + final sheetController = DraggableScrollableController(); showModalBottomSheet( context: context, @@ -616,17 +616,17 @@ void _showEditDialog(BuildContext context, AppState state, Product product) { builder: (sheetContext) { final bottomInset = MediaQuery.of(context).viewInsets.bottom; return DraggableScrollableSheet( - controller: _sheetController, + controller: sheetController, initialChildSize: 0.65, minChildSize: 0.5, maxChildSize: 0.92, builder: (_, scrollController) { - if (!_listenersAdded) { - _listenersAdded = true; + if (!listenersAdded) { + listenersAdded = true; for (final node in focusNodes) { node.addListener(() { if (node.hasFocus && context.mounted) { - _sheetController.animateTo( + sheetController.animateTo( 0.92, duration: const Duration(milliseconds: 300), curve: Curves.easeOut, diff --git a/lib/screens/riwayat_screen.dart b/lib/screens/riwayat_screen.dart index 8b322b9..420a123 100644 --- a/lib/screens/riwayat_screen.dart +++ b/lib/screens/riwayat_screen.dart @@ -211,7 +211,7 @@ class _RiwayatScreenState extends State { lastDate: DateTime.now(), initialDateRange: _dateRange, ); - if (mounted && picked != null) { + if (picked != null && context.mounted) { setState(() => _dateRange = picked); context.read().resetPagination(); } @@ -691,7 +691,6 @@ class _RiwayatScreenState extends State { final result = await showDialog( context: parentContext, builder: (ctx) { - bool submitting = false; return StatefulBuilder( builder: (context, setDialog) { final isUnpaid = currentSale.paymentStatus == 'unpaid'; @@ -784,7 +783,7 @@ class _RiwayatScreenState extends State { children: [ Expanded( child: OutlinedButton( - onPressed: submitting ? null : () => Navigator.pop(ctx), + onPressed: () => Navigator.pop(ctx), style: OutlinedButton.styleFrom( foregroundColor: kMuted, side: const BorderSide(color: kBorder), @@ -795,17 +794,13 @@ class _RiwayatScreenState extends State { const SizedBox(width: 10), Expanded( child: FilledButton( - onPressed: submitting - ? null - : () { + onPressed: () { final val = (RupiahInputFormatter.getRawValue(payCtrl.text) ?? 0).toDouble(); if (val <= 0) return; Navigator.pop(ctx, val); }, style: FilledButton.styleFrom(backgroundColor: kSuccess, foregroundColor: const Color(0xFF06210F)), - child: submitting - ? const SizedBox(height: 18, width: 18, child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF06210F))) - : const Text('Simpan'), + child: const Text('Simpan'), ), ), ], @@ -830,7 +825,7 @@ class _RiwayatScreenState extends State { if (sheetContext.mounted) { Navigator.pop(sheetContext); } - if (mounted) { + if (parentContext.mounted) { final messenger = ScaffoldMessenger.of(parentContext); final msg = err == null ? isNowPaid @@ -865,7 +860,6 @@ class _RiwayatScreenState extends State { final confirm = await showDialog( context: parentContext, builder: (ctx) { - bool cancelling = false; return StatefulBuilder( builder: (context, setDialog) { return AlertDialog( @@ -879,7 +873,7 @@ class _RiwayatScreenState extends State { children: [ Expanded( child: OutlinedButton( - onPressed: cancelling ? null : () => Navigator.pop(ctx, false), + onPressed: () => Navigator.pop(ctx, false), style: OutlinedButton.styleFrom( foregroundColor: kMuted, side: const BorderSide(color: kBorder), @@ -890,13 +884,9 @@ class _RiwayatScreenState extends State { const SizedBox(width: 10), Expanded( child: FilledButton( - onPressed: cancelling - ? null - : () => Navigator.pop(ctx, true), + onPressed: () => Navigator.pop(ctx, true), style: FilledButton.styleFrom(backgroundColor: kDanger), - child: cancelling - ? const SizedBox(height: 18, width: 18, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white)) - : const Text('Batalkan'), + child: const Text('Batalkan'), ), ), ], @@ -909,7 +899,7 @@ class _RiwayatScreenState extends State { ); if (confirm == true && mounted) { final err = await state.cancelSale(currentSale.id); - if (mounted) { + if (sheetContext.mounted) { Navigator.pop(sheetContext); messenger.showSnackBar( SnackBar( diff --git a/lib/services/offline_queue_service.dart b/lib/services/offline_queue_service.dart index 1ed2b3a..645ac5f 100644 --- a/lib/services/offline_queue_service.dart +++ b/lib/services/offline_queue_service.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; +import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; @@ -24,7 +25,7 @@ class OfflineQueueService { onTimeout: () => throw TimeoutException('${operation ?? 'Operasi'} timeout setelah $_timeout'), ); } on TimeoutException catch (e) { - print('OfflineQueue timeout: $e'); + debugPrint('OfflineQueue timeout: $e'); rethrow; } } diff --git a/lib/state/app_state.dart b/lib/state/app_state.dart index a254285..9c8c0cd 100644 --- a/lib/state/app_state.dart +++ b/lib/state/app_state.dart @@ -264,14 +264,6 @@ class AppState extends ChangeNotifier { notifyListeners(); } - Future _initAuth() async { - final session = _supabase.auth.currentSession; - if (session != null) { - userId = session.user.id; - await _loadProfile(); - } - } - Future _loadProfile() async { if (userId == null) return; try {