大幅変更&環境バージョンアップ
This commit is contained in:
193
lib/pages/entry/entry_detail_page.dart
Normal file
193
lib/pages/entry/entry_detail_page.dart
Normal file
@ -0,0 +1,193 @@
|
||||
// lib/pages/entry/entry_detail_page.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:gifunavi/pages/entry/entry_controller.dart';
|
||||
import 'package:gifunavi/model/event.dart';
|
||||
import 'package:gifunavi/model/category.dart';
|
||||
import 'package:gifunavi/model/team.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
|
||||
class EntryDetailPage extends GetView<EntryController> {
|
||||
const EntryDetailPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Map<String, dynamic> arguments = Get.arguments ?? {};
|
||||
final mode = Get.arguments['mode'] as String? ?? 'new';
|
||||
final entry = Get.arguments['entry'];
|
||||
|
||||
if (mode == 'edit' && entry != null) {
|
||||
controller.initializeEditMode(entry);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(mode == 'new' ? 'エントリー登録' : 'エントリー詳細'),
|
||||
),
|
||||
body: Obx(() {
|
||||
if (controller.isLoading.value) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildDropdown<Event>(
|
||||
label: 'イベント',
|
||||
items: controller.events,
|
||||
selectedId: controller.selectedEvent.value?.id,
|
||||
onChanged: (eventId) => controller.updateEvent(
|
||||
controller.events.firstWhere((e) => e.id == eventId)
|
||||
),
|
||||
getDisplayName: (event) => event.eventName,
|
||||
getId: (event) => event.id,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildDropdown<Team>(
|
||||
label: 'チーム',
|
||||
items: controller.teams,
|
||||
selectedId: controller.selectedTeam.value?.id,
|
||||
onChanged: (teamId) => controller.updateTeam(
|
||||
controller.teams.firstWhere((t) => t.id == teamId)
|
||||
),
|
||||
getDisplayName: (team) => team.teamName,
|
||||
getId: (team) => team.id,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildCategoryDropdown(),
|
||||
/*
|
||||
_buildDropdown<NewCategory>()
|
||||
label: 'カテゴリ',
|
||||
items: controller.categories,
|
||||
selectedId: controller.selectedCategory.value?.id,
|
||||
onChanged: (categoryId) => controller.updateCategory(
|
||||
controller.categories.firstWhere((c) => c.id == categoryId)
|
||||
),
|
||||
getDisplayName: (category) => category.categoryName,
|
||||
getId: (category) => category.id,
|
||||
),
|
||||
|
||||
*/
|
||||
const SizedBox(height: 16),
|
||||
ListTile(
|
||||
title: const Text('日付'),
|
||||
subtitle: Text(
|
||||
controller.selectedDate.value != null
|
||||
? DateFormat('yyyy-MM-dd').format(tz.TZDateTime.from(controller.selectedDate.value!, tz.getLocation('Asia/Tokyo')))
|
||||
: '日付を選択してください',
|
||||
),
|
||||
onTap: () async {
|
||||
if (controller.selectedEvent.value == null) {
|
||||
Get.snackbar('Error', 'Please select an event first');
|
||||
return;
|
||||
}
|
||||
final tz.TZDateTime now = tz.TZDateTime.now(tz.getLocation('Asia/Tokyo'));
|
||||
final tz.TZDateTime eventStart = tz.TZDateTime.from(controller.selectedEvent.value!.startDatetime, tz.getLocation('Asia/Tokyo'));
|
||||
final tz.TZDateTime eventEnd = tz.TZDateTime.from(controller.selectedEvent.value!.endDatetime, tz.getLocation('Asia/Tokyo'));
|
||||
|
||||
final tz.TZDateTime initialDate = controller.selectedDate.value != null
|
||||
? tz.TZDateTime.from(controller.selectedDate.value!, tz.getLocation('Asia/Tokyo'))
|
||||
: (now.isAfter(eventStart) ? now : eventStart);
|
||||
|
||||
// 選択可能な最初の日付を設定(今日かイベント開始日のうち、より後の日付)
|
||||
final tz.TZDateTime firstDate = now.isAfter(eventStart) ? now : eventStart;
|
||||
|
||||
final DateTime? picked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: initialDate.isAfter(firstDate) ? initialDate : firstDate,
|
||||
firstDate: firstDate,
|
||||
lastDate: eventEnd,
|
||||
);
|
||||
if (picked != null) {
|
||||
controller.updateDate(tz.TZDateTime.from(picked, tz.getLocation('Asia/Tokyo')));
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
if (mode == 'new')
|
||||
ElevatedButton(
|
||||
onPressed: () => controller.createEntry(),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
minimumSize: const Size(double.infinity, 50),
|
||||
),
|
||||
child: const Text('エントリーを作成'),
|
||||
)
|
||||
else
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => controller.deleteEntry(),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
minimumSize: const Size(0, 50),
|
||||
),
|
||||
child: const Text('エントリーを削除'),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => controller.updateEntry(),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.lightBlue,
|
||||
foregroundColor: Colors.white,
|
||||
minimumSize: const Size(0, 50),
|
||||
),
|
||||
child: const Text('エントリーを更新'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDropdown<T>({
|
||||
required String label,
|
||||
required List<T> items,
|
||||
required int? selectedId,
|
||||
required void Function(int?) onChanged,
|
||||
required String Function(T) getDisplayName,
|
||||
required int Function(T) getId,
|
||||
}) {
|
||||
return DropdownButtonFormField<int>(
|
||||
decoration: InputDecoration(labelText: label),
|
||||
value: selectedId,
|
||||
items: items.map((item) => DropdownMenuItem<int>(
|
||||
value: getId(item),
|
||||
child: Text(getDisplayName(item)),
|
||||
)).toList(),
|
||||
onChanged: onChanged,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCategoryDropdown() {
|
||||
final eligibleCategories = controller.categories.where((c) =>
|
||||
c.baseCategory == controller.selectedCategory.value?.baseCategory
|
||||
).toList();
|
||||
|
||||
return DropdownButtonFormField<NewCategory>(
|
||||
decoration: InputDecoration(labelText: 'カテゴリ'),
|
||||
value: controller.selectedCategory.value,
|
||||
items: eligibleCategories.map((category) => DropdownMenuItem<NewCategory>(
|
||||
value: category,
|
||||
child: Text(category.categoryName),
|
||||
)).toList(),
|
||||
onChanged: (value) => controller.updateCategory(value),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user