Files
rog_app/lib/pages/entry/entry_list_page.dart
2024-09-08 18:16:51 +09:00

174 lines
5.6 KiB
Dart

// lib/pages/entry/entry_list_page.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:gifunavi/pages/entry/entry_controller.dart';
import 'package:gifunavi/routes/app_pages.dart';
import 'package:timezone/timezone.dart' as tz;
import '../../model/entry.dart';
class EntryListPage extends GetView<EntryController> {
const EntryListPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('エントリー管理'),
actions: [
IconButton(
icon: const Icon(Icons.add),
onPressed: () => Get.toNamed(AppPages.ENTRY_DETAIL, arguments: {'mode': 'new'}),
),
],
),
body: Obx(() {
if (controller.entries.isEmpty) {
return const Center(
child: Text('表示するエントリーがありません。'),
);
}
final sortedEntries = controller.entries.toList()
..sort((b, a) => a.date!.compareTo(b.date!));
return ListView.builder(
itemCount: sortedEntries.length,
itemBuilder: (context, index) {
final entry = sortedEntries[index];
final now = DateTime.now();
final isEntryInFuture = _compareDatesOnly(entry.date!, now) >= 0;
//final isEntryInFuture = entry.date!.isAfter(now) || entry.date!.isAtSameMomentAs(now);
Widget? leadingIcon;
if (!isEntryInFuture) {
if (entry.hasParticipated) {
if (entry.hasGoaled) {
leadingIcon =
const Icon(Icons.check_circle, color: Colors.green);
} else {
leadingIcon = const Icon(Icons.warning, color: Colors.yellow);
}
} else {
leadingIcon = const Icon(Icons.cancel, color: Colors.red);
}
}
return ListTile(
leading: leadingIcon,
title: Row(
children: [
Expanded(
child: Text('${_formatDate(entry.date)}: ${entry.event.eventName}'),
),
Text(entry.team.teamName, style: const TextStyle(fontWeight: FontWeight.bold)),
],
),
subtitle: Row(
children: [
Expanded(
child: Text('カテゴリー: ${entry.category.categoryName}'),
),
Text('ゼッケン: ${entry.zekkenNumber ?? "未設定"}'),
],
),
onTap: () {
if (isEntryInFuture) {
Get.toNamed(AppPages.ENTRY_DETAIL,
arguments: {'mode': 'edit', 'entry': entry});
} else if (entry.hasParticipated) {
Get.toNamed(AppPages.EVENT_RESULT, arguments: {'entry': entry});
} else {
_showNonParticipationDialog(context, entry);
}
}
);
},
);
}),
);
}
// 新しく追加するメソッド
int _compareDatesOnly(DateTime a, DateTime b) {
return DateTime(a.year, a.month, a.day).compareTo(DateTime(b.year, b.month, b.day));
}
String _formatDate(DateTime? date) {
if (date == null) {
return '日時未設定';
}
final jstDate = tz.TZDateTime.from(date, tz.getLocation('Asia/Tokyo'));
return DateFormat('yyyy-MM-dd').format(jstDate);
}
void _showNonParticipationDialog(BuildContext context, Entry entry) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(entry.event.eventName),
content: Text('${_formatDate(entry.date)}\n\n不参加でした'),
actions: <Widget>[
TextButton(
child: const Text('閉じる'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
class EntryListPage_old extends GetView<EntryController> {
const EntryListPage_old({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('エントリー管理'),
actions: [
IconButton(
icon: const Icon(Icons.add),
onPressed: () => Get.toNamed(AppPages.ENTRY_DETAIL, arguments: {'mode': 'new'}),
),
],
),
body: Obx((){
if (controller.isLoading.value) {
return const Center(child: CircularProgressIndicator()); // EntryList
}
// エントリーを日付昇順にソート
final sortedEntries = controller.entries.toList()
..sort((a, b) => (a.date ?? DateTime(0)).compareTo(b.date ?? DateTime(0)));
return ListView.builder(
itemCount: sortedEntries.length,
itemBuilder: (context, index) {
final entry = sortedEntries[index];
return ListTile(
title: Text(entry.event.eventName ?? 'イベント未設定'),
subtitle: Text(
'${entry.team.teamName ?? 'チーム未設定'} - ${entry.category
.categoryName ?? 'カテゴリ未設定'}'),
trailing: Text(
entry.date?.toString().substring(0, 10) ?? '日付未設定'),
onTap: () =>
Get.toNamed(AppPages.ENTRY_DETAIL,
arguments: {'mode': 'edit', 'entry': entry}),
);
},
);
}),
);
}
}