// lib/controllers/member_controller.dart import 'package:get/get.dart'; import 'package:rogapp/model/user.dart'; import 'package:rogapp/pages/team/team_controller.dart'; import 'package:rogapp/services/api_service.dart'; class MemberController extends GetxController { late final ApiService _apiService; final selectedMember = Rx(null); int teamId = 0; final member = Rx(null); final email = ''.obs; final firstname = ''.obs; final lastname = ''.obs; final female = false.obs; final dateOfBirth = Rx(null); final isLoading = false.obs; // isLoadingプロパティを追加 final isActive = false.obs; //MemberController(this._apiService); @override void onInit() { super.onInit(); _apiService = Get.find(); ever(member, (_) => _initializeMemberData()); loadInitialData(); } bool get isDummyEmail => email.value.startsWith('dummy_'); bool get isApproved => !email.value.startsWith('dummy_') && member.value?.isActive == true; Future loadInitialData() async { try { isLoading.value = true; if (Get.arguments != null) { if (Get.arguments['member'] != null) { member.value = Get.arguments['member']; } if (Get.arguments['teamId'] != null) { teamId = Get.arguments['teamId']; } } // 他の必要な初期データの取得をここで行う } catch (e) { print('Error loading initial data: $e'); } finally { isLoading.value = false; } } 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; } } void setSelectedMember(User member) { this.member.value = member; email.value = member.email ?? ''; firstname.value = member.firstname ?? ''; lastname.value = member.lastname ?? ''; dateOfBirth.value = member.dateOfBirth; female.value = member.female ?? false; isActive.value = member.isActive ?? false; } bool _validateInputs() { if (email.value.isNotEmpty && !isDummyEmail) { return true; // Emailのみの場合は有効 } if (firstname.value.isEmpty || lastname.value.isEmpty || dateOfBirth.value == null || female.value == null) { Get.snackbar('エラー', 'Emailが空の場合、姓名と生年月日及び性別は必須です', snackPosition: SnackPosition.BOTTOM); return false; } return true; } void updateFirstName(String value) { firstname.value = value; } void updateLastName(String value) { lastname.value = value; } Future saveMember() async { if (!_validateInputs()) return false; try { isLoading.value = true; User updatedMember; if (member.value == null || member.value!.id == null) { // 新規メンバー作成 updatedMember = await _apiService.createTeamMember( teamId, isDummyEmail ? null : email.value, // dummy_メールの場合はnullを送信 firstname.value, lastname.value, dateOfBirth.value, female.value, ); } else { // 既存メンバー更新 updatedMember = await _apiService.updateTeamMember( teamId, member.value!.id!, firstname.value, lastname.value, dateOfBirth.value, female.value, ); } member.value = updatedMember; Get.snackbar('成功', 'メンバーが保存されました', snackPosition: SnackPosition.BOTTOM); return true; } catch (e) { print('Error saving member: $e'); Get.snackbar('エラー', 'メンバーの保存に失敗しました: ${e.toString()}', snackPosition: SnackPosition.BOTTOM); return false; } finally { isLoading.value = false; } } String getDisplayName() { if (!isActive.value && !isDummyEmail) { final displayName = email.value.split('@')[0]; return '$displayName(未承認)'; } return '${lastname.value} ${firstname.value}'.trim(); } Future 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, female.value, ); member.value = updatedMember; } catch (e) { print('Error updating member: $e'); } } Future deleteMember() async { if (member.value == null || member.value!.id == null) { Get.snackbar('エラー', 'メンバー情報が不正です', snackPosition: SnackPosition.BOTTOM); return; } try { isLoading.value = true; await _apiService.deleteTeamMember(teamId, member.value!.id!); Get.snackbar('成功', 'メンバーが削除されました', snackPosition: SnackPosition.BOTTOM); member.value = null; } catch (e) { print('Error deleting member: $e'); Get.snackbar('エラー', 'メンバーの削除に失敗しました: ${e.toString()}', snackPosition: SnackPosition.BOTTOM); } finally { isLoading.value = false; } } /* Future 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 resendInvitation() async { if (isDummyEmail) { Get.snackbar('エラー', 'ダミーメールアドレスには招待メールを送信できません', snackPosition: SnackPosition.BOTTOM); return; } 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 '招待中'; } int calculateAge() { if (dateOfBirth.value == null) return 0; final today = DateTime.now(); int age = today.year - dateOfBirth.value!.year; if (today.month < dateOfBirth.value!.month || (today.month == dateOfBirth.value!.month && today.day < dateOfBirth.value!.day)) { age--; } return age; } String calculateGrade() { if (dateOfBirth.value == null) return '不明'; final today = DateTime.now(); final birthDate = dateOfBirth.value!; // 今年の4月1日 final thisYearSchoolStart = DateTime(today.year, 4, 1); // 生まれた年の翌年の4月1日(学齢期の始まり) final schoolStartDate = DateTime(birthDate.year + 1, 4, 1); // 学齢期の開始からの年数 int yearsFromSchoolStart = today.year - schoolStartDate.year; // 今年の4月1日より前なら1年引く if (today.isBefore(thisYearSchoolStart)) { yearsFromSchoolStart--; } if (yearsFromSchoolStart < 0) return '未就学'; if (yearsFromSchoolStart < 6) return '小${yearsFromSchoolStart + 1}'; if (yearsFromSchoolStart < 9) return '中${yearsFromSchoolStart - 5}'; if (yearsFromSchoolStart < 12) return '高${yearsFromSchoolStart - 8}'; return '成人'; } String getAgeAndGrade() { final age = calculateAge(); final grade = calculateGrade(); return '$age歳/$grade'; } bool isOver18() { return calculateAge() >= 18; } }