Line data Source code
1 : import 'dart:convert';
2 : import 'package:flutter/foundation.dart';
3 : import 'package:shared_preferences/shared_preferences.dart';
4 :
5 : import '../config/api_config.dart';
6 : import '../models/club_model.dart';
7 : import './api_service.dart';
8 : import './event_bus.dart';
9 :
10 : class ClubService with ChangeNotifier {
11 : List<Club> _clubs = [];
12 : Club? _currentClub;
13 : bool _isLoading = false;
14 : String? _token;
15 : ApiService _apiService;
16 :
17 : // 기본 생성자
18 0 : ClubService() : _apiService = ApiService();
19 :
20 : // 테스트용 생성자
21 2 : ClubService.forTest(this._apiService);
22 :
23 6 : List<Club> get clubs => [..._clubs];
24 4 : Club? get currentClub => _currentClub;
25 0 : bool get isLoading => _isLoading;
26 :
27 : // 초기화 함수
28 2 : Future<void> initialize(String token) async {
29 2 : _token = token;
30 4 : _apiService.setToken(token);
31 :
32 : // 저장된 현재 클럽 ID 가져오기
33 2 : final prefs = await SharedPreferences.getInstance();
34 2 : final clubId = prefs.getString(ApiConfig.clubIdKey);
35 :
36 : if (clubId != null) {
37 2 : await fetchClubById(clubId);
38 : }
39 : }
40 :
41 : // 사용자의 모든 클럽 가져오기
42 2 : Future<void> fetchUserClubs() async {
43 2 : if (_token == null) return;
44 :
45 2 : _isLoading = true;
46 2 : notifyListeners();
47 :
48 : try {
49 4 : final data = await _apiService.post('${ApiConfig.clubs}/user');
50 :
51 : final List<dynamic> clubsData = data;
52 :
53 10 : _clubs = clubsData.map((clubData) => Club.fromJson(clubData)).toList();
54 :
55 2 : _isLoading = false;
56 2 : notifyListeners();
57 : } catch (e) {
58 0 : _isLoading = false;
59 0 : notifyListeners();
60 0 : throw Exception('클럽 목록을 불러오는데 실패했습니다: $e');
61 : }
62 : }
63 :
64 : // ID로 클럽 정보 가져오기
65 2 : Future<void> fetchClubById(String clubId) async {
66 2 : if (_token == null) return;
67 :
68 2 : _isLoading = true;
69 2 : notifyListeners();
70 :
71 : try {
72 4 : final data = await _apiService.post(
73 : '${ApiConfig.clubs}',
74 2 : data: {'clubId': clubId},
75 : );
76 :
77 : // 백엔드에서는 club 키로 감싸지 않고 직접 클럽 객체를 반환합니다
78 4 : _currentClub = Club.fromJson(data);
79 :
80 : // 현재 클럽 ID 저장
81 2 : final prefs = await SharedPreferences.getInstance();
82 2 : await prefs.setString(ApiConfig.clubIdKey, clubId);
83 :
84 2 : _isLoading = false;
85 2 : notifyListeners();
86 : } catch (e) {
87 1 : _isLoading = false;
88 1 : notifyListeners();
89 2 : throw Exception('클럽 정보를 불러오는데 실패했습니다: $e');
90 : }
91 : }
92 :
93 : // 현재 클럽 설정
94 2 : Future<void> setCurrentClub(String clubId) async {
95 2 : await fetchClubById(clubId);
96 : }
97 :
98 : // 백엔드에 클럽 선택 요청 (세션에 clubId 저장)
99 2 : Future<void> selectClub(String clubId) async {
100 2 : if (_token == null) return;
101 :
102 2 : _isLoading = true;
103 2 : notifyListeners();
104 :
105 : try {
106 4 : await _apiService.post(
107 : '${ApiConfig.clubs}/select-club',
108 2 : data: {'clubId': clubId},
109 : );
110 :
111 : // 클럽 선택 성공 후 클럽 정보 가져오기
112 2 : await fetchClubById(clubId);
113 :
114 : // 클럽 ID를 로컬에 저장
115 2 : final prefs = await SharedPreferences.getInstance();
116 2 : await prefs.setString(ApiConfig.clubIdKey, clubId);
117 :
118 : // 클럽 데이터도 함께 저장
119 2 : if (_currentClub != null) {
120 8 : await prefs.setString('${ApiConfig.clubIdKey}_data', jsonEncode(_currentClub!.toJson()));
121 : }
122 :
123 : // 클럽 변경 이벤트 발생 - 다른 서비스들에게 알림
124 6 : EventBus().fire(ClubChangedEvent(clubId));
125 :
126 2 : _isLoading = false;
127 2 : notifyListeners();
128 : } catch (e) {
129 0 : _isLoading = false;
130 0 : notifyListeners();
131 0 : throw Exception('클럽 선택에 실패했습니다: $e');
132 : }
133 : }
134 :
135 : // 클럽 생성
136 2 : Future<Club> createClub(Club club) async {
137 2 : if (_token == null) {
138 0 : throw Exception('인증이 필요합니다');
139 : }
140 :
141 2 : _isLoading = true;
142 2 : notifyListeners();
143 :
144 : try {
145 4 : final data = await _apiService.post(
146 : '${ApiConfig.clubs}',
147 2 : data: club.toJson(),
148 : );
149 :
150 4 : final newClub = Club.fromJson(data['club']);
151 :
152 4 : _clubs.add(newClub);
153 2 : _currentClub = newClub;
154 :
155 : // 현재 클럽 ID 저장
156 2 : final prefs = await SharedPreferences.getInstance();
157 4 : await prefs.setString(ApiConfig.clubIdKey, newClub.id);
158 :
159 2 : _isLoading = false;
160 2 : notifyListeners();
161 :
162 : return newClub;
163 : } catch (e) {
164 1 : _isLoading = false;
165 1 : notifyListeners();
166 2 : throw Exception('클럽 생성에 실패했습니다: $e');
167 : }
168 : }
169 :
170 : // 클럽 정보 업데이트
171 2 : Future<Club> updateClub(String clubId, Map<String, dynamic> updates) async {
172 2 : if (_token == null) {
173 0 : throw Exception('인증이 필요합니다');
174 : }
175 :
176 2 : _isLoading = true;
177 2 : notifyListeners();
178 :
179 : try {
180 4 : final data = await _apiService.put(
181 : ApiConfig.clubs,
182 2 : data: {
183 2 : 'clubId': clubId,
184 2 : ...updates,
185 : },
186 : );
187 :
188 : // 백엔드 응답 처리: 직접 클럽 객체가 반환되거나 {club: {...}} 형태로 반환될 수 있음
189 4 : final updatedClub = data is Map && data.containsKey('club')
190 4 : ? Club.fromJson(data['club'])
191 1 : : Club.fromJson(data);
192 :
193 : // 클럽 목록 업데이트
194 10 : final index = _clubs.indexWhere((club) => club.id == clubId);
195 2 : if (index >= 0) {
196 4 : _clubs[index] = updatedClub;
197 : }
198 :
199 : // 현재 클럽이 업데이트된 클럽인 경우 업데이트
200 6 : if (_currentClub?.id == clubId) {
201 2 : _currentClub = updatedClub;
202 : }
203 :
204 2 : _isLoading = false;
205 2 : notifyListeners();
206 :
207 : return updatedClub;
208 : } catch (e) {
209 0 : _isLoading = false;
210 0 : notifyListeners();
211 0 : throw Exception('클럽 정보 업데이트에 실패했습니다: $e');
212 : }
213 : }
214 :
215 : // 클럽 정보 가져오기 (ID로)
216 0 : Future<Club> fetchClub(String clubId) async {
217 0 : if (_token == null) {
218 0 : throw Exception('인증이 필요합니다');
219 : }
220 :
221 : try {
222 : // 현재 클럽이 요청한 클럽과 동일한 경우 캐시된 데이터 반환
223 0 : if (_currentClub != null && _currentClub!.id == clubId) {
224 0 : return _currentClub!;
225 : }
226 :
227 0 : final data = await _apiService.post(
228 : '${ApiConfig.clubs}',
229 0 : data: {'clubId': clubId},
230 : );
231 :
232 0 : final club = Club.fromJson(data);
233 : return club;
234 : } catch (e) {
235 0 : throw Exception('클럽 정보를 불러오는데 실패했습니다: $e');
236 : }
237 : }
238 : }
|