Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughCallvan UI 전반에 Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant UI as AddPostForm
participant Logger as AnalyticsLogger
participant Router as Router
User->>UI: 작성 후 제출 클릭
UI->>Logger: logger.actionEventClick(callvan_write_done...)
UI->>Router: navigate to target (e.g., list)
Router-->>User: 화면 전환
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/Callvan/components/AddPostForm/index.tsx (1)
80-103:⚠️ Potential issue | 🟠 Major성공/실패 분기 없이 로깅되어 분석 지표가 왜곡됩니다
Line 102의
logger.actionEventClick()호출이mutate()외부(직후)에 위치하여, API 요청 실패 시에도callvan_write_done이벤트가 기록됩니다. 성공/실패를 구분하지 않고 항상 로그가 전송되므로 분석 데이터의 신뢰성이 떨어집니다.수정 제안
mutate( { departure_type: form.departureType, departure_custom_name: form.departureType === 'CUSTOM' ? form.departureCustomName : null, arrival_type: form.arrivalType, arrival_custom_name: form.arrivalType === 'CUSTOM' ? form.arrivalCustomName : null, departure_date: formatDateParam(form.departureDate), departure_time: departureTime, max_participants: form.maxParticipants, }, { onSuccess: () => { openToast('작성되었습니다.'); + logger.actionEventClick({ event_label: 'callvan_write_done', team: 'CAMPUS', value: '' }); router.replace({ pathname: ROUTES.Callvan(), query: { created: '1' } }); }, + onError: () => { + logger.actionEventClick({ event_label: 'callvan_write_fail', team: 'CAMPUS', value: '' }); + }, }, ); - logger.actionEventClick({ event_label: 'callvan_write_done', team: 'CAMPUS', value: '' });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/AddPostForm/index.tsx` around lines 80 - 103, The logger.actionEventClick call for 'callvan_write_done' is executed immediately after mutate(), so failures still record a success event; move this logging into the mutate onSuccess callback (inside the existing onSuccess in handleSubmit) so it only fires on successful API response, and optionally add a logger.actionEventClick or logger.actionEventError call in the mutate onError callback to record failures; update references in handleSubmit, mutate, and the onSuccess/onError callbacks accordingly.src/components/Callvan/components/CallvanChatRoom/index.tsx (1)
78-94:⚠️ Potential issue | 🟡 Minor로깅 호출 위치가 적절하지 않습니다.
logger.actionEventClick이sendMessage의onSuccess콜백 외부에서 호출되고 있습니다. 이렇게 되면 메시지 전송이 실패하더라도 로그가 기록되어 분석 데이터의 정확성이 떨어질 수 있습니다.🔧 제안하는 수정 사항
sendMessage( { is_image: false, content }, { onSuccess: () => { setInputValue(''); if (textareaRef.current) { textareaRef.current.style.height = 'auto'; } + logger.actionEventClick({ event_label: 'callvan_chat_send', team: 'CAMPUS', value: '' }); }, }, ); - logger.actionEventClick({ event_label: 'callvan_chat_send', team: 'CAMPUS', value: '' });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/CallvanChatRoom/index.tsx` around lines 78 - 94, The logger.actionEventClick call is currently outside sendMessage's onSuccess so it logs even on failures; move the logger.actionEventClick invocation inside the onSuccess callback of sendMessage (in the same block that calls setInputValue('') and resets textareaRef.style.height) so the event is recorded only after a successful send; keep the existing payload ({ event_label: 'callvan_chat_send', team: 'CAMPUS', value: '' }) and placement order (reset input then log) in the handleSend function.
🧹 Nitpick comments (7)
src/components/Callvan/components/CallvanChatRoom/CallvanChatRoom.module.scss (2)
298-311: 키보드 포커스 스타일을 명시해 접근성을 보강해주세요.현재 버튼은 포커스 상태를 커스텀하지 않아 브라우저 기본 스타일에 의존합니다.
:focus-visible을 명시하면 키보드 사용자에게 더 일관된 포커스 피드백을 줄 수 있습니다.예시 diff
&__image-button { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; background: none; border: none; border-radius: 12px; cursor: pointer; padding: 0; background-color: `#fff`; flex-shrink: 0; + + &:focus-visible { + outline: 2px solid `#980ac9`; + outline-offset: 2px; + } }As per coding guidelines
src/components/**: 4. 접근성(a11y) 관련 속성이 적절히 사용되고 있는지 확인해주세요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/CallvanChatRoom/CallvanChatRoom.module.scss` around lines 298 - 311, The .__image-button currently relies on browser default focus styles; add explicit keyboard focus styles using the :focus-visible pseudo-class on the &__image-button selector (and optionally a subtle :focus fallback) to provide consistent visible focus for keyboard users—e.g., set a visible outline or box-shadow color with outline-offset and preserve border-radius, ensure high contrast (meets contrast requirements), and avoid removing focus for mouse users by targeting :focus-visible rather than :focus.
304-309: 배경 속성 선언을 하나로 정리해 가독성을 높여주세요.Line [304]의
background: none;은 Line [309]의background-color:#fff;로 바로 덮여 실질 효과가 없습니다. 하나로 정리하면 의도가 더 명확해집니다.예시 diff
- background: none; + background-color: `#fff`; border: none; border-radius: 12px; cursor: pointer; padding: 0; - background-color: `#fff`;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/CallvanChatRoom/CallvanChatRoom.module.scss` around lines 304 - 309, 현재 스타일블록에 background: none; 와 background-color: `#fff`; 가 중복되어 의도가 불명확하므로 background 선언을 하나로 정리하세요 — CallvanChatRoom.module.scss에서 background: none; 을 제거하고 background-color: `#fff`; 만 남기거나, 의도대로라면 background: `#fff`; 같은 단일 background 속성으로 통합하여 가독성과 명확성을 확보하세요 (참조: 기존 background: none; 및 background-color: `#fff`;).src/components/IndexComponents/IndexCallvan/index.tsx (1)
36-36: Line 36 인라인 핸들러/객체 생성은 분리하는 편이 좋습니다.렌더마다 함수와 payload 객체가 새로 만들어집니다. 현재는 영향이 작지만, 카드 수가 늘면 추적/최적화가 어려워질 수 있습니다.
장점: 렌더 안정성/테스트 용이성 향상, 단점: 코드가 약간 늘어남.♻️ 제안 코드
+import { useMemo } from 'react'; import Link from 'next/link'; import ChevronRight from 'assets/svg/IndexPage/Bus/chevron-right.svg'; import ROUTES from 'static/routes'; import useLogger from 'utils/hooks/analytics/useLogger'; import styles from './IndexCallvan.module.scss'; @@ function IndexCallvan() { const logger = useLogger(); + const linksWithHandler = useMemo( + () => + CALLVAN_LINKS.map((item) => ({ + ...item, + onClick: () => + logger.actionEventClick({ + team: 'CAMPUS', + event_label: `main_callvan_${item.key}`, + value: '', + }), + })), + [logger], + ); return ( @@ - {CALLVAN_LINKS.map(({ key, title, subtitle, link }) => ( + {linksWithHandler.map(({ key, title, subtitle, link, onClick }) => ( <Link href={link} key={key} className={styles.card} - onClick={() => logger.actionEventClick({ team: 'CAMPUS', event_label: `main_callvan_${key}`, value: '' })} + onClick={onClick} >As per coding guidelines,
src/components/**: "3. 불필요한 리렌더링을 유발하는 패턴(인라인 함수, 객체 리터럴 등)이 있는지 확인해주세요."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/IndexComponents/IndexCallvan/index.tsx` at line 36, Extract the inline onClick payload into a stable handler: create a memoized factory like getCallvanClick using useCallback (e.g., const getCallvanClick = useCallback((itemKey) => () => logger.actionEventClick({ team: 'CAMPUS', event_label: `main_callvan_${itemKey}`, value: '' }), [logger]) ) and replace the inline onClick with onClick={getCallvanClick(key)} so the logger.actionEventClick payload creation is no longer done inline on each render.src/components/Callvan/components/LocationBottomSheet/index.tsx (1)
52-56:title문자열 비교로event_label을 결정하는 방식은 취약합니다.
titleprop의 문자열 값에 의존하여 이벤트 레이블을 결정하면, 추후 title 텍스트가 변경되거나 다국어 지원 시 로깅이 깨질 수 있습니다. 또한 템플릿 리터럴 내 불필요한 백틱이 있습니다.♻️ Props로 eventLabel을 전달하거나 타입으로 구분하는 방식 제안
interface LocationBottomSheetProps { isOpen: boolean; title: string; + locationType: 'departure' | 'arrival'; initialType: CallvanPostLocationType | null; initialCustomName: string; onClose: () => void; onConfirm: (type: CallvanPostLocationType, customName: string) => void; }- logger.actionEventClick({ - event_label: `${title === '출발지가 어디인가요?' ? 'callvan_write_departure' : 'callvan_write_arrival'}`, - team: 'CAMPUS', - value: selectedType, - }); + logger.actionEventClick({ + event_label: locationType === 'departure' ? 'callvan_write_departure' : 'callvan_write_arrival', + team: 'CAMPUS', + value: selectedType, + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/LocationBottomSheet/index.tsx` around lines 52 - 56, The event_label decision using the title string is fragile; update the component to accept an explicit prop (e.g., eventLabel) or a typed discriminator (e.g., sheetType or locationType) and use that instead of comparing title, then call logger.actionEventClick with a plain string (remove the unnecessary template literal/backticks) for event_label and pass selectedType unchanged; locate the logger.actionEventClick call and replace its event_label expression to use the new prop (or switch on the typed discriminator) so labels remain stable across text changes and i18n.src/components/Callvan/components/CallvanCard/index.tsx (1)
89-89: 로깅value에 버튼 레이블 대신 의미 있는 값을 사용하세요.
value: '예, 아니요'는 모달의 버튼 레이블이지 사용자 행동의 의미 있는 값이 아닙니다. 분석 목적으로는post.id나 참여자 수 같은 컨텍스트 정보가 더 유용할 수 있습니다.♻️ 의미 있는 value 사용 제안
- logger.actionEventClick({ event_label: 'callvan_join', team: 'CAMPUS', value: '예, 아니요' }); + logger.actionEventClick({ event_label: 'callvan_join', team: 'CAMPUS', value: String(post.id) });Also applies to: 95-95
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/CallvanCard/index.tsx` at line 89, The call to logger.actionEventClick currently sends the UI button labels as value (logger.actionEventClick({ event_label: 'callvan_join', team: 'CAMPUS', value: '예, 아니요' })), so change both occurrences of logger.actionEventClick in this component to send meaningful context (e.g., post.id, participantCount, or a boolean like joined: true/false) instead of the button text; locate the calls to logger.actionEventClick inside CallvanCard (the join modal confirm/cancel handlers) and replace value with a descriptive field such as value: post.id or value: `${post.id}:${participantCount}` or add a separate property like metadata: { postId: post.id, participantCount } to preserve richer analytics context.src/components/Callvan/components/TimeDropdown/index.tsx (1)
214-218: 로깅 시 시간 값 포맷이 일관성 없습니다.
value에 기록되는 시간 포맷이${tempHour}:${tempMinute}로 되어 있어 "9:05"와 같이 시(hour)가 패딩되지 않습니다. Line 181-183의formatTriggerTime함수를 재사용하면 "09:05"와 같이 일관된 포맷을 유지할 수 있습니다.♻️ formatTriggerTime 재사용 제안
const handleConfirm = () => { onChange({ hour: tempHour, minute: tempMinute, isPM: tempIsPM }); - logger.actionEventClick({ event_label: 'callvan_write_time', team: 'CAMPUS', value: `${tempHour}:${tempMinute}` }); + logger.actionEventClick({ event_label: 'callvan_write_time', team: 'CAMPUS', value: formatTriggerTime(tempHour, tempMinute) }); close(); };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/TimeDropdown/index.tsx` around lines 214 - 218, The logger in handleConfirm uses `${tempHour}:${tempMinute}` which yields inconsistent padding; replace that inline format with the existing formatTriggerTime(...) helper to produce a consistent "HH:MM" string when calling logger.actionEventClick. Update the call in handleConfirm (where onChange, logger.actionEventClick and close are invoked) to compute the formatted time via formatTriggerTime(tempHour, tempMinute, tempIsPM) and pass that result as the value argument.src/components/Callvan/components/CallvanPageLayout/index.tsx (1)
110-110: 검색 인풋 클릭 시마다 로깅이 발생합니다.
onClick에서 로깅하면 사용자가 인풋을 클릭할 때마다 이벤트가 기록됩니다. 검색 의도를 추적하려면 실제 검색 실행 시(handleSearch) 로깅하는 것이 더 정확한 분석 데이터를 제공할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Callvan/components/CallvanPageLayout/index.tsx` at line 110, The click handler currently logs every input click; move the logging into the actual search execution (handleSearch) so only real searches are recorded: remove the logger.actionEventClick call from the onClick prop and add a logger.actionEventClick invocation inside handleSearch (use the same payload keys: event_label: 'callvan_search', team: 'CAMPUS' and set value to the search term or '' if empty). Ensure handleSearch is the single place that logs searches (including submissions or programmatic triggers) so duplicate logs from onClick are eliminated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/Callvan/components/CallvanCard/index.tsx`:
- Around line 113-116: The phone button currently rendered with <button
className={styles.card__phone} onClick={handleCallClick}> lacks accessibility
attributes; update the CallvanCard button (the element using styles.card__phone,
onClick handler handleCallClick, and child PhoneCallingIcon) to include
type="button" to prevent implicit form submission and add an appropriate
aria-label (e.g., aria-label="Call" or a localized string) so screen readers
convey the button's purpose.
- Line 224: In CallvanCard (component CallvanCard in index.tsx) remove the empty
aria-label="" on the button used for "참여취소" or replace it with an appropriate
label (e.g., aria-label="참여취소") so screen readers can announce the button
purpose; locate the button element in CallvanCard that currently has
aria-label="" and either delete that attribute (since visible text exists) or
set a meaningful value.
- Line 27: In the CallvanCard component, update the empty aria-label on the
cancel button to match its visible text (set aria-label="참여취소") so accessibility
labels are consistent with other buttons (e.g., the chat button and 참여하기
button); also remove the magic literal in CALLVAN_CATEGORY (currently '11') by
extracting it to a well-named constant or config entry (e.g.,
DEFAULT_CALLVAN_CATEGORY or from a settings/shopCategories source) in the same
module or a central constants/config file, add a brief comment explaining why
that specific category ID is required, and if feasible replace the hardcoded ID
with the dynamic lookup from shop_categories API used elsewhere.
In `@src/components/Callvan/components/CallvanPageLayout/index.tsx`:
- Around line 43-46: The event_label construction in handleBack currently uses
&& which produces unwanted strings like "false false"; update handleBack (the
logger.actionEventClick call) to compute a proper label before logging—e.g.,
determine label via a conditional/ternary or a small helper (check
router.pathname against ROUTES.Callvan() and ROUTES.CallvanAdd()) and pass
either "callvan_back", "callvan_write_back", or an empty string (not boolean
values) to event_label so the log receives a single correct string.
---
Outside diff comments:
In `@src/components/Callvan/components/AddPostForm/index.tsx`:
- Around line 80-103: The logger.actionEventClick call for 'callvan_write_done'
is executed immediately after mutate(), so failures still record a success
event; move this logging into the mutate onSuccess callback (inside the existing
onSuccess in handleSubmit) so it only fires on successful API response, and
optionally add a logger.actionEventClick or logger.actionEventError call in the
mutate onError callback to record failures; update references in handleSubmit,
mutate, and the onSuccess/onError callbacks accordingly.
In `@src/components/Callvan/components/CallvanChatRoom/index.tsx`:
- Around line 78-94: The logger.actionEventClick call is currently outside
sendMessage's onSuccess so it logs even on failures; move the
logger.actionEventClick invocation inside the onSuccess callback of sendMessage
(in the same block that calls setInputValue('') and resets
textareaRef.style.height) so the event is recorded only after a successful send;
keep the existing payload ({ event_label: 'callvan_chat_send', team: 'CAMPUS',
value: '' }) and placement order (reset input then log) in the handleSend
function.
---
Nitpick comments:
In `@src/components/Callvan/components/CallvanCard/index.tsx`:
- Line 89: The call to logger.actionEventClick currently sends the UI button
labels as value (logger.actionEventClick({ event_label: 'callvan_join', team:
'CAMPUS', value: '예, 아니요' })), so change both occurrences of
logger.actionEventClick in this component to send meaningful context (e.g.,
post.id, participantCount, or a boolean like joined: true/false) instead of the
button text; locate the calls to logger.actionEventClick inside CallvanCard (the
join modal confirm/cancel handlers) and replace value with a descriptive field
such as value: post.id or value: `${post.id}:${participantCount}` or add a
separate property like metadata: { postId: post.id, participantCount } to
preserve richer analytics context.
In
`@src/components/Callvan/components/CallvanChatRoom/CallvanChatRoom.module.scss`:
- Around line 298-311: The .__image-button currently relies on browser default
focus styles; add explicit keyboard focus styles using the :focus-visible
pseudo-class on the &__image-button selector (and optionally a subtle :focus
fallback) to provide consistent visible focus for keyboard users—e.g., set a
visible outline or box-shadow color with outline-offset and preserve
border-radius, ensure high contrast (meets contrast requirements), and avoid
removing focus for mouse users by targeting :focus-visible rather than :focus.
- Around line 304-309: 현재 스타일블록에 background: none; 와 background-color: `#fff`; 가
중복되어 의도가 불명확하므로 background 선언을 하나로 정리하세요 — CallvanChatRoom.module.scss에서
background: none; 을 제거하고 background-color: `#fff`; 만 남기거나, 의도대로라면 background:
`#fff`; 같은 단일 background 속성으로 통합하여 가독성과 명확성을 확보하세요 (참조: 기존 background: none; 및
background-color: `#fff`;).
In `@src/components/Callvan/components/CallvanPageLayout/index.tsx`:
- Line 110: The click handler currently logs every input click; move the logging
into the actual search execution (handleSearch) so only real searches are
recorded: remove the logger.actionEventClick call from the onClick prop and add
a logger.actionEventClick invocation inside handleSearch (use the same payload
keys: event_label: 'callvan_search', team: 'CAMPUS' and set value to the search
term or '' if empty). Ensure handleSearch is the single place that logs searches
(including submissions or programmatic triggers) so duplicate logs from onClick
are eliminated.
In `@src/components/Callvan/components/LocationBottomSheet/index.tsx`:
- Around line 52-56: The event_label decision using the title string is fragile;
update the component to accept an explicit prop (e.g., eventLabel) or a typed
discriminator (e.g., sheetType or locationType) and use that instead of
comparing title, then call logger.actionEventClick with a plain string (remove
the unnecessary template literal/backticks) for event_label and pass
selectedType unchanged; locate the logger.actionEventClick call and replace its
event_label expression to use the new prop (or switch on the typed
discriminator) so labels remain stable across text changes and i18n.
In `@src/components/Callvan/components/TimeDropdown/index.tsx`:
- Around line 214-218: The logger in handleConfirm uses
`${tempHour}:${tempMinute}` which yields inconsistent padding; replace that
inline format with the existing formatTriggerTime(...) helper to produce a
consistent "HH:MM" string when calling logger.actionEventClick. Update the call
in handleConfirm (where onChange, logger.actionEventClick and close are invoked)
to compute the formatted time via formatTriggerTime(tempHour, tempMinute,
tempIsPM) and pass that result as the value argument.
In `@src/components/IndexComponents/IndexCallvan/index.tsx`:
- Line 36: Extract the inline onClick payload into a stable handler: create a
memoized factory like getCallvanClick using useCallback (e.g., const
getCallvanClick = useCallback((itemKey) => () => logger.actionEventClick({ team:
'CAMPUS', event_label: `main_callvan_${itemKey}`, value: '' }), [logger]) ) and
replace the inline onClick with onClick={getCallvanClick(key)} so the
logger.actionEventClick payload creation is no longer done inline on each
render.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9fb0f42e-5153-4009-ae75-2e888717daff
⛔ Files ignored due to path filters (1)
src/assets/svg/Callvan/image-upload.svgis excluded by!**/*.svgand included by**
📒 Files selected for processing (11)
src/components/Callvan/components/AddPostForm/index.tsxsrc/components/Callvan/components/CallvanCard/index.tsxsrc/components/Callvan/components/CallvanChatRoom/CallvanChatRoom.module.scsssrc/components/Callvan/components/CallvanChatRoom/index.tsxsrc/components/Callvan/components/CallvanFilterPanel/index.tsxsrc/components/Callvan/components/CallvanPageLayout/CallvanPageLayout.module.scsssrc/components/Callvan/components/CallvanPageLayout/index.tsxsrc/components/Callvan/components/LocationBottomSheet/index.tsxsrc/components/Callvan/components/ParticipantsList/index.tsxsrc/components/Callvan/components/TimeDropdown/index.tsxsrc/components/IndexComponents/IndexCallvan/index.tsx
💤 Files with no reviewable changes (1)
- src/components/Callvan/components/CallvanPageLayout/CallvanPageLayout.module.scss
| import { redirectToLogin } from 'utils/ts/auth'; | ||
| import styles from './CallvanCard.module.scss'; | ||
|
|
||
| const CALLVAN_CATEGORY = '11'; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Search for category ID usage and definition in the codebase
# Find where category IDs are defined or used
rg -n "category.*11|CALLVAN.*CATEGORY" --type=ts --type=tsx -g '!node_modules'
# Check API entity files for category definitions
fd -e ts -e tsx entity | xargs rg -l "category" | head -10Repository: BCSDLab/KOIN_WEB_RECODE
Length of output: 185
🏁 Script executed:
#!/bin/bash
# First, let's look at the CallvanCard component to see how CALLVAN_CATEGORY is used
echo "=== CallvanCard component usage of CALLVAN_CATEGORY ==="
rg -n "CALLVAN_CATEGORY" src/components/Callvan/components/CallvanCard/ -A 3 -B 3
echo -e "\n=== Checking entity files for category structure ==="
cat src/api/store/entity.ts | head -100
echo -e "\n=== Search for other category ID definitions/constants ==="
rg -n "const.*CATEGORY.*=.*['\"]" src/ --type=ts --type=tsx | head -20
echo -e "\n=== How shop_categories is used (from IndexStore) ==="
rg -n "shop_categories" src/components/IndexComponents/IndexStore/ -B 2 -A 2Repository: BCSDLab/KOIN_WEB_RECODE
Length of output: 4608
🏁 Script executed:
#!/bin/bash
# Search for category definitions, enums, or mappings
echo "=== Search for category definitions or enums ==="
rg -n "category" src/api/ -B 1 -A 1 | grep -i "interface\|type\|enum\|export" | head -30
echo -e "\n=== Search for Callvan API or data fetching ==="
rg -n "Callvan\|callvan" src/api/ src/hooks/ -l
echo -e "\n=== Check if there's a types or constants file with category mappings ==="
fd -e ts -e tsx -e js -path "*/types/*" -o -path "*/constants/*" | xargs grep -l "category\|CATEGORY" 2>/dev/null | head -10
echo -e "\n=== Look at the entire CallvanCard file to understand context ==="
wc -l src/components/Callvan/components/CallvanCard/index.tsxRepository: BCSDLab/KOIN_WEB_RECODE
Length of output: 998
🏁 Script executed:
#!/bin/bash
# Read the CallvanCard component
echo "=== CallvanCard component ==="
cat -n src/components/Callvan/components/CallvanCard/index.tsx | head -150
echo -e "\n=== Search for CallvanPost type/interface ==="
rg -n "interface CallvanPost|type CallvanPost" src/
echo -e "\n=== Search for where CallvanCard is used ==="
rg -n "CallvanCard" src/ -B 1 -A 1 | head -30
echo -e "\n=== Search for Callvan data/hooks ==="
rg -n "useCallvan|callvan" src/hooks/ src/api/ 2>/dev/nullRepository: BCSDLab/KOIN_WEB_RECODE
Length of output: 9528
🏁 Script executed:
#!/bin/bash
# Check if there's a config or constants file for category mappings
echo "=== Search for category IDs or shop categories elsewhere ==="
rg -n "category.*11|shop.*category|CATEGORY.*=" src/static/ src/config/ 2>/dev/null | head -20
echo -e "\n=== Check CallvanPost entity to see if it has category info ==="
cat src/api/callvan/entity.ts | head -100
echo -e "\n=== Check if ORDER_BASE_URL uses category for filtering ==="
rg -n "ORDER_BASE_URL\|category" src/static/url.ts
echo -e "\n=== Search for any documentation about category 11 ==="
rg -n "11.*callvan\|callvan.*11\|food.*delivery\|음식" src/ --type=ts -i | head -20Repository: BCSDLab/KOIN_WEB_RECODE
Length of output: 2948
🏁 Script executed:
#!/bin/bash
# Check the category.ts file for category ID 11
echo "=== Full CATEGORY constant from static/category.ts ==="
cat src/static/category.ts
echo -e "\n=== Search for category 11 specifically ==="
rg -n "^.*11.*$" src/static/category.ts -A 2 -B 2
echo -e "\n=== Check filterOptions for more context ==="
cat src/static/filterOptions.ts | head -50Repository: BCSDLab/KOIN_WEB_RECODE
Length of output: 3965
🏁 Script executed:
#!/bin/bash
# Check what ORDER_BASE_URL is
echo "=== ORDER_BASE_URL definition ==="
rg -n "ORDER_BASE_URL" src/static/ -B 2 -A 2
echo -e "\n=== Search for any category ID definitions or comments ==="
rg -n "category.*id|shop.*category" src/api/store/ -i | head -20
echo -e "\n=== Check if there are any other hardcoded category IDs elsewhere ==="
rg -n "category.*=" src/ -i | grep -E "'[0-9]+'" | head -20
echo -e "\n=== Search for documentation or README about shop categories ==="
find src -name "README*" -o -name "*.md" | xargs grep -l "category\|shop" 2>/dev/nullRepository: BCSDLab/KOIN_WEB_RECODE
Length of output: 823
🏁 Script executed:
#!/bin/bash
# Let's check if we can find what category 11 represents in the shop data
echo "=== Search for StoreCategory interface to understand the structure ==="
rg -n "interface StoreCategory|type StoreCategory" src/api/store/entity.ts -A 5
echo -e "\n=== Check if there are API calls that fetch categories ==="
rg -n "shop_categories\|StoreCategory" src/api/store/ -B 2 -A 2
echo -e "\n=== Search for any test files or mock data with category IDs ==="
find src -name "*.mock.ts" -o -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "category" 2>/dev/null | head -5
echo -e "\n=== Check comment or commit history context around CALLVAN_CATEGORY ==="
git log -p --all -S "CALLVAN_CATEGORY" -- src/components/Callvan/components/CallvanCard/index.tsx 2>/dev/null | head -50Repository: BCSDLab/KOIN_WEB_RECODE
Length of output: 447
🏁 Script executed:
#!/bin/bash
# Check the full CallvanCard file for aria-label issues around line 224
echo "=== CallvanCard file around line 220-230 ==="
sed -n '220,230p' src/components/Callvan/components/CallvanCard/index.tsx
echo -e "\n=== Search for all aria-label instances in CallvanCard ==="
rg -n "aria-label" src/components/Callvan/components/CallvanCard/index.tsx
echo -e "\n=== Check if category 11 is mentioned anywhere in documentation or comments ==="
rg -n "food\|delivery\|주문\|음식" src/api/store/entity.ts src/components/Callvan/ -i | grep -i "category\|11\|type" | head -10Repository: BCSDLab/KOIN_WEB_RECODE
Length of output: 873
Line 224에서 버튼의 접근성 레이블이 비어있습니다.
aria-label=""로 설정되어 있으나, 버튼 텍스트가 "참여취소"이므로 aria-label="참여취소"로 설정해야 합니다. 같은 파일의 다른 버튼들(예: 120번 줄의 aria-label="채팅하기", 247번 줄의 aria-label="참여하기")처럼 일관되게 접근성 레이블을 제공해주세요.
라인 27의 하드코딩된 카테고리 ID '11'은 유지보수 관점에서 개선 필요합니다.
다른 컴포넌트들은 API 응답의 shop_categories에서 카테고리 정보를 동적으로 가져오는 반면, 이 코드는 카테고리 ID를 매직 넘버로 하드코딩하고 있습니다. 백엔드에서 카테고리 ID 체계가 변경되면 이 코드가 깨질 수 있습니다. 카테고리 ID를 상수로 분리하면서 왜 특정 값이 필요한지 주석을 추가하거나, 가능하면 설정에서 관리하는 것을 검토해주세요.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/Callvan/components/CallvanCard/index.tsx` at line 27, In the
CallvanCard component, update the empty aria-label on the cancel button to match
its visible text (set aria-label="참여취소") so accessibility labels are consistent
with other buttons (e.g., the chat button and 참여하기 button); also remove the
magic literal in CALLVAN_CATEGORY (currently '11') by extracting it to a
well-named constant or config entry (e.g., DEFAULT_CALLVAN_CATEGORY or from a
settings/shopCategories source) in the same module or a central constants/config
file, add a brief comment explaining why that specific category ID is required,
and if feasible replace the hardcoded ID with the dynamic lookup from
shop_categories API used elsewhere.
| <button className={styles.card__phone} onClick={handleCallClick}> | ||
| <PhoneCallingIcon /> | ||
| </span> | ||
| </button> | ||
| ); |
There was a problem hiding this comment.
전화 버튼에 type 속성과 aria-label이 누락되었습니다.
버튼 요소에 type="button" 속성이 없으면 form 내에서 submit으로 동작할 수 있고, aria-label이 없으면 스크린 리더 사용자가 버튼의 목적을 알 수 없습니다. As per coding guidelines, 접근성(a11y) 관련 속성이 적절히 사용되어야 합니다.
🔧 수정 제안
- <button className={styles.card__phone} onClick={handleCallClick}>
+ <button type="button" className={styles.card__phone} onClick={handleCallClick} aria-label="콜밴 업체 전화">
<PhoneCallingIcon />
</button>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <button className={styles.card__phone} onClick={handleCallClick}> | |
| <PhoneCallingIcon /> | |
| </span> | |
| </button> | |
| ); | |
| <button type="button" className={styles.card__phone} onClick={handleCallClick} aria-label="콜밴 업체 전화"> | |
| <PhoneCallingIcon /> | |
| </button> | |
| ); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/Callvan/components/CallvanCard/index.tsx` around lines 113 -
116, The phone button currently rendered with <button
className={styles.card__phone} onClick={handleCallClick}> lacks accessibility
attributes; update the CallvanCard button (the element using styles.card__phone,
onClick handler handleCallClick, and child PhoneCallingIcon) to include
type="button" to prevent implicit form submission and add an appropriate
aria-label (e.g., aria-label="Call" or a localized string) so screen readers
convey the button's purpose.
| }} | ||
| disabled={isCancelPending} | ||
| aria-label="참여취소" | ||
| aria-label="" |
There was a problem hiding this comment.
빈 aria-label은 접근성 문제를 야기합니다.
aria-label=""은 스크린 리더가 버튼의 목적을 전달하지 못하게 합니다. 버튼 텍스트가 "참여취소"이므로, aria-label을 제거하거나 적절한 값으로 설정해야 합니다.
🔧 수정 제안
- aria-label=""
+ aria-label="참여취소"또는 버튼 내부에 텍스트가 있으므로 aria-label 속성을 완전히 제거할 수도 있습니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| aria-label="" | |
| aria-label="참여취소" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/Callvan/components/CallvanCard/index.tsx` at line 224, In
CallvanCard (component CallvanCard in index.tsx) remove the empty aria-label=""
on the button used for "참여취소" or replace it with an appropriate label (e.g.,
aria-label="참여취소") so screen readers can announce the button purpose; locate the
button element in CallvanCard that currently has aria-label="" and either delete
that attribute (since visible text exists) or set a meaningful value.
What is this PR? 🔍
Changes 📝
Precaution
N/A
✔️ Please check if the PR fulfills these requirements
developbranch unconditionally?main?yarn lintSummary by CodeRabbit
릴리스 노트
새로운 기능
스타일
버그 수정