135 lines
4.4 KiB
Dart
135 lines
4.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:cashumit/models/receipt_item.dart';
|
|
|
|
class AddItemScreen extends StatefulWidget {
|
|
const AddItemScreen({super.key, this.item});
|
|
|
|
// Constructor untuk mode edit
|
|
const AddItemScreen.fromItem(this.item, {super.key});
|
|
|
|
final ReceiptItem? item;
|
|
|
|
@override
|
|
State<AddItemScreen> createState() => _AddItemScreenState();
|
|
}
|
|
|
|
class _AddItemScreenState extends State<AddItemScreen> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
late final TextEditingController _descriptionController;
|
|
late final TextEditingController _quantityController;
|
|
late final TextEditingController _priceController;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
// Inisialisasi controller dengan nilai default atau dari item yang diedit
|
|
_descriptionController = TextEditingController(text: widget.item?.description ?? '');
|
|
_quantityController = TextEditingController(text: widget.item != null ? widget.item!.quantity.toString() : '1');
|
|
_priceController = TextEditingController(text: widget.item?.price.toString() ?? '');
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_descriptionController.dispose();
|
|
_quantityController.dispose();
|
|
_priceController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void _saveItem() {
|
|
if (_formKey.currentState!.validate()) {
|
|
final item = ReceiptItem(
|
|
description: _descriptionController.text,
|
|
quantity: int.parse(_quantityController.text),
|
|
price: double.parse(_priceController.text),
|
|
);
|
|
|
|
Navigator.pop(context, item);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AlertDialog(
|
|
title: Text(widget.item == null ? 'Tambah Item' : 'Edit Item'),
|
|
content: SingleChildScrollView(
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
TextFormField(
|
|
controller: _descriptionController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Deskripsi Item',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
validator: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Mohon masukkan deskripsi item';
|
|
}
|
|
return null;
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: TextFormField(
|
|
controller: _quantityController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Jumlah',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
keyboardType: TextInputType.number,
|
|
validator: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Mohon masukkan jumlah';
|
|
}
|
|
if (int.tryParse(value) == null) {
|
|
return 'Jumlah harus berupa angka';
|
|
}
|
|
return null;
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(width: 16),
|
|
Expanded(
|
|
child: TextFormField(
|
|
controller: _priceController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Harga',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
keyboardType: TextInputType.number,
|
|
validator: (value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Mohon masukkan harga';
|
|
}
|
|
if (double.tryParse(value) == null) {
|
|
return 'Harga harus berupa angka';
|
|
}
|
|
return null;
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.pop(context),
|
|
child: const Text('Batal'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: _saveItem,
|
|
child: Text(widget.item == null ? 'Simpan' : 'Update'),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
} |