feat(IN-271): 경쟁사 영상 분석 - 선택 액션바 및 AI 인사이트 구현#138
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review 🎯 Walkthrough유튜브 영상 ID 목록으로 POST /brand-collaborations/trends를 호출해 콘텐츠 키워드, 채널 특성, 전략 인사이트를 받아오는 타입·API·훅·MSW 핸들러와 이를 렌더링하는 인사이트 카드·섹션, 페이지·필터 연동을 추가합니다. 📋 Changes트렌드 분석 기능 개발
🎯 Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 👥 Suggested reviewers
🐰 Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
src/pages/competitor/ui/CompetitorPage.tsx (1)
60-66: ⚡ Quick win초기화 시 상세 검색 열림 상태도 함께 리셋하는 편이 일관적입니다.
Line 61의
handleReset은 필터/선택/분석 상태를 모두 초기화하는데,isDetailOpen은 유지됩니다. 초기화 의미를 맞추려면setIsDetailOpen(false)도 포함해 주세요.수정 예시
function handleReset() { setDraftFilter(DEFAULT_COMPETITOR_FILTER) setAppliedFilter(null) setSelectedVideoIds(new Set()) setAnalyzedVideoIds([]) + setIsDetailOpen(false) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/competitor/ui/CompetitorPage.tsx` around lines 60 - 66, handleReset currently resets draft/applied filters and selected/analyzed video state but leaves the detail-panel open state untouched; update the handleReset function to also call setIsDetailOpen(false) so the isDetailOpen state is reset when clearing filters/selection/analysis (look for the handleReset definition and add setIsDetailOpen(false) alongside setDraftFilter, setAppliedFilter, setSelectedVideoIds, and setAnalyzedVideoIds).src/widgets/competitor/competitorFilter/ui/CompetitorFilterPanel.tsx (1)
105-107: ⚡ Quick win상세 검색 토글에 ARIA 상태를 연결해 주세요.
Line 114의 토글 버튼은 시각적으로는 동작하지만, 스크린리더에는 펼침 상태가 전달되지 않습니다.
aria-expanded와aria-controls를 추가하고, Line 105의 상세 영역에id를 연결해 주세요.수정 예시
- {isDetailOpen && ( - <CompetitorFilterDetailFields filter={filter} onChange={onChange} /> - )} + {isDetailOpen && ( + <div id='competitor-detail-filters'> + <CompetitorFilterDetailFields filter={filter} onChange={onChange} /> + </div> + )} <button type='button' onClick={() => setIsDetailOpen(!isDetailOpen)} + aria-expanded={isDetailOpen} + aria-controls='competitor-detail-filters' className='flex cursor-pointer items-center gap-4 rounded-full px-16 py-6 text-noto-label-md-normal text-text-and-icon-secondary transition-colors hover:bg-background-gray-default'>Also applies to: 114-117
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/widgets/competitor/competitorFilter/ui/CompetitorFilterPanel.tsx` around lines 105 - 107, The detail toggle button currently doesn't expose its expanded state to assistive tech; update the toggle (the element that flips isDetailOpen) to include aria-expanded={isDetailOpen} and aria-controls pointing to the detail region, and give the detail container rendered by CompetitorFilterDetailFields a matching id (e.g. "competitor-filter-detail" or a generated id) so screen readers receive the expanded/collapsed state; ensure the id passed to the detail component matches the aria-controls string and keep using the existing props (filter, onChange) when rendering CompetitorFilterDetailFields.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/shared/api/msw/handlers/brandCollaborationsHandlers.ts`:
- Around line 69-70: The POST handler returning HttpResponse.json currently uses
the wrong response field name isSuccess; update that response object to use
success: true so it matches the ApiResponse<T> contract and the GET handler and
aligns with fetchBrandCollaborationsTrends expectations—locate the POST
/brand-collaborations/trends handler that calls HttpResponse.json and replace
isSuccess with success (and ensure any tests or consumers expect success).
In `@src/widgets/competitor/competitorInsight/ui/CompetitorInsightSection.tsx`:
- Around line 41-57: The StatusCard always shows a spinner which causes the
error UI to display a loading indicator; update StatusCard to accept a prop
(e.g., showSpinner: boolean) that controls spinner rendering, then in
CompetitorInsightSection's error branch (the block that returns <StatusCard>
when isError is true) pass showSpinner={false} so the error message and retry
Button render without the spinner; also update the other StatusCard usages
around the loading/empty branches (the similar block at lines ~70-83) to pass
showSpinner={true} only when loading is intended. Ensure the prop name
(showSpinner) is used consistently in StatusCard's implementation and all places
where StatusCard is rendered.
- Around line 33-35: 현재 CompetitorInsightSection의 useEffect([data,
onAnalysisComplete])가 data가 이미 있는 상태에서 부모(예: CompetitorPage)가 인라인
콜백(onAnalysisComplete={() => setIsDetailOpen(false)})을 매 렌더 재생성하면 의도한 “한 번만 호출”
동작이 깨질 수 있습니다; 수정 방법은 두 가지 중 하나를 선택하세요: 1) CompetitorPage에서 setIsDetailOpen 관련
콜백을 useCallback으로 안정화하여 onAnalysisComplete가 재생성되지 않게 하거나, 2)
CompetitorInsightSection 내부에서 useEffect 트리거를 onAnalysisComplete 변화가 아닌 data의 “첫
수신”으로 한정(예: useRef로 prevData 존재 여부 체크 또는 이미Handled 플래그)해 onAnalysisComplete를 한
번만 호출하도록 변경하세요; 관련 식별자: CompetitorInsightSection, useEffect, onAnalysisComplete,
CompetitorPage, setIsDetailOpen, useCallback, prev/data-handled ref.
In `@src/widgets/competitor/competitorInsight/ui/ImpactCard.tsx`:
- Line 46: The div in ImpactCard currently uses 'px-44' which applies 44px
padding on both sides and shrinks flex children; change the className on the
container div (the element rendering {children} in ImpactCard) from 'px-44' to
'pl-44' to apply left-only padding, and update the nearby comment that mentions
"44px left indent" (around the earlier comment) to reflect that we're using left
padding only.
---
Nitpick comments:
In `@src/pages/competitor/ui/CompetitorPage.tsx`:
- Around line 60-66: handleReset currently resets draft/applied filters and
selected/analyzed video state but leaves the detail-panel open state untouched;
update the handleReset function to also call setIsDetailOpen(false) so the
isDetailOpen state is reset when clearing filters/selection/analysis (look for
the handleReset definition and add setIsDetailOpen(false) alongside
setDraftFilter, setAppliedFilter, setSelectedVideoIds, and setAnalyzedVideoIds).
In `@src/widgets/competitor/competitorFilter/ui/CompetitorFilterPanel.tsx`:
- Around line 105-107: The detail toggle button currently doesn't expose its
expanded state to assistive tech; update the toggle (the element that flips
isDetailOpen) to include aria-expanded={isDetailOpen} and aria-controls pointing
to the detail region, and give the detail container rendered by
CompetitorFilterDetailFields a matching id (e.g. "competitor-filter-detail" or a
generated id) so screen readers receive the expanded/collapsed state; ensure the
id passed to the detail component matches the aria-controls string and keep
using the existing props (filter, onChange) when rendering
CompetitorFilterDetailFields.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 08f0973a-38e5-4ace-9588-71b5504a570f
📒 Files selected for processing (14)
src/features/competitor/api/competitorApi.tssrc/features/competitor/index.tssrc/features/competitor/model/types.tssrc/features/competitor/model/useBrandCollaborationsTrends.tssrc/pages/competitor/ui/CompetitorPage.tsxsrc/shared/api/msw/handlers/brandCollaborationsHandlers.tssrc/widgets/competitor/competitorFilter/ui/CompetitorFilterPanel.tsxsrc/widgets/competitor/competitorInsight/index.tssrc/widgets/competitor/competitorInsight/ui/ChannelCharacteristicsCard.tsxsrc/widgets/competitor/competitorInsight/ui/CompetitorInsightSection.tsxsrc/widgets/competitor/competitorInsight/ui/ContentKeywordsCard.tsxsrc/widgets/competitor/competitorInsight/ui/ImpactCard.tsxsrc/widgets/competitor/competitorInsight/ui/StrategyInsightCard.tsxsrc/widgets/competitor/index.ts
kimYunHyeong
left a comment
There was a problem hiding this comment.
고생하셨습니다~ 코드 확인했습니다!
📌 작업 개요
/brand-collaborations,/brand-collaborations/trends)🗂 작업 유형
✏️ 작업 내용
✅ 셀프 체크리스트
💬 리뷰어에게
Summary by CodeRabbit
새로운 기능
개선