From ebee579b3744733c8881f2cfeed8720f036a69ba Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Fri, 3 Apr 2026 11:17:30 +0100 Subject: [PATCH] [#797] Deduplicate RatingSummary, add aria-hidden to separator Add optional `separator` prop to RatingSummary that renders a trailing dot when ratings exist. Delete RatingSummaryWithSeparator duplicate. Add aria-hidden="true" to the decorative separator dot. Fixes #797 Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/OVERNIGHT-QUEUE.md | 63 +++++++++---------- src/app/story/[storylineId]/page.tsx | 4 +- src/components/RatingSummary.tsx | 21 +++++-- src/components/RatingSummaryWithSeparator.tsx | 38 ----------- 4 files changed, 45 insertions(+), 81 deletions(-) delete mode 100644 src/components/RatingSummaryWithSeparator.tsx diff --git a/docs/OVERNIGHT-QUEUE.md b/docs/OVERNIGHT-QUEUE.md index 9995a854..87f6bd48 100644 --- a/docs/OVERNIGHT-QUEUE.md +++ b/docs/OVERNIGHT-QUEUE.md @@ -134,41 +134,34 @@ --- -## Tonight's Queue — Batch 59: Reader Redesign + Storyline Page Polish - -### 1. plotlink#771 — Reader tab: holdings grid full width on mobile -- 4-box grid under each holdings card doesn't stretch to full width on mobile -- Fix: ensure grid spans full card width below the Moleskine on small screens -- Branch: `task/771-reader-grid-fullwidth` - -### 2. plotlink#772 — Reader tab: simplify holdings + portfolio boxes, add trade history -- Holdings card: 2 boxes (Value with % from cost basis, Balance) instead of 4 -- Add simple list of recent 5 transactions below each holdings card -- Portfolio dashboard: 2 boxes (Total Value with % from cost basis, Holdings count) instead of 4 -- Branch: `task/772-reader-cost-pnl` - -### 3. plotlink#775 — Storyline page: redesign top info section + Writer label -- Change "by" prefix to "Writer" -- Come up with a tidier, mobile-friendly layout for title/author/stats/genre/rating -- Branch: `task/775-storyline-header-redesign` - -### 4. plotlink#773 — Storyline page: Market Cap USD + 24h change instead of Token Price -- Replace TOKEN PRICE box with MARKET CAP in USD + 24h percent change -- Keep Supply Minted as-is -- Branch: `task/773-storyline-mcap` - -### 5. plotlink#774 — Storyline page: restructure deadline + stats into 2-col grid -- Wrap deadline in proper section box titled "Next Plot Publish Deadline" -- Desktop: 2-col grid (MCap + Supply), deadline box below -- Mobile: stack vertically -- Depends on #773 -- Branch: `task/774-storyline-deadline-layout` - -### 6. plotlink#776 — Research: price chart USD feasibility -- Investigate if we can convert PLOT-based price chart to USD -- We don't store historical PLOT→USD rates per trade — research if data is available -- Report findings BEFORE implementing — do not guess -- Branch: `task/776-chart-usd-research` +## Completed — Batch 59 + +- Batch 59: Reader grid fullwidth #777, Reader simplify #778, MCap USD #779, Deadline layout #780, Header redesign #781, USD chart #787 + +--- + +## Completed — Batch 60 + +- Batch 60: Zap nonce fix #790, Trading format #791, MCap+Deadline grid #792, MCap+Supply mobile #793, Moleskine header #794, Reader trades style #795 + +--- + +## Tonight's Queue — Batch 61: Post-Review Fixes + +### 1. plotlink#796 — DonateWidget: unformatted balance shows raw 18-decimal values +- Same bug as #789 but in DonateWidget.tsx (lines ~152, 164) +- Apply same `formatTokenAmount` or extract to shared `src/lib/format.ts` +- Branch: `task/796-donate-format` + +### 2. plotlink#797 — Storyline header: RatingSummaryWithSeparator duplicates RatingSummary +- Refactor to compose existing `RatingSummary` instead of duplicating query+render +- Add `aria-hidden="true"` to decorative separator dot +- Branch: `task/797-rating-summary-dedup` + +### 3. plotlink#798 — Storyline stats: add min-w-0 overflow guard on mobile grid +- MCap + Supply grid children need `min-w-0` for 320px screens +- Prevents text overflow with large USD values + 24h% badge +- Branch: `task/798-stats-overflow-guard` --- diff --git a/src/app/story/[storylineId]/page.tsx b/src/app/story/[storylineId]/page.tsx index a08ef80d..e8e3f733 100644 --- a/src/app/story/[storylineId]/page.tsx +++ b/src/app/story/[storylineId]/page.tsx @@ -7,7 +7,7 @@ import { TradingWidget } from "../../../components/TradingWidget"; import { PriceChart } from "../../../components/PriceChart"; import { DonateWidget } from "../../../components/DonateWidget"; import { RatingWidget } from "../../../components/RatingWidget"; -import { RatingSummaryWithSeparator } from "../../../components/RatingSummaryWithSeparator"; +import { RatingSummary } from "../../../components/RatingSummary"; import { ShareButtons } from "../../../components/ShareButtons"; import { StoryContent } from "../../../components/StoryContent"; import { ReadingModeWrapper } from "../../../components/ReadingModeWrapper"; @@ -304,7 +304,7 @@ function StoryHeader({ {/* Rating + Views */}
- +
diff --git a/src/components/RatingSummary.tsx b/src/components/RatingSummary.tsx index f5e451ee..a846b80a 100644 --- a/src/components/RatingSummary.tsx +++ b/src/components/RatingSummary.tsx @@ -8,7 +8,13 @@ interface RatingsResponse { count: number; } -export function RatingSummary({ storylineId }: { storylineId: number }) { +export function RatingSummary({ + storylineId, + separator, +}: { + storylineId: number; + separator?: boolean; +}) { const { data } = useQuery({ queryKey: ["ratings", storylineId], queryFn: async () => { @@ -21,11 +27,14 @@ export function RatingSummary({ storylineId }: { storylineId: number }) { if (!data || data.count === 0) return null; return ( - - - - {data.average.toFixed(1)} ({data.count}) + <> + + + + {data.average.toFixed(1)} ({data.count}) + - + {separator && } + ); } diff --git a/src/components/RatingSummaryWithSeparator.tsx b/src/components/RatingSummaryWithSeparator.tsx deleted file mode 100644 index f1f467e7..00000000 --- a/src/components/RatingSummaryWithSeparator.tsx +++ /dev/null @@ -1,38 +0,0 @@ -"use client"; - -import { useQuery } from "@tanstack/react-query"; -import { StarDisplay } from "./StarRating"; - -interface RatingsResponse { - average: number; - count: number; -} - -/** - * RatingSummary that includes a trailing separator dot. - * Renders nothing (no dot) when there are no ratings. - */ -export function RatingSummaryWithSeparator({ storylineId }: { storylineId: number }) { - const { data } = useQuery({ - queryKey: ["ratings", storylineId], - queryFn: async () => { - const res = await fetch(`/api/ratings?storylineId=${storylineId}`); - if (!res.ok) throw new Error("Failed to fetch ratings"); - return res.json(); - }, - }); - - if (!data || data.count === 0) return null; - - return ( - <> - - - - {data.average.toFixed(1)} ({data.count}) - - - · - - ); -}