fix(sched): 날짜 기본 선택·가운데 정렬 전 리그 통일
- 기본 날짜: 오늘 → 경기 없으면 다음 경기일 → 시즌 종료면 마지막 날짜 (기존엔 첫 날짜(가장 과거)로 떨어져 백필 후 3주 전이 기본 선택되던 문제) - '오늘' 을 KST 로 계산 (기존 UTC — KST 오전 9시 전엔 어제로 잡힘) - 선택 칩 가운데 정렬을 리그/탭 전환뿐 아니라 선택 변경·비동기 로드에도 적용 - 목록 비동기 로드 시에도 세션 저장 선택 복원 동작 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
eecc9829b4
commit
e2d1647100
@ -99,13 +99,19 @@ export default function ScheduleBoard({
|
||||
);
|
||||
}, [matches, isBaseball, lang]);
|
||||
|
||||
// 기본 선택: 오늘(없으면 첫 날짜) / A조 / 현재 진행 라운드.
|
||||
// 기본 선택: 오늘(경기 없으면 다음 경기일, 시즌 종료면 마지막 날짜) / A조 / 현재 진행 라운드.
|
||||
// 단, 직전 세션 선택을 sessionStorage 에 보관 → 상세 진입 후 뒤로가기 시 그대로 복원(오늘로 초기화 X).
|
||||
const todayKey = useMemo(() => new Date().toISOString().slice(0, 10), []);
|
||||
// 사이트 전체가 KST 기준이라 "오늘"도 클라이언트 시간대와 무관하게 KST 로 계산.
|
||||
const todayKey = useMemo(
|
||||
() => new Date(Date.now() + 9 * 3600_000).toISOString().slice(0, 10),
|
||||
[],
|
||||
);
|
||||
const defaultDate = (ds: string[], today: string) =>
|
||||
(ds.includes(today) ? today : ds.find((d) => d > today) ?? ds[ds.length - 1]) ?? "";
|
||||
const [selDate, setSelDate] = useState(() => {
|
||||
const saved = sessionStorage.getItem("tp.sched.date");
|
||||
if (saved && dates.includes(saved)) return saved;
|
||||
return (dates.includes(todayKey) ? todayKey : dates[0]) ?? "";
|
||||
return defaultDate(dates, todayKey);
|
||||
});
|
||||
const [selGroup, setSelGroup] = useState(() => {
|
||||
const saved = sessionStorage.getItem("tp.sched.group");
|
||||
@ -140,7 +146,11 @@ export default function ScheduleBoard({
|
||||
|
||||
useEffect(() => {
|
||||
if (dates.length && !dates.includes(selDate)) {
|
||||
setSelDate(dates.includes(todayKey) ? todayKey : dates[0]);
|
||||
// 목록이 비동기 로드될 때도 세션 복원이 동작하게 saved 를 우선 확인
|
||||
const saved = sessionStorage.getItem("tp.sched.date");
|
||||
setSelDate(
|
||||
saved && dates.includes(saved) ? saved : defaultDate(dates, todayKey),
|
||||
);
|
||||
}
|
||||
}, [dates, selDate, todayKey]);
|
||||
// 리그 전환 시 목록에 없는 팀이면 첫 팀으로
|
||||
@ -216,7 +226,18 @@ export default function ScheduleBoard({
|
||||
|
||||
{/* 칩: 날짜 / 조 / 라운드 — 단일 줄 가로 스크롤 + 양 끝 화살표(PC에서 마우스로 넘김, 끝 도달 시 숨김) */}
|
||||
{effTab !== "rank" && (
|
||||
<ChipScroller resetKey={`${league}:${effTab}`}>
|
||||
<ChipScroller
|
||||
resetKey={`${league}:${effTab}`}
|
||||
centerKey={
|
||||
effTab === "date"
|
||||
? selDate
|
||||
: effTab === "team"
|
||||
? selTeam
|
||||
: effTab === "group"
|
||||
? selGroup
|
||||
: selRound
|
||||
}
|
||||
>
|
||||
{effTab === "date"
|
||||
? dates.map((d) => (
|
||||
<Chip key={d} active={d === selDate} onClick={() => setSelDate(d)}>
|
||||
@ -274,9 +295,11 @@ export default function ScheduleBoard({
|
||||
function ChipScroller({
|
||||
children,
|
||||
resetKey,
|
||||
centerKey,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
resetKey?: string | number;
|
||||
centerKey?: string; // 현재 선택값 — 바뀔 때마다 선택 칩을 가운데로 (비동기 로드·칩 클릭 포함)
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [atStart, setAtStart] = useState(true);
|
||||
@ -290,7 +313,7 @@ function ChipScroller({
|
||||
setAtEnd(el.scrollLeft >= max - 1);
|
||||
};
|
||||
|
||||
// 탭/목록 변경 시: 선택된 칩을 가운데로 + 재측정 (레이아웃 확정 후)
|
||||
// 탭/목록/선택 변경 시: 선택된 칩을 가운데로 + 재측정 (레이아웃 확정 후)
|
||||
// 선택 칩이 없으면 맨 앞으로 되감는다.
|
||||
useLayoutEffect(() => {
|
||||
const el = ref.current;
|
||||
@ -301,7 +324,7 @@ function ChipScroller({
|
||||
: 0;
|
||||
}
|
||||
measure();
|
||||
}, [resetKey]);
|
||||
}, [resetKey, centerKey]);
|
||||
|
||||
useEffect(() => {
|
||||
measure();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user