Skip to content

feat: 대기 중 견적 목록·상세 UI 및 찜/캐시 정합 - #17

Merged
juengseulki merged 4 commits into
devfrom
feature/received-estimate-list
Jul 27, 2026
Merged

feat: 대기 중 견적 목록·상세 UI 및 찜/캐시 정합#17
juengseulki merged 4 commits into
devfrom
feature/received-estimate-list

Conversation

@juengseulki

@juengseulki juengseulki commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

📋 작업 내용

고객 견적 관리의 받은 견적·대기 중 견적 목록/상세 UI를 구현하고, 찜·확정·견적 요청 시 React Query 캐시가 화면과 맞게 갱신되도록 정리했습니다.

  • 받은 견적: 목록·상세·확정 API 연동, 반응형 UI
  • 대기 중 견적: /estimates/pending, /estimates/pending/[estimateId] (mock 기반)
  • 비로그인 찜 시 토스트 후 로그인 이동
  • 찜/확정/견적 요청 생성에 따른 캐시 낙관적 갱신·무효화

🔥 변경 사항

받은 견적

  • /estimates/received, /estimates/[estimateId] 라우트 및 Desktop/Mobile UI
  • 견적 조회·확정·찜 API 연동
  • 개발 전용 /dev-login (개발 환경에서만)

대기 중 견적

  • pending 목록·상세 페이지 및 공유 상세 UI 재사용
  • Page → Hook → Service → Mock 흐름
  • Figma Desktop 기준 레이아웃·Hero 장식 아이콘
  • mock 확정 (useConfirmPendingEstimate / Detail)

React Query / 인증

  • useFavoriteMover: received + pending MY_LIST / PENDING_DETAIL 낙관적 갱신·롤백·invalidate
  • 견적 요청 생성 성공 시 MY_LIST invalidate
  • hasAuthSession / getLoginRedirectPath로 로그인 경로 통일
  • 미사용 providers/QueryProvider.tsx 제거

✅ 체크리스트

  • 로컬에서 정상 동작을 확인했습니다.
  • 기존 기능에 영향을 주지 않는지 확인했습니다.
  • 불필요한 console.log를 제거했습니다.
  • lint를 통과했습니다.
  • README 또는 문서를 수정했습니다. (필요 시)
  • API 명세와 일치하는지 확인했습니다. (대기 목록/상세·확정은 현재 mock)

📷 스크린샷 (선택)

localhost_3000_estimates_pending localhost_3000_estimates_pending(iPad Mini) localhost_3000_estimates_pending(iPhone 12 Pro) localhost_3000_estimates_pending12 localhost_3000_estimates_pending(iPad Air)12 localhost_3000_estimates_pending(iPhone 12 Pro)12

🔗 관련 이슈

Closes #


💬 To Reviewer

  • 대기 상세·목록 확정은 실 confirm API가 아닌 mock입니다. 실 API 연결 시 mutation만 교체하면 됩니다.
  • 찜 낙관적 업데이트 범위가 pending 목록/상세까지 포함됩니다. 롤백·invalidate 경로를 중점 리뷰해 주세요.
  • Hero 장식·Desktop 레이아웃은 Figma Desktop pending detail 프레임 기준입니다.

Summary by CodeRabbit

  • 새로운 기능
    • 대기 중 견적 목록/상세 페이지를 추가하고, 로딩·오류·빈 상태 및 “다시 시도”를 지원합니다.
    • 대기 견적 확정 및 즐겨찾기 기능을 제공하며 처리 결과가 화면에 즉시 반영됩니다.
  • 버그 수정
    • 견적 탭 표시 조건을 정밀화해 상세 화면에서 불필요한 탭 노출을 줄였습니다.
  • 스타일/개선
    • 버튼·칩·상세 레이아웃의 반응형 간격/줄바꿈을 개선하고, 이미지·평점 관련 접근성 표기를 보강했습니다.

jeungseulki and others added 2 commits July 26, 2026 00:36
내 견적 관리 pending 라우트와 mock 기반 상세를 추가하고, 찜·확정·견적 요청 시 React Query 캐시가 목록·상세와 맞게 갱신되도록 정리한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
Tablet 아바타를 100×100 둥근 네모로 맞추고, 기본 프로필 아이콘 원형 배경을 사각으로 변경한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

대기 견적 목록·상세 페이지와 조회·확정 API, React Query 캐시 동기화, 즐겨찾기 인증 처리, 관련 UI·디자인 토큰 및 SVG 로더 설정이 추가·변경되었습니다.

Changes

대기 견적 데이터와 서비스

Layer / File(s) Summary
데이터 계약과 서비스
src/types/*, src/lib/api/myEstimateRequests.ts, src/lib/mocks/*, src/lib/constants/*, src/lib/utils/estimateFormat.ts
대기 견적 요청·오퍼·상세 타입, 페이지네이션, 조회·확정 목 서비스, 쿼리 키와 KST 날짜 포맷을 추가했습니다.

대기 견적 목록

Layer / File(s) Summary
목록 화면과 카드 상호작용
src/app/estimates/pending/page.tsx, src/components/estimate/pending/*, src/hooks/useMyEstimateRequests.ts, src/components/estimate/EstimateRequestForm.tsx, src/components/estimate/received/MoveTypeChip.tsx
로딩·오류·빈 상태, 요청 요약, 오퍼 카드, 확정·즐겨찾기 동작과 목록 캐시 무효화를 연결했습니다.

대기 견적 상세

Layer / File(s) Summary
상세 조회와 확정
src/app/estimates/pending/[estimateId]/page.tsx, src/components/estimate/pending/PendingEstimateDetail*.tsx, src/hooks/usePendingEstimateDetail.ts, src/components/estimate/EstimatesShell.tsx
라우트 파라미터 검증, 상세 조회, 확정 상태별 액션, 오류 재시도와 토스트 처리를 구현했습니다.

캐시와 인증

Layer / File(s) Summary
즐겨찾기 캐시와 로그인 경로
src/hooks/useFavoriteMover.ts, src/lib/auth/session.ts, src/lib/api/axiosInstance.ts, src/lib/constants/appRoutes.ts, src/components/common/Header/Header.tsx
대기 견적 목록·상세 캐시에 즐겨찾기 낙관적 업데이트와 롤백을 적용하고 로그인 경로를 상수화했습니다.

공통 UI와 빌드 설정

Layer / File(s) Summary
스타일·아이콘·SVGR 설정
src/components/common/Button/Button.tsx, src/components/estimate/detail/*, src/components/estimate/received/MoveTypeChip.tsx, src/components/estimate/received/EstimateOfferCard.tsx, src/icons/*, src/styles/tokens.theme.css, next.config.ts, .coderabbit.yaml
버튼·칩·상세 화면 스타일, 접근성 표기, hero 장식 아이콘, 디자인 토큰과 SVG 로더 옵션을 변경했습니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PageClient as PendingEstimatesPageClient
  participant QueryHook as useMyEstimateRequests
  participant Service as fetchPendingEstimateSections
  participant List as PendingEstimatesList
  participant Card as PendingEstimateCard

  PageClient->>QueryHook: 대기 견적 목록 조회
  QueryHook->>Service: query 전달
  Service-->>QueryHook: sections 반환
  QueryHook-->>PageClient: 조회 상태와 sections 전달
  PageClient->>List: sections 렌더링
  List->>Card: offer 전달
  Card->>Card: 확정 또는 즐겨찾기 처리
Loading

Possibly related PRs

Suggested labels: 🐛 fix

Suggested reviewers: youngmis

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 대기 중 견적 목록·상세 UI와 찜/캐시 정합 개선을 잘 요약한 제목입니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/received-estimate-list

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (9)
src/components/common/Button/Button.tsx (1)

18-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

CTA shadow와 min-width를 디자인 토큰으로 이동해 주세요.

min-w-[300px], min-w-[600px], shadow-[...rgba(...)]가 컴포넌트에 직접 하드코딩되어 있습니다. As per path instructions, 컴포넌트의 디자인 값은 프로젝트 토큰을 우선 사용해야 합니다. ``

수정 예시
+  --shadow-button-cta: 4px 4px 10px 0 rgba(195, 217, 242, 0.2);

-        class: "px-24 py-16 shadow-[4px_4px_10px_0_rgba(195,217,242,0.2)]",
+        class: "px-24 py-16 shadow-button-cta",

min-width도 동일하게 명명된 토큰으로 분리해 주세요.

🤖 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/components/common/Button/Button.tsx` around lines 18 - 35, Update the
Button variant definitions and the outline/cta compound variant to replace the
hardcoded min-width values and CTA shadow with the project’s existing design
tokens. Define or reuse clearly named tokens for the sm/md min-widths and CTA
shadow, while preserving the current sizing and visual behavior.

Source: Path instructions

src/types/estimate.ts (1)

165-170: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

PendingEstimateDetailViewModelEstimateDetail과 완전 동일 — 주석의 "분리" 설명과 불일치

주석은 대기 견적 상세 UI ViewModel이며 기존 EstimateDetail API DTO와 분리한다고 되어 있지만, 실제로는 export type PendingEstimateDetailViewModel = EstimateDetail;로 완전히 같은 타입입니다. EstimateDetail이 나중에 변경되면 대기 견적 ViewModel도 그대로 영향을 받아, 문서상 의도(분리)와 다르게 강하게 결합되어 있습니다. 실제 필드를 명시한 별도 interface로 정의하거나, 주석을 사실에 맞게 고쳐주세요.

🤖 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/types/estimate.ts` around lines 165 - 170, Resolve the mismatch between
the PendingEstimateDetailViewModel declaration and its documentation: either
define PendingEstimateDetailViewModel as an explicit interface containing the
intended fields independently of EstimateDetail, or revise the comment to
accurately state that it is an alias. Prefer the explicit interface when the
ViewModel is intended to remain decoupled from the EstimateDetail API DTO.
src/lib/mocks/myEstimateRequests.mock.ts (1)

205-209: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

확정 불가 안내 문구가 두 파일에 동일하게 하드코딩됨

"이미 확정된 견적이 있어 추가로 확정할 수 없습니다."라는 문구가 mock의 confirmDisabledReason 계산과 UI의 fallback 로직에 각각 독립적으로 하드코딩되어 있습니다. 근본 원인은 공유 상수가 없다는 점이며, 문구를 바꿀 때 한쪽만 수정하면 서버 값과 UI fallback이 어긋나 사용자에게 잘못된 비활성 이유가 노출될 수 있습니다.

  • src/lib/mocks/myEstimateRequests.mock.ts#L205-L209: 이 문구를 공유 상수(예: src/lib/constants)로 추출해 재사용하세요.
  • src/components/estimate/pending/PendingEstimateDetailActions.tsx#L52-L55: 로컬 하드코딩 fallback을 제거하고, 위에서 추출한 공유 상수를 참조하거나 서버가 내려주는 confirmDisabledReason 값만 신뢰하도록 단순화하세요.
♻️ 제안 diff
+// src/lib/constants/estimateMessages.ts
+export const ALREADY_CONFIRMED_REASON =
+  "이미 확정된 견적이 있어 추가로 확정할 수 없습니다.";
     const confirmDisabledReason = canConfirm
       ? null
       : isConfirmed
         ? null
-        : "이미 확정된 견적이 있어 추가로 확정할 수 없습니다.";
+        : ALREADY_CONFIRMED_REASON;
   const disabled = !canConfirm || isConfirming;
-  const reason =
-    confirmDisabledReason ??
-    (!canConfirm ? "이미 확정된 견적이 있어 추가로 확정할 수 없습니다." : null);
+  const reason = confirmDisabledReason;
🤖 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/lib/mocks/myEstimateRequests.mock.ts` around lines 205 - 209, Extract the
duplicated confirmation-disabled message into a shared constant and use it in
the confirmDisabledReason calculation in
src/lib/mocks/myEstimateRequests.mock.ts (lines 205-209). Replace the local
fallback in src/components/estimate/pending/PendingEstimateDetailActions.tsx
(lines 52-55) with the same shared constant, or simplify it to trust the
server-provided confirmDisabledReason.

Source: Coding guidelines

src/components/estimate/received/MoveTypeChip.tsx (2)

7-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

size variant를 cva로 통합 권장.

MoveTypeChip/DesignatedChip 모두 size에 따라 className과 Text variant를 분기하는 동일한 패턴을 개별 ternary로 반복하고 있습니다. 프로젝트 규칙상 variant가 여러 개인 컴포넌트는 cva를 사용해야 하며 Text.tsx가 참고 사례로 지정되어 있습니다. cva로 전환하면 두 컴포넌트의 sm/md 분기를 일관되게 관리할 수 있습니다.

♻️ cva 전환 예시
const chipVariants = cva("flex items-center justify-center shadow-chip", {
  variants: {
    size: {
      sm: "rounded-4 gap-2 py-2 pr-7 pl-4",
      md: "rounded-6 gap-4 py-4 pr-8 pl-6",
    },
  },
  defaultVariants: { size: "md" },
});
🤖 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/components/estimate/received/MoveTypeChip.tsx` around lines 7 - 59,
Replace the duplicated size-based className ternaries in MoveTypeChip and
DesignatedChip with a shared cva variant definition, using sm and md entries and
md as the default. Reuse that variant for both chip containers while preserving
each component’s existing icon, text color, and size-dependent Text variant
behavior.

Source: Path instructions


23-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

shadow 값이 디자인 토큰 없이 rgba로 하드코딩됨. (PendingEstimateCard.tsx와 동일 근본 원인 — 아래 consolidated 참고)

Also applies to: 48-49

🤖 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/components/estimate/received/MoveTypeChip.tsx` around lines 23 - 24,
MoveTypeChip의 클래스 조합에서 하드코딩된 rgba 기반 shadow 값을 제거하고 프로젝트의 기존 디자인 토큰 shadow를
사용하도록 변경하세요. isSm 분기와 나머지 레이아웃 클래스는 유지하며, PendingEstimateCard.tsx에서 사용하는 동일한
shadow 토큰을 재사용하세요.

Source: Path instructions

src/components/estimate/pending/PendingEstimateCard.tsx (1)

58-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

shadow 값이 디자인 토큰 없이 rgba로 하드코딩됨.

tokens.theme.css에 이번 PR에서 추가된 토큰 목록에는 shadow가 없고, 이 컴포넌트에서 shadow-[-2px_-2px_10px_0_rgba(220,220,220,0.2),...]처럼 임의 값을 직접 사용하고 있습니다. MoveTypeChip.tsx에도 동일한 패턴이 반복되므로, 카드/칩 공용 shadow 토큰을 tokens.theme.css에 추가하고 참조하는 방식을 권장합니다.

🤖 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/components/estimate/pending/PendingEstimateCard.tsx` around lines 58 -
63, Replace the hardcoded shadow values in the PendingEstimateCard article and
the matching MoveTypeChip shadow usage with a shared design-token class. Add the
common card/chip shadow token to tokens.theme.css, then reference that token
from both components instead of inline rgba values.

Source: Path instructions

src/hooks/usePendingEstimateDetail.ts (1)

38-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

stable-callback-ref 보일러플레이트 중복.

onSuccessRef/onErrorRef를 최신 값으로 유지하는 useRef+useEffect 패턴이 이 파일 내 두 훅에서 반복되고, useFavoriteMover.ts에도 동일 패턴이 있습니다(아래 consolidated 참고). 공용 useLatestCallbacks 같은 내부 훅으로 추출을 권장합니다.

Also applies to: 75-81

🤖 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/hooks/usePendingEstimateDetail.ts` around lines 38 - 44, Extract the
repeated onSuccessRef/onErrorRef useRef and useEffect logic from the hooks in
usePendingEstimateDetail.ts into a shared internal useLatestCallbacks hook, and
reuse it in both locations. Also replace the equivalent callback-ref boilerplate
in useFavoriteMover.ts with this helper while preserving the latest callback
behavior.

Source: Path instructions

src/hooks/useFavoriteMover.ts (1)

64-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

stable-callback-ref 보일러플레이트 중복. (usePendingEstimateDetail.ts와 동일 근본 원인 — 아래 consolidated 참고)

🤖 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/hooks/useFavoriteMover.ts` around lines 64 - 69, Replace the manual
onErrorRef useRef/useEffect synchronization in the favorite-mover hook with the
shared stable-callback-ref utility already used for this pattern, matching
usePendingEstimateDetail. Preserve the behavior of always invoking the latest
options.onError callback while removing the duplicated ref-update boilerplate.

Source: Path instructions

src/app/estimates/pending/page.tsx (1)

1-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

페이지 전용 metadata를 추가하거나 공통 설정을 확인해 주세요.

이 route는 Server Component이므로 metadata를 export할 수 있지만 현재 페이지 제목·설정이 없습니다. 공통 layout에서 이 페이지의 metadata를 명시적으로 제공하지 않는다면 대기 중인 견적에 맞는 metadata를 추가해 주세요.

As per path instructions: App Router 페이지는 페이지별 metadata export 설정 여부를 확인해야 합니다.

🤖 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/app/estimates/pending/page.tsx` around lines 1 - 5, PendingEstimatesPage에
페이지별 metadata export가 있는지 확인하고, 공통 layout에서 제공하지 않는 경우 `대기 중인 견적`에 맞는 title
metadata를 추가하세요. 기존 PendingEstimatesPageClient 렌더링은 유지하세요.

Source: Path instructions

🤖 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 `@next.config.ts`:
- Around line 26-35: Update the svgoConfig.plugins configuration in
next.config.ts so preset-default remains enabled, and restrict
convertColors.currentColor to icons explicitly intended to inherit currentColor
rather than applying it globally. Preserve fixed-color assets such as
ProfileDefaultIcon and their original color combinations.

In `@src/components/common/Button/Button.tsx`:
- Around line 18-23: Resolve a null size before passing variants to
buttonVariants so the default size classes are applied. Update the Button
component’s buttonVariants invocation to pass size: resolvedSize instead of the
raw size value, preserving the existing size mappings and other variant props.

In `@src/components/estimate/detail/EstimateDetailHero.tsx`:
- Around line 18-19: Update the arbitrary Tailwind position classes on
HeroDecorationRightIcon, HeroDecorationLeftIcon, and the related avatar
positioning to use underscores for spaces around calc() operators, including the
nested max() expression, so Tailwind generates valid CSS while preserving the
existing coordinates.

In `@src/components/estimate/pending/PendingEstimateRequestHeader.tsx`:
- Line 20: Replace the arbitrary shadow utility on the
PendingEstimateRequestHeader component with the project’s existing semantic
shadow token and its corresponding Tailwind utility. If no suitable token
exists, define one in tokens.theme.css first, then reference it from the
component; preserve the current layout and other classes.

In `@src/lib/utils/estimateFormat.ts`:
- Around line 53-55: Update formatKoreanDateLong to format createdAt values in
the Asia/Seoul timezone rather than the browser’s local timezone. Use the
existing date-formatting approach or normalize to a date-only value before
extracting the year, month, and day, while preserving the current Korean output
format.

---

Nitpick comments:
In `@src/app/estimates/pending/page.tsx`:
- Around line 1-5: PendingEstimatesPage에 페이지별 metadata export가 있는지 확인하고, 공통
layout에서 제공하지 않는 경우 `대기 중인 견적`에 맞는 title metadata를 추가하세요. 기존
PendingEstimatesPageClient 렌더링은 유지하세요.

In `@src/components/common/Button/Button.tsx`:
- Around line 18-35: Update the Button variant definitions and the outline/cta
compound variant to replace the hardcoded min-width values and CTA shadow with
the project’s existing design tokens. Define or reuse clearly named tokens for
the sm/md min-widths and CTA shadow, while preserving the current sizing and
visual behavior.

In `@src/components/estimate/pending/PendingEstimateCard.tsx`:
- Around line 58-63: Replace the hardcoded shadow values in the
PendingEstimateCard article and the matching MoveTypeChip shadow usage with a
shared design-token class. Add the common card/chip shadow token to
tokens.theme.css, then reference that token from both components instead of
inline rgba values.

In `@src/components/estimate/received/MoveTypeChip.tsx`:
- Around line 7-59: Replace the duplicated size-based className ternaries in
MoveTypeChip and DesignatedChip with a shared cva variant definition, using sm
and md entries and md as the default. Reuse that variant for both chip
containers while preserving each component’s existing icon, text color, and
size-dependent Text variant behavior.
- Around line 23-24: MoveTypeChip의 클래스 조합에서 하드코딩된 rgba 기반 shadow 값을 제거하고 프로젝트의
기존 디자인 토큰 shadow를 사용하도록 변경하세요. isSm 분기와 나머지 레이아웃 클래스는 유지하며,
PendingEstimateCard.tsx에서 사용하는 동일한 shadow 토큰을 재사용하세요.

In `@src/hooks/useFavoriteMover.ts`:
- Around line 64-69: Replace the manual onErrorRef useRef/useEffect
synchronization in the favorite-mover hook with the shared stable-callback-ref
utility already used for this pattern, matching usePendingEstimateDetail.
Preserve the behavior of always invoking the latest options.onError callback
while removing the duplicated ref-update boilerplate.

In `@src/hooks/usePendingEstimateDetail.ts`:
- Around line 38-44: Extract the repeated onSuccessRef/onErrorRef useRef and
useEffect logic from the hooks in usePendingEstimateDetail.ts into a shared
internal useLatestCallbacks hook, and reuse it in both locations. Also replace
the equivalent callback-ref boilerplate in useFavoriteMover.ts with this helper
while preserving the latest callback behavior.

In `@src/lib/mocks/myEstimateRequests.mock.ts`:
- Around line 205-209: Extract the duplicated confirmation-disabled message into
a shared constant and use it in the confirmDisabledReason calculation in
src/lib/mocks/myEstimateRequests.mock.ts (lines 205-209). Replace the local
fallback in src/components/estimate/pending/PendingEstimateDetailActions.tsx
(lines 52-55) with the same shared constant, or simplify it to trust the
server-provided confirmDisabledReason.

In `@src/types/estimate.ts`:
- Around line 165-170: Resolve the mismatch between the
PendingEstimateDetailViewModel declaration and its documentation: either define
PendingEstimateDetailViewModel as an explicit interface containing the intended
fields independently of EstimateDetail, or revise the comment to accurately
state that it is an alias. Prefer the explicit interface when the ViewModel is
intended to remain decoupled from the EstimateDetail API DTO.
🪄 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 Plus

Run ID: 03d57df6-2ca4-4c45-b5df-2381eaf86d4b

📥 Commits

Reviewing files that changed from the base of the PR and between 66d56ec and daa8b93.

⛔ Files ignored due to path filters (2)
  • public/images/empty-moving-car.png is excluded by !**/*.png
  • src/icons/profile-default.svg is excluded by !**/*.svg
📒 Files selected for processing (42)
  • .coderabbit.yaml
  • next.config.ts
  • src/app/estimates/pending/[estimateId]/page.tsx
  • src/app/estimates/pending/page.tsx
  • src/components/common/Button/Button.tsx
  • src/components/common/Header/Header.tsx
  • src/components/estimate/EstimateRequestForm.tsx
  • src/components/estimate/EstimatesShell.tsx
  • src/components/estimate/detail/EstimateDetailDriverSummary.tsx
  • src/components/estimate/detail/EstimateDetailHero.tsx
  • src/components/estimate/detail/EstimateDetailInfo.tsx
  • src/components/estimate/detail/EstimateDetailPrice.tsx
  • src/components/estimate/detail/EstimateDetailShare.tsx
  • src/components/estimate/pending/PendingEstimateCard.tsx
  • src/components/estimate/pending/PendingEstimateDetailActions.tsx
  • src/components/estimate/pending/PendingEstimateDetailView.tsx
  • src/components/estimate/pending/PendingEstimateRequestHeader.tsx
  • src/components/estimate/pending/PendingEstimatesEmpty.tsx
  • src/components/estimate/pending/PendingEstimatesList.tsx
  • src/components/estimate/pending/PendingEstimatesPageClient.tsx
  • src/components/estimate/received/MoveTypeChip.tsx
  • src/hooks/useFavoriteMover.ts
  • src/hooks/useMyEstimateRequests.ts
  • src/hooks/usePendingEstimateDetail.ts
  • src/icons/hero-decoration-left.tsx
  • src/icons/hero-decoration-right.tsx
  • src/icons/index.ts
  • src/lib/api/axiosInstance.ts
  • src/lib/api/estimateRequest.ts
  • src/lib/api/myEstimateRequests.ts
  • src/lib/auth/session.ts
  • src/lib/constants/apiRoutes.ts
  • src/lib/constants/appRoutes.ts
  • src/lib/constants/queryKeys.ts
  • src/lib/mocks/myEstimateRequests.mock.ts
  • src/lib/mocks/pagination.ts
  • src/lib/utils/estimateFormat.ts
  • src/providers/QueryProvider.tsx
  • src/styles/tokens.theme.css
  • src/types/estimate.ts
  • src/types/pagination.ts
  • svgr.config.ts
💤 Files with no reviewable changes (2)
  • svgr.config.ts
  • src/providers/QueryProvider.tsx

Comment thread next.config.ts Outdated
Comment thread src/components/common/Button/Button.tsx
Comment thread src/components/estimate/detail/EstimateDetailHero.tsx Outdated
Comment thread src/components/estimate/pending/PendingEstimateRequestHeader.tsx Outdated
Comment thread src/lib/utils/estimateFormat.ts Outdated
svgr preset-default와 webpack 동일 적용, button null 처리,
hero calc/kst 날짜/shadow 토큰/a11y alt를 정리한다.

Co-authored-by: Cursor <cursoragent@cursor.com>

@yooseohyeon yooseohyeon 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.

사실 useFavoriteMover은 찜 api를 구현한 제가 해야할 일인데 제가 진도가 느린 탓에.. 미리 해주셔서 감사합니다. 그 외에도 여러 공통 작업을 해주셔서 작업이 수월하네요. 늘 감사드립니다!

useFavoriteMover은 관련 캐시의 찜 상태를 함께 바꾸고, 실패 시 여러 캐시를 함께 복구하는 점, 비로그인 상태에서는 API와 낙관적 업데이트를 실행하지 않는 점, timeout을 cleanup하는 로직이 있는 점, 여러 파라미터의 상세/목록 캐시를 prefix로 처리하는 점 등 여러 케이스를 고려해 잘 설계되었다고 느껴졌습니다!
또한 컴포넌트에서도 <article>, <Link> 등 의미 있는 태그를 사용하신 점, 찜 버튼에 키보드 focus 스타일이 존재하는 점, 중복 요청이 가지 않도록 요청 중에는 찜 버튼에 disabled을 사용하신 등 잘 설계되었다고 느껴졌습니다!

개선하면 더 좋을 사항은 아래 인라인 코멘트로 남겨놨습니다!

Comment thread src/hooks/useFavoriteMover.ts
Comment thread src/hooks/useFavoriteMover.ts
Comment thread src/hooks/useFavoriteMover.ts
Comment thread src/components/estimate/pending/PendingEstimateCard.tsx Outdated
Comment thread src/components/estimate/pending/PendingEstimateCard.tsx
Comment thread src/components/estimate/pending/PendingEstimateCard.tsx
Comment thread src/components/estimate/pending/PendingEstimateRequestHeader.tsx Outdated
Comment thread src/components/estimate/pending/PendingEstimatesList.tsx Outdated
Comment thread src/components/estimate/pending/PendingEstimateRequestHeader.tsx Outdated
Comment thread src/components/estimate/pending/PendingEstimateCard.tsx Outdated
찜은 nextIsFavorite와 count 가드, invalidate는 onSettled로 옮기고
카드/헤더 a11y·dl/header 시맨틱을 정리한다.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/components/estimate/pending/PendingEstimateRequestHeader.tsx (1)

28-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Text에 반응형 variant를 추가해 이 헤더의 타이포그래피를 공통화해 주세요.
src/components/estimate/pending/PendingEstimateRequestHeader.tsx:32,39md:text-[length:var(...)] / md:leading-[var(...)]Text의 variant 체계를 우회합니다. 같은 패턴이 다른 estimate 화면에도 있어, Text에 반응형 variant를 넣고 여기서는 variant만 쓰는 쪽이 좋습니다.

🤖 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/components/estimate/pending/PendingEstimateRequestHeader.tsx` around
lines 28 - 39, Update the Text component’s variant definitions to support the
required responsive typography for this estimate header, then replace the
md:text and md:leading utility classes on the title and subtitle Text elements
in PendingEstimateRequestHeader with the appropriate responsive variant values.
Keep the existing visual styles and use variants only for the responsive
typography.

Sources: Coding guidelines, Path instructions

🤖 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.

Nitpick comments:
In `@src/components/estimate/pending/PendingEstimateRequestHeader.tsx`:
- Around line 28-39: Update the Text component’s variant definitions to support
the required responsive typography for this estimate header, then replace the
md:text and md:leading utility classes on the title and subtitle Text elements
in PendingEstimateRequestHeader with the appropriate responsive variant values.
Keep the existing visual styles and use variants only for the responsive
typography.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d19f0a8-4ad9-424c-8638-3d1acb9961a2

📥 Commits

Reviewing files that changed from the base of the PR and between f3a6c97 and 7d1d7d8.

📒 Files selected for processing (6)
  • src/components/estimate/detail/EstimateDetailDriverSummary.tsx
  • src/components/estimate/pending/PendingEstimateCard.tsx
  • src/components/estimate/pending/PendingEstimateRequestHeader.tsx
  • src/components/estimate/pending/PendingEstimatesList.tsx
  • src/components/estimate/received/EstimateOfferCard.tsx
  • src/hooks/useFavoriteMover.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/estimate/pending/PendingEstimatesList.tsx
  • src/components/estimate/pending/PendingEstimateCard.tsx
  • src/hooks/useFavoriteMover.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants