チーム編集時の文字化け修正済み
This commit is contained in:
@ -19,6 +19,16 @@ class NewCategory {
|
|||||||
required this.female,
|
required this.female,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is NewCategory &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
id == other.id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => id.hashCode;
|
||||||
|
|
||||||
factory NewCategory.fromJson(Map<String, dynamic> json) {
|
factory NewCategory.fromJson(Map<String, dynamic> json) {
|
||||||
return NewCategory(
|
return NewCategory(
|
||||||
id: json['id'] ?? 0,
|
id: json['id'] ?? 0,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
// lib/models/team.dart
|
// lib/models/team.dart
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
import 'category.dart';
|
import 'category.dart';
|
||||||
import 'user.dart';
|
import 'user.dart';
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ class Team {
|
|||||||
final NewCategory category;
|
final NewCategory category;
|
||||||
final User owner;
|
final User owner;
|
||||||
|
|
||||||
|
|
||||||
Team({
|
Team({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.zekkenNumber,
|
required this.zekkenNumber,
|
||||||
|
|||||||
@ -7,18 +7,23 @@ import 'package:rogapp/services/api_service.dart';
|
|||||||
class MemberController extends GetxController {
|
class MemberController extends GetxController {
|
||||||
late final ApiService _apiService;
|
late final ApiService _apiService;
|
||||||
|
|
||||||
|
final selectedMember = Rx<User?>(null);
|
||||||
final int teamId = 0;
|
final int teamId = 0;
|
||||||
final member = Rx<User?>(null);
|
final member = Rx<User?>(null);
|
||||||
final email = ''.obs;
|
final email = ''.obs;
|
||||||
final firstname = ''.obs;
|
final firstname = ''.obs;
|
||||||
final lastname = ''.obs;
|
final lastname = ''.obs;
|
||||||
final dateOfBirth = Rx<DateTime?>(null);
|
final dateOfBirth = Rx<DateTime?>(null);
|
||||||
|
final isLoading = true.obs; // isLoadingプロパティを追加
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() async{
|
void onInit() async{
|
||||||
super.onInit();
|
super.onInit();
|
||||||
await Get.putAsync(() => ApiService().init());
|
await Get.putAsync(() => ApiService().init());
|
||||||
_apiService = Get.find<ApiService>();
|
_apiService = Get.find<ApiService>();
|
||||||
|
await loadInitialData();
|
||||||
|
|
||||||
if (Get.arguments != null && Get.arguments['member'] != null) {
|
if (Get.arguments != null && Get.arguments['member'] != null) {
|
||||||
member.value = Get.arguments['member'];
|
member.value = Get.arguments['member'];
|
||||||
_initializeMemberData();
|
_initializeMemberData();
|
||||||
@ -35,6 +40,46 @@ class MemberController extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> loadInitialData() async {
|
||||||
|
try {
|
||||||
|
isLoading.value = true;
|
||||||
|
// 必要な初期データの取得をここで行う
|
||||||
|
// 例: await fetchTeamMembers();
|
||||||
|
} catch (e) {
|
||||||
|
print('Error loading initial data: $e');
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setSelectedMember(User member) {
|
||||||
|
selectedMember.value = member;
|
||||||
|
firstname.value = member.firstname;
|
||||||
|
lastname.value = member.lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFirstName(String value) {
|
||||||
|
firstname.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateLastName(String value) {
|
||||||
|
lastname.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> saveMember() async {
|
||||||
|
try {
|
||||||
|
isLoading.value = true;
|
||||||
|
// メンバー保存のロジックをここに実装
|
||||||
|
// 例: await _apiService.updateMember(selectedMember.value!.id, firstName.value, lastName.value);
|
||||||
|
} catch (e) {
|
||||||
|
print('Error saving member: $e');
|
||||||
|
// エラーハンドリング(例:ユーザーへの通知)
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> createMember(int teamId) async {
|
Future<void> createMember(int teamId) async {
|
||||||
try {
|
try {
|
||||||
final newMember = await _apiService.createTeamMember(
|
final newMember = await _apiService.createTeamMember(
|
||||||
|
|||||||
@ -5,16 +5,51 @@ import 'package:get/get.dart';
|
|||||||
import 'package:rogapp/pages/team/member_controller.dart';
|
import 'package:rogapp/pages/team/member_controller.dart';
|
||||||
|
|
||||||
class MemberDetailPage extends GetView<MemberController> {
|
class MemberDetailPage extends GetView<MemberController> {
|
||||||
|
final TextEditingController _firstNameController = TextEditingController();
|
||||||
|
final TextEditingController _lastNameController = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final mode = Get.arguments['mode'];
|
final mode = Get.arguments['mode'];
|
||||||
final member = Get.arguments['member'];
|
final member = Get.arguments['member'];
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mode == 'edit' && member != null) {
|
||||||
|
controller.setSelectedMember(member);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(mode == 'new' ? 'メンバー追加' : 'メンバー詳細'),
|
title: Text(mode == 'new' ? 'メンバー追加' : 'メンバー詳細'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.save),
|
||||||
|
onPressed: () async {
|
||||||
|
await controller.saveMember();
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
body: Padding(
|
],
|
||||||
|
),
|
||||||
|
body: Obx(()
|
||||||
|
{
|
||||||
|
if (controller.isLoading.value) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
|
||||||
|
_firstNameController.value = _firstNameController.value.copyWith(
|
||||||
|
text: controller.firstname.value,
|
||||||
|
selection: TextSelection.collapsed(
|
||||||
|
offset: controller.firstname.value.length),
|
||||||
|
);
|
||||||
|
_lastNameController.value = _lastNameController.value.copyWith(
|
||||||
|
text: controller.lastname.value,
|
||||||
|
selection: TextSelection.collapsed(
|
||||||
|
offset: controller.lastname.value.length),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Padding(
|
||||||
padding: EdgeInsets.all(16.0),
|
padding: EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -28,12 +63,15 @@ class MemberDetailPage extends GetView<MemberController> {
|
|||||||
),
|
),
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(labelText: '姓'),
|
decoration: InputDecoration(labelText: '姓'),
|
||||||
onChanged: (value) => controller.updateLastname(value),
|
controller: _lastNameController,
|
||||||
|
onChanged: (value) => controller.updateLastName(value),
|
||||||
),
|
),
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(labelText: '名'),
|
decoration: InputDecoration(labelText: '名'),
|
||||||
onChanged: (value) => controller.updateFirstname(value),
|
controller: _firstNameController,
|
||||||
|
onChanged: (value) => controller.updateFirstName(value),
|
||||||
),
|
),
|
||||||
|
|
||||||
// 誕生日選択ウィジェットを追加
|
// 誕生日選択ウィジェットを追加
|
||||||
if (mode == 'edit')
|
if (mode == 'edit')
|
||||||
Text('ステータス: ${controller.getMemberStatus()}'),
|
Text('ステータス: ${controller.getMemberStatus()}'),
|
||||||
@ -49,7 +87,8 @@ class MemberDetailPage extends GetView<MemberController> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
// lib/controllers/team_controller.dart
|
// lib/controllers/team_controller.dart
|
||||||
|
import 'dart:convert';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:rogapp/model/team.dart';
|
import 'package:rogapp/model/team.dart';
|
||||||
import 'package:rogapp/model/category.dart';
|
import 'package:rogapp/model/category.dart';
|
||||||
@ -9,44 +9,78 @@ import 'package:rogapp/services/api_service.dart';
|
|||||||
class TeamController extends GetxController {
|
class TeamController extends GetxController {
|
||||||
late final ApiService _apiService;
|
late final ApiService _apiService;
|
||||||
|
|
||||||
|
|
||||||
final teams = <Team>[].obs;
|
final teams = <Team>[].obs;
|
||||||
final categories = <NewCategory>[].obs;
|
final categories = <NewCategory>[].obs;
|
||||||
final teamMembers = <User>[].obs;
|
final teamMembers = <User>[].obs;
|
||||||
|
|
||||||
|
|
||||||
final selectedCategory = Rx<NewCategory?>(null);
|
final selectedCategory = Rx<NewCategory?>(null);
|
||||||
|
final selectedTeam = Rx<Team?>(null);
|
||||||
final currentUser = Rx<User?>(null);
|
final currentUser = Rx<User?>(null);
|
||||||
|
|
||||||
final isLoading = true.obs;
|
final teamName = ''.obs;
|
||||||
|
final isLoading = false.obs;
|
||||||
final error = RxString('');
|
final error = RxString('');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() async{
|
void onInit() async{
|
||||||
super.onInit();
|
super.onInit();
|
||||||
try {
|
try {
|
||||||
//await Get.putAsync(() => ApiService().init());
|
|
||||||
_apiService = Get.find<ApiService>();
|
_apiService = Get.find<ApiService>();
|
||||||
|
|
||||||
|
await fetchCategories();
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
fetchTeams(),
|
fetchTeams(),
|
||||||
fetchCategories(),
|
|
||||||
getCurrentUser(),
|
getCurrentUser(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
print("selectedCategory=$selectedCategory.value");
|
||||||
|
// カテゴリが取得できたら、最初のカテゴリを選択状態にする
|
||||||
|
if (categories.isNotEmpty && selectedCategory.value == null) {
|
||||||
|
selectedCategory.value = categories.first;
|
||||||
|
}
|
||||||
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
print("Team Controller error: $e");
|
print("Team Controller error: $e");
|
||||||
|
error.value = e.toString();
|
||||||
}finally{
|
}finally{
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = '';
|
||||||
|
selectedCategory.value = categories.isNotEmpty ? categories.first : null;
|
||||||
|
teamMembers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> fetchTeams() async {
|
Future<void> fetchTeams() async {
|
||||||
try {
|
try {
|
||||||
|
isLoading.value = true;
|
||||||
final fetchedTeams = await _apiService.getTeams();
|
final fetchedTeams = await _apiService.getTeams();
|
||||||
teams.assignAll(fetchedTeams);
|
teams.assignAll(fetchedTeams);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
error.value = 'チームの取得に失敗しました: $e';
|
||||||
print('Error fetching teams: $e');
|
print('Error fetching teams: $e');
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +88,8 @@ class TeamController extends GetxController {
|
|||||||
try {
|
try {
|
||||||
final fetchedCategories = await _apiService.getCategories();
|
final fetchedCategories = await _apiService.getCategories();
|
||||||
categories.assignAll(fetchedCategories);
|
categories.assignAll(fetchedCategories);
|
||||||
|
print("Fetched categories: ${categories.length}"); // デバッグ用
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error fetching categories: $e');
|
print('Error fetching categories: $e');
|
||||||
}
|
}
|
||||||
@ -68,25 +104,15 @@ class TeamController extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createTeam(String teamName, int categoryId) async {
|
Future<Team> createTeam(String teamName, int categoryId) async {
|
||||||
try {
|
|
||||||
final newTeam = await _apiService.createTeam(teamName, categoryId);
|
final newTeam = await _apiService.createTeam(teamName, categoryId);
|
||||||
teams.add(newTeam);
|
return newTeam;
|
||||||
} catch (e) {
|
|
||||||
print('Error creating team: $e');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateTeam(int teamId, String teamName, int categoryId) async {
|
Future<Team> updateTeam(int teamId, String teamName, int categoryId) async {
|
||||||
try {
|
// APIサービスを使用してチームを更新
|
||||||
final updatedTeam = await _apiService.updateTeam(teamId, teamName, categoryId);
|
final updatedTeam = await _apiService.updateTeam(teamId, teamName, categoryId);
|
||||||
final index = teams.indexWhere((team) => team.id == teamId);
|
return updatedTeam;
|
||||||
if (index != -1) {
|
|
||||||
teams[index] = updatedTeam;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
print('Error updating team: $e');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteTeam(int teamId) async {
|
Future<void> deleteTeam(int teamId) async {
|
||||||
@ -108,10 +134,56 @@ class TeamController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateTeamName(String value) {
|
void updateTeamName(String value) {
|
||||||
// Update local state
|
teamName.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateCategory(NewCategory? value) {
|
void updateCategory(NewCategory? value) {
|
||||||
selectedCategory.value = value;
|
if (value != null) {
|
||||||
|
selectedCategory.value = categories.firstWhere(
|
||||||
|
(category) => category.id == value.id,
|
||||||
|
orElse: () => value,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
// 選択中のチームを更新
|
||||||
|
if (selectedTeam.value != null) {
|
||||||
|
selectedTeam.value = teams.firstWhere((t) => t.id == selectedTeam.value!.id);
|
||||||
|
teamName.value = selectedTeam.value!.teamName;
|
||||||
|
selectedCategory.value = selectedTeam.value!.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(); // UIを強制的に更新
|
||||||
|
} catch (e) {
|
||||||
|
error.value = 'チームの保存に失敗しました: $e';
|
||||||
|
print("Team save error: $e");
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> deleteSelectedTeam() async {
|
||||||
|
if (selectedTeam.value != null) {
|
||||||
|
await deleteTeam(selectedTeam.value!.id);
|
||||||
|
selectedTeam.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4,35 +4,69 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:rogapp/pages/team/team_controller.dart';
|
import 'package:rogapp/pages/team/team_controller.dart';
|
||||||
import 'package:rogapp/routes/app_pages.dart';
|
import 'package:rogapp/routes/app_pages.dart';
|
||||||
import 'package:rogapp/services/api_service.dart';
|
import 'package:rogapp/model/team.dart';
|
||||||
|
import 'package:rogapp/model/category.dart';
|
||||||
|
|
||||||
class TeamDetailPage extends GetView<TeamController> {
|
class TeamDetailPage extends GetView<TeamController> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final mode = Get.arguments['mode'];
|
final mode = Get.arguments['mode'] as String;
|
||||||
final team = Get.arguments['team'];
|
final team = Get.arguments['team'] as Team?;
|
||||||
|
|
||||||
|
if (mode == 'edit' && team != null) {
|
||||||
|
controller.setSelectedTeam(team);
|
||||||
|
} else {
|
||||||
|
controller.resetForm();
|
||||||
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(mode == 'new' ? '新規チーム作成' : 'チーム詳細'),
|
title: Text(mode == 'new' ? '新規チーム作成' : 'チーム詳細'),
|
||||||
actions: [
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.save),
|
||||||
|
onPressed: () async {
|
||||||
|
try {
|
||||||
|
await controller.saveTeam();
|
||||||
|
Get.back();
|
||||||
|
} catch (e) {
|
||||||
|
Get.snackbar('エラー', e.toString(), snackPosition: SnackPosition.BOTTOM);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
if (mode == 'edit')
|
if (mode == 'edit')
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.add),
|
icon: Icon(Icons.delete),
|
||||||
onPressed: () => Get.toNamed(AppPages.MEMBER_DETAIL, arguments: {'mode': 'new', 'teamId': team.id}),
|
onPressed: () async {
|
||||||
|
try {
|
||||||
|
await controller.deleteSelectedTeam();
|
||||||
|
Get.back();
|
||||||
|
} catch (e) {
|
||||||
|
Get.snackbar('エラー', e.toString(), snackPosition: SnackPosition.BOTTOM);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: GetBuilder<TeamController>(
|
||||||
|
builder: (controller) {
|
||||||
|
if (controller.isLoading.value) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16.0),
|
padding: EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
TextFormField(
|
||||||
|
initialValue: controller.teamName.value,
|
||||||
decoration: InputDecoration(labelText: 'チーム名'),
|
decoration: InputDecoration(labelText: 'チーム名'),
|
||||||
onChanged: (value) => controller.updateTeamName(value),
|
onChanged: (value) => controller.updateTeamName(value),
|
||||||
),
|
),
|
||||||
DropdownButtonFormField(
|
SizedBox(height: 16),
|
||||||
|
DropdownButtonFormField<NewCategory>(
|
||||||
decoration: InputDecoration(labelText: 'カテゴリ'),
|
decoration: InputDecoration(labelText: 'カテゴリ'),
|
||||||
value: controller.selectedCategory.value,
|
value: controller.selectedCategory.value,
|
||||||
items: controller.categories.map((category) => DropdownMenuItem(
|
items: controller.categories.map((category) => DropdownMenuItem(
|
||||||
@ -42,28 +76,51 @@ class TeamDetailPage extends GetView<TeamController> {
|
|||||||
onChanged: (value) => controller.updateCategory(value),
|
onChanged: (value) => controller.updateCategory(value),
|
||||||
),
|
),
|
||||||
if (mode == 'edit')
|
if (mode == 'edit')
|
||||||
Text('ゼッケン番号: ${team.zekkenNumber}'),
|
Padding(
|
||||||
Obx(() {
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
final currentUser = controller.currentUser.value;
|
child: Text('ゼッケン番号: ${controller.selectedTeam.value?.zekkenNumber ?? ""}'),
|
||||||
return Text('所有者: ${currentUser?.email ?? "未設定"}');
|
),
|
||||||
}),
|
Padding(
|
||||||
SizedBox(height: 20),
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
child: Text('所有者: ${controller.currentUser.value?.email ?? "未設定"}'),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24),
|
||||||
Text('メンバーリスト', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
Text('メンバーリスト', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
Expanded(
|
SizedBox(height: 8),
|
||||||
child: Obx(() => ListView.builder(
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
itemCount: controller.teamMembers.length,
|
itemCount: controller.teamMembers.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final member = controller.teamMembers[index];
|
final member = controller.teamMembers[index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text('${member.lastname}, ${member.firstname}'),
|
title: Text('${member.lastname}, ${member.firstname}'),
|
||||||
onTap: () => Get.toNamed(AppPages.MEMBER_DETAIL, arguments: {'mode': 'edit', 'member': member}),
|
onTap: () => Get.toNamed(
|
||||||
|
AppPages.MEMBER_DETAIL,
|
||||||
|
arguments: {'mode': 'edit', 'member': member, 'teamId': controller.selectedTeam.value?.id},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)),
|
),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
ElevatedButton(
|
||||||
|
child: Text('新しいメンバーを追加'),
|
||||||
|
onPressed: () => Get.toNamed(
|
||||||
|
AppPages.MEMBER_DETAIL,
|
||||||
|
arguments: {'mode': 'new', 'teamId': controller.selectedTeam.value?.id},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import 'package:rogapp/pages/team/team_controller.dart';
|
|||||||
import 'package:rogapp/routes/app_pages.dart';
|
import 'package:rogapp/routes/app_pages.dart';
|
||||||
import 'package:rogapp/services/api_service.dart';
|
import 'package:rogapp/services/api_service.dart';
|
||||||
|
|
||||||
class TeamListPage extends GetView<TeamController> {
|
class TeamListPage extends GetWidget<TeamController> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -19,36 +19,38 @@ class TeamListPage extends GetView<TeamController> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: FutureBuilder(
|
body: Obx(() {
|
||||||
future: Get.putAsync(() => ApiService().init()),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
|
||||||
return Obx(() {
|
|
||||||
if (controller.isLoading.value) {
|
if (controller.isLoading.value) {
|
||||||
return Center(child: CircularProgressIndicator());
|
return Center(child: CircularProgressIndicator());
|
||||||
} else if (controller.error.value.isNotEmpty) {
|
} else if (controller.error.value.isNotEmpty) {
|
||||||
return Center(child: Text('エラー: ${controller.error.value}'));
|
return Center(child: Text(controller.error.value));
|
||||||
|
} else if (controller.teams.isEmpty) {
|
||||||
|
return Center(child: Text('チームがありません'));
|
||||||
} else {
|
} else {
|
||||||
return ListView.builder(
|
return RefreshIndicator(
|
||||||
|
onRefresh: controller.fetchTeams,
|
||||||
|
child: ListView.builder(
|
||||||
itemCount: controller.teams.length,
|
itemCount: controller.teams.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final team = controller.teams[index];
|
final team = controller.teams[index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(team.teamName),
|
title: Text(team.teamName),
|
||||||
subtitle: Text('${team.category.categoryName} - ${team.zekkenNumber}'),
|
subtitle: Text('${team.category.categoryName} - ${team.zekkenNumber}'),
|
||||||
trailing: Text('メンバー: (メンバー数表示予定)'),
|
onTap: () async {
|
||||||
onTap: () => Get.toNamed(AppPages.TEAM_DETAIL, arguments: {'mode': 'edit', 'team': team}),
|
await Get.toNamed(
|
||||||
|
AppPages.TEAM_DETAIL,
|
||||||
|
arguments: {'mode': 'edit', 'team': team},
|
||||||
);
|
);
|
||||||
|
controller.fetchTeams();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return Center(child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class ApiService extends GetxService{
|
|||||||
static ApiService get to => Get.find<ApiService>();
|
static ApiService get to => Get.find<ApiService>();
|
||||||
String serverUrl = '';
|
String serverUrl = '';
|
||||||
String baseUrl = '';
|
String baseUrl = '';
|
||||||
String token = 'your-auth-token'; // これが使用されている。
|
String token = 'your-auth-token';
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
try {
|
try {
|
||||||
@ -65,7 +65,7 @@ class ApiService extends GetxService{
|
|||||||
try {
|
try {
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
Uri.parse('$baseUrl/teams/'),
|
Uri.parse('$baseUrl/teams/'),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token',"Content-Type": "application/json; charset=UTF-8"},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
@ -100,7 +100,7 @@ class ApiService extends GetxService{
|
|||||||
try {
|
try {
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
Uri.parse('$baseUrl/categories/'),
|
Uri.parse('$baseUrl/categories/'),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token',"Content-Type": "application/json; charset=UTF-8"},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
@ -134,7 +134,7 @@ class ApiService extends GetxService{
|
|||||||
try {
|
try {
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
Uri.parse('$baseUrl/user/'),
|
Uri.parse('$baseUrl/user/'),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token',"Content-Type": "application/json; charset=UTF-8"},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
@ -223,7 +223,7 @@ class ApiService extends GetxService{
|
|||||||
Uri.parse('$baseUrl/teams/'),
|
Uri.parse('$baseUrl/teams/'),
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Token $token',
|
'Authorization': 'Token $token',
|
||||||
'Content-Type': 'application/json',
|
"Content-Type": "application/json; charset=UTF-8",
|
||||||
},
|
},
|
||||||
body: json.encode({
|
body: json.encode({
|
||||||
'team_name': teamName,
|
'team_name': teamName,
|
||||||
@ -246,7 +246,7 @@ class ApiService extends GetxService{
|
|||||||
Uri.parse('$baseUrl/teams/$teamId/'),
|
Uri.parse('$baseUrl/teams/$teamId/'),
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Token $token',
|
'Authorization': 'Token $token',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
},
|
},
|
||||||
body: json.encode({
|
body: json.encode({
|
||||||
'team_name': teamName,
|
'team_name': teamName,
|
||||||
@ -267,7 +267,7 @@ class ApiService extends GetxService{
|
|||||||
|
|
||||||
final response = await http.delete(
|
final response = await http.delete(
|
||||||
Uri.parse('$baseUrl/teams/$teamId/'),
|
Uri.parse('$baseUrl/teams/$teamId/'),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token','Content-Type': 'application/json; charset=UTF-8'},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode != 204) {
|
if (response.statusCode != 204) {
|
||||||
@ -281,7 +281,7 @@ class ApiService extends GetxService{
|
|||||||
|
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
Uri.parse('$baseUrl/teams/$teamId/members/'),
|
Uri.parse('$baseUrl/teams/$teamId/members/'),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token','Content-Type': 'application/json; charset=UTF-8'},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
@ -303,7 +303,7 @@ class ApiService extends GetxService{
|
|||||||
Uri.parse('$baseUrl/teams/$teamId/members/'),
|
Uri.parse('$baseUrl/teams/$teamId/members/'),
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Token $token',
|
'Authorization': 'Token $token',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
},
|
},
|
||||||
body: json.encode({
|
body: json.encode({
|
||||||
'email': email,
|
'email': email,
|
||||||
@ -328,7 +328,7 @@ class ApiService extends GetxService{
|
|||||||
Uri.parse('$baseUrl/teams/$teamId/members/$memberId/'),
|
Uri.parse('$baseUrl/teams/$teamId/members/$memberId/'),
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Token $token',
|
'Authorization': 'Token $token',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
},
|
},
|
||||||
body: json.encode({
|
body: json.encode({
|
||||||
'firstname': firstname,
|
'firstname': firstname,
|
||||||
@ -364,7 +364,8 @@ class ApiService extends GetxService{
|
|||||||
|
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
Uri.parse('$baseUrl/members/$memberId/resend-invitation/'),
|
Uri.parse('$baseUrl/members/$memberId/resend-invitation/'),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token', 'Content-Type': 'application/json; charset=UTF-8',
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
@ -378,7 +379,8 @@ class ApiService extends GetxService{
|
|||||||
|
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
Uri.parse('$baseUrl/entries/'),
|
Uri.parse('$baseUrl/entries/'),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token', 'Content-Type': 'application/json; charset=UTF-8',
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
@ -394,8 +396,9 @@ class ApiService extends GetxService{
|
|||||||
getToken();
|
getToken();
|
||||||
|
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
Uri.parse('$baseUrl/new-events/'),
|
Uri.parse('$baseUrl/new-events/',),
|
||||||
headers: {'Authorization': 'Token $token'},
|
headers: {'Authorization': 'Token $token', 'Content-Type': 'application/json; charset=UTF-8',
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
@ -417,7 +420,7 @@ class ApiService extends GetxService{
|
|||||||
Uri.parse('$baseUrl/entry/'),
|
Uri.parse('$baseUrl/entry/'),
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Token $token',
|
'Authorization': 'Token $token',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
},
|
},
|
||||||
body: json.encode({
|
body: json.encode({
|
||||||
'team': teamId,
|
'team': teamId,
|
||||||
@ -442,7 +445,7 @@ class ApiService extends GetxService{
|
|||||||
Uri.parse('$baseUrl/entry/$entryId/'),
|
Uri.parse('$baseUrl/entry/$entryId/'),
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Token $token',
|
'Authorization': 'Token $token',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
},
|
},
|
||||||
body: json.encode({
|
body: json.encode({
|
||||||
'event': eventId,
|
'event': eventId,
|
||||||
|
|||||||
Reference in New Issue
Block a user