Skip to content

fix: 과거 날짜 대응 관련 문제 수정#842

Merged
spoyodevelop merged 13 commits intofe/devfrom
fe/fix/past-time
Mar 21, 2026
Merged

fix: 과거 날짜 대응 관련 문제 수정#842
spoyodevelop merged 13 commits intofe/devfrom
fe/fix/past-time

Conversation

@spoyodevelop
Copy link
Copy Markdown
Contributor

@spoyodevelop spoyodevelop commented Mar 12, 2026

#️⃣ 연관된 이슈 설명

  1. 백엔드 API 변경으로 과거 시간 검증 책임이 클라이언트로 넘어왔습니다.
  2. 클라이언트에서 검증을 시도했으나, 현재 구조상 과거 시간을 검증하기 어려운 상황에 맞닥뜨렸습니다.
  3. 방 생성 시 v3 API를 사용하여, 과거 날짜에 해당하는 timeslot을 제거한 뒤 방을 새로 생성합니다.
  4. timeslot이 제거되면 해당 슬롯을 선택할 수 없어야 하는데, 직사각형 구조 특성상 선택 불가한 과거 슬롯이 check 페이지에 여전히 노출되는 문제가 있었습니다.
  5. 해당 슬롯을 disabled 처리하여, 현재는 과거 슬롯이 노출되더라도 드래그할 수 없도록 클라이언트에서 차단하고 있으며, 유효성 검증이 정상적으로 동작합니다.

📝 작업 내용

과거 시간대를 선택하면 자동으로 방을 만들때 해당 날짜/시간이 제외됩니다.
예시에서는 3월 12일 23시 30분에 방을 만들었습니다.
before: 3월 12일이 포함된 방이 만들어집니다. or 과거날짜 유효성 검사에 걸려 동작하지 않습니다.
after: 과거날짜인 3월 12일 23시 30분보다 빠른 날짜는 3월 13일 이후 밖에 없으므로, 13일 이후의 타임슬롯만이 포함된 방이 만들어집니다.

CleanShot.2026-03-12.at.23.42.59.mp4

만약, 과거 시간대를 포함해서 방을 만들면 해당 날짜/시간을 disabled 처리합니다.

output.mp4
  • 방 생성 시 v3 API 적용. date + time 조합이 아닌 TimeSlot(number) 구조로 방을 생성하게 됩니다.
  • 해당 구조를 check에도 적용하되, 기존과 동일하게 직사각형으로 모든 date + time slot을 보여주는 구조는 유지합니다.
  • 다만 rooms/session에 v3 API를 사용하여 가장 작은 timeslot을 구하고, 그보다 작은 timetable slot은 비활성화 처리합니다.

따라서 유저 플로우가 다음과 같이 일부 변경되었습니다.

  1. 과거 시간을 포함한 방은 해당 시간을 자동으로 제거한 timeslot만으로 생성됩니다.
  2. 제외된 과거 시간들은 투표 페이지에서 disabled 처리되어 상호작용이 불가합니다.

💬 리뷰 요구사항

  • 광범위한 유저 플로우/스펙 체인지가 있었습니다. 꼼꼼히 확인을 해주시면 감사하겠습니당.
  • 모바일, PC 양쪽에서 간단한 QA를 부탁드립니다. 전반적인 변경 범위는 크지 않으나, v3 API 대응 과정에서 수정이 일부 있었습니다. 변경된 부분은 코멘트로 설명해 두었습니다.
  • 과거 시간을 포함하여 방을 생성해 보시고, check 페이지도 함께 테스트해 보시면 좋을 것 같습니다.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 12, 2026

⚡️ Lighthouse Report

Category Score
🔴 Performance (성능) 38
🟢 Accessibility (접근성) 94
🟠 Best Practices (모범 사례) 75
🟢 SEO (검색엔진 최적화) 100

📊 Performance Details (성능 세부 지표)

Metric (지표) Value
🔴 First Contentful Paint (최초 콘텐츠 표시) 4.7 s
🔴 Largest Contentful Paint (최대 콘텐츠 표시) 8.5 s
🔴 Total Blocking Time (총 차단 시간) 1,180 ms
🟢 Cumulative Layout Shift (누적 레이아웃 이동) 0
🔴 Time To Interactive (상호작용 가능 시간) 8.6 s

@github-actions
Copy link
Copy Markdown

🚀 Storybook preview: https://687852cd7789368357f3bb71-zdyfztsyto.chromatic.com/

return (days << 8) | timeSlotIndex;
},

/**
Copy link
Copy Markdown
Contributor Author

@spoyodevelop spoyodevelop Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버에서 내려오는 availableSlots는 날짜와 시간이 하나의 숫자로 합쳐진 슬롯 코드 배열입니다.
(예시 12244.. 13444...)

히트맵 그리드를 그리려면 이걸 날짜(DateSlot)와 시간(TimeSlot)으로 분리해야 하는데, populateGridAxes가 그 역할을 합니다.

availableDateSlots — 날짜 축 ('YYYY-MM-DD' Set)
availableTimeSlots — 시간 축 ('HH:mm' 배열, 30분 단위)

날짜 최소값 ~ 날짜 최대값 이 availableDateSlots에 들어가고
시간 최소값 ~ 시간 최대값 이 availableTimeSlots에 들어갑니다.

}

const roomInfoStore = createStore<RoomInfoStore>({
minSlotCode: Infinity,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v3를 사용하면 , GET 'room/session' 에 timeSlots가 number[] 따라서, Math.min(timeSlots)를 하면 가장 빠른 날짜를 계산할수 있게 됩니다. 날짜 비교를 할때 단순히 이 시간보다 작은 Timeslot 키를 가지고 있으면 과거로 치부 할수 있습니다. 해당 키를 가진 TimeTableCell, heatmapCell, heatMapPreviewCell은 비활성화 됩니다.

return (
<div
className="time-table-cell"
className={`time-table-cell${isPast ? ' isPast' : ''}`}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

className에 isPast가 달리면, 해당 셀은 disabled 해줍니다.

const availableSlots: number[] = [];
let isPastSelected = false;

for (const date of availableDateSlots) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for 문 내에서, 이전 시간의 경우 isPastSelected를 true로 하고, Toast를 띄울 플래그를 넘겨줍니다.

@m-a-king
Copy link
Copy Markdown
Contributor

@codex review focusing on the existing review comments and unresolved threads

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f87d96dc53

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +151 to +152
for (let d = minDay; d <= maxDay; d++) {
availableDateSlots.add(FormatManager.decodeSlotCode(d << 8).slice(0, 10));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Build grid axes from actual slots, not min/max range

populateGridAxes currently fills every date/time between the minimum and maximum slot indices, which fabricates cells that are not in availableSlots. Because date selection in create flow is non-contiguous (a Set of picked days), a room with gaps (e.g., only Mon/Wed selected) will render Tue cells as valid on check page, allowing users to vote on slots the host never opened. Derive axes from unique decoded slot values instead of expanding continuous min→max ranges.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

@spoyodevelop spoyodevelop Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 실제 사용하는 슬롯만 보여줄수 있죠. 하지만 그럴경우 현재같은 직사각형 형태의 TimeTable이 모양이 변형되어서 나오겠죠. 대대적인 레이아웃 개선이 필요해지기 때문에, 해당부분은 기각하고, 지금 직사각형 형태로 유지하는 쪽이 더 좋다고 생각합니다.

Comment on lines +30 to +34
if (platformType && channelId) {
const response = await roomWithPlatformSubmit();
const response = await createChannelRoomV3({
...payload,
platformType: platformType as 'DISCORD' | 'SLACK',
channelId: channelId || 'DISCORD',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve create-room error handling on API failures

roomInfoSubmit now calls the API functions directly, so failures bypass the useFetch/useHandleError path that previously showed user-facing error toasts and logged context. In the current controllers, submit handlers await this promise without local try/catch, so a rejected create request now surfaces as an unhandled async error with no actionable feedback in the create flow. Wrap these calls with the same fetch error handler (or equivalent explicit catch + toast) to keep failure behavior consistent.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

@spoyodevelop spoyodevelop Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 에러핸들링 수정했습니다. 기존코드는 useFetch단에서 에러헨들링을 처리 하고 있었는데, 해당 내용 인지 못하고 작업했습니다. useFetch를 써서 api fetch 콜백을 만들고 이것을 수행하는 기존 방식으로 변경했습니다.
1f8d452

@github-actions
Copy link
Copy Markdown

🚀 Storybook preview: https://687852cd7789368357f3bb71-kvmopyqlrx.chromatic.com/

Copy link
Copy Markdown
Contributor

@m-a-king m-a-king left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

마햄 수고하셨습니다~

영상 확인해봤는데 좋은 것 같아요! 배포되면 자주 사용하면서 피드백 해볼게요

Copy link
Copy Markdown
Contributor

@hoyyChoi hoyyChoi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

마빈을 믿습니다

@spoyodevelop spoyodevelop merged commit ba09187 into fe/dev Mar 21, 2026
3 checks passed
@spoyodevelop spoyodevelop deleted the fe/fix/past-time branch March 21, 2026 08:58
hoyyChoi pushed a commit that referenced this pull request Mar 21, 2026
* feat: v3 rooms api 대응 및 validation 로직 추가

* fix: 잘못된 날짜 파싱 로직 수정

* feat: v3로 api 마이그레이션 타입 설정 및 url 작업

* feat: minSlotCode을 위한 store 생성

* feat: availableSlots를 제공해주면, dateSlots와 TimeSlots를 파생하는 함수 생성

* feat: avaliableSlots를 DateSlots와 TimeSlots로 변환하는 작업을 추가

* feat: 타입 재선언 및 정돈

* feat: 타입 수정

* feat: minSlotCode를 통해 과거의 시간을 isPast로 파생, 관리하도록 설정

* style: isPast시 disable 설정 및 색 보정

* feat: 요소 선택에 isPast를 선택하지 않도록 설정

* feat: v3 api 적용

* fix: 명확한 에러핸들링을 하게 수정
hoyyChoi added a commit that referenced this pull request Mar 21, 2026
* chore: 버전 변경 (v1.6.4)

* feat: buildspec.yml 파일 수정 (#778)

* buildspec.yml 수정 (#779)

* feat: buildspec.yml 파일 수정

* fix: buildspec.yml 파일 수정

* fix: buildspec.yml 파일 수정

* pnpm + 빌드 결과물 cache 적용 (#780)

* fix: buildspec.yml 파일 수정

* fix: buildspec.yml 파일 수정

* chore: webpack 빌드 결과물 캐시

* chore: webpack 빌드 결과물 캐시

* fix: buildspec.yml 파일 수정 (#781)

* chore: webpack 빌드 결과물 캐시 제거 (#782)

* fix: 과거 날짜 대응 관련 문제 수정 (#842)

* feat: v3 rooms api 대응 및 validation 로직 추가

* fix: 잘못된 날짜 파싱 로직 수정

* feat: v3로 api 마이그레이션 타입 설정 및 url 작업

* feat: minSlotCode을 위한 store 생성

* feat: availableSlots를 제공해주면, dateSlots와 TimeSlots를 파생하는 함수 생성

* feat: avaliableSlots를 DateSlots와 TimeSlots로 변환하는 작업을 추가

* feat: 타입 재선언 및 정돈

* feat: 타입 수정

* feat: minSlotCode를 통해 과거의 시간을 isPast로 파생, 관리하도록 설정

* style: isPast시 disable 설정 및 색 보정

* feat: 요소 선택에 isPast를 선택하지 않도록 설정

* feat: v3 api 적용

* fix: 명확한 에러핸들링을 하게 수정

* chore: 버전 변경 (v1.9.0)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: spoyodevelop <73924592+spoyodevelop@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FE Frontend 🛠 fix 버그

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants