Team,Member, Entryの登録まで完了

This commit is contained in:
2024-07-29 08:41:28 +09:00
parent 7f8adeea01
commit 9c98d3ed53
10 changed files with 803 additions and 260 deletions

View File

@ -1,6 +1,7 @@
// lib/entry/entry_controller.dart
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rogapp/model/entry.dart';
import 'package:rogapp/model/event.dart';
import 'package:rogapp/model/team.dart';
@ -8,7 +9,7 @@ import 'package:rogapp/model/category.dart';
import 'package:rogapp/services/api_service.dart';
class EntryController extends GetxController {
late final ApiService _apiService;
late ApiService _apiService;
final entries = <Entry>[].obs;
final events = <Event>[].obs;
@ -21,14 +22,27 @@ class EntryController extends GetxController {
final selectedDate = Rx<DateTime?>(null);
final currentEntry = Rx<Entry?>(null);
final isLoading = true.obs;
@override
void onInit() async{
void onInit() async {
super.onInit();
await Get.putAsync(() => ApiService().init());
_apiService = Get.find<ApiService>();
await initializeApiService();
await loadInitialData();
}
Future<void> initializeApiService() async {
try {
_apiService = await Get.putAsync(() => ApiService().init());
} catch (e) {
print('Error initializing ApiService: $e');
Get.snackbar('Error', 'Failed to initialize API service');
}
}
Future<void> loadInitialData() async {
try {
isLoading.value = true;
await Future.wait([
fetchEntries(),
fetchEvents(),
@ -37,14 +51,53 @@ class EntryController extends GetxController {
]);
if (Get.arguments != null && Get.arguments['entry'] != null) {
currentEntry.value = Get.arguments['entry'];
_initializeEntryData();
initializeEditMode(currentEntry.value!);
} else {
// 新規作成モードの場合、最初のイベントを選択
if (events.isNotEmpty) {
selectedEvent.value = events.first;
selectedDate.value = events.first.startDatetime;
}
}
Get.putAsync(() => ApiService().init());
}catch(e){
} catch(e) {
print('Error initializing data: $e');
Get.snackbar('Error', 'Failed to load initial data');
} finally {
isLoading.value = false;
}
}
void initializeEditMode(Entry entry) {
selectedEvent.value = entry.event;
selectedTeam.value = entry.team;
selectedCategory.value = entry.category;
selectedDate.value = entry.date;
}
void updateEvent(Event? value) {
selectedEvent.value = value;
if (value != null) {
// イベント変更時に日付を調整
if (selectedDate.value == null ||
selectedDate.value!.isBefore(value.startDatetime) ||
selectedDate.value!.isAfter(value.endDatetime)) {
selectedDate.value = value.startDatetime;
}
}
}
void updateTeam(Team? value) => selectedTeam.value = value;
void updateCategory(NewCategory? value) => selectedCategory.value = value;
void updateDate(DateTime value) => selectedDate.value = value;
/*
void updateDate(DateTime value){
selectedDate.value = DateFormat('yyyy-MM-dd').format(value!) as DateTime?;
}
*/
void _initializeEntryData() {
if (currentEntry.value != null) {
selectedEvent.value = currentEntry.value!.event;
@ -60,6 +113,7 @@ class EntryController extends GetxController {
entries.assignAll(fetchedEntries);
} catch (e) {
print('Error fetching entries: $e');
Get.snackbar('Error', 'Failed to fetch entries');
}
}
@ -69,6 +123,7 @@ class EntryController extends GetxController {
events.assignAll(fetchedEvents);
} catch (e) {
print('Error fetching events: $e');
Get.snackbar('Error', 'Failed to fetch events');
}
}
@ -78,6 +133,7 @@ class EntryController extends GetxController {
teams.assignAll(fetchedTeams);
} catch (e) {
print('Error fetching teams: $e');
Get.snackbar('Error', 'Failed to fetch team');
}
}
@ -87,6 +143,7 @@ class EntryController extends GetxController {
categories.assignAll(fetchedCategories);
} catch (e) {
print('Error fetching categories: $e');
Get.snackbar('Error', 'Failed to fetch categories');
}
}
@ -143,10 +200,6 @@ class EntryController extends GetxController {
}
}
void updateEvent(Event? value) => selectedEvent.value = value;
void updateTeam(Team? value) => selectedTeam.value = value;
void updateCategory(NewCategory? value) => selectedCategory.value = value;
void updateDate(DateTime value) => selectedDate.value = value;
bool isOwner() {
// Implement logic to check if the current user is the owner of the entry

View File

@ -3,6 +3,10 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rogapp/pages/entry/entry_controller.dart';
import 'package:rogapp/model/event.dart';
import 'package:rogapp/model/category.dart';
import 'package:rogapp/model/team.dart';
import 'package:intl/intl.dart';
class EntryDetailPage extends GetView<EntryController> {
@override
@ -11,52 +15,121 @@ class EntryDetailPage extends GetView<EntryController> {
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: Padding(
padding: EdgeInsets.all(16.0),
child: Obx(() => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DropdownButtonFormField(
decoration: InputDecoration(labelText: 'イベント'),
value: controller.selectedEvent.value,
items: controller.events.map((event) => DropdownMenuItem(
value: event,
child: Text(event.eventName),
)).toList(),
onChanged: (value) => controller.updateEvent(value),
body: Obx(() {
if (controller.isLoading.value) {
return Center(child: CircularProgressIndicator());
}
return Padding(
padding: 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,
),
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,
),
SizedBox(height: 16),
_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,
),
SizedBox(height: 16),
ListTile(
title: Text('日付'),
subtitle: Text(
controller.selectedDate.value != null
? DateFormat('yyyy-MM-dd').format(controller.selectedDate.value!)
: '日付を選択してください',
),
onTap: () async {
if (controller.selectedEvent.value == null) {
Get.snackbar('Error', 'Please select an event first');
return;
}
final DateTime? picked = await showDatePicker(
context: context,
initialDate: controller.selectedDate.value ?? controller.selectedEvent.value!.startDatetime,
firstDate: controller.selectedEvent.value!.startDatetime,
lastDate: controller.selectedEvent.value!.endDatetime,
);
if (picked != null) {
controller.updateDate(picked);
}
},
),
SizedBox(height: 32),
ElevatedButton(
child: Text(mode == 'new' ? 'エントリーを作成' : 'エントリーを更新'),
onPressed: () {
if (mode == 'new') {
controller.createEntry();
} else {
controller.updateEntry();
}
},
),
if (mode == 'edit' && controller.isOwner())
ElevatedButton(
child: Text('エントリーを削除'),
onPressed: () => controller.deleteEntry(),
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
),
],
),
DropdownButtonFormField(
decoration: InputDecoration(labelText: 'チーム'),
value: controller.selectedTeam.value,
items: controller.teams.map((team) => DropdownMenuItem(
value: team,
child: Text(team.teamName),
)).toList(),
onChanged: (value) => controller.updateTeam(value),
),
DropdownButtonFormField(
decoration: InputDecoration(labelText: 'カテゴリ'),
value: controller.selectedCategory.value,
items: controller.categories.map((category) => DropdownMenuItem(
value: category,
child: Text(category.categoryName),
)).toList(),
onChanged: (value) => controller.updateCategory(value),
),
// 日付選択ウィジェットを追加
if (mode == 'edit' && controller.isOwner())
ElevatedButton(
child: Text('エントリーを削除'),
onPressed: () => controller.deleteEntry(),
),
],
),
),
)
),
);
}),
);
}
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,
);
}
}