/// 멤버 컨트롤러 (MVCS의 Controller 레이어) /// /// 비즈니스 로직과 상태 관리를 담당합니다. /// View는 이 Controller를 통해 데이터에 접근합니다. library; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/member.dart'; import '../services/members_service.dart'; /// 멤버 상태 class MembersState { final List members; final int currentIndex; final bool isLoading; final String? error; const MembersState({ this.members = const [], this.currentIndex = 0, this.isLoading = true, this.error, }); /// 상태 복사 (불변성 유지) MembersState copyWith({ List? members, int? currentIndex, bool? isLoading, String? error, }) { return MembersState( members: members ?? this.members, currentIndex: currentIndex ?? this.currentIndex, isLoading: isLoading ?? this.isLoading, error: error, ); } /// 현재 선택된 멤버 Member? get currentMember => members.isNotEmpty ? members[currentIndex] : null; } /// 멤버 컨트롤러 class MembersController extends Notifier { @override MembersState build() { // 초기 데이터 로드 Future.microtask(() => loadMembers()); return const MembersState(); } /// 멤버 목록 로드 Future loadMembers() async { state = state.copyWith(isLoading: true, error: null); try { final members = await getMembers(); // 현재 멤버 먼저, 전 멤버 나중에 정렬 members.sort((a, b) { if (a.isFormer != b.isFormer) { return a.isFormer ? 1 : -1; } return 0; }); state = state.copyWith( members: members, isLoading: false, ); } catch (e) { state = state.copyWith( isLoading: false, error: e.toString(), ); } } /// 현재 인덱스 변경 void setCurrentIndex(int index) { if (index >= 0 && index < state.members.length) { state = state.copyWith(currentIndex: index); } } /// 나이 계산 int? calculateAge(String? birthDate) { if (birthDate == null) return null; final birth = DateTime.tryParse(birthDate); if (birth == null) return null; final today = DateTime.now(); int age = today.year - birth.year; if (today.month < birth.month || (today.month == birth.month && today.day < birth.day)) { age--; } return age; } /// 생일 포맷팅 String formatBirthDate(String? birthDate) { if (birthDate == null) return ''; return birthDate.substring(0, 10).replaceAll('-', '.'); } } /// 멤버 Provider final membersProvider = NotifierProvider( MembersController.new, );