CommunityAPP/lib/reapair.dart

251 lines
8.7 KiB
Dart
Raw Normal View History

2025-05-09 16:49:13 +08:00
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;
2025-05-09 16:49:13 +08:00
@override
State<RepairPage> createState() => _RepairPageState();
}
class _RepairPageState extends State<RepairPage> {
final _formKey = GlobalKey<FormState>();
String? _repairType;
final _locationController = TextEditingController();
final _descriptionController = TextEditingController();
XFile? _photo;
final List<Map<String, String>> _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<void> _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('報修已提交!')));
// 這裡可以擴充送出資料到伺服器的邏輯
2025-05-09 16:49:13 +08:00
}
}
@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)),
2025-05-09 16:49:13 +08:00
),
child: Column(
2025-05-09 16:49:13 +08:00
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(
2025-05-09 16:49:13 +08:00
children: [
IconButton(
icon: const Icon(Icons.close, color: Colors.white),
onPressed: () => Navigator.pop(context),
2025-05-09 16:49:13 +08:00
),
const SizedBox(width: 8),
2025-05-09 16:49:13 +08:00
const Text(
'水電網路報修',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white,
),
2025-05-09 16:49:13 +08:00
),
],
),
),
Expanded(
child: ListView(
controller: widget.scrollController,
padding: const EdgeInsets.all(16),
children: [
const Text('🛠️ 填寫報修單', style: TextStyle(fontSize: 16)),
2025-05-09 16:49:13 +08:00
const SizedBox(height: 12),
Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'報修類別',
style: TextStyle(fontWeight: FontWeight.bold),
),
DropdownButtonFormField<String>(
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),
),
),
],
2025-05-09 16:49:13 +08:00
),
),
const SizedBox(height: 24),
const Text('📋 已申報紀錄', style: TextStyle(fontSize: 16)),
2025-05-09 16:49:13 +08:00
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"]}'),
],
2025-05-09 16:49:13 +08:00
),
),
),
],
),
),
],
),
);
}
}
// 浮層包裝元件,給 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),
);
},
);
}
}