Files
flutter-learn/lib/leave/leave_detail.dart
T
2026-01-13 23:11:25 +08:00

154 lines
5.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import './leave_model.dart';
class LeaveDetail extends StatelessWidget {
final Leave leave;
const LeaveDetail({required this.leave, super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('請假單詳情'),
backgroundColor: Colors.white,
foregroundColor: Colors.black,
elevation: 0.5,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 頂部狀態區塊
_buildHeaderStatus(),
const SizedBox(height: 24),
// 主要資訊區塊 (使用卡片包裝)
_buildInfoCard(context),
const SizedBox(height: 24),
// 請假事由區塊
const Text(
'請假事由',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.blueGrey),
),
const SizedBox(height: 8),
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.grey.shade300),
),
child: Text(
leave.leaveNote ?? '未填寫事由',
style: const TextStyle(fontSize: 15, height: 1.5),
),
),
const SizedBox(height: 32),
// 底部操作按鈕 (例如:若為草稿可編輯,或撤回)
if (leave.flowStatus == '0' || leave.flowStatus == '1')
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: () {
// 實作撤回或取消邏輯
},
icon: const Icon(Icons.history_outlined),
label: const Text('撤回申請'),
style: OutlinedButton.styleFrom(
foregroundColor: Colors.red,
side: const BorderSide(color: Colors.red),
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
),
],
),
),
);
}
// 頂部狀態顯示:呈現單號與醒目的狀態標籤
Widget _buildHeaderStatus() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'單號: ${leave.billNo}',
style: const TextStyle(fontSize: 14, color: Colors.grey),
),
const SizedBox(height: 4),
Text(
leave.leaveType,
style: const TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
],
),
Chip(
backgroundColor: leave.statusColor.withOpacity(0.1),
side: BorderSide(color: leave.statusColor),
label: Text(
leave.statusText,
style: TextStyle(color: leave.statusColor, fontWeight: FontWeight.bold),
),
),
],
);
}
// 核心資訊卡片
Widget _buildInfoCard(BuildContext context) {
return Card(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
side: BorderSide(color: Colors.grey.shade200),
),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
_buildDetailRow(Icons.calendar_month, '請假期間', leave.formattedRange),
const Divider(height: 30),
_buildDetailRow(Icons.timer_outlined, '請假時數', '${leave.days}${leave.hours} 小時'),
const Divider(height: 30),
_buildDetailRow(Icons.person_outline, '代理人', leave.agentId),
const Divider(height: 30),
_buildDetailRow(Icons.edit_calendar, '申請日期',
leave.billDate != null ? DateFormat('yyyy-MM-dd').format(leave.billDate!) : 'N/A'),
],
),
),
);
}
// 輔助元件:建立細節列
Widget _buildDetailRow(IconData icon, String label, String value) {
return Row(
children: [
Icon(icon, size: 20, color: Colors.blueAccent),
const SizedBox(width: 12),
Text(label, style: const TextStyle(color: Colors.grey, fontSize: 14)),
const Spacer(),
// 使用 Flexible 限制文字寬度並允許換行
Flexible(
child: Text(
value,
textAlign: TextAlign.end, // 靠右對齊
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 15),
softWrap: true, // 允許自動換行
),
),
],
);
}
}