import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../models/saham_transaksi.dart'; import '../services/stock_service.dart'; class AddTransaksiScreen extends StatefulWidget { const AddTransaksiScreen({super.key, required this.service}); final StockService service; @override State createState() => _AddTransaksiScreenState(); } class _AddTransaksiScreenState extends State { final _tanggal = TextEditingController( text: DateFormat('yyyy-MM-dd').format(DateTime.now())); final _volume = TextEditingController(); final _harga = TextEditingController(); final _fee = TextEditingController(text: '0'); late Future> _sahamFut; int? _sahamId; bool _isBuy = true; bool _busy = false; String? _err; @override void initState() { super.initState(); _sahamFut = widget.service.listSaham(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Catat Transaksi')), body: Padding( padding: const EdgeInsets.all(16), child: ListView( children: [ SegmentedButton( segments: const [ ButtonSegment(value: true, label: Text('Beli'), icon: Icon(Icons.add)), ButtonSegment(value: false, label: Text('Jual'), icon: Icon(Icons.remove)), ], selected: {_isBuy}, onSelectionChanged: (s) => setState(() => _isBuy = s.first), ), const SizedBox(height: 16), TextField(controller: _tanggal, decoration: const InputDecoration(labelText: 'Tanggal (YYYY-MM-DD)', prefixIcon: Icon(Icons.calendar_today))), const SizedBox(height: 12), FutureBuilder>( future: _sahamFut, builder: (context, snap) { if (snap.connectionState != ConnectionState.done) { return const ListTile( leading: SizedBox(width:18,height:18,child:CircularProgressIndicator(strokeWidth:2)), title: Text('Memuat saham...')); } if (snap.hasError) { return Text('Error saham: ${snap.error}', style: const TextStyle(color: Colors.red)); } final saham = snap.data ?? []; return DropdownButtonFormField( initialValue: _sahamId, decoration: const InputDecoration(labelText: 'Pilih Saham', prefixIcon: Icon(Icons.business)), items: [ for (final s in saham) DropdownMenuItem(value: s.id, child: Text('${s.kode} — ${s.perusahaan ?? ''}')), ], onChanged: (v) => setState(() => _sahamId = v), ); }, ), const SizedBox(height: 12), TextField(controller: _volume, keyboardType: TextInputType.number, decoration: const InputDecoration(labelText: 'Jumlah Lembar', prefixIcon: Icon(Icons.numbers))), const SizedBox(height: 12), TextField(controller: _harga, keyboardType: const TextInputType.numberWithOptions(decimal: true), decoration: const InputDecoration(labelText: 'Harga per Lembar (Rp)', prefixIcon: Icon(Icons.attach_money))), const SizedBox(height: 12), TextField(controller: _fee, keyboardType: const TextInputType.numberWithOptions(decimal: true), decoration: const InputDecoration(labelText: 'Biaya / Fee (Rp)', prefixIcon: Icon(Icons.payments))), if (_err != null) Padding(padding: const EdgeInsets.only(top: 8), child: Text(_err!, style: const TextStyle(color: Colors.red))), const SizedBox(height: 20), FilledButton.icon( onPressed: _busy ? null : _save, icon: _busy ? const SizedBox(width:18,height:18,child:CircularProgressIndicator(strokeWidth:2)) : const Icon(Icons.save), label: const Text('Simpan'), ), ], ), ), ); } Future _save() async { setState(() { _busy = true; _err = null; }); try { final date = _tanggal.text.trim(); final vol = int.tryParse(_volume.text.trim()) ?? 0; final harga = double.tryParse(_harga.text.replaceAll('.', '').replaceAll(',', '.')) ?? 0; final feeC = double.tryParse(_fee.text.trim().isEmpty ? '0' : _fee.text.trim()) ?? 0; if (_sahamId == null) throw Exception('Pilih saham dulu'); if (vol <= 0) throw Exception('Volume harus > 0'); if (harga <= 0) throw Exception('Harga harus > 0'); if (!date.contains('-')) throw Exception('Format tanggal salah'); await widget.service.addTransaksi( sahamId: _sahamId!, tipe: _isBuy ? 'buy' : 'sell', volume: vol, harga: harga, fee: feeC, tanggal: date); if (!mounted) return; Navigator.pop(context, true); } catch (e) { if (!mounted) return; setState(() { _busy = false; _err = e.toString().replaceFirst('Exception: ', ''); }); } } }