feat(app): implement Product Scan review flow, dynamic batch expiry picker, custom PDFs, PO relationships, and aligned card layouts

This commit is contained in:
Rafhan Mazaya Fathurrahman committed 2026-07-09 12:36:06 +07:00
1 parent 9ff4a4a922
commit 577be04308
69 files changed
+5645 -1657

No files matched your search

@@ -0,0 +1,101 @@
import 'package:flutter/material.dart';
import '../../../config/app_config.dart';
class ConfirmationDialog extends StatefulWidget {
final TextEditingController nameController;
final bool initialAgreed;
final void Function(bool, String) onConfirm;
const ConfirmationDialog({
super.key,
required this.nameController,
required this.initialAgreed,
required this.onConfirm,
});
@override
State<ConfirmationDialog> createState() => _ConfirmationDialogState();
}
class _ConfirmationDialogState extends State<ConfirmationDialog> {
late bool _isAgreed;
@override
void initState() {
super.initState();
_isAgreed = widget.initialAgreed;
}
@override
Widget build(BuildContext context) {
final isButtonEnabled = _isAgreed && widget.nameController.text.trim().isNotEmpty;
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
left: AppConfig.spaceXL,
right: AppConfig.spaceXL,
top: AppConfig.spaceXL,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Konfirmasi Pengiriman', style: AppConfig.h2),
const SizedBox(height: AppConfig.spaceLarge),
Text(
'Masukkan nama Anda (sebagai penerima/penjaga toko) dan centang kotak persetujuan untuk mengonfirmasi pengiriman.',
style: AppConfig.bodyMedium.copyWith(color: AppConfig.textSecondary),
),
const SizedBox(height: AppConfig.spaceLarge),
TextField(
controller: widget.nameController,
onChanged: (val) {
setState(() {});
},
style: AppConfig.bodyMedium,
decoration: InputDecoration(
labelText: 'Nama Penerima (Penjaga Toko)',
labelStyle: AppConfig.bodyMedium.copyWith(color: AppConfig.textSecondary),
filled: true,
fillColor: Colors.grey.shade50,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadiusMedium),
borderSide: BorderSide(color: Colors.grey.shade300),
),
),
),
const SizedBox(height: AppConfig.spaceLarge),
Row(
children: [
Checkbox(
value: _isAgreed,
activeColor: AppConfig.primaryColor,
onChanged: (val) {
setState(() {
_isAgreed = val ?? false;
});
},
),
Expanded(
child: Text('Saya setuju dan mengonfirmasi bahwa data ini sudah benar.', style: AppConfig.bodyMedium),
)
],
),
const SizedBox(height: AppConfig.spaceXL),
SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: isButtonEnabled ? () {
widget.onConfirm(_isAgreed, widget.nameController.text.trim());
} : null,
child: const Text('Konfirmasi'),
),
),
const SizedBox(height: AppConfig.spaceXL),
],
),
);
}
}