Files
Kifi/kifi-app/lib/features/sales/presentation/widgets/receive_payment_sheet.dart

155 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lucide_icons/lucide_icons.dart';
import '../../../../core/widgets/premium_text_field.dart';
import '../../../transactions/providers/providers.dart';
import '../../providers/invoices_provider.dart';
import '../../domain/invoice.dart';
class ReceivePaymentSheet extends ConsumerStatefulWidget {
final Invoice invoice;
const ReceivePaymentSheet({super.key, required this.invoice});
@override
ConsumerState<ReceivePaymentSheet> createState() => _ReceivePaymentSheetState();
}
class _ReceivePaymentSheetState extends ConsumerState<ReceivePaymentSheet> {
final TextEditingController _amountCtrl = TextEditingController();
String _paymentMethod = 'Cash';
int? _selectedWalletId;
bool _isLoading = false;
@override
void initState() {
super.initState();
final balance = widget.invoice.totalAmount - widget.invoice.amountPaid;
_amountCtrl.text = balance.toStringAsFixed(2);
}
@override
Widget build(BuildContext context) {
final walletsState = ref.watch(walletProvider);
final wallets = walletsState.value ?? [];
if (wallets.isNotEmpty && _selectedWalletId == null) {
_selectedWalletId = wallets.first.id;
}
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
top: 24,
left: 24,
right: 24,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Receive Payment', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
IconButton(icon: const Icon(LucideIcons.x), onPressed: () => Navigator.pop(context)),
],
),
const SizedBox(height: 16),
PremiumTextField(
controller: _amountCtrl,
labelText: 'Amount Paid (₹)',
keyboardType: const TextInputType.numberWithOptions(decimal: true),
),
const SizedBox(height: 16),
const Text('Receive Into Wallet', style: TextStyle(fontWeight: FontWeight.w600, color: Colors.grey)),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(16),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<int>(
value: _selectedWalletId,
isExpanded: true,
hint: const Text('Select Wallet'),
items: wallets
.map((w) => DropdownMenuItem(value: w.id, child: Text(w.name)))
.toList(),
onChanged: (val) => setState(() => _selectedWalletId = val),
),
),
),
const SizedBox(height: 16),
const Text('Payment Method', style: TextStyle(fontWeight: FontWeight.w600, color: Colors.grey)),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(16),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: _paymentMethod,
isExpanded: true,
items: ['Cash', 'UPI', 'Bank Transfer', 'Card']
.map((m) => DropdownMenuItem(value: m, child: Text(m)))
.toList(),
onChanged: (val) => setState(() => _paymentMethod = val!),
),
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
),
onPressed: _isLoading ? null : () async {
final amount = double.tryParse(_amountCtrl.text) ?? 0;
if (amount <= 0) return;
setState(() => _isLoading = true);
try {
await ref.read(invoicesProvider.notifier).addPayment(
widget.invoice.id!,
InvoicePayment(
amount: amount,
paymentMethod: _paymentMethod,
walletId: _selectedWalletId,
),
);
if (mounted) {
Navigator.pop(context, true); // true indicates success
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Payment Received Successfully!')));
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.toString())));
setState(() => _isLoading = false);
}
}
},
child: _isLoading
? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
: const Text('Confirm Payment', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
),
),
const SizedBox(height: 24),
],
),
);
}
}