Skip to content

feat(web): performance + design + UX polish (preconnect, unrated cards, insufficient-balance)#18

Merged
blue45f merged 3 commits into
mainfrom
feat/perf-design-ux
May 29, 2026
Merged

feat(web): performance + design + UX polish (preconnect, unrated cards, insufficient-balance)#18
blue45f merged 3 commits into
mainfrom
feat/perf-design-ux

Conversation

@blue45f
Copy link
Copy Markdown
Owner

@blue45f blue45f commented May 29, 2026

Tackles all three follow-up directions in one pass — each is a bounded, low-risk, tested improvement grounded in a parallel audit.

1. Performance

  • index.html: add a preconnect to cdn.jsdelivr.net (the Pretendard font CDN had none), starting the DNS+TLS handshake earlier on first paint.

2. Design polish

  • ListingCard: new listings rendered five hollow stars + (0) — false precision that read as broken controls and flattened the Browse grid into identical rows. When reviewCount is 0, show a quiet localized "no reviews yet" label (volt accent) instead; rated cards keep the star rating. Honest empty state, existing tokens only.

3. UX

  • Insufficient-balance guidance on the listing detail: a logged-in user who can't afford a paid listing used to get no signal until an English-only server error after clicking Buy. Now the client compares wallet balance to price — pre-empts the doomed request with a localized toast and shows an inline "short by $X · Top up" hint linking to the wallet.

Verification

  • typecheck, 327 unit tests (added 4: unrated-card both states, insufficient-balance shown/hidden), build — all pass.
  • New i18n keys (common.listing.unrated, detail.purchase.*) added in ko+en; the locale-parity test enforces both.

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 리뷰가 없는 상품에 "아직 리뷰 없음" 메시지 표시
    • 상품 구매 시 지갑 잔액 부족 여부를 미리 확인하고 알림 표시
    • 잔액 부족 시 충전 페이지로 이동하는 링크 제공
  • Tests

    • 리뷰 없음 상태 및 잔액 부족 시나리오에 대한 테스트 추가
  • Refactor

    • 상품 카드 컴포넌트 코드 정리
  • Chores

    • 다국어 지원 확대 (영문, 한글)
    • 폰트 리소스 로딩 최적화

Review Change Stack

blue45f added 3 commits May 30, 2026 02:27
The Pretendard font CSS loads from cdn.jsdelivr.net with no preconnect, so the
browser pays a fresh DNS+TLS round-trip mid-paint. Add a preconnect alongside
the existing Google Fonts ones to start that handshake earlier.
New listings have no reviews, so every Browse-grid card rendered five hollow
stars + (0) — false precision that read as broken controls and flattened the
grid into identical rows. When reviewCount is 0, show a quiet localized
"no reviews yet" label (volt accent) instead; rated cards keep the star
rating unchanged. Honest empty state per PRODUCT.md, existing tokens only.

Adds ListingCard tests for both states; common.listing.unrated in ko/en.
A logged-in user who can't afford a paid listing previously got no signal
until after clicking Buy, then an English-only server error with no recovery
path. Now the client compares wallet balance to price: it pre-empts the
doomed request with a localized toast and shows an inline "short by $X /
Top up" hint (linking to the wallet) under the buy button. Uses data already
in scope; no new deps.

Adds ListingDetailPage tests (hint shows when short, hidden when affordable);
detail.purchase.* in ko/en.
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

변경 사항 요약

상품 카드에서 미평가 상태를 i18n 번역으로 표시하고, 구매 전 지갑 잔액을 검증해 부족 시 토스트 알림과 충전 링크를 제공하는 기능을 추가했습니다.

변경 사항

잔액 검증 및 미평가 상품 UI

계층 / 파일(s) 요약
다국어 지원 및 CDN 설정
apps/web/index.html, apps/web/src/i18n/locales/en/common.json, apps/web/src/i18n/locales/en/detail.json, apps/web/src/i18n/locales/ko/common.json, apps/web/src/i18n/locales/ko/detail.json
CDN 교차 출처 요청 설정을 추가하고, 미평가 상품(listing.unrated) 및 구매 부족 관련 번역 키(purchase.insufficient, purchase.shortBy, purchase.topUp)를 영문과 한국어로 정의합니다.
상품 카드 미평가 상태 표시 및 스타일링
apps/web/src/components/ListingCard.tsx, apps/web/src/components/ListingCard.test.tsx
ListingCard가 useTranslation으로 리뷰 수 0일 때 별점 대신 "아직 리뷰 없음" 텍스트를 렌더링합니다. JSX와 Tailwind 클래스 구조를 cn() 중심으로 재정리하고, 미평가 상태 표시 여부를 검증하는 테스트를 추가합니다.
구매 잔액 검증 로직 및 UI
apps/web/src/pages/ListingDetail/ListingDetailPage.tsx
handlePurchase 함수에서 구매 전 지갑 잔액을 검증해 부족 시 토스트 알림으로 로컬라이즈된 안내를 표시하고 구매를 중단합니다. 사이드바에서 부족 금액을 계산해 충전 안내와 /dashboard 링크를 조건부로 렌더링합니다.
구매 잔액 검증 테스트
apps/web/src/pages/ListingDetail/ListingDetailPage.test.tsx
테스트 설정을 정리하고, 지갑 잔액이 부족할 때 충전 링크가 노출되는지, 충분할 때 숨겨지는지를 검증하는 테스트 케이스를 추가합니다.

🎯 3 (Moderate) | ⏱️ ~25 분

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 PR 제목이 세 가지 주요 변경사항(성능 개선, 디자인, UX)을 모두 포함하며 실제 변경사항과 일치합니다.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat/perf-design-ux

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

❤️ Share

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/web/src/pages/ListingDetail/ListingDetailPage.test.tsx (1)

148-151: 💤 Low value

부족 금액 표기까지 단언하면 회귀 방지에 도움이 됩니다.

현재는 링크 존재/href만 확인합니다. PR이 제공하는 "short by $X" 힌트 금액(여기서는 $3.99)도 함께 단언하면 금액 계산 회귀를 잡을 수 있습니다.

♻️ 부족 금액 단언 추가 예시
     const topUp = screen.getByRole('link', { name: /충전하기|Top up/i })
     expect(topUp.getAttribute('href')).toBe('/dashboard')
+    expect(screen.getByText(/\$3\.99/)).toBeTruthy()
🤖 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 `@apps/web/src/pages/ListingDetail/ListingDetailPage.test.tsx` around lines 148
- 151, The test currently renders the page with renderPage(), finds the top-up
link via screen.getByRole (assigned to topUp) and asserts only its href; add an
assertion that the link's visible text contains the expected shortfall amount
string (e.g., "short by $3.99" or the localized "충전하기" label plus the amount) to
catch regressions in the shortfall calculation; locate the topUp variable
(result of screen.getByRole('link', { name: /충전하기|Top up/i })) and add a
contains/text match assertion against the expected amount/phrase so the test
verifies both the link target and the displayed shortfall.
🤖 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 `@apps/web/src/pages/ListingDetail/ListingDetailPage.test.tsx`:
- Around line 148-151: The test currently renders the page with renderPage(),
finds the top-up link via screen.getByRole (assigned to topUp) and asserts only
its href; add an assertion that the link's visible text contains the expected
shortfall amount string (e.g., "short by $3.99" or the localized "충전하기" label
plus the amount) to catch regressions in the shortfall calculation; locate the
topUp variable (result of screen.getByRole('link', { name: /충전하기|Top up/i }))
and add a contains/text match assertion against the expected amount/phrase so
the test verifies both the link target and the displayed shortfall.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e542e8c8-32f0-43e0-9672-1afd274a8a55

📥 Commits

Reviewing files that changed from the base of the PR and between 26988e9 and e1df2c9.

📒 Files selected for processing (9)
  • apps/web/index.html
  • apps/web/src/components/ListingCard.test.tsx
  • apps/web/src/components/ListingCard.tsx
  • apps/web/src/i18n/locales/en/common.json
  • apps/web/src/i18n/locales/en/detail.json
  • apps/web/src/i18n/locales/ko/common.json
  • apps/web/src/i18n/locales/ko/detail.json
  • apps/web/src/pages/ListingDetail/ListingDetailPage.test.tsx
  • apps/web/src/pages/ListingDetail/ListingDetailPage.tsx

@blue45f blue45f merged commit 252db63 into main May 29, 2026
6 checks passed
@blue45f blue45f deleted the feat/perf-design-ux branch May 29, 2026 17:38
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