Files
bowlingManager/mobile/lib/screens/club/event_calendar_screen.dart
T
2025-08-09 03:09:17 +09:00

203 lines
6.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:intl/intl.dart';
import '../../models/event_model.dart';
import '../../services/event_service.dart';
import '../../services/auth_service.dart';
import '../../services/club_service.dart';
import 'event_details_screen.dart';
class EventCalendarScreen extends StatefulWidget {
const EventCalendarScreen({super.key});
@override
State<EventCalendarScreen> createState() => _EventCalendarScreenState();
}
class _EventCalendarScreenState extends State<EventCalendarScreen> {
CalendarFormat _calendarFormat = CalendarFormat.month;
DateTime _focusedDay = DateTime.now();
DateTime? _selectedDay;
Map<DateTime, List<Event>> _events = {};
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadEvents();
}
Future<void> _loadEvents() async {
setState(() {
_isLoading = true;
});
try {
final authService = Provider.of<AuthService>(context, listen: false);
final clubService = Provider.of<ClubService>(context, listen: false);
final eventService = Provider.of<EventService>(context, listen: false);
if (clubService.currentClub != null) {
eventService.initialize(authService.token!);
await eventService.fetchClubEvents();
// 이벤트를 날짜별로 그룹화
final Map<DateTime, List<Event>> eventMap = {};
for (final event in eventService.events) {
final date = DateTime(
event.startDate.year,
event.startDate.month,
event.startDate.day,
);
if (eventMap[date] == null) {
eventMap[date] = [];
}
eventMap[date]!.add(event);
}
setState(() {
_events = eventMap;
_isLoading = false;
});
}
} catch (e) {
setState(() {
_isLoading = false;
});
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('이벤트를 불러오는데 실패했습니다: $e')),
);
}
}
}
List<Event> _getEventsForDay(DateTime day) {
final normalizedDay = DateTime(day.year, day.month, day.day);
return _events[normalizedDay] ?? [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('이벤트 캘린더'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _loadEvents,
),
],
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: Column(
children: [
TableCalendar(
firstDay: DateTime.now().subtract(const Duration(days: 365)),
lastDay: DateTime.now().add(const Duration(days: 365)),
focusedDay: _focusedDay,
calendarFormat: _calendarFormat,
selectedDayPredicate: (day) {
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
},
onFormatChanged: (format) {
setState(() {
_calendarFormat = format;
});
},
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
eventLoader: _getEventsForDay,
calendarStyle: const CalendarStyle(
markersMaxCount: 3,
markerDecoration: BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
),
headerStyle: const HeaderStyle(
formatButtonShowsNext: false,
titleCentered: true,
),
),
const SizedBox(height: 8),
Expanded(
child: _selectedDay == null
? const Center(child: Text('날짜를 선택하세요'))
: _buildEventList(),
),
],
),
);
}
Widget _buildEventList() {
final events = _getEventsForDay(_selectedDay!);
final dateFormat = DateFormat('HH:mm');
if (events.isEmpty) {
return const Center(child: Text('선택한 날짜에 이벤트가 없습니다'));
}
return ListView.builder(
itemCount: events.length,
itemBuilder: (context, index) {
final event = events[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
leading: Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: BorderRadius.circular(8),
),
child: const Icon(Icons.event, color: Colors.blue),
),
title: Text(
event.title,
style: const TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(dateFormat.format(event.startDate)),
if (event.location != null) Text(event.location!),
],
),
onTap: () => _navigateToEventDetails(event),
),
);
},
);
}
void _navigateToEventDetails(Event event) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => EventDetailsScreen(event: event),
),
).then((result) {
if (result == true) {
// 이벤트가 수정되었으면 목록 새로고침
_loadEvents();
}
});
}
}