2025-08-24 11:02:07 +07:00
import ' package:flutter/material.dart ' ;
2025-12-27 15:45:41 +07:00
import ' package:provider/provider.dart ' ;
import ' package:cashumit/providers/receipt_provider.dart ' ;
2025-08-24 11:02:07 +07:00
class ReceiptTotal extends StatelessWidget {
final double total ;
2025-12-27 15:45:41 +07:00
const ReceiptTotal ( {
Key ? key ,
required this . total ,
} ) : super ( key: key ) ;
2025-08-24 11:02:07 +07:00
@ override
Widget build ( BuildContext context ) {
2025-12-27 15:45:41 +07:00
final receiptProvider = Provider . of < ReceiptProvider > ( context ) ;
final state = receiptProvider . state ;
double changeAmount = state . paymentAmount - total ;
bool hasSufficientPayment = state . paymentAmount > = total ;
2025-08-24 11:02:07 +07:00
return Container (
width: double . infinity ,
padding: const EdgeInsets . all ( 8.0 ) ,
color: Colors . white ,
2025-12-27 15:45:41 +07:00
child: SingleChildScrollView (
child: Column (
children: [
// Total - Tap to open payment dialog
GestureDetector (
onTap: ( ) {
// Call the dialog from provider
receiptProvider . showPaymentTipDialog ( context ) ;
} ,
child: Container (
padding: const EdgeInsets . all ( 8.0 ) ,
decoration: BoxDecoration (
border: Border . all ( color: Colors . grey [ 300 ] ! ) ,
borderRadius: BorderRadius . circular ( 4 ) ,
color: Colors . grey [ 50 ] ,
) ,
child: Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
const Expanded (
flex: 4 ,
child: Text (
' TOTAL: ' ,
style: TextStyle (
fontSize: 16 ,
fontWeight: FontWeight . bold ,
fontFamily: ' Courier ' ,
) ,
) ,
) ,
Expanded (
flex: 4 ,
child: Text (
total . toStringAsFixed ( 0 ) . replaceAllMapped (
RegExp ( r'(\d{1,3})(?=(\d{3})+(?!\d))' ) ,
( Match m ) = > ' ${ m [ 1 ] } , ' ) ,
style: const TextStyle (
fontSize: 16 ,
fontWeight: FontWeight . bold ,
fontFamily: ' Courier ' ,
) ,
textAlign: TextAlign . right ,
) ,
) ,
] ,
) ,
) ,
) ,
const SizedBox ( height: 8 ) ,
// Payment Amount Display
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Expanded (
flex: 4 ,
child: Text (
' BAYAR: ' ,
style: TextStyle (
fontSize: 14 ,
fontWeight: FontWeight . w500 ,
color: Colors . grey [ 700 ] ,
fontFamily: ' Courier ' ,
) ,
) ,
) ,
Expanded (
flex: 4 ,
child: Text (
state . paymentAmount > 0
? state . paymentAmount
. toStringAsFixed ( 0 )
. replaceAllMapped (
RegExp ( r'(\d{1,3})(?=(\d{3})+(?!\d))' ) ,
( Match m ) = > ' ${ m [ 1 ] } , ' )
: ' 0 ' ,
style: TextStyle (
fontSize: 14 ,
fontWeight: FontWeight . w500 ,
color: Colors . grey [ 700 ] ,
fontFamily: ' Courier ' ,
) ,
textAlign: TextAlign . right ,
2025-08-24 11:02:07 +07:00
) ,
) ,
2025-12-27 15:45:41 +07:00
] ,
) ,
const SizedBox ( height: 8 ) ,
// Change Amount
if ( state . paymentAmount > 0 )
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Expanded (
flex: 4 ,
child: Text (
' KEMBALI: ' ,
style: TextStyle (
fontSize: 14 ,
fontWeight: FontWeight . w500 ,
color: hasSufficientPayment
? Colors . grey [ 700 ]
: Colors . red ,
fontFamily: ' Courier ' ,
) ,
) ,
) ,
Expanded (
flex: 4 ,
child: Text (
changeAmount > = 0
? changeAmount . toStringAsFixed ( 0 ) . replaceAllMapped (
RegExp ( r'(\d{1,3})(?=(\d{3})+(?!\d))' ) ,
( Match m ) = > ' ${ m [ 1 ] } , ' )
: ( changeAmount * - 1 )
. toStringAsFixed ( 0 )
. replaceAllMapped (
RegExp ( r'(\d{1,3})(?=(\d{3})+(?!\d))' ) ,
( Match m ) = > ' ${ m [ 1 ] } , ' ) ,
style: TextStyle (
fontSize: 14 ,
fontWeight: FontWeight . w500 ,
color: hasSufficientPayment & & changeAmount > = 0
? Colors . green
: Colors . red ,
fontFamily: ' Courier ' ,
) ,
textAlign: TextAlign . right ,
) ,
) ,
] ,
2025-08-24 11:02:07 +07:00
) ,
2025-12-27 15:45:41 +07:00
// Tip Status
if ( state . paymentAmount > 0 & &
state . paymentAmount > = total & &
changeAmount > 0 )
Padding (
padding: const EdgeInsets . only ( top: 8 ) ,
child: Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Expanded (
flex: 4 ,
child: Text (
' SEBAGAI TIP: ' ,
style: TextStyle (
fontSize: 14 ,
fontWeight: FontWeight . w500 ,
color: Colors . grey [ 700 ] ,
fontFamily: ' Courier ' ,
) ,
) ,
) ,
Expanded (
flex: 4 ,
child: Align (
alignment: Alignment . centerRight ,
child: Text (
state . isTip ? ' Ya ' : ' Tidak ' ,
style: TextStyle (
fontSize: 14 ,
fontWeight: FontWeight . w500 ,
color: state . isTip ? Colors . orange : Colors . grey ,
fontFamily: ' Courier ' ,
) ,
) ,
) ,
) ,
] ,
) ,
) ,
// Tip Indicator
if ( state . isTip & & changeAmount > 0 )
Padding (
padding: const EdgeInsets . only ( top: 4 ) ,
child: Container (
padding: const EdgeInsets . all ( 4 ) ,
decoration: BoxDecoration (
color: Colors . orange [ 100 ] ,
borderRadius: BorderRadius . circular ( 4 ) ,
border: Border . all ( color: Colors . orange ) ,
) ,
child: Text (
' Uang kembalian sebesar ${ changeAmount . abs ( ) . toStringAsFixed ( 0 ) . replaceAllMapped ( RegExp ( r ' ( \d {1,3 } )(?=( \d {3})+(?! \d )) ' ) , ( Match m ) = > ' ${ m [ 1 ] } , ' ) } sebagai tip untuk toko ' ,
style: TextStyle (
fontSize: 12 ,
color: Colors . orange [ 800 ] ,
fontStyle: FontStyle . italic ,
fontFamily: ' Courier ' ,
) ,
textAlign: TextAlign . center ,
2025-08-24 11:02:07 +07:00
) ,
) ,
) ,
2025-12-27 15:45:41 +07:00
] ,
) ,
2025-08-24 11:02:07 +07:00
) ,
) ;
}
2025-12-27 15:45:41 +07:00
}