refact: improve counter logic in cart
This commit is contained in:
parent
e1f62103b9
commit
b951af1eec
|
@ -3,6 +3,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:rijig_mobile/core/utils/guide.dart';
|
import 'package:rijig_mobile/core/utils/guide.dart';
|
||||||
import 'package:rijig_mobile/widget/buttoncard.dart';
|
import 'package:rijig_mobile/widget/buttoncard.dart';
|
||||||
|
import 'package:rijig_mobile/widget/counter_dialog.dart';
|
||||||
|
|
||||||
class CartScreen extends StatefulWidget {
|
class CartScreen extends StatefulWidget {
|
||||||
const CartScreen({super.key});
|
const CartScreen({super.key});
|
||||||
|
@ -12,17 +13,65 @@ class CartScreen extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CartScreenState extends State<CartScreen> {
|
class _CartScreenState extends State<CartScreen> {
|
||||||
|
double totalWeight = 1.0;
|
||||||
|
double pricePerKg = 700;
|
||||||
|
|
||||||
|
void _openEditAmountDialog(String itemName) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return EditAmountDialog(
|
||||||
|
initialAmount: totalWeight,
|
||||||
|
itemName: itemName,
|
||||||
|
pricePerKg: pricePerKg,
|
||||||
|
onSave: (newAmount) {
|
||||||
|
setState(() {
|
||||||
|
totalWeight = newAmount;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _increment() {
|
||||||
|
setState(() {
|
||||||
|
totalWeight += 0.25;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _decrement() {
|
||||||
|
if (totalWeight > 0.25) {
|
||||||
|
setState(() {
|
||||||
|
totalWeight -= 0.25;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatAmount(double value) {
|
||||||
|
String formattedValue = value.toStringAsFixed(2);
|
||||||
|
|
||||||
|
if (formattedValue.endsWith('.00')) {
|
||||||
|
return formattedValue.split('.').first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedValue;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: whiteColor,
|
backgroundColor: whiteColor,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('Keranjang', style: Tulisan.subheading()),
|
title: Text(
|
||||||
backgroundColor: whiteColor,
|
'Keranjang Sampah',
|
||||||
|
style: Tulisan.subheading(color: blackNavyColor),
|
||||||
),
|
),
|
||||||
body: Padding(
|
),
|
||||||
padding: const EdgeInsets.all(16.0),
|
body: SafeArea(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: PaddingCustom().paddingHorizontal(20),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
@ -66,15 +115,12 @@ class _CartScreenState extends State<CartScreen> {
|
||||||
horizontal: double.infinity,
|
horizontal: double.infinity,
|
||||||
vertical: 40,
|
vertical: 40,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
debugPrint("lanjutkan tapped");
|
debugPrint("pilih alamat tapped");
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 20),
|
|
||||||
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
@ -93,37 +139,44 @@ class _CartScreenState extends State<CartScreen> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Jenis Sampah',
|
'Jenis Sampah',
|
||||||
style: TextStyle(
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.delete, color: Colors.blue),
|
Icon(Icons.delete, color: Colors.blue),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Text('Plastik', style: TextStyle(fontSize: 14)),
|
Text('Kertas Campur'),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
Row(
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
_openEditAmountDialog('Kertas Campur');
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
Text("${formatAmount(totalWeight)} kg"),
|
||||||
onPressed: () {},
|
Icon(Icons.edit, color: Colors.blue),
|
||||||
icon: Icon(Icons.remove),
|
|
||||||
),
|
|
||||||
Text('4.75 kg'),
|
|
||||||
IconButton(onPressed: () {}, icon: Icon(Icons.add)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
Text(
|
Row(
|
||||||
'Dijumlahkan: 4.75 kg',
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
style: TextStyle(
|
children: [
|
||||||
fontWeight: FontWeight.bold,
|
IconButton(
|
||||||
fontSize: 14,
|
onPressed: _decrement,
|
||||||
|
icon: Icon(Icons.remove),
|
||||||
|
color: Colors.red,
|
||||||
),
|
),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
IconButton(
|
||||||
|
onPressed: _increment,
|
||||||
|
icon: Icon(Icons.add),
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -147,10 +200,13 @@ class _CartScreenState extends State<CartScreen> {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Berat Total',
|
'Estimasi Total Berat',
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Text('4.75 kg', style: TextStyle(fontSize: 18)),
|
Text(
|
||||||
|
"${formatAmount(totalWeight)} kg",
|
||||||
|
style: TextStyle(fontSize: 18),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -174,6 +230,7 @@ class _CartScreenState extends State<CartScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class PaymentItem extends StatelessWidget {
|
class ButtonWIthIcon extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final String? category;
|
final String? category;
|
||||||
final IconData iconData;
|
final IconData iconData;
|
||||||
final String amount;
|
final String amount;
|
||||||
|
|
||||||
const PaymentItem({
|
const ButtonWIthIcon({
|
||||||
super.key,
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
this.category,
|
this.category,
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class EditAmountDialog extends StatefulWidget {
|
||||||
|
final double initialAmount;
|
||||||
|
final String itemName;
|
||||||
|
final double pricePerKg;
|
||||||
|
final ValueChanged<double> onSave;
|
||||||
|
|
||||||
|
const EditAmountDialog({
|
||||||
|
super.key,
|
||||||
|
required this.initialAmount,
|
||||||
|
required this.itemName,
|
||||||
|
required this.pricePerKg,
|
||||||
|
required this.onSave,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
EditAmountDialogState createState() => EditAmountDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditAmountDialogState extends State<EditAmountDialog> {
|
||||||
|
late double _currentAmount;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_currentAmount = widget.initialAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatAmount(double value) {
|
||||||
|
String formattedValue = value.toStringAsFixed(2);
|
||||||
|
|
||||||
|
if (formattedValue.endsWith('.00')) {
|
||||||
|
return formattedValue.split('.').first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text("Edit Jumlah ${widget.itemName}"),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
initialValue: formatAmount(_currentAmount),
|
||||||
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_currentAmount = double.tryParse(value) ?? 0.0;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "Jumlah (kg)",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
suffixText: 'kg',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
Text(
|
||||||
|
"Estimasi Harga: Rp ${(widget.pricePerKg * _currentAmount).toStringAsFixed(0)}",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text("Batal"),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
widget.onSave(_currentAmount);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text("Simpan"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CounterInput extends StatefulWidget {
|
||||||
|
final double initialValue;
|
||||||
|
final ValueChanged<double> onChanged;
|
||||||
|
|
||||||
|
const CounterInput({
|
||||||
|
super.key,
|
||||||
|
this.initialValue = 0,
|
||||||
|
required this.onChanged,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
CounterInputState createState() => CounterInputState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class CounterInputState extends State<CounterInput> {
|
||||||
|
late double _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_value = widget.initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _increment() {
|
||||||
|
setState(() {
|
||||||
|
_value += 0.25;
|
||||||
|
});
|
||||||
|
widget.onChanged(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _decrement() {
|
||||||
|
if (_value > 0.25) {
|
||||||
|
setState(() {
|
||||||
|
_value -= 0.25;
|
||||||
|
});
|
||||||
|
widget.onChanged(_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onChanged(String text) {
|
||||||
|
double? parsedValue = double.tryParse(text);
|
||||||
|
if (parsedValue != null && parsedValue >= 0) {
|
||||||
|
setState(() {
|
||||||
|
_value = parsedValue;
|
||||||
|
});
|
||||||
|
widget.onChanged(_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: _decrement,
|
||||||
|
icon: Icon(Icons.remove),
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(
|
||||||
|
width: 60,
|
||||||
|
child: TextField(
|
||||||
|
onChanged: _onChanged,
|
||||||
|
controller: TextEditingController(text: _value.toStringAsFixed(2)),
|
||||||
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
decoration: InputDecoration(border: OutlineInputBorder()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: _increment,
|
||||||
|
icon: Icon(Icons.add),
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
16
pubspec.lock
16
pubspec.lock
|
@ -121,6 +121,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
|
custom_refresh_indicator:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: custom_refresh_indicator
|
||||||
|
sha256: c34dd1dfb1f6b9ee2db9c5972586dba5e4445d79f8431f6ab098a6e963ccd39c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.1"
|
||||||
dbus:
|
dbus:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -821,14 +829,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
wolt_modal_sheet:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: wolt_modal_sheet
|
|
||||||
sha256: "03e28e39dd4de44dc58a7c623877488a89ca3b41a62fc3e70bfc86b64be067d6"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.11.0"
|
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -12,6 +12,7 @@ dependencies:
|
||||||
concentric_transition: ^1.0.3
|
concentric_transition: ^1.0.3
|
||||||
connectivity_plus: ^6.1.4
|
connectivity_plus: ^6.1.4
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
|
custom_refresh_indicator: ^4.0.1
|
||||||
device_info_plus: ^11.4.0
|
device_info_plus: ^11.4.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
@ -38,7 +39,6 @@ dependencies:
|
||||||
smooth_page_indicator: ^1.2.1
|
smooth_page_indicator: ^1.2.1
|
||||||
toastification: ^3.0.2
|
toastification: ^3.0.2
|
||||||
uuid: ^4.5.1
|
uuid: ^4.5.1
|
||||||
wolt_modal_sheet: ^0.11.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^5.0.0
|
flutter_lints: ^5.0.0
|
||||||
|
|
Loading…
Reference in New Issue