import 'package:flutter/material.dart'; import './leave_model.dart'; import './leave_api.dart'; import 'package:intl/intl.dart'; import '../services/person_picker_dialog.dart'; class LeaveForm extends StatefulWidget { final String userId; const LeaveForm({required this.userId, super.key}); @override State createState() => _LeaveFormState(); } class _LeaveFormState extends State { final _formKey = GlobalKey(); final LeaveApiService _leaveApi = LeaveApiService(); // 狀態變數 List _dbLeaveTypes = []; LeaveType? _selectedType; bool _isLoadingTypes = true; Map? _selectedAgent; // 改為這個 DateTime _startDate = DateTime.now(); TimeOfDay _startTime = const TimeOfDay(hour: 09, minute: 00); DateTime _endDate = DateTime.now(); TimeOfDay _endTime = const TimeOfDay(hour: 18, minute: 00); String _note = ''; Future _pickDateTime(bool isStart) async { final date = await showDatePicker( context: context, initialDate: isStart ? _startDate : _endDate, firstDate: DateTime(2020), lastDate: DateTime(2030), ); if (date == null) return; final time = await showTimePicker( context: context, initialTime: isStart ? _startTime : _endTime, ); if (time == null) return; setState(() { if (isStart) { _startDate = date; _startTime = time; } else { _endDate = date; _endTime = time; } }); } void _submit() async { if (_formKey.currentState!.validate() && _selectedType != null && _selectedAgent != null) { _formKey.currentState!.save(); // 合併日期時間 final start = DateTime(_startDate.year, _startDate.month, _startDate.day, _startTime.hour, _startTime.minute); final end = DateTime(_endDate.year, _endDate.month, _endDate.day, _endTime.hour, _endTime.minute); final newLeave = Leave( billNo: '', // API 端生成 personId: widget.userId, agentId: _selectedAgent!['id'].toString(), // 確保轉為 String leaveType: _selectedType!.id, // 傳送 ID 給後端 startTime: start, endTime: end, days: 1.0, // 簡化處理,實際可依 start/end 計算 hours: 8.0, leaveNote: _note, ); await LeaveApiService().createLeave(newLeave); if (mounted) { Navigator.pop(context, true); } } } @override void initState() { super.initState(); _loadInitialData(); } // 從 API 載入假別 Future _loadInitialData() async { try { final types = await _leaveApi.fetchLeaveTypes(); setState(() { _dbLeaveTypes = types; // 預設選取第一筆(如有資料) if (_dbLeaveTypes.isNotEmpty) { _selectedType = _dbLeaveTypes.first; } _isLoadingTypes = false; }); } catch (e) { setState(() => _isLoadingTypes = false); // 實務上應加入錯誤處理提示 } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('新增請假申請')), body: _isLoadingTypes ? const Center(child: CircularProgressIndicator()) // 載入中顯示轉圈 :Form( key: _formKey, child: ListView( padding: const EdgeInsets.all(16), children: [ // 假別選擇 (顯示名稱,存入代碼) DropdownButtonFormField( value: _selectedType, decoration: const InputDecoration(labelText: '請假類別', border: OutlineInputBorder()), // 將 API 取得的資料轉換為選單項目 items: _dbLeaveTypes.map((t) => DropdownMenuItem( value: t, child: Text(t.name) // 顯示 leavetype_name )).toList(), onChanged: (v) => setState(() => _selectedType = v), validator: (v) => v == null ? '請選擇假別' : null, ), const SizedBox(height: 16), // 代理人開窗 // 在 _LeaveFormState 內部的 Widget Tree 中 ListTile( title: const Text('代理人'), // 顯示已選擇的代理人姓名與 ID,若無則顯示提示 subtitle: Text(_selectedAgent == null ? '請點擊選擇代理人' : '${_selectedAgent!['name']} (${_selectedAgent!['id']})'), trailing: const Icon(Icons.person_add_alt_1, color: Colors.blue), shape: RoundedRectangleBorder( side: BorderSide(color: Colors.grey.shade300), borderRadius: BorderRadius.circular(8), ), onTap: () async { // 呼叫獨立的彈窗組件 final Map? result = await showDialog>( context: context, builder: (context) => const PersonPickerDialog(title: '查詢代理人'), ); // 如果使用者有選取人員(result 不為 null),則更新 UI 狀態 if (result != null) { setState(() { _selectedAgent = result; // 這裡 result 的內容為 {'id': '...', 'name': '...', 'dept': '...'} }); } }, ), const SizedBox(height: 16), // 起訖時間選擇區 _buildTimePickerTile('開始時間', _startDate, _startTime, true), const SizedBox(height: 10), _buildTimePickerTile('結束時間', _endDate, _endTime, false), const SizedBox(height: 16), TextFormField( decoration: const InputDecoration(labelText: '事由說明'), maxLines: 3, onSaved: (v) => _note = v!, ), const SizedBox(height: 30), ElevatedButton( onPressed: _submit, style: ElevatedButton.styleFrom(minimumSize: const Size(double.infinity, 50)), child: const Text('提交申請'), ), ], ), ), ); } Widget _buildTimePickerTile(String label, DateTime date, TimeOfDay time, bool isStart) { final format = DateFormat('yyyy/MM/dd'); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: const TextStyle(fontSize: 14, color: Colors.blueGrey)), const SizedBox(height: 5), InkWell( onTap: () => _pickDateTime(isStart), child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 15), decoration: BoxDecoration(border: Border.all(color: Colors.grey.shade400), borderRadius: BorderRadius.circular(4)), child: Row( children: [ const Icon(Icons.access_time, size: 20, color: Colors.blue), const SizedBox(width: 10), Text('${format.format(date)} ${time.format(context)}', style: const TextStyle(fontSize: 16)), ], ), ), ), ], ); } }