Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/web/e2e/reflow-contrast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const PHONE_PAGES = [
// (DOS/Rate#1082).
'/en/smartphones',
'/cs/smartphones',
// Czech copy is the longest; the merchant rating line did not wrap
// (DOS/Rate#1084).
'/cs/leaderboard',
Comment thread
coderabbitai[bot] marked this conversation as resolved.
'/cs/merchants/excluded-review-store',
];

for (const path of PHONE_PAGES) {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@
"rank3Label": "3. místo",
"fullTableTitle": "Kompletní žebříček kategorie",
"verifiedReviewsSuffix": "ověřených recenzí",
"blockedSpamCount": "{count, plural, one {Zablokována # falešná/spamová recenze} few {Zablokovány # falešné/spamové recenze} other {Zablokováno # falešných/spamových recenzí}}",
"blockedSpamCount": "{count, plural, one {Zablokována # falešná či spamová recenze} few {Zablokovány # falešné či spamové recenze} other {Zablokováno # falešných či spamových recenzí}}",
"storesTrackedSuffix": "obchodů",
"viewAuditDetailBtn": "Recenze a 10 skupin parametrů →",
"inspectBtn": "Ověřit cenu",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"lint": "eslint . --max-warnings 0",
"preview": "next build && next start",
"start": "next start",
"test": "pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/server/rate/__tests__/core-rate-architecture.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/app/api/v1/rate/__tests__/write-paths.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/logger.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/review-display.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/concurrency.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/catalog-listing.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/discount-verdict-copy.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/product-detail-copy.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/product-competitors.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/analyzer-copy.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/sold-count.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/content-lang.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/image-url.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/client-messages.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/seo.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/offer-plausibility.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/sitemap-lastmod.test.ts",
"test": "pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/server/rate/__tests__/core-rate-architecture.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/app/api/v1/rate/__tests__/write-paths.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/logger.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/review-display.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/concurrency.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/catalog-listing.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/discount-verdict-copy.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/product-detail-copy.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/product-competitors.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/analyzer-copy.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/sold-count.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/content-lang.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/image-url.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/client-messages.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/seo.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/offer-plausibility.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/sitemap-lastmod.test.ts && pnpm --filter @repo/crawlers exec tsx --tsconfig ../web/tsconfig.test.json ../web/src/lib/__tests__/leaderboard-badge-copy.test.ts",
"typecheck": "tsc --noEmit"
},
"browserslist": [
Expand Down
8 changes: 5 additions & 3 deletions apps/web/src/app/[locale]/merchants/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,9 @@ export default async function MerchantProfilePage({
className="d-flex align-items-center small flex-wrap gap-3"
style={{ color: '#94a3b8' }}
>
<span className="d-inline-flex align-items-center gap-1">
{/* Items wrap: "Hodnocení tržiště: Neaktualizováno" is wider
than a 320px header column (DOS/Rate#1084). */}
<span className="d-inline-flex align-items-center flex-wrap gap-1">
<BsStarFill className="text-warning" />
{t('platformRatingLabel')}{' '}
<strong className="font-monospace text-white">
Expand All @@ -291,7 +293,7 @@ export default async function MerchantProfilePage({
: t('notUpdatedYet')}
</strong>
</span>
<span className="d-inline-flex align-items-center gap-1">
<span className="d-inline-flex align-items-center flex-wrap gap-1">
<BsPeopleFill className="text-info" />
{t('followersLabel')}{' '}
<strong className="font-monospace text-white">
Expand All @@ -300,7 +302,7 @@ export default async function MerchantProfilePage({
: '-'}
</strong>
</span>
<span className="d-inline-flex align-items-center gap-1">
<span className="d-inline-flex align-items-center flex-wrap gap-1">
<BsBoxSeam className="text-success" />
{t('trackedModelsLabel')}{' '}
<strong className="font-monospace text-white">
Expand Down
33 changes: 33 additions & 0 deletions apps/web/src/lib/__tests__/leaderboard-badge-copy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';

// The leaderboard's blocked-spam badge is about 114px wide on a 320px phone
// (~12 characters at its font size). "falešných/spamových" had no line-break
// opportunity (a slash only allows a break before digits), so the badge
// pushed /cs/leaderboard 16px sideways (DOS/Rate#1084). The E2E seed has no
// ignored reviews, so this guards the copy directly.
const MAX_UNBREAKABLE_CHARS = 12;

for (const locale of ['vi', 'en', 'cs'] as const) {
const file = join(__dirname, '..', '..', '..', 'locales', `${locale}.json`);
const message: string = JSON.parse(readFileSync(file, 'utf8')).leaderboard
.blockedSpamCount;
assert.ok(message, `${locale}: missing leaderboard.blockedSpamCount`);

// Keep the text of every plural branch; drop ICU syntax and placeholders.
const text = message
.replace(/\{count\}/g, '0')
.replace(/\{count, plural,/, '')
.replace(/\b(?:zero|one|two|few|many|other)\s*\{/g, ' ')
.replace(/[{}#]/g, ' ');

for (const word of text.split(/\s+/).filter(Boolean)) {
assert.ok(
word.length <= MAX_UNBREAKABLE_CHARS,
`${locale}: "${word}" cannot wrap inside the leaderboard badge`
);
}
}

console.log('leaderboard-badge-copy: ok');
Loading