216 lines
8.1 KiB
Dart
216 lines
8.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:cashumit/widgets/store_info_widget.dart';
|
|
import 'package:cashumit/widgets/receipt_group_section.dart';
|
|
import 'package:cashumit/widgets/customer_name_field.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:cashumit/widgets/receipt_total.dart';
|
|
import 'package:cashumit/widgets/store_disclaimer.dart';
|
|
import 'package:cashumit/widgets/thank_you_pantun.dart';
|
|
import 'package:cashumit/widgets/dotted_line.dart';
|
|
import 'package:cashumit/widgets/horizontal_divider.dart';
|
|
import 'package:cashumit/widgets/dashed_border.dart';
|
|
import 'package:cashumit/utils/app_text_styles.dart';
|
|
import 'package:cashumit/models/receipt_group.dart';
|
|
|
|
class ReceiptBody extends StatelessWidget {
|
|
final List<ReceiptGroup> groups;
|
|
final DateTime transactionDate;
|
|
final VoidCallback onOpenStoreInfoConfig;
|
|
final VoidCallback onChangeDate;
|
|
final VoidCallback onOpenCustomTextConfig;
|
|
final double total;
|
|
final Function(String groupId, int index)? onEditItem;
|
|
final Function(String groupId, int index)? onRemoveItem;
|
|
final Function(String groupId)? onAddItem;
|
|
final Function(String groupId)? onRemoveGroup;
|
|
final Function(String groupId)? onSelectGroupSource;
|
|
final VoidCallback onAddGroup;
|
|
final VoidCallback? onSetTip;
|
|
final VoidCallback? onClearTip;
|
|
final String tagsText;
|
|
final List<String> availableTags;
|
|
final ValueChanged<String>? onTagsChanged;
|
|
final Function(String groupId)? onEditGroupTags;
|
|
final String customerName;
|
|
final ValueChanged<String>? onCustomerNameChanged;
|
|
|
|
const ReceiptBody({
|
|
super.key,
|
|
required this.groups,
|
|
required this.transactionDate,
|
|
required this.onOpenStoreInfoConfig,
|
|
required this.onChangeDate,
|
|
required this.onOpenCustomTextConfig,
|
|
required this.total,
|
|
this.onEditItem,
|
|
this.onRemoveItem,
|
|
this.onAddItem,
|
|
this.onRemoveGroup,
|
|
this.onSelectGroupSource,
|
|
required this.onAddGroup,
|
|
this.onSetTip,
|
|
this.onClearTip,
|
|
this.tagsText = '',
|
|
this.availableTags = const [],
|
|
this.onTagsChanged,
|
|
this.onEditGroupTags,
|
|
this.customerName = '',
|
|
this.onCustomerNameChanged,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
width: double.infinity,
|
|
decoration: const BoxDecoration(
|
|
color: Colors.white,
|
|
),
|
|
child: SingleChildScrollView(
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
child: Column(
|
|
children: [
|
|
// Bagian atas - Header (akun tujuan di Config, bukan di sini)
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
child: Column(
|
|
children: [
|
|
StoreInfoWidget(
|
|
onTap: onOpenStoreInfoConfig,
|
|
),
|
|
const DottedLine(),
|
|
const SizedBox(height: 8),
|
|
const HorizontalDivider(),
|
|
],
|
|
),
|
|
),
|
|
|
|
// Baris nama pembeli (75%) & tanggal (25%)
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 7,
|
|
child: CustomerNameField(
|
|
value: customerName,
|
|
onChanged: onCustomerNameChanged ?? (_) {},
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
flex: 3,
|
|
child: InkWell(
|
|
onTap: onChangeDate,
|
|
borderRadius: BorderRadius.circular(4),
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 6, vertical: 8),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: Colors.grey[300]!),
|
|
borderRadius: BorderRadius.circular(4),
|
|
color: Colors.grey[50],
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
const Icon(Icons.calendar_today,
|
|
size: 14, color: Colors.grey),
|
|
const SizedBox(width: 4),
|
|
Text(
|
|
DateFormat('dd/MM').format(transactionDate),
|
|
style: const TextStyle(
|
|
fontSize: 11, fontWeight: FontWeight.w600),
|
|
),
|
|
const SizedBox(width: 2),
|
|
const Icon(Icons.edit,
|
|
size: 10, color: Colors.grey),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
|
|
// Bagian tengah - Grup-grup dan total
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
child: Column(
|
|
children: [
|
|
// Daftar grup
|
|
...groups.asMap().entries.map((entry) {
|
|
int gi = entry.key;
|
|
ReceiptGroup group = entry.value;
|
|
return ReceiptGroupSection(
|
|
group: group,
|
|
groupIndex: gi,
|
|
onSelectSource: () =>
|
|
onSelectGroupSource?.call(group.id),
|
|
onRemoveGroup: () => onRemoveGroup?.call(group.id),
|
|
onEditItem: (itemIndex) =>
|
|
onEditItem?.call(group.id, itemIndex),
|
|
onRemoveItem: (itemIndex) =>
|
|
onRemoveItem?.call(group.id, itemIndex),
|
|
onAddItem: () => onAddItem?.call(group.id),
|
|
onEditTags: () => onEditGroupTags?.call(group.id),
|
|
canRemove: groups.length > 1,
|
|
);
|
|
}),
|
|
|
|
// Tombol tambah grup sumber (gaya template card border putus-putus)
|
|
if (groups.length < 10)
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 4, bottom: 8),
|
|
child: GestureDetector(
|
|
onTap: onAddGroup,
|
|
child: DashedBorder(
|
|
color: Colors.grey,
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(Icons.add,
|
|
size: 16, color: Colors.grey[700]),
|
|
const SizedBox(width: 8),
|
|
Text(
|
|
'Tambah Sumber',
|
|
style: CourierStyles.bold
|
|
.copyWith(color: Colors.grey[700]),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
const HorizontalDivider(),
|
|
ReceiptTotal(
|
|
total: total,
|
|
onSetTip: onSetTip,
|
|
onClearTip: onClearTip,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
|
|
// Bagian bawah - Footer
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
child: Column(
|
|
children: [
|
|
const DottedLine(),
|
|
StoreDisclaimer(onTap: onOpenCustomTextConfig),
|
|
ThankYouPantun(onTap: onOpenCustomTextConfig),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|