/// 일정 컨트롤러 (MVCS의 Controller 레이어) /// /// 비즈니스 로직과 상태 관리를 담당합니다. /// View는 이 Controller를 통해 데이터에 접근합니다. library; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import '../models/schedule.dart'; import '../services/schedules_service.dart'; /// 일정 상태 class ScheduleState { final DateTime selectedDate; final List schedules; final bool isLoading; final String? error; const ScheduleState({ required this.selectedDate, this.schedules = const [], this.isLoading = false, this.error, }); /// 상태 복사 (불변성 유지) ScheduleState copyWith({ DateTime? selectedDate, List? schedules, bool? isLoading, String? error, }) { return ScheduleState( selectedDate: selectedDate ?? this.selectedDate, schedules: schedules ?? this.schedules, isLoading: isLoading ?? this.isLoading, error: error, ); } /// 선택된 날짜의 일정 목록 List get selectedDateSchedules { final dateStr = DateFormat('yyyy-MM-dd').format(selectedDate); return schedules.where((s) => s.date.split('T')[0] == dateStr).toList(); } /// 특정 날짜의 일정 (점 표시용, 최대 3개) List getDaySchedules(DateTime date) { final dateStr = DateFormat('yyyy-MM-dd').format(date); return schedules.where((s) => s.date.split('T')[0] == dateStr).take(3).toList(); } /// 해당 달의 모든 날짜 배열 List get daysInMonth { final year = selectedDate.year; final month = selectedDate.month; final lastDay = DateTime(year, month + 1, 0).day; return List.generate(lastDay, (i) => DateTime(year, month, i + 1)); } } /// 일정 컨트롤러 class ScheduleController extends Notifier { @override ScheduleState build() { // 초기 상태 final initialState = ScheduleState(selectedDate: DateTime.now()); // 초기 데이터 로드 Future.microtask(() => loadSchedules()); return initialState; } /// 월별 일정 로드 Future loadSchedules() async { state = state.copyWith(isLoading: true, error: null); try { final schedules = await getSchedules( state.selectedDate.year, state.selectedDate.month, ); state = state.copyWith(schedules: schedules, isLoading: false); } catch (e) { state = state.copyWith(isLoading: false, error: e.toString()); } } /// 날짜 선택 void selectDate(DateTime date) { state = state.copyWith(selectedDate: date); } /// 월 변경 void changeMonth(int delta) { final newDate = DateTime( state.selectedDate.year, state.selectedDate.month + delta, 1, ); final today = DateTime.now(); // 이번 달이면 오늘 날짜, 다른 달이면 1일 선택 final selectedDay = (newDate.year == today.year && newDate.month == today.month) ? today.day : 1; state = state.copyWith( selectedDate: DateTime(newDate.year, newDate.month, selectedDay), ); loadSchedules(); } /// 오늘 여부 bool isToday(DateTime date) { final today = DateTime.now(); return date.year == today.year && date.month == today.month && date.day == today.day; } /// 선택된 날짜 여부 bool isSelected(DateTime date) { return date.year == state.selectedDate.year && date.month == state.selectedDate.month && date.day == state.selectedDate.day; } } /// 일정 Provider final scheduleProvider = NotifierProvider( ScheduleController.new, );