2024-07-27 09:46:00 +09:00
|
|
|
|
// lib/controllers/team_controller.dart
|
2024-07-28 08:39:10 +09:00
|
|
|
|
import 'dart:convert';
|
2024-08-01 20:08:12 +09:00
|
|
|
|
import 'package:flutter/material.dart';
|
2024-07-27 09:46:00 +09:00
|
|
|
|
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;
|
|
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
|
2024-07-27 09:46:00 +09:00
|
|
|
|
final selectedCategory = Rx<NewCategory?>(null);
|
2024-07-28 08:39:10 +09:00
|
|
|
|
final selectedTeam = Rx<Team?>(null);
|
2024-07-27 09:46:00 +09:00
|
|
|
|
final currentUser = Rx<User?>(null);
|
|
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
final teamName = ''.obs;
|
|
|
|
|
|
final isLoading = false.obs;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
final error = RxString('');
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
void onInit() async{
|
|
|
|
|
|
super.onInit();
|
|
|
|
|
|
try {
|
|
|
|
|
|
_apiService = Get.find<ApiService>();
|
2024-08-01 20:08:12 +09:00
|
|
|
|
isLoading.value = true;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
await fetchCategories();
|
|
|
|
|
|
await Future.wait([
|
2024-07-27 09:46:00 +09:00
|
|
|
|
fetchTeams(),
|
|
|
|
|
|
getCurrentUser(),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
print("selectedCategory=$selectedCategory.value");
|
|
|
|
|
|
// カテゴリが取得できたら、最初のカテゴリを選択状態にする
|
|
|
|
|
|
if (categories.isNotEmpty && selectedCategory.value == null) {
|
|
|
|
|
|
selectedCategory.value = categories.first;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}catch(e){
|
|
|
|
|
|
print("Team Controller error: $e");
|
2024-07-28 08:39:10 +09:00
|
|
|
|
error.value = e.toString();
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}finally{
|
|
|
|
|
|
isLoading.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
void setSelectedTeam(Team team) {
|
|
|
|
|
|
selectedTeam.value = team;
|
|
|
|
|
|
teamName.value = team.teamName;
|
|
|
|
|
|
if (categories.isNotEmpty) {
|
|
|
|
|
|
selectedCategory.value = categories.firstWhere(
|
|
|
|
|
|
(category) => category.id == team.category.id,
|
|
|
|
|
|
orElse: () => categories.first,
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// カテゴリリストが空の場合、teamのカテゴリをそのまま使用
|
|
|
|
|
|
selectedCategory.value = team.category;
|
|
|
|
|
|
}
|
|
|
|
|
|
fetchTeamMembers(team.id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void resetForm() {
|
|
|
|
|
|
selectedTeam.value = null;
|
|
|
|
|
|
teamName.value = '';
|
2024-08-01 20:08:12 +09:00
|
|
|
|
if (categories.isNotEmpty) {
|
|
|
|
|
|
selectedCategory.value = categories.first;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
selectedCategory.value = null;
|
|
|
|
|
|
// カテゴリが空の場合、エラーメッセージをセット
|
|
|
|
|
|
error.value = 'カテゴリデータが取得できませんでした。';
|
|
|
|
|
|
} teamMembers.clear();
|
2024-07-28 08:39:10 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-29 08:41:28 +09:00
|
|
|
|
void cleanupForNavigation() {
|
|
|
|
|
|
selectedTeam.value = null;
|
|
|
|
|
|
teamName.value = '';
|
|
|
|
|
|
selectedCategory.value = categories.isNotEmpty ? categories.first : null;
|
|
|
|
|
|
teamMembers.clear();
|
|
|
|
|
|
//teamMembersはクリアしない
|
|
|
|
|
|
// 必要に応じて他のクリーンアップ処理を追加
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-27 09:46:00 +09:00
|
|
|
|
Future<void> fetchTeams() async {
|
|
|
|
|
|
try {
|
2024-07-28 08:39:10 +09:00
|
|
|
|
isLoading.value = true;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
final fetchedTeams = await _apiService.getTeams();
|
|
|
|
|
|
teams.assignAll(fetchedTeams);
|
|
|
|
|
|
} catch (e) {
|
2024-07-28 08:39:10 +09:00
|
|
|
|
error.value = 'チームの取得に失敗しました: $e';
|
2024-07-27 09:46:00 +09:00
|
|
|
|
print('Error fetching teams: $e');
|
2024-07-28 08:39:10 +09:00
|
|
|
|
} finally {
|
|
|
|
|
|
isLoading.value = false;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-01 20:08:12 +09:00
|
|
|
|
bool checkIfUserHasEntryData(){
|
|
|
|
|
|
if (teams.isEmpty) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}else {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-27 09:46:00 +09:00
|
|
|
|
Future<void> fetchCategories() async {
|
|
|
|
|
|
try {
|
|
|
|
|
|
final fetchedCategories = await _apiService.getCategories();
|
|
|
|
|
|
categories.assignAll(fetchedCategories);
|
2024-07-28 08:39:10 +09:00
|
|
|
|
print("Fetched categories: ${categories.length}"); // デバッグ用
|
|
|
|
|
|
|
2024-07-27 09:46:00 +09:00
|
|
|
|
} 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');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
Future<Team> createTeam(String teamName, int categoryId) async {
|
|
|
|
|
|
final newTeam = await _apiService.createTeam(teamName, categoryId);
|
2024-08-01 20:08:12 +09:00
|
|
|
|
|
|
|
|
|
|
// 自分自身をメンバーとして自動登録
|
|
|
|
|
|
await _apiService.createTeamMember(
|
|
|
|
|
|
newTeam.id,
|
|
|
|
|
|
currentUser.value?.email,
|
|
|
|
|
|
currentUser.value!.firstname,
|
|
|
|
|
|
currentUser.value!.lastname,
|
|
|
|
|
|
currentUser.value?.dateOfBirth,
|
|
|
|
|
|
currentUser.value?.female,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
return newTeam;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
Future<Team> updateTeam(int teamId, String teamName, int categoryId) async {
|
|
|
|
|
|
// APIサービスを使用してチームを更新
|
|
|
|
|
|
final updatedTeam = await _apiService.updateTeam(teamId, teamName, categoryId);
|
|
|
|
|
|
return updatedTeam;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> deleteTeam(int teamId) async {
|
2024-08-01 20:08:12 +09:00
|
|
|
|
bool confirmDelete = await Get.dialog(
|
|
|
|
|
|
AlertDialog(
|
|
|
|
|
|
title: Text('チーム削除の確認'),
|
|
|
|
|
|
content: Text('このチームとそのすべてのメンバーを削除しますか?この操作は取り消せません。'),
|
|
|
|
|
|
actions: [
|
|
|
|
|
|
TextButton(
|
|
|
|
|
|
child: Text('キャンセル'),
|
|
|
|
|
|
onPressed: () => Get.back(result: false),
|
|
|
|
|
|
),
|
|
|
|
|
|
TextButton(
|
|
|
|
|
|
child: Text('削除'),
|
|
|
|
|
|
onPressed: () => Get.back(result: true),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
) ?? false;
|
|
|
|
|
|
|
|
|
|
|
|
if (confirmDelete) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// まず、チームのメンバーを全て削除
|
|
|
|
|
|
await _apiService.deleteAllTeamMembers(teamId);
|
|
|
|
|
|
|
|
|
|
|
|
// その後、チームを削除
|
|
|
|
|
|
await _apiService.deleteTeam(teamId);
|
|
|
|
|
|
|
|
|
|
|
|
// ローカルのチームリストを更新
|
|
|
|
|
|
teams.removeWhere((team) => team.id == teamId);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Get.snackbar(
|
|
|
|
|
|
'成功',
|
|
|
|
|
|
'チームとそのメンバーが削除されました',
|
|
|
|
|
|
backgroundColor: Colors.green,
|
|
|
|
|
|
colorText: Colors.white,
|
|
|
|
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
|
|
|
|
);
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// チームリスト画面に戻る
|
|
|
|
|
|
Get.back();
|
|
|
|
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
print('Error deleting team and members: $e');
|
|
|
|
|
|
Get.snackbar('エラー', 'チームとメンバーの削除に失敗しました');
|
|
|
|
|
|
}
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> fetchTeamMembers(int teamId) async {
|
|
|
|
|
|
try {
|
2024-07-29 08:41:28 +09:00
|
|
|
|
isLoading.value = true;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
final members = await _apiService.getTeamMembers(teamId);
|
|
|
|
|
|
teamMembers.assignAll(members);
|
|
|
|
|
|
} catch (e) {
|
2024-07-29 08:41:28 +09:00
|
|
|
|
error.value = 'メンバーの取得に失敗しました: $e';
|
2024-07-27 09:46:00 +09:00
|
|
|
|
print('Error fetching team members: $e');
|
2024-07-29 08:41:28 +09:00
|
|
|
|
} finally {
|
|
|
|
|
|
isLoading.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> updateMember(teamId, User member) async {
|
|
|
|
|
|
try {
|
|
|
|
|
|
isLoading.value = true;
|
|
|
|
|
|
await _apiService.updateTeamMember(teamId,member.id, member.firstname, member.lastname, member.dateOfBirth, member.female);
|
|
|
|
|
|
await fetchTeamMembers(selectedTeam.value!.id);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
error.value = 'メンバーの更新に失敗しました: $e';
|
|
|
|
|
|
print('Error updating member: $e');
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
isLoading.value = false;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-29 08:41:28 +09:00
|
|
|
|
Future<void> deleteMember(int memberId, int teamId) async {
|
|
|
|
|
|
try {
|
|
|
|
|
|
isLoading.value = true;
|
|
|
|
|
|
await _apiService.deleteTeamMember(teamId,memberId);
|
|
|
|
|
|
await fetchTeamMembers(teamId);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
error.value = 'メンバーの削除に失敗しました: $e';
|
|
|
|
|
|
print('Error deleting member: $e');
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
isLoading.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Future<void> addMember(User member, int teamId) async {
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// isLoading.value = true;
|
|
|
|
|
|
// await _apiService.createTeamMember(teamId, member.email, member.firstname, member.lastname, member.dateOfBirth);
|
|
|
|
|
|
// await fetchTeamMembers(teamId);
|
|
|
|
|
|
// } catch (e) {
|
|
|
|
|
|
// error.value = 'メンバーの追加に失敗しました: $e';
|
|
|
|
|
|
// print('Error adding member: $e');
|
|
|
|
|
|
// } finally {
|
|
|
|
|
|
// isLoading.value = false;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-27 09:46:00 +09:00
|
|
|
|
void updateTeamName(String value) {
|
2024-07-28 08:39:10 +09:00
|
|
|
|
teamName.value = value;
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void updateCategory(NewCategory? value) {
|
2024-07-28 08:39:10 +09:00
|
|
|
|
if (value != null) {
|
2024-07-29 08:41:28 +09:00
|
|
|
|
selectedCategory.value = value;
|
2024-07-28 08:39:10 +09:00
|
|
|
|
}
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|
2024-07-29 08:41:28 +09:00
|
|
|
|
//void updateCategory(NewCategory? value) {
|
|
|
|
|
|
// if (value != null) {
|
|
|
|
|
|
// selectedCategory.value = categories.firstWhere(
|
|
|
|
|
|
// (category) => category.id == value.id,
|
|
|
|
|
|
// orElse: () => value,
|
|
|
|
|
|
// );
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
2024-07-28 08:39:10 +09:00
|
|
|
|
|
|
|
|
|
|
Future<void> saveTeam() async {
|
|
|
|
|
|
try {
|
|
|
|
|
|
isLoading.value = true;
|
|
|
|
|
|
if (selectedCategory.value == null) {
|
|
|
|
|
|
throw Exception('カテゴリを選択してください');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (selectedTeam.value == null) {
|
|
|
|
|
|
await createTeam(teamName.value, selectedCategory.value!.id);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
await updateTeam(selectedTeam.value!.id, teamName.value, selectedCategory.value!.id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// サーバーから最新のデータを再取得
|
|
|
|
|
|
await fetchTeams();
|
|
|
|
|
|
update(); // UIを強制的に更新
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
error.value = 'チームの保存に失敗しました: $e';
|
2024-07-29 08:41:28 +09:00
|
|
|
|
|
2024-07-28 08:39:10 +09:00
|
|
|
|
} finally {
|
|
|
|
|
|
isLoading.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> deleteSelectedTeam() async {
|
|
|
|
|
|
if (selectedTeam.value != null) {
|
|
|
|
|
|
await deleteTeam(selectedTeam.value!.id);
|
|
|
|
|
|
selectedTeam.value = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-01 20:08:12 +09:00
|
|
|
|
List<NewCategory> getFilteredCategories() {
|
|
|
|
|
|
//List<User> teamMembers = getCurrentTeamMembers();
|
|
|
|
|
|
return categories.where((category) {
|
|
|
|
|
|
return isCategoryValid(category, teamMembers);
|
|
|
|
|
|
}).toList();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isCategoryValid(NewCategory category, List<User> teamMembers) {
|
|
|
|
|
|
int maleCount = teamMembers.where((member) => !member.female).length;
|
|
|
|
|
|
int femaleCount = teamMembers.where((member) => member.female).length;
|
|
|
|
|
|
int totalCount = teamMembers.length;
|
|
|
|
|
|
|
|
|
|
|
|
bool isValidGender = category.female ? (femaleCount == totalCount) : true;
|
|
|
|
|
|
bool isValidMemberCount = totalCount == category.numOfMember;
|
|
|
|
|
|
bool isValidFamily = category.family ? areAllMembersFamily(teamMembers) : true;
|
|
|
|
|
|
|
|
|
|
|
|
return isValidGender && isValidMemberCount && isValidFamily;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool areAllMembersFamily(List<User> teamMembers) {
|
|
|
|
|
|
// 家族かどうかを判断するロジック(例: 同じ姓を持つメンバーが2人以上いる場合は家族とみなす)
|
|
|
|
|
|
Set<String> familyNames = teamMembers.map((member) => member.lastname).toSet();
|
|
|
|
|
|
return familyNames.length < teamMembers.length;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-27 09:46:00 +09:00
|
|
|
|
}
|