Skip to content

LC-3134 하반기 멤버십 랜딩페이지 프로토 타입 배포#2407

Merged
dusvlf111 merged 36 commits into
mainfrom
LC-3134-하반기-멤버십-랜딩페이지-프로토-타입-배포
Jun 22, 2026

Hidden character warning

The head ref may contain hidden characters: "LC-3134-\ud558\ubc18\uae30-\uba64\ubc84\uc2ed-\ub79c\ub529\ud398\uc774\uc9c0-\ud504\ub85c\ud1a0-\ud0c0\uc785-\ubc30\ud3ec"
Merged

LC-3134 하반기 멤버십 랜딩페이지 프로토 타입 배포#2407
dusvlf111 merged 36 commits into
mainfrom
LC-3134-하반기-멤버십-랜딩페이지-프로토-타입-배포

Conversation

@dusvlf111

@dusvlf111 dusvlf111 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

개요

하반기 멤버십 랜딩을 분리 배포 iframe 임베드에서 웹앱 직접 마운트로 전환하고, 단일 올패스 플랜 개편·13주 합격 플랜·현직자 세미나·VOD 옵션을 추가했으며, 전반적인 디자인/UX를 개선했습니다. (LC-3134)

주요 변경

구조

  • 별도 레포(Vite) 랜딩을 domain/membership/ 로 복사·직접 마운트, 전역 CSS를 .membership-root 스코프로 격리(전역 누수 방지), 포털 모달 래핑·body.heroin 스코핑 버그 수정
  • iframe(MembershipEmbed) 및 분기 제거, 글로벌 NavBar 복원(ConditionalLayout)

결제

  • 복사해온 자체 결제(PlanSheet)·토스 링크·3단계 플랜 제거기존 챌린지 결제 플로우(PricePlanBottomSheet) 재사용 (env 챌린지 ID NEXT_PUBLIC_MEMBERSHIP_CHALLENGE_ID). 기본/+VOD 옵션은 어드민 가격플랜으로 세팅
  • 시트 열림 시 ApplyBar 겹침 해결(zustand 공유 상태)

신규 섹션

  • 단일 올패스 플랜 + VOD 옵션 카드(+옵션 추가 분리)
  • 하반기 공채 13주 합격 플랜: 전체 매트릭스(멤버십 제공 강조 스티커) / 월별 13주 타임라인 토글
  • 현직자 무료 세미나: 라이브 2회(확정/미정 위계)
  • Solution 섹션 허브-위성 통합 다이어그램

버그·디자인

  • 하이드레이션(BarCountdown)·MUI kebab-case·RadioGroup uncontrolled 경고 해결
  • 혜택·VOD·세미나 아이콘 lucide 통일, 올패스 네온 글로우, 블루 톤 통일, STEP 헤더 색 통일

검증

  • tsc --noEmit · ESLint · Prettier 통과
  • Jest 멤버십 44 테스트 통과 (lucide-react ESM은 테스트용 stub 매핑)
  • next build 정상 · /membership 정적 생성 · 데스크탑/모바일 렌더 확인

참고 (배포 전 확인)

  • 어드민: 챌린지 100000427 에 가격플랜 2개(기본/+VOD)를 서로 다른 플랜 타입으로 세팅
  • Vercel 환경변수 NEXT_PUBLIC_MEMBERSHIP_CHALLENGE_ID 등록
  • 일부 콘텐츠(13주 차트 미정 셀·세미나 링크/멘토 사진)는 placeholder

🤖 Generated with Claude Code

dusvlf111 and others added 30 commits June 23, 2026 03:41
- letscareer-membership-landing(Vite) 의 section/ui/data/lib 를 도메인에 복사
- 전역 CSS 20종을 .membership-root 하위로 스코핑(전역 누수 차단)
- 진입점 MembershipLanding 신설, page.tsx·ConditionalLayout 직접 마운트로 전환
- MembershipEmbed(iframe) 및 관련 분기 제거, 글로벌 NavBar 복원
- 포털 모달(PlanSheet/BenefitModal/ImageLightbox) .membership-root 래핑으로 스타일 복원
- body.heroin 등 body 앵커 셀렉터 스코핑 교정(첫 화면 히어로 미표시 버그 수정)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
멤버십 자체 결제 폐기에 앞서, 어드민 챌린지(100000427)에 결제를 위임하기
위한 NEXT_PUBLIC_MEMBERSHIP_CHALLENGE_ID env 와 유효성 가드 헬퍼를 신설한다.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CTA 이벤트 구독 → 로그인 게이트 → 기존 챌린지 결제 시트(PricePlanBottomSheet)를
env 챌린지(100000427)로 연다. challenge 조회는 컨트롤러 1곳에서만 수행.

useChallengeQuery 반환 타입(Dayjs 날짜)이 PricePlanBottomSheet 가 요구하는
ChallengeIdPrimitive(string 날짜)와 불일치해, reuse 파일 수정 없이 primitive
스키마로 파싱하는 useMembershipChallengeQuery 를 신설해 연결한다.
로그인 redirect 경로 빌더(buildLoginRedirectPath)도 추출해 단위 테스트.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
단일 올패스 플랜이라 플랜 선택 인자가 불필요 → openPlanSheet()/onOpenPlanSheet(()=>void)
로 축소하고 MembershipPlanKey 의존을 제거한다. 이벤트 라운드트립 단위 테스트 추가.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3단계 카드/비교표/탭 제거 → 단일 상품 카드. 가격 위계(정가 취소선 → 특가 →
84% OFF 배지)와 혜택 7종 스캔형 그리드로 밀도·여백 재설계(.membership-root 스코프).
data/plans.ts 를 단일 플랜 표시 데이터로 교체, 할인율 계산 단위 테스트 추가.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MembershipLanding 에서 <PlanSheet/> → <MembershipPaymentSheet/> 로 교체하고
앱 컴포넌트라 .membership-root 스코프 밖에 마운트한다. 미사용 plan CSS import 정리
(plan-single.css 추가). membership.ts 의 MEMBERSHIP_PLANS·MembershipPlanKey 와
links.ts 의 TOSS_LINKS, apply.css 복사 시트 규칙 제거(날짜·seats·formatKRW 보존).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
매트릭스(5단계×6카테고리)와 13주 타임라인을 단일 출처로 정의.
미확정 셀/주차는 placeholder로 두고 차원·주차 연속성은 완전하게 채움.
직접/무료자료/챌린지 owner 범례와 무결성 테스트 포함.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5단계×6카테고리 매트릭스 렌더. 셀에 과업+수행주체 라벨(직접/무료자료/챌린지).
챌린지=멤버십 강조 색으로 owner별 일관 색 체계+범례 구현.
모바일은 가로 스크롤로 컬럼 가독성 보존. 셀은 데이터 map.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
JUL/AUG/SEP 월 카드 + 주차별 세로 타임라인(연결선·노드).
챌린지 주차는 owner 색으로 강조. 모바일 세로 스택.
미확정 주차는 placeholder로 명시.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
전체↔월별 토글(CoursePlanToggle)+범례+뷰 전환 페이드 애니메이션.
SolutionSection 다음에 CoursePlanSection 마운트, course-plan.css import.
CSS는 .membership-root 스코프로 전역 누수 없음.
빌드/타입체크/린트 통과, /membership 정적 prerender 확인.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
확정(confirmed)/추후공개(tba) 2개 세션을 status 로 구분하고,
시간·주제·멘토·신청링크를 nullable 로 두어 미정 상태를 1급으로 모델링.
상태별 필수 필드 가드 테스트 포함.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
확정(LIVE 01)은 오렌지 강조·그림자로 띄우고, 추후공개(LIVE 02)는
점선·톤다운 + '추후 공개' placeholder 로 1급 표시해 위계를 구분.
멘토 신뢰 카드(이니셜 폴백)·상태별 CTA(링크/비활성) 분기.
상태 분기는 작은 컴포넌트로 분리, 렌더 테스트 포함.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CoursePlanSection(13주 플랜) 다음에 SeminarSection 배치 + seminar.css
import(course-plan.css 뒤, cascade 순서 유지). 섹션 스모크 테스트 포함.
빌드/타입체크/린트/테스트 통과, /membership 정적 생성 확인.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- owner 에 challenge-deep 추가, 매트릭스 6카테고리×STEP01~05(서류 STEP03 2셀=31셀)
- 각 셀 title·desc 시안 원문 그대로 입력
- 월별 3개월(JUL/AUG/SEP) 액센트·배지·타이틀·서브, 12카드(12·13 묶음) + isChallenge
- 다크 푸터 한 줄 동선 칩(FLOW_CHIPS), 헤더 카피 풀텍스트
- 데이터 무결성 테스트 갱신(31셀·STEP03 2셀·13주 커버)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 빽빽한 grid 대신 카테고리 행 × STEP 카드 레이아웃으로 밀도·여백·위계 재설계
- owner 4색 일관: challenge/challenge-deep 오렌지 강조, free 정보색, self 중립
- 셀에 title+desc 노출, document STEP03 2셀 세로 적층
- 준비(prep)/실전(live) 구간을 STEP 헤더 색으로 안내
- 모바일(<=920px): 가로 스크롤 제거, 카테고리 카드로 분해 + STEP 태그 노출
- 범례 4종으로 확장, 매트릭스 스크롤 힌트 제거
- UI 테스트 신규 구조에 맞게 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 월 헤더(wk-mon 큰 숫자 액센트 + 타이틀 + 서브 + 배지) + wk-line 액센트 라인
- wk-cards 4열(반응형 2->1열), 챌린지 카드 wk-ch 배지
- 월 액센트 --m-accent(JUL/AUG/SEP) + 배지 3색을 월 래퍼 인라인 변수로 주입
- 12·13 묶음 카드(wk-no 12·13), 다크 wk-flow 한 줄 동선 푸터
- 시안 CSS 값 그대로 .membership-root 스코프로 이식

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 🎬 아이콘 + 구매자 전용 배지 + 취준위키 VOD 모음집 타이틀/서브
- 정가 300,000원 취소선 -> 29,900원 강조, VOD 옵션 추가 버튼
- 버튼 클릭 시 openPlanSheet()로 기존 결제 시트 오픈(별도 결제 로직 없음)
- PlansSection 단일 올패스 카드 하단에 배치, .membership-root 스코프 CSS

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- role=cell/listitem 의존 제거 -> 콘텐츠 텍스트(채용 캘린더 / WEEK) 기반 단언

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
useState 초기값에서 Date.now()를 호출하던 것을 마운트 전 0 고정으로 바꾸고,
useEffect에서 즉시 실제 값을 계산하도록 변경해 SSR/CSR 출력을 일치시킴.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
DEFAULT_LABEL_SX의 'white-space'를 camelCase whiteSpace로 교체.
MUI sx는 camelCase 키만 인식하므로 동작 동일, 콘솔 경고만 제거됨.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RadioGroup을 defaultValue에서 value={pricePlan} controlled로 변경해
MUI uncontrolled→controlled 경고를 제거. pricePlan useState 초기값이
기존 defaultValue 계산식(LIGHT>PREMIUM>STANDARD>BASIC)이라 기본 선택값 동일.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
useMembershipSheetStore(zustand)를 추가해 MembershipPaymentSheet 의 시트
열림/닫힘을 공유 상태로 동기화하고, ApplyBar 가 이를 구독해 시트가 열려 있으면
렌더하지 않도록 변경. 닫히면 ApplyBar 복귀.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… 블룸)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cp-legend 블록·OWNER_LEGEND 데이터·cp-legend* CSS 제거.
매트릭스 셀 owner 색 구분은 유지. 관련 테스트 갱신.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
background #1b1e2b → 연한 틴트(--bg-cool)+보더로 페이지 톤 통일.
칩 시퀀스 내용·구조 유지, 컨테이너만 통일해 혼자 튀지 않게.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
기존 messy chips→arrow→pass 흐름을 허브 앤 스포크로 교체.
중앙 허브(하반기 멤버십)로 위성 6종(챌린지·가이드북·스터디·VOD·
현직자 멘토링·외부 제휴)이 화살표로 수렴해 "하나로 통합" 인상.
데스크탑 방사형 그리드 / 모바일 세로 스택+허브 강조. .rv 리빌 유지.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…13주 헤더 줄바꿈

- Solution 허브: 중앙 박스 컴팩트화 + 글자 강조, 6위성 화살표를 대각선 수렴형(SVG)으로, 상하 간격 축소, 제목 한 줄
- 올패스 카드: 패딩·폰트·간격 축소로 한 화면에 들어오게
- VOD 카드: 올패스와 사이에 "+옵션 추가" 구분 배지 추가
- 13주 합격 플랜 헤더: 제목/설명 의도된 줄바꿈 적용

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dusvlf111 and others added 4 commits June 23, 2026 05:51
- 위성 6종에 lucide 아이콘 칩(그라데이션) + 카드 그림자·블루틴트로 존재감 강화
- 수렴 화살표 두께↑·길이↓, col-gap 확대로 허브에 닿지 않게 간격 확보
- "+옵션 추가" 배지 크기 확대(그라데이션 원형)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 직접(self) 셀의 owner 태그 모두 제거하고 흐리게 처리(뒤로 물러나게)
- 멤버십 제공 셀(무료자료·챌린지·심화)은 밝게 강조 + 우상단에 "✓ 멤버십 제공" 스티커(붙여놓은 듯한 모서리 라벨)
- 하단에 흐린 안내: 태그 없는 단계는 직접 준비 영역
- 테스트를 새 태그 구조에 맞게 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 세미나: 이모지(📅⏰🎯) → lucide 아이콘 칩, 확정 카드 블루 프리미엄 톤(그라데이션 아바타·블루 펄스·블루 그라데이션 상태칩)으로 사이트 톤 통일
- 매트릭스 STEP 01~05 헤더의 phase(준비/실전) 색 구분 제거 → 전부 동일(블루)
- jest: lucide-react(ESM) 를 테스트용 stub 으로 moduleNameMapper 매핑(next/jest SWC 파싱 회피)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot changed the title feat(membership): 하반기 멤버십 랜딩 — iframe 임베드 → 웹앱 직접 마운트 + 단일 플랜·13주 플랜·세미나·디자인 개선 LC-3134 하반기 멤버십 랜딩페이지 프로토 타입 배포 Jun 22, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

이번 풀요청은 기존 iframe 임베드 방식의 멤버십 랜딩 페이지를 본 웹앱에 직접 마운트하는 방식으로 전환하며, 이에 필요한 다양한 섹션 컴포넌트, 스타일시트, 데이터 파일 및 테스트 코드를 추가하는 변경사항을 담고 있습니다. 코드 리뷰에서는 도메인 간 직접 import 제한 규칙 위반 사항이 지적되었으며, 직접 마운트 전환으로 인해 무동작하게 된 headerSync.ts 레거시 코드 제거, MutationObserver 사용으로 인한 성능 저하 우려 및 선언적 애니메이션 제어로의 개선, 그리고 BenefitModal에서 매 렌더링마다 불필요하게 모든 모달의 JSX 트리를 생성하는 구조에 대한 최적화 피드백이 제시되었습니다.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread apps/web/src/domain/membership/ui/MembershipPaymentSheet.tsx
Comment thread apps/web/src/domain/membership/lib/headerSync.ts Outdated
Comment thread apps/web/src/domain/membership/ui/MembershipAnimations.tsx
Comment thread apps/web/src/domain/membership/ui/BenefitModal.tsx
…tionObserver 제거)

- 출시 전: NEXT_PUBLIC_MEMBERSHIP_CHALLENGE_ID 미설정이면 5개 CTA(Hero·Plans·VOD·FinalCta·ApplyBar)를 "출시 전" 비활성으로 표시(IS_MEMBERSHIP_LAUNCHED)
- 리뷰#2: 직접 마운트로 무동작이 된 headerSync postMessage/스크롤 리스너 제거, 모달 배경 스크롤 잠금만 유지(startHeaderSync 호출 제거)
- 리뷰#3: MembershipAnimations 의 MutationObserver 제거(매초 Countdown 틱마다 발화하는 비용 제거) — 1회 관찰 + 안전 타이머로 커버

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dusvlf111

Copy link
Copy Markdown
Collaborator Author

@gemini-code-assist 리뷰 감사합니다. 4건 검토 후 반영했습니다.

#2 headerSync 무동작 코드 (HIGH) — 수정
직접 마운트 전환으로 죽은 startHeaderSync(스크롤 리스너 + no-op postMessage)를 제거하고, MembershipLanding의 호출도 삭제했습니다. 모달 배경 스크롤 잠금(setOverlayOpen)만 남겼습니다(모달은 자체 스크롤 락이 없어 필요).

#3 MutationObserver 성능 (HIGH) — 수정
MembershipAnimationsMutationObserver를 제거했습니다. 지적대로 매초 갱신되는 Countdown 텍스트 변화에도 발화해 불필요한 querySelectorAll 비용이 컸습니다. .rv/.timeline은 모두 마운트 시 존재하고 토글 뷰는 .rv를 쓰지 않으므로, 1회 observeAll() + 안전 타이머로 누락 없이 커버됩니다. (선언적 훅 전면 전환은 별도 리팩터 이슈로 추적)

🟡 #4 BenefitModal 전체 JSX 생성 (MEDIUM) — 부분 완화 + 후속
현재 if (!modalId) return null닫힌 상태(상시)에서는 8개 JSX를 만들지 않습니다. 8개 생성은 모달이 열린 순간(사용자 클릭, 비핫패스)에만 발생합니다. 제안하신 모달별 컴포넌트 분리(switch 렌더)는 가독성/효율 개선에 동의하며, 복사 이관된 600+줄 파일이라 별도 후속 PR로 진행하겠습니다.

ℹ️ #1 도메인 간 import (HIGH) — 의도된 공용 결제 흐름 재사용
MembershipPaymentSheet → domain/program/PricePlanBottomSheet는 가이드라인상 cross-domain이 맞습니다. 다만 이는 앱 전역에서 쓰는 검증된 챌린지 결제 플로우를 멤버십이 재사용하도록 한 의도된 제품 결정으로(자체 결제 UI 중복/토스 링크 관리 제거 목적), PRD에서 합의된 사항입니다. PricePlanBottomSheetcommon/ 공용 결제 모듈로 승격하는 리팩터는 챌린지 상세 등 program 도메인 전반에 영향이 커, 본 PR 범위 밖 별도 작업으로 분리하겠습니다.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

안녕하세요, dusvlf111님. 상세한 피드백 반영과 설명 감사합니다.

제시해주신 수정 사항들은 코드의 성능과 유지보수성을 크게 개선하는 방향으로 잘 이루어졌습니다. 특히 MutationObserver 제거를 통한 성능 최적화와 MembershipLanding의 직접 마운트 전환은 이번 리팩터링의 핵심을 잘 짚어주셨습니다.

말씀하신 대로 BenefitModal의 컴포넌트 분리나 PricePlanBottomSheet의 공용 모듈 승격은 현재 PR의 범위를 넘어선 중요한 작업이므로, 별도 PR로 분리하여 진행하는 것이 합리적입니다. 제품 결정 사항(도메인 간 import)에 대해서도 충분히 이해했습니다.

제시해주신 변경 사항들을 바탕으로 검토를 마무리하겠습니다. 고생 많으셨습니다!

`rev-track${reverse?'reverse':''}` → 공백 없이 `rev-trackreverse`(무효 클래스)가 되어
두 번째 줄에 .rev-track.reverse 애니메이션이 안 걸렸음. 공백을 템플릿 리터럴 쪽에 두어 수정.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dusvlf111 dusvlf111 self-assigned this Jun 22, 2026
@dusvlf111 dusvlf111 merged commit 5a0b37d into main Jun 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant