import React, { useState, useCallback } from 'react' import { View, Text, TouchableOpacity, FlatList, StyleSheet, RefreshControl } from 'react-native' import { useFocusEffect } from 'expo-router' import { COLORS } from '../../constants/Config' import client from '../../services/api' const WEEKDAYS = ['일', '월', '화', '수', '목', '금', '토'] export default function WorkCalendarScreen() { const today = new Date() const [year, setYear] = useState(today.getFullYear()) const [month, setMonth] = useState(today.getMonth()) const [events, setEvents] = useState([]) const [selected, setSelected] = useState('') const [loading, setLoading] = useState(false) const load = useCallback(async (y: number, m: number) => { setLoading(true) try { const r = await client.get('/api/mobile2/work-calendar', { params: { year: y, month: m + 1 } }) setEvents(r.data?.events ?? r.data?.items ?? []) } catch { setEvents([]) } finally { setLoading(false) } }, []) useFocusEffect(useCallback(() => { load(year, month) }, [year, month, load])) const firstDay = new Date(year, month, 1).getDay() const daysInMonth = new Date(year, month + 1, 0).getDate() const cells = Array.from({ length: firstDay }, () => null).concat(Array.from({ length: daysInMonth }, (_, i) => i + 1)) const eventsOn = (day: number) => { const key = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}` return events.filter(e => (e.date ?? e.scheduled_at ?? '').startsWith(key)) } const selectedEvents = selected ? events.filter(e => (e.date ?? e.scheduled_at ?? '').startsWith(selected)) : [] const prev = () => { if (month === 0) { setYear(y => y - 1); setMonth(11) } else setMonth(m => m - 1) } const next = () => { if (month === 11) { setYear(y => y + 1); setMonth(0) } else setMonth(m => m + 1) } return ( {year}년 {month + 1}월 {WEEKDAYS.map(d => {d})} {cells.map((day, i) => { if (!day) return const key = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}` const dayEvents = eventsOn(day) const isToday = day === today.getDate() && month === today.getMonth() && year === today.getFullYear() const isSel = key === selected return ( setSelected(isSel ? '' : key)}> {day} {dayEvents.length > 0 && } ) })} {selectedEvents.length > 0 && ( String(i)} style={s.eventList} renderItem={({ item }) => ( {item.title ?? item.name} {item.start_time ?? ''} · {item.category ?? item.type ?? ''} )} /> )} ) } const s = StyleSheet.create({ container: { flex: 1, backgroundColor: COLORS.bg }, nav: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: 12 }, navBtn: { padding: 8 }, navText: { fontSize: 16, color: COLORS.accent }, monthLabel: { fontSize: 18, fontWeight: '800', color: COLORS.text }, weekRow: { flexDirection: 'row', paddingHorizontal: 4 }, weekDay: { flex: 1, textAlign: 'center', fontSize: 11, fontWeight: '700', color: COLORS.muted, paddingVertical: 4 }, grid: { flexDirection: 'row', flexWrap: 'wrap', paddingHorizontal: 4 }, cell: { width: '14.28%', aspectRatio: 1, alignItems: 'center', justifyContent: 'center', padding: 2 }, today: { backgroundColor: COLORS.accent, borderRadius: 20 }, selCell: { backgroundColor: COLORS.accent + '30', borderRadius: 20 }, dayNum: { fontSize: 13, color: COLORS.text }, dot: { width: 5, height: 5, borderRadius: 3, backgroundColor: COLORS.danger, marginTop: 2 }, eventList: { flex: 1, padding: 12 }, eventCard: { backgroundColor: '#fff', borderRadius: 8, padding: 12, marginBottom: 6, elevation: 1 }, eventTitle: { fontSize: 13, fontWeight: '700', color: COLORS.text, marginBottom: 2 }, eventMeta: { fontSize: 11, color: COLORS.muted }, })