179 lines
4.7 KiB
Dart
179 lines
4.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
class BillItem {
|
|
final String date;
|
|
final String title;
|
|
final int amount;
|
|
final String dueDate;
|
|
final String? reminder;
|
|
|
|
BillItem({
|
|
required this.date,
|
|
required this.title,
|
|
required this.amount,
|
|
required this.dueDate,
|
|
this.reminder,
|
|
});
|
|
}
|
|
|
|
class BillPage extends StatelessWidget {
|
|
final ScrollController scrollController;
|
|
|
|
BillPage({super.key, required this.scrollController});
|
|
|
|
final List<BillItem> bills = [
|
|
BillItem(
|
|
date: '2025/04/22',
|
|
title: '管理費',
|
|
amount: 1200,
|
|
dueDate: '2025/04/30',
|
|
reminder: '第 2 次催繳',
|
|
),
|
|
BillItem(
|
|
date: '2025/04/20',
|
|
title: '水費',
|
|
amount: 340,
|
|
dueDate: '2025/04/28',
|
|
),
|
|
BillItem(
|
|
date: '2025/04/18',
|
|
title: '停車費',
|
|
amount: 2000,
|
|
dueDate: '2025/04/25',
|
|
reminder: '第 3 次催繳',
|
|
),
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return 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: Container(
|
|
color: const Color(0xFFF7F8FA),
|
|
padding: const EdgeInsets.all(16),
|
|
child: Card(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: ListView(
|
|
controller: scrollController,
|
|
children: [
|
|
const Text(
|
|
'💰 繳費項目',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
...bills.map((bill) => BillTile(bill: bill)).toList(),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class BillTile extends StatelessWidget {
|
|
final BillItem bill;
|
|
|
|
const BillTile({super.key, required this.bill});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
|
decoration: const BoxDecoration(
|
|
border: Border(bottom: BorderSide(color: Color(0xFFDDDDDD))),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
bill.date,
|
|
style: const TextStyle(fontSize: 14, color: Color(0xFF555555)),
|
|
),
|
|
Text(
|
|
'${bill.title} - \$${bill.amount}',
|
|
style: const TextStyle(fontSize: 14, color: Color(0xFF222222)),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
'繳費截止日:${bill.dueDate}',
|
|
style: const TextStyle(fontSize: 13, color: Color(0xFF777777)),
|
|
),
|
|
if (bill.reminder != null)
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 4.0),
|
|
child: Text(
|
|
bill.reminder!,
|
|
style: TextStyle(
|
|
fontSize: 13,
|
|
color: Colors.red[700],
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// 👇 浮層包裝元件
|
|
class BillPageWrapper extends StatelessWidget {
|
|
const BillPageWrapper({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: BillPage(scrollController: scrollController),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|