First Commit

This commit is contained in:
2026-04-17 00:37:21 +08:00
parent f445b408a4
commit fb33d42ab1
83 changed files with 3832 additions and 2 deletions
+140
View File
@@ -0,0 +1,140 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // 支援 SystemNavigator.pop()
import 'house_note_model.dart';
import 'house_note_api.dart';
import 'house_note_form.dart';
import 'house_note_detail.dart';
class HouseNoteManager extends StatefulWidget {
const HouseNoteManager({super.key});
@override
State<HouseNoteManager> createState() => _HouseNoteManagerState();
}
class _HouseNoteManagerState extends State<HouseNoteManager> {
final HouseNoteApiService _api = HouseNoteApiService();
late Future<List<House>> _houseFuture;
@override
void initState() {
super.initState();
_refreshList();
}
void _refreshList() {
setState(() {
_houseFuture = _api.fetchHouses();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('🏠 我的賞屋筆記'),
actions: [
IconButton(
icon: const Icon(Icons.exit_to_app, color: Colors.redAccent),
tooltip: '離開系統',
onPressed: () => SystemNavigator.pop(), // 實作離開系統功能
)
],
),
body: FutureBuilder<List<House>>(
future: _houseFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (!snapshot.hasData || snapshot.data!.isEmpty) {
return _buildEmptyState();
}
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: snapshot.data!.length,
itemBuilder: (ctx, i) => _buildHouseCard(snapshot.data![i]),
);
},
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HouseNoteForm()),
);
if (result == true) _refreshList();
},
label: const Text('新增看屋'),
icon: const Icon(Icons.add_location_alt_outlined),
),
);
}
// 修正:補回遺失的 _buildHouseCard 方法
Widget _buildHouseCard(House item) {
return Card(
elevation: 2,
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: ListTile(
contentPadding: const EdgeInsets.all(12),
onTap: () {
// 導向詳情頁,這會用到 house_note_detail.dart
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HouseNoteDetail(house: item)),
);
},
title: Text(item.title, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 4),
Text(item.address ?? '暫無地址', maxLines: 1, overflow: TextOverflow.ellipsis),
const SizedBox(height: 8),
Row(
children: [
_buildTag(item.priceTag, Colors.blueGrey),
const SizedBox(width: 8),
_buildTag('${item.overallRating}', item.ratingColor),
],
),
],
),
trailing: const Icon(Icons.chevron_right),
),
);
}
// 修正:補回遺失的 _buildTag 方法
Widget _buildTag(String text, Color color) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(4),
border: Border.all(color: color),
),
child: Text(
text,
style: TextStyle(color: color, fontSize: 12, fontWeight: FontWeight.bold),
),
);
}
// 修正:補回遺失的 _buildEmptyState 方法
Widget _buildEmptyState() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.house_siding, size: 80, color: Colors.grey.shade300),
const SizedBox(height: 16),
const Text('還沒有記錄,點擊右下角開始第一筆看屋吧!', style: TextStyle(color: Colors.grey)),
],
),
);
}
}