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