チームまでは表示できた。表示と更新及びメンバー編集不可。エントリー以降も表示不可。
This commit is contained in:
@ -206,6 +206,22 @@ class DrawerPage extends StatelessWidget {
|
||||
width: 0,
|
||||
height: 0,
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.group),
|
||||
title: Text('チーム管理'),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Get.toNamed(AppPages.TEAM_LIST);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.event),
|
||||
title: Text('エントリー管理'),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Get.toNamed(AppPages.ENTRY_LIST);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.privacy_tip),
|
||||
title: Text("privacy".tr),
|
||||
|
||||
12
lib/pages/entry/entry_binding.dart
Normal file
12
lib/pages/entry/entry_binding.dart
Normal file
@ -0,0 +1,12 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/entry/entry_controller.dart';
|
||||
import 'package:rogapp/pages/team/member_controller.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class EntryBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut<ApiService>(() => ApiService());
|
||||
Get.lazyPut<EntryController>(() => EntryController());
|
||||
}
|
||||
}
|
||||
155
lib/pages/entry/entry_controller.dart
Normal file
155
lib/pages/entry/entry_controller.dart
Normal file
@ -0,0 +1,155 @@
|
||||
// lib/entry/entry_controller.dart
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/entry.dart';
|
||||
import 'package:rogapp/model/event.dart';
|
||||
import 'package:rogapp/model/team.dart';
|
||||
import 'package:rogapp/model/category.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class EntryController extends GetxController {
|
||||
late final ApiService _apiService;
|
||||
|
||||
final entries = <Entry>[].obs;
|
||||
final events = <Event>[].obs;
|
||||
final teams = <Team>[].obs;
|
||||
final categories = <NewCategory>[].obs;
|
||||
|
||||
final selectedEvent = Rx<Event?>(null);
|
||||
final selectedTeam = Rx<Team?>(null);
|
||||
final selectedCategory = Rx<NewCategory?>(null);
|
||||
final selectedDate = Rx<DateTime?>(null);
|
||||
|
||||
final currentEntry = Rx<Entry?>(null);
|
||||
|
||||
@override
|
||||
void onInit() async{
|
||||
super.onInit();
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
_apiService = Get.find<ApiService>();
|
||||
|
||||
try {
|
||||
await Future.wait([
|
||||
fetchEntries(),
|
||||
fetchEvents(),
|
||||
fetchTeams(),
|
||||
fetchCategories(),
|
||||
]);
|
||||
if (Get.arguments != null && Get.arguments['entry'] != null) {
|
||||
currentEntry.value = Get.arguments['entry'];
|
||||
_initializeEntryData();
|
||||
}
|
||||
Get.putAsync(() => ApiService().init());
|
||||
}catch(e){
|
||||
print('Error initializing data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void _initializeEntryData() {
|
||||
if (currentEntry.value != null) {
|
||||
selectedEvent.value = currentEntry.value!.event;
|
||||
selectedTeam.value = currentEntry.value!.team;
|
||||
selectedCategory.value = currentEntry.value!.category;
|
||||
selectedDate.value = currentEntry.value!.date;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchEntries() async {
|
||||
try {
|
||||
final fetchedEntries = await _apiService.getEntries();
|
||||
entries.assignAll(fetchedEntries);
|
||||
} catch (e) {
|
||||
print('Error fetching entries: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchEvents() async {
|
||||
try {
|
||||
final fetchedEvents = await _apiService.getEvents();
|
||||
events.assignAll(fetchedEvents);
|
||||
} catch (e) {
|
||||
print('Error fetching events: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchTeams() async {
|
||||
try {
|
||||
final fetchedTeams = await _apiService.getTeams();
|
||||
teams.assignAll(fetchedTeams);
|
||||
} catch (e) {
|
||||
print('Error fetching teams: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchCategories() async {
|
||||
try {
|
||||
final fetchedCategories = await _apiService.getCategories();
|
||||
categories.assignAll(fetchedCategories);
|
||||
} catch (e) {
|
||||
print('Error fetching categories: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> createEntry() async {
|
||||
if (selectedEvent.value == null || selectedTeam.value == null ||
|
||||
selectedCategory.value == null || selectedDate.value == null) {
|
||||
Get.snackbar('Error', 'Please fill all fields');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final newEntry = await _apiService.createEntry(
|
||||
selectedTeam.value!.id,
|
||||
selectedEvent.value!.id,
|
||||
selectedCategory.value!.id,
|
||||
selectedDate.value!,
|
||||
);
|
||||
entries.add(newEntry);
|
||||
Get.back();
|
||||
} catch (e) {
|
||||
print('Error creating entry: $e');
|
||||
Get.snackbar('Error', 'Failed to create entry');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateEntry() async {
|
||||
if (currentEntry.value == null) return;
|
||||
try {
|
||||
final updatedEntry = await _apiService.updateEntry(
|
||||
currentEntry.value!.id,
|
||||
selectedEvent.value!.id,
|
||||
selectedCategory.value!.id,
|
||||
selectedDate.value!,
|
||||
);
|
||||
final index = entries.indexWhere((entry) => entry.id == updatedEntry.id);
|
||||
if (index != -1) {
|
||||
entries[index] = updatedEntry;
|
||||
}
|
||||
Get.back();
|
||||
} catch (e) {
|
||||
print('Error updating entry: $e');
|
||||
Get.snackbar('Error', 'Failed to update entry');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteEntry() async {
|
||||
if (currentEntry.value == null) return;
|
||||
try {
|
||||
await _apiService.deleteEntry(currentEntry.value!.id);
|
||||
entries.removeWhere((entry) => entry.id == currentEntry.value!.id);
|
||||
Get.back();
|
||||
} catch (e) {
|
||||
print('Error deleting entry: $e');
|
||||
Get.snackbar('Error', 'Failed to delete entry');
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
return true; // Placeholder
|
||||
}
|
||||
}
|
||||
62
lib/pages/entry/entry_detail_page.dart
Normal file
62
lib/pages/entry/entry_detail_page.dart
Normal file
@ -0,0 +1,62 @@
|
||||
// lib/pages/entry/entry_detail_page.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/entry/entry_controller.dart';
|
||||
|
||||
class EntryDetailPage extends GetView<EntryController> {
|
||||
@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'];
|
||||
|
||||
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),
|
||||
),
|
||||
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(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
35
lib/pages/entry/entry_list_page.dart
Normal file
35
lib/pages/entry/entry_list_page.dart
Normal file
@ -0,0 +1,35 @@
|
||||
// lib/pages/entry/entry_list_page.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/entry/entry_controller.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart';
|
||||
|
||||
class EntryListPage extends GetView<EntryController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('エントリー管理'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () => Get.toNamed(AppPages.ENTRY_DETAIL, arguments: {'mode': 'new'}),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Obx(() => ListView.builder(
|
||||
itemCount: controller.entries.length,
|
||||
itemBuilder: (context, index) {
|
||||
final entry = controller.entries[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}),
|
||||
);
|
||||
},
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,8 @@ import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/widgets/debug_widget.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
import '../../main.dart';
|
||||
|
||||
|
||||
@ -190,11 +192,19 @@ class IndexController extends GetxController with WidgetsBindingObserver {
|
||||
WidgetsBinding.instance?.addObserver(this);
|
||||
_startLocationService(); // アプリ起動時にLocationServiceを開始する
|
||||
|
||||
initializeApiService();
|
||||
|
||||
print('IndexController onInit called'); // デバッグ用の出力を追加
|
||||
|
||||
}
|
||||
|
||||
|
||||
Future<void> initializeApiService() async {
|
||||
if (currentUser.isNotEmpty) {
|
||||
// 既にログインしている場合
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
// 必要に応じて追加の初期化処理
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void checkPermission()
|
||||
@ -314,9 +324,9 @@ class IndexController extends GetxController with WidgetsBindingObserver {
|
||||
|
||||
// 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。
|
||||
//
|
||||
void login(String email, String password, BuildContext context) {
|
||||
void login(String email, String password, BuildContext context) async{
|
||||
|
||||
AuthService.login(email, password).then((value) {
|
||||
AuthService.login(email, password).then((value) async {
|
||||
print("------- logged in user details ######## $value ###### --------");
|
||||
if (value.isNotEmpty) {
|
||||
logManager.addOperationLog("User logged in : ${value}.");
|
||||
@ -324,6 +334,11 @@ class IndexController extends GetxController with WidgetsBindingObserver {
|
||||
// Navigator.pop(context);
|
||||
print("--------- user details login ----- $value");
|
||||
changeUser(value);
|
||||
|
||||
// ログイン成功後、api_serviceを初期化
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
|
||||
|
||||
} else {
|
||||
logManager.addOperationLog("User failed login : ${email} , ${password}.");
|
||||
isLoading.value = false;
|
||||
|
||||
11
lib/pages/team/member_binding.dart
Normal file
11
lib/pages/team/member_binding.dart
Normal file
@ -0,0 +1,11 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/team/member_controller.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class MemberBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut<ApiService>(() => ApiService());
|
||||
Get.lazyPut<MemberController>(() => MemberController());
|
||||
}
|
||||
}
|
||||
105
lib/pages/team/member_controller.dart
Normal file
105
lib/pages/team/member_controller.dart
Normal file
@ -0,0 +1,105 @@
|
||||
// lib/controllers/member_controller.dart
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/user.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class MemberController extends GetxController {
|
||||
late final ApiService _apiService;
|
||||
|
||||
final int teamId = 0;
|
||||
final member = Rx<User?>(null);
|
||||
final email = ''.obs;
|
||||
final firstname = ''.obs;
|
||||
final lastname = ''.obs;
|
||||
final dateOfBirth = Rx<DateTime?>(null);
|
||||
|
||||
@override
|
||||
void onInit() async{
|
||||
super.onInit();
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
_apiService = Get.find<ApiService>();
|
||||
if (Get.arguments != null && Get.arguments['member'] != null) {
|
||||
member.value = Get.arguments['member'];
|
||||
_initializeMemberData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _initializeMemberData() {
|
||||
if (member.value != null) {
|
||||
email.value = member.value!.email ?? '';
|
||||
firstname.value = member.value!.firstname ?? '';
|
||||
lastname.value = member.value!.lastname ?? '';
|
||||
dateOfBirth.value = member.value!.dateOfBirth;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> createMember(int teamId) async {
|
||||
try {
|
||||
final newMember = await _apiService.createTeamMember(
|
||||
teamId,
|
||||
email.value,
|
||||
firstname.value,
|
||||
lastname.value,
|
||||
dateOfBirth.value,
|
||||
);
|
||||
member.value = newMember;
|
||||
} catch (e) {
|
||||
print('Error creating member: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateMember() async {
|
||||
if (member.value == null) return;
|
||||
int? memberId = member.value?.id;
|
||||
try {
|
||||
final updatedMember = await _apiService.updateTeamMember(
|
||||
teamId,
|
||||
memberId!,
|
||||
firstname.value,
|
||||
lastname.value,
|
||||
dateOfBirth.value,
|
||||
);
|
||||
member.value = updatedMember;
|
||||
} catch (e) {
|
||||
print('Error updating member: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteMember() async {
|
||||
if (member.value == null) return;
|
||||
int? memberId = member.value?.id;
|
||||
try {
|
||||
await _apiService.deleteTeamMember(teamId,memberId!);
|
||||
member.value = null;
|
||||
Get.back();
|
||||
} catch (e) {
|
||||
print('Error deleting member: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> resendInvitation() async {
|
||||
if (member.value == null || member.value!.email == null) return;
|
||||
int? memberId = member.value?.id;
|
||||
try {
|
||||
await _apiService.resendMemberInvitation(memberId!);
|
||||
Get.snackbar('Success', 'Invitation resent successfully');
|
||||
} catch (e) {
|
||||
print('Error resending invitation: $e');
|
||||
Get.snackbar('Error', 'Failed to resend invitation');
|
||||
}
|
||||
}
|
||||
|
||||
void updateEmail(String value) => email.value = value;
|
||||
void updateFirstname(String value) => firstname.value = value;
|
||||
void updateLastname(String value) => lastname.value = value;
|
||||
void updateDateOfBirth(DateTime value) => dateOfBirth.value = value;
|
||||
|
||||
String getMemberStatus() {
|
||||
if (member.value == null) return '';
|
||||
if (member.value!.email == null) return '未登録';
|
||||
if (member.value!.isActive) return '承認済';
|
||||
return '招待中';
|
||||
}
|
||||
}
|
||||
55
lib/pages/team/member_detail_page.dart
Normal file
55
lib/pages/team/member_detail_page.dart
Normal file
@ -0,0 +1,55 @@
|
||||
// lib/pages/team/member_detail_page.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/team/member_controller.dart';
|
||||
|
||||
class MemberDetailPage extends GetView<MemberController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mode = Get.arguments['mode'];
|
||||
final member = Get.arguments['member'];
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(mode == 'new' ? 'メンバー追加' : 'メンバー詳細'),
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (mode == 'edit' && member.email != null)
|
||||
Text('Email: ${member.email}'),
|
||||
if (mode == 'new' || (mode == 'edit' && member.email == null))
|
||||
TextField(
|
||||
decoration: InputDecoration(labelText: 'Email'),
|
||||
onChanged: (value) => controller.updateEmail(value),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(labelText: '姓'),
|
||||
onChanged: (value) => controller.updateLastname(value),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(labelText: '名'),
|
||||
onChanged: (value) => controller.updateFirstname(value),
|
||||
),
|
||||
// 誕生日選択ウィジェットを追加
|
||||
if (mode == 'edit')
|
||||
Text('ステータス: ${controller.getMemberStatus()}'),
|
||||
if (mode == 'edit' && controller.getMemberStatus() == '招待中')
|
||||
ElevatedButton(
|
||||
child: Text('招待メールを再送信'),
|
||||
onPressed: () => controller.resendInvitation(),
|
||||
),
|
||||
if (mode == 'edit')
|
||||
ElevatedButton(
|
||||
child: Text('メンバーから除外'),
|
||||
onPressed: () => controller.deleteMember(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
11
lib/pages/team/team_binding.dart
Normal file
11
lib/pages/team/team_binding.dart
Normal file
@ -0,0 +1,11 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/team/team_controller.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class TeamBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut<ApiService>(() => ApiService());
|
||||
Get.lazyPut<TeamController>(() => TeamController());
|
||||
}
|
||||
}
|
||||
117
lib/pages/team/team_controller.dart
Normal file
117
lib/pages/team/team_controller.dart
Normal file
@ -0,0 +1,117 @@
|
||||
// lib/controllers/team_controller.dart
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/team.dart';
|
||||
import 'package:rogapp/model/category.dart';
|
||||
import 'package:rogapp/model/user.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class TeamController extends GetxController {
|
||||
late final ApiService _apiService;
|
||||
|
||||
|
||||
final teams = <Team>[].obs;
|
||||
final categories = <NewCategory>[].obs;
|
||||
final teamMembers = <User>[].obs;
|
||||
|
||||
final selectedCategory = Rx<NewCategory?>(null);
|
||||
final currentUser = Rx<User?>(null);
|
||||
|
||||
final isLoading = true.obs;
|
||||
final error = RxString('');
|
||||
|
||||
@override
|
||||
void onInit() async{
|
||||
super.onInit();
|
||||
try {
|
||||
//await Get.putAsync(() => ApiService().init());
|
||||
_apiService = Get.find<ApiService>();
|
||||
|
||||
await Future.wait([
|
||||
fetchTeams(),
|
||||
fetchCategories(),
|
||||
getCurrentUser(),
|
||||
]);
|
||||
|
||||
}catch(e){
|
||||
print("Team Controller error: $e");
|
||||
}finally{
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Future<void> fetchTeams() async {
|
||||
try {
|
||||
final fetchedTeams = await _apiService.getTeams();
|
||||
teams.assignAll(fetchedTeams);
|
||||
} catch (e) {
|
||||
print('Error fetching teams: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchCategories() async {
|
||||
try {
|
||||
final fetchedCategories = await _apiService.getCategories();
|
||||
categories.assignAll(fetchedCategories);
|
||||
} catch (e) {
|
||||
print('Error fetching categories: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCurrentUser() async {
|
||||
try {
|
||||
final user = await _apiService.getCurrentUser();
|
||||
currentUser.value = user;
|
||||
} catch (e) {
|
||||
print('Error getting current user: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> createTeam(String teamName, int categoryId) async {
|
||||
try {
|
||||
final newTeam = await _apiService.createTeam(teamName, categoryId);
|
||||
teams.add(newTeam);
|
||||
} catch (e) {
|
||||
print('Error creating team: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateTeam(int teamId, String teamName, int categoryId) async {
|
||||
try {
|
||||
final updatedTeam = await _apiService.updateTeam(teamId, teamName, categoryId);
|
||||
final index = teams.indexWhere((team) => team.id == teamId);
|
||||
if (index != -1) {
|
||||
teams[index] = updatedTeam;
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error updating team: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteTeam(int teamId) async {
|
||||
try {
|
||||
await _apiService.deleteTeam(teamId);
|
||||
teams.removeWhere((team) => team.id == teamId);
|
||||
} catch (e) {
|
||||
print('Error deleting team: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchTeamMembers(int teamId) async {
|
||||
try {
|
||||
final members = await _apiService.getTeamMembers(teamId);
|
||||
teamMembers.assignAll(members);
|
||||
} catch (e) {
|
||||
print('Error fetching team members: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void updateTeamName(String value) {
|
||||
// Update local state
|
||||
}
|
||||
|
||||
void updateCategory(NewCategory? value) {
|
||||
selectedCategory.value = value;
|
||||
}
|
||||
}
|
||||
69
lib/pages/team/team_detail_page.dart
Normal file
69
lib/pages/team/team_detail_page.dart
Normal file
@ -0,0 +1,69 @@
|
||||
// lib/pages/team/team_detail_page.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/team/team_controller.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class TeamDetailPage extends GetView<TeamController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mode = Get.arguments['mode'];
|
||||
final team = Get.arguments['team'];
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(mode == 'new' ? '新規チーム作成' : 'チーム詳細'),
|
||||
actions: [
|
||||
if (mode == 'edit')
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () => Get.toNamed(AppPages.MEMBER_DETAIL, arguments: {'mode': 'new', 'teamId': team.id}),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextField(
|
||||
decoration: InputDecoration(labelText: 'チーム名'),
|
||||
onChanged: (value) => controller.updateTeamName(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')
|
||||
Text('ゼッケン番号: ${team.zekkenNumber}'),
|
||||
Obx(() {
|
||||
final currentUser = controller.currentUser.value;
|
||||
return Text('所有者: ${currentUser?.email ?? "未設定"}');
|
||||
}),
|
||||
SizedBox(height: 20),
|
||||
Text('メンバーリスト', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
Expanded(
|
||||
child: Obx(() => ListView.builder(
|
||||
itemCount: controller.teamMembers.length,
|
||||
itemBuilder: (context, index) {
|
||||
final member = controller.teamMembers[index];
|
||||
return ListTile(
|
||||
title: Text('${member.lastname}, ${member.firstname}'),
|
||||
onTap: () => Get.toNamed(AppPages.MEMBER_DETAIL, arguments: {'mode': 'edit', 'member': member}),
|
||||
);
|
||||
},
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
54
lib/pages/team/team_list_page.dart
Normal file
54
lib/pages/team/team_list_page.dart
Normal file
@ -0,0 +1,54 @@
|
||||
// lib/pages/team/team_list_page.dart
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/pages/team/team_controller.dart';
|
||||
import 'package:rogapp/routes/app_pages.dart';
|
||||
import 'package:rogapp/services/api_service.dart';
|
||||
|
||||
class TeamListPage extends GetView<TeamController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('チーム管理'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () => Get.toNamed(AppPages.TEAM_DETAIL, arguments: {'mode': 'new'}),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: FutureBuilder(
|
||||
future: Get.putAsync(() => ApiService().init()),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
return Obx(() {
|
||||
if (controller.isLoading.value) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
} else if (controller.error.value.isNotEmpty) {
|
||||
return Center(child: Text('エラー: ${controller.error.value}'));
|
||||
} else {
|
||||
return ListView.builder(
|
||||
itemCount: controller.teams.length,
|
||||
itemBuilder: (context, index) {
|
||||
final team = controller.teams[index];
|
||||
return ListTile(
|
||||
title: Text(team.teamName),
|
||||
subtitle: Text('${team.category.categoryName} - ${team.zekkenNumber}'),
|
||||
trailing: Text('メンバー: (メンバー数表示予定)'),
|
||||
onTap: () => Get.toNamed(AppPages.TEAM_DETAIL, arguments: {'mode': 'edit', 'team': team}),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user