161 lines
5.0 KiB
Dart
161 lines
5.0 KiB
Dart
|
import 'package:flutter/material.dart';
|
|||
|
import 'package:http/http.dart' as http;
|
|||
|
import 'dart:convert';
|
|||
|
|
|||
|
class ActivityDetailPage extends StatefulWidget {
|
|||
|
final int activityId;
|
|||
|
|
|||
|
const ActivityDetailPage({super.key, required this.activityId});
|
|||
|
|
|||
|
@override
|
|||
|
State<ActivityDetailPage> createState() => _ActivityDetailPageState();
|
|||
|
}
|
|||
|
|
|||
|
class _ActivityDetailPageState extends State<ActivityDetailPage> {
|
|||
|
Map<String, dynamic>? activity;
|
|||
|
bool isLoading = true;
|
|||
|
|
|||
|
// 切換為 false 就會改為從 API 載入資料
|
|||
|
final bool useMockData = true;
|
|||
|
|
|||
|
@override
|
|||
|
void initState() {
|
|||
|
super.initState();
|
|||
|
fetchActivityDetail();
|
|||
|
}
|
|||
|
|
|||
|
Future<void> fetchActivityDetail() async {
|
|||
|
if (useMockData) {
|
|||
|
//await Future.delayed(const Duration(seconds: 1)); // 模擬延遲
|
|||
|
setState(() {
|
|||
|
activity = {
|
|||
|
"title": "🎉 社區春季市集",
|
|||
|
"time": "2025/04/27(日)10:00 - 16:00",
|
|||
|
"location": "中庭花園",
|
|||
|
"desc": "市集將有手作小物、美食攤販及親子遊戲活動,歡迎全體住戶參與!",
|
|||
|
"image": "https://picsum.photos/id/1011/600/300",
|
|||
|
"canRegister": true,
|
|||
|
};
|
|||
|
isLoading = false;
|
|||
|
});
|
|||
|
} else {
|
|||
|
try {
|
|||
|
final response = await http.get(
|
|||
|
// API 位置
|
|||
|
Uri.parse('https://your-api.com/activities/${widget.activityId}'),
|
|||
|
);
|
|||
|
if (response.statusCode == 200) {
|
|||
|
setState(() {
|
|||
|
activity = json.decode(response.body);
|
|||
|
isLoading = false;
|
|||
|
});
|
|||
|
} else {
|
|||
|
throw Exception('Failed to load activity');
|
|||
|
}
|
|||
|
} catch (e) {
|
|||
|
setState(() {
|
|||
|
isLoading = false;
|
|||
|
activity = null;
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void _showRegisterDialog() {
|
|||
|
int peopleCount = 1;
|
|||
|
showDialog(
|
|||
|
context: context,
|
|||
|
builder: (context) {
|
|||
|
return AlertDialog(
|
|||
|
title: const Text('確認報名'),
|
|||
|
content: DropdownButtonFormField<int>(
|
|||
|
value: peopleCount,
|
|||
|
items:
|
|||
|
[1, 2, 3, 4]
|
|||
|
.map((e) => DropdownMenuItem(value: e, child: Text('$e 人')))
|
|||
|
.toList(),
|
|||
|
onChanged: (value) {
|
|||
|
if (value != null) peopleCount = value;
|
|||
|
},
|
|||
|
decoration: const InputDecoration(labelText: '選擇報名人數'),
|
|||
|
),
|
|||
|
actions: [
|
|||
|
TextButton(
|
|||
|
onPressed: () => Navigator.pop(context),
|
|||
|
child: const Text('取消'),
|
|||
|
),
|
|||
|
ElevatedButton(
|
|||
|
onPressed: () {
|
|||
|
Navigator.pop(context);
|
|||
|
ScaffoldMessenger.of(context).showSnackBar(
|
|||
|
SnackBar(
|
|||
|
content: Text(
|
|||
|
'已報名活動 ID ${widget.activityId},人數:$peopleCount',
|
|||
|
),
|
|||
|
),
|
|||
|
);
|
|||
|
},
|
|||
|
child: const Text('確認報名'),
|
|||
|
),
|
|||
|
],
|
|||
|
);
|
|||
|
},
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
@override
|
|||
|
Widget build(BuildContext context) {
|
|||
|
return Scaffold(
|
|||
|
appBar: AppBar(title: const Text('活動詳情')),
|
|||
|
body:
|
|||
|
isLoading
|
|||
|
? const Center(child: CircularProgressIndicator())
|
|||
|
: activity == null
|
|||
|
? const Center(child: Text('找不到該活動。'))
|
|||
|
: SingleChildScrollView(
|
|||
|
padding: const EdgeInsets.all(16),
|
|||
|
child: Column(
|
|||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|||
|
children: [
|
|||
|
ClipRRect(
|
|||
|
borderRadius: BorderRadius.circular(12),
|
|||
|
child: Image.network(
|
|||
|
activity!['image'],
|
|||
|
fit: BoxFit.cover,
|
|||
|
),
|
|||
|
),
|
|||
|
const SizedBox(height: 16),
|
|||
|
Text(
|
|||
|
activity!['title'],
|
|||
|
style: const TextStyle(
|
|||
|
fontSize: 20,
|
|||
|
fontWeight: FontWeight.bold,
|
|||
|
),
|
|||
|
),
|
|||
|
const SizedBox(height: 8),
|
|||
|
Text(
|
|||
|
'時間:${activity!['time']}',
|
|||
|
style: const TextStyle(color: Colors.grey),
|
|||
|
),
|
|||
|
const SizedBox(height: 4),
|
|||
|
Text(
|
|||
|
'地點:${activity!['location']}',
|
|||
|
style: const TextStyle(color: Colors.grey),
|
|||
|
),
|
|||
|
const SizedBox(height: 12),
|
|||
|
Text(activity!['desc']),
|
|||
|
const SizedBox(height: 24),
|
|||
|
if (activity!['canRegister'] == true)
|
|||
|
Center(
|
|||
|
child: ElevatedButton(
|
|||
|
onPressed: _showRegisterDialog,
|
|||
|
child: const Text('我要報名'),
|
|||
|
),
|
|||
|
),
|
|||
|
],
|
|||
|
),
|
|||
|
),
|
|||
|
);
|
|||
|
}
|
|||
|
}
|