웹: Schedule 페이지 일정/카테고리 로딩 useQuery로 리팩토링
This commit is contained in:
parent
990d360520
commit
d999872517
2 changed files with 35 additions and 62 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import { useState, useEffect, useMemo, useRef, useCallback } from 'react';
|
import { useState, useEffect, useMemo, useRef, useCallback } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Clock, Tag, Link2, ChevronLeft, ChevronRight, ChevronDown, Search, X, Calendar } from 'lucide-react';
|
import { Clock, Tag, Link2, ChevronLeft, ChevronRight, ChevronDown, Search, X, Calendar } from 'lucide-react';
|
||||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
import { useQuery, useInfiniteQuery } from '@tanstack/react-query';
|
||||||
import { useInView } from 'react-intersection-observer';
|
import { useInView } from 'react-intersection-observer';
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import { getSchedules, getCategories, searchSchedules } from '../../../api/public/schedules';
|
import { getSchedules, getCategories, searchSchedules } from '../../../api/public/schedules';
|
||||||
|
|
@ -17,9 +17,6 @@ const decodeHtmlEntities = (text) => {
|
||||||
// 모바일 일정 페이지
|
// 모바일 일정 페이지
|
||||||
function MobileSchedule() {
|
function MobileSchedule() {
|
||||||
const [selectedDate, setSelectedDate] = useState(new Date());
|
const [selectedDate, setSelectedDate] = useState(new Date());
|
||||||
const [schedules, setSchedules] = useState([]);
|
|
||||||
const [categories, setCategories] = useState([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [isSearchMode, setIsSearchMode] = useState(false);
|
const [isSearchMode, setIsSearchMode] = useState(false);
|
||||||
const [searchInput, setSearchInput] = useState(''); // 입력값
|
const [searchInput, setSearchInput] = useState(''); // 입력값
|
||||||
const [searchTerm, setSearchTerm] = useState(''); // 실제 검색어
|
const [searchTerm, setSearchTerm] = useState(''); // 실제 검색어
|
||||||
|
|
@ -130,23 +127,21 @@ function MobileSchedule() {
|
||||||
}
|
}
|
||||||
}, [inView, hasNextPage, isFetchingNextPage, fetchNextPage, isSearchMode, searchTerm]);
|
}, [inView, hasNextPage, isFetchingNextPage, fetchNextPage, isSearchMode, searchTerm]);
|
||||||
|
|
||||||
// 일정 및 카테고리 로드 (월이 변경될 때만 실행)
|
// 일정 및 카테고리 로드 (useQuery)
|
||||||
const viewMonth = `${selectedDate.getFullYear()}-${selectedDate.getMonth()}`;
|
const viewYear = selectedDate.getFullYear();
|
||||||
|
const viewMonth = selectedDate.getMonth() + 1;
|
||||||
useEffect(() => {
|
|
||||||
const year = selectedDate.getFullYear();
|
// 카테고리 데이터 로드
|
||||||
const month = selectedDate.getMonth() + 1;
|
const { data: categories = [] } = useQuery({
|
||||||
|
queryKey: ['scheduleCategories'],
|
||||||
setLoading(true);
|
queryFn: getCategories,
|
||||||
Promise.all([
|
});
|
||||||
getSchedules(year, month),
|
|
||||||
getCategories()
|
// 월별 일정 데이터 로드
|
||||||
]).then(([schedulesData, categoriesData]) => {
|
const { data: schedules = [], isLoading: loading } = useQuery({
|
||||||
setSchedules(schedulesData);
|
queryKey: ['schedules', viewYear, viewMonth],
|
||||||
setCategories(categoriesData);
|
queryFn: () => getSchedules(viewYear, viewMonth),
|
||||||
setLoading(false);
|
});
|
||||||
}).catch(console.error);
|
|
||||||
}, [viewMonth]);
|
|
||||||
|
|
||||||
// 월 변경
|
// 월 변경
|
||||||
const changeMonth = (delta) => {
|
const changeMonth = (delta) => {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useMemo, useDeferredValue, memo } from 're
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Clock, ChevronLeft, ChevronRight, ChevronDown, Tag, Search, ArrowLeft, Link2, X } from 'lucide-react';
|
import { Clock, ChevronLeft, ChevronRight, ChevronDown, Tag, Search, ArrowLeft, Link2, X } from 'lucide-react';
|
||||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
import { useQuery, useInfiniteQuery } from '@tanstack/react-query';
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import { useInView } from 'react-intersection-observer';
|
import { useInView } from 'react-intersection-observer';
|
||||||
import { getTodayKST } from '../../../utils/date';
|
import { getTodayKST } from '../../../utils/date';
|
||||||
|
|
@ -28,10 +28,21 @@ function Schedule() {
|
||||||
|
|
||||||
|
|
||||||
// 데이터 상태
|
// 데이터 상태
|
||||||
const [schedules, setSchedules] = useState([]);
|
|
||||||
const [categories, setCategories] = useState([]);
|
|
||||||
const [selectedCategories, setSelectedCategories] = useState([]);
|
const [selectedCategories, setSelectedCategories] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
|
// 카테고리 데이터 로드 (useQuery)
|
||||||
|
const { data: categories = [] } = useQuery({
|
||||||
|
queryKey: ['scheduleCategories'],
|
||||||
|
queryFn: getCategories,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 월별 일정 데이터 로드 (useQuery)
|
||||||
|
const year = currentDate.getFullYear();
|
||||||
|
const month = currentDate.getMonth();
|
||||||
|
const { data: schedules = [], isLoading: loading } = useQuery({
|
||||||
|
queryKey: ['schedules', year, month + 1],
|
||||||
|
queryFn: () => getSchedules(year, month + 1),
|
||||||
|
});
|
||||||
|
|
||||||
// 카테고리 필터 툴팁
|
// 카테고리 필터 툴팁
|
||||||
const [showCategoryTooltip, setShowCategoryTooltip] = useState(false);
|
const [showCategoryTooltip, setShowCategoryTooltip] = useState(false);
|
||||||
|
|
@ -132,39 +143,7 @@ function Schedule() {
|
||||||
return () => clearTimeout(timeoutId);
|
return () => clearTimeout(timeoutId);
|
||||||
}, [originalSearchQuery]);
|
}, [originalSearchQuery]);
|
||||||
|
|
||||||
// 데이터 로드
|
// 카테고리/일정 데이터는 상단에서 useQuery로 관리됨
|
||||||
// 초기 데이터 로드 (카테고리만)
|
|
||||||
useEffect(() => {
|
|
||||||
loadCategories();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 월 변경 시 일정 로드
|
|
||||||
useEffect(() => {
|
|
||||||
const year = currentDate.getFullYear();
|
|
||||||
const month = currentDate.getMonth();
|
|
||||||
loadSchedules(year, month + 1);
|
|
||||||
}, [currentDate]);
|
|
||||||
|
|
||||||
const loadSchedules = async (year, month) => {
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
const data = await getSchedules(year, month);
|
|
||||||
setSchedules(data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('일정 로드 오류:', error);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadCategories = async () => {
|
|
||||||
try {
|
|
||||||
const data = await getCategories();
|
|
||||||
setCategories(data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('카테고리 로드 오류:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 외부 클릭시 팝업 닫기
|
// 외부 클릭시 팝업 닫기
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -195,11 +174,10 @@ function Schedule() {
|
||||||
}, [selectedDate]);
|
}, [selectedDate]);
|
||||||
|
|
||||||
// 달력 관련 함수
|
// 달력 관련 함수
|
||||||
const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
|
const getDaysInMonth = (y, m) => new Date(y, m + 1, 0).getDate();
|
||||||
const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay();
|
const getFirstDayOfMonth = (y, m) => new Date(y, m, 1).getDay();
|
||||||
|
|
||||||
const year = currentDate.getFullYear();
|
// year, month는 상단에서 이미 선언됨 (useQuery)
|
||||||
const month = currentDate.getMonth();
|
|
||||||
const daysInMonth = getDaysInMonth(year, month);
|
const daysInMonth = getDaysInMonth(year, month);
|
||||||
const firstDay = getFirstDayOfMonth(year, month);
|
const firstDay = getFirstDayOfMonth(year, month);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue