LCOV - code coverage report
Current view: | top level - lib/screens/club - event_calendar_screen.dart |  |  | Coverage | Total | Hit
Test: | lcov.info |  | Lines: | 1.1 % | 92 | 1
Test Date: | 2025-08-12 03:21:51 |  | Functions: | - | 0 | 0

                Line data    Source code
           1              : import 'package:flutter/material.dart';
           2              : import 'package:provider/provider.dart';
           3              : import 'package:table_calendar/table_calendar.dart';
           4              : import 'package:intl/intl.dart';
           5              :
           6              : import '../../models/event_model.dart';
           7              : import '../../services/event_service.dart';
           8              : import '../../services/auth_service.dart';
           9              : import '../../services/club_service.dart';
          10              : import 'event_details_screen.dart';
          11              :
          12              : class EventCalendarScreen extends StatefulWidget {
          13           24 :   const EventCalendarScreen({super.key});
          14              :
          15            0 :   @override
          16            0 :   State<EventCalendarScreen> createState() => _EventCalendarScreenState();
          17              : }
          18              :
          19              : class _EventCalendarScreenState extends State<EventCalendarScreen> {
          20              :   CalendarFormat _calendarFormat = CalendarFormat.month;
          21              :   DateTime _focusedDay = DateTime.now();
          22              :   DateTime? _selectedDay;
          23              :   Map<DateTime, List<Event>> _events = {};
          24              :   bool _isLoading = true;
          25              :
          26            0 :   @override
          27              :   void initState() {
          28            0 :     super.initState();
          29            0 :     _loadEvents();
          30              :   }
          31              :
          32            0 :   Future<void> _loadEvents() async {
          33            0 :     setState(() {
          34            0 :       _isLoading = true;
          35              :     });
          36              :
          37              :     try {
          38            0 :       final authService = Provider.of<AuthService>(context, listen: false);
          39            0 :       final clubService = Provider.of<ClubService>(context, listen: false);
          40            0 :       final eventService = Provider.of<EventService>(context, listen: false);
          41              :
          42            0 :       if (clubService.currentClub != null) {
          43            0 :         eventService.initialize(authService.token!);
          44            0 :         await eventService.fetchClubEvents();
          45              :
          46              :         // 이벤트를 날짜별로 그룹화
          47            0 :         final Map<DateTime, List<Event>> eventMap = {};
          48              :
          49            0 :         for (final event in eventService.events) {
          50            0 :           final date = DateTime(
          51            0 :             event.startDate.year,
          52            0 :             event.startDate.month,
          53            0 :             event.startDate.day,
          54              :           );
          55              :
          56            0 :           if (eventMap[date] == null) {
          57            0 :             eventMap[date] = [];
          58              :           }
          59              :
          60            0 :           eventMap[date]!.add(event);
          61              :         }
          62              :
          63            0 :         setState(() {
          64            0 :           _events = eventMap;
          65            0 :           _isLoading = false;
          66              :         });
          67              :       }
          68              :     } catch (e) {
          69            0 :       setState(() {
          70            0 :         _isLoading = false;
          71              :       });
          72              :
          73            0 :       if (mounted) {
          74            0 :         ScaffoldMessenger.of(context).showSnackBar(
          75            0 :           SnackBar(content: Text('이벤트를 불러오는데 실패했습니다: $e')),
          76              :         );
          77              :       }
          78              :     }
          79              :   }
          80              :
          81            0 :   List<Event> _getEventsForDay(DateTime day) {
          82            0 :     final normalizedDay = DateTime(day.year, day.month, day.day);
          83            0 :     return _events[normalizedDay] ?? [];
          84              :   }
          85              :
          86            0 :   @override
          87              :   Widget build(BuildContext context) {
          88            0 :     return Scaffold(
          89            0 :       appBar: AppBar(
          90              :         title: const Text('이벤트 캘린더'),
          91            0 :         actions: [
          92            0 :           IconButton(
          93              :             icon: const Icon(Icons.refresh),
          94            0 :             onPressed: _loadEvents,
          95              :           ),
          96              :         ],
          97              :       ),
          98            0 :       body: _isLoading
          99              :           ? const Center(child: CircularProgressIndicator())
         100            0 :           : Column(
         101            0 :               children: [
         102            0 :                 TableCalendar(
         103            0 :                   firstDay: DateTime.now().subtract(const Duration(days: 365)),
         104            0 :                   lastDay: DateTime.now().add(const Duration(days: 365)),
         105            0 :                   focusedDay: _focusedDay,
         106            0 :                   calendarFormat: _calendarFormat,
         107            0 :                   selectedDayPredicate: (day) {
         108            0 :                     return isSameDay(_selectedDay, day);
         109              :                   },
         110            0 :                   onDaySelected: (selectedDay, focusedDay) {
         111            0 :                     setState(() {
         112            0 :                       _selectedDay = selectedDay;
         113            0 :                       _focusedDay = focusedDay;
         114              :                     });
         115              :                   },
         116            0 :                   onFormatChanged: (format) {
         117            0 :                     setState(() {
         118            0 :                       _calendarFormat = format;
         119              :                     });
         120              :                   },
         121            0 :                   onPageChanged: (focusedDay) {
         122            0 :                     _focusedDay = focusedDay;
         123              :                   },
         124            0 :                   eventLoader: _getEventsForDay,
         125              :                   calendarStyle: const CalendarStyle(
         126              :                     markersMaxCount: 3,
         127              :                     markerDecoration: BoxDecoration(
         128              :                       color: Colors.blue,
         129              :                       shape: BoxShape.circle,
         130              :                     ),
         131              :                   ),
         132              :                   headerStyle: const HeaderStyle(
         133              :                     formatButtonShowsNext: false,
         134              :                     titleCentered: true,
         135              :                   ),
         136              :                 ),
         137              :                 const SizedBox(height: 8),
         138            0 :                 Expanded(
         139            0 :                   child: _selectedDay == null
         140              :                       ? const Center(child: Text('날짜를 선택하세요'))
         141            0 :                       : _buildEventList(),
         142              :                 ),
         143              :               ],
         144              :             ),
         145              :     );
         146              :   }
         147              :
         148            0 :   Widget _buildEventList() {
         149            0 :     final events = _getEventsForDay(_selectedDay!);
         150            0 :     final dateFormat = DateFormat('HH:mm');
         151              :
         152            0 :     if (events.isEmpty) {
         153              :       return const Center(child: Text('선택한 날짜에 이벤트가 없습니다'));
         154              :     }
         155              :
         156            0 :     return ListView.builder(
         157            0 :       itemCount: events.length,
         158            0 :       itemBuilder: (context, index) {
         159            0 :         final event = events[index];
         160            0 :         return Card(
         161              :           margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
         162            0 :           child: ListTile(
         163            0 :             leading: Container(
         164              :               width: 48,
         165              :               height: 48,
         166            0 :               decoration: BoxDecoration(
         167            0 :                 color: Colors.blue[100],
         168            0 :                 borderRadius: BorderRadius.circular(8),
         169              :               ),
         170              :               child: const Icon(Icons.event, color: Colors.blue),
         171              :             ),
         172            0 :             title: Text(
         173            0 :               event.title,
         174              :               style: const TextStyle(fontWeight: FontWeight.bold),
         175              :             ),
         176            0 :             subtitle: Column(
         177              :               crossAxisAlignment: CrossAxisAlignment.start,
         178            0 :               children: [
         179            0 :                 Text(dateFormat.format(event.startDate)),
         180            0 :                 if (event.location != null) Text(event.location!),
         181              :               ],
         182              :             ),
         183            0 :             onTap: () => _navigateToEventDetails(event),
         184              :           ),
         185              :         );
         186              :       },
         187              :     );
         188              :   }
         189              :
         190            0 :   void _navigateToEventDetails(Event event) {
         191            0 :     Navigator.of(context).push(
         192            0 :       MaterialPageRoute(
         193            0 :         builder: (context) => EventDetailsScreen(event: event),
         194              :       ),
         195            0 :     ).then((result) {
         196            0 :       if (result == true) {
         197              :         // 이벤트가 수정되었으면 목록 새로고침
         198            0 :         _loadEvents();
         199              :       }
         200              :     });
         201              :   }
         202              : }

Generated by: LCOV version 2.3.1-1