import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; class RepairPage extends StatefulWidget { const RepairPage({super.key, required this.scrollController}); final ScrollController scrollController; @override State createState() => _RepairPageState(); } class _RepairPageState extends State { final _formKey = GlobalKey(); String? _repairType; final _locationController = TextEditingController(); final _descriptionController = TextEditingController(); XFile? _photo; final List> _repairRecords = [ { "date": "2025/04/20", "type": "水管漏水", "location": "A棟 2F", "status": "處理中", }, { "date": "2025/04/18", "type": "網路異常", "location": "C棟 5F", "status": "已完成", }, { "date": "2025/04/15", "type": "電力問題", "location": "B棟 6F", "status": "待處理", }, ]; Future _pickImage() async { final picker = ImagePicker(); final picked = await picker.pickImage(source: ImageSource.gallery); if (picked != null) { setState(() { _photo = picked; }); } } void _submitForm() { if (_formKey.currentState!.validate() && _repairType != null) { ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('報修已提交!'))); // 這裡可以擴充送出資料到伺服器的邏輯 } } @override void dispose() { _locationController.dispose(); _descriptionController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration( color: Color(0xFFF7F8FA), borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), child: Column( children: [ // 標題列 Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: const BoxDecoration( color: Color(0xFF9EAF9F), borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), child: Row( children: [ IconButton( icon: const Icon(Icons.close, color: Colors.white), onPressed: () => Navigator.pop(context), ), const SizedBox(width: 8), const Text( '水電網路報修', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 20, color: Colors.white, ), ), ], ), ), Expanded( child: ListView( controller: widget.scrollController, padding: const EdgeInsets.all(16), children: [ const Text('🛠️ 填寫報修單', style: TextStyle(fontSize: 16)), const SizedBox(height: 12), Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '報修類別', style: TextStyle(fontWeight: FontWeight.bold), ), DropdownButtonFormField( value: _repairType, items: const [ DropdownMenuItem(value: '電力問題', child: Text('電力問題')), DropdownMenuItem(value: '水管漏水', child: Text('水管漏水')), DropdownMenuItem(value: '網路異常', child: Text('網路異常')), DropdownMenuItem(value: '其他', child: Text('其他')), ], hint: const Text('請選擇'), onChanged: (value) { setState(() { _repairType = value; }); }, validator: (value) => value == null ? '請選擇報修類別' : null, ), const SizedBox(height: 12), const Text( '地點/房號', style: TextStyle(fontWeight: FontWeight.bold), ), TextFormField( controller: _locationController, decoration: const InputDecoration(hintText: '如:B棟 3F'), validator: (value) => value == null || value.isEmpty ? '請輸入地點' : null, ), const SizedBox(height: 12), const Text( '問題描述', style: TextStyle(fontWeight: FontWeight.bold), ), TextFormField( controller: _descriptionController, maxLines: 3, decoration: const InputDecoration( hintText: '請簡要描述問題...', border: OutlineInputBorder(), ), validator: (value) => value == null || value.isEmpty ? '請輸入問題描述' : null, ), const SizedBox(height: 12), const Text( '照片上傳(選填)', style: TextStyle(fontWeight: FontWeight.bold), ), Row( children: [ ElevatedButton( onPressed: _pickImage, style: ElevatedButton.styleFrom( backgroundColor: Colors.white, ), child: const Text( '選擇照片', style: TextStyle(color: Colors.purple), ), ), const SizedBox(width: 8), if (_photo != null) const Text( '已選擇圖片', style: TextStyle(color: Colors.green), ), ], ), const SizedBox(height: 16), ElevatedButton( onPressed: _submitForm, style: ElevatedButton.styleFrom( backgroundColor: Colors.green, minimumSize: const Size.fromHeight(48), ), child: const Text( '送出報修', style: TextStyle(color: Colors.white), ), ), ], ), ), const SizedBox(height: 24), const Text('📋 已申報紀錄', style: TextStyle(fontSize: 16)), const SizedBox(height: 12), ..._repairRecords.map( (record) => Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${record["date"]} - ${record["type"]}', style: const TextStyle(fontWeight: FontWeight.bold), ), Text('地點:${record["location"]}|狀態:${record["status"]}'), ], ), ), ), ], ), ), ], ), ); } } // 浮層包裝元件,給 showModalBottomSheet 使用 class RepairPageWrapper extends StatelessWidget { const RepairPageWrapper({super.key}); @override Widget build(BuildContext context) { return DraggableScrollableSheet( initialChildSize: 0.95, minChildSize: 0.5, maxChildSize: 1.0, expand: false, builder: (_, scrollController) { return Container( color: Colors.transparent, child: RepairPage(scrollController: scrollController), ); }, ); } }