From 4c533d27df980c23042e65dde3b0ff8cf3e4cb26 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Wed, 1 Apr 2026 12:07:01 +0100 Subject: [PATCH 1/2] =?UTF-8?q?[#699]=20Redesign=20Stories=20tab=20?= =?UTF-8?q?=E2=80=94=20compact=20stats,=20cleaner=20cards,=20collapsible?= =?UTF-8?q?=20details?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Writer Stats: replace grid with compact horizontal stat row - Storyline cards: inline key stats (plots, holders, views, price, date) on one line with better visual hierarchy - TVL, donations, donation history collapsed into expandable details - Donation history collapsed by default (own profile only) - All formatUnits outputs go through formatPrice (4 decimals max) - Remove unused StatCell component Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/profile/[address]/page.tsx | 186 ++++++++++++++++------------- 1 file changed, 102 insertions(+), 84 deletions(-) diff --git a/src/app/profile/[address]/page.tsx b/src/app/profile/[address]/page.tsx index 2276c517..078824ff 100644 --- a/src/app/profile/[address]/page.tsx +++ b/src/app/profile/[address]/page.tsx @@ -693,30 +693,38 @@ function StoriesTab({ const sortedGenres = Array.from(genreCounts.entries()).sort((a, b) => b[1] - a[1]); return ( -
- {/* Writer Stats */} -
-

Writer Stats

-
- - - - BigInt(0) - ? `${formatPrice(formatUnits(totalDonations, 18))} ${RESERVE_LABEL}${plotUsd != null ? ` (≈ ${formatUsdValue(Number(formatUnits(totalDonations, 18)) * plotUsd)})` : ""}` - : "—"} - /> - {isOwnProfile && royaltyInfo && ( - BigInt(0) - ? `${formatPrice(formatUnits(royaltyInfo.unclaimed, 18))} ${RESERVE_LABEL}${plotUsd != null ? ` (≈ ${formatUsdValue(Number(formatUnits(royaltyInfo.unclaimed, 18)) * plotUsd)})` : ""}` - : "—"} - /> +
+ {/* Writer Stats — compact horizontal row */} +
+
+ Writer + {storylines.length} + stories + · + {totalPlots} + plots + · + {totalHolders !== undefined ? totalHolders : "—"} + holders + {totalDonations > BigInt(0) && ( + <> + · + {formatPrice(formatUnits(totalDonations, 18))} {RESERVE_LABEL} + {plotUsd != null && ( + (≈ {formatUsdValue(Number(formatUnits(totalDonations, 18)) * plotUsd)}) + )} + donated + + )} + {isOwnProfile && royaltyInfo && royaltyInfo.unclaimed > BigInt(0) && ( + <> + · + {formatPrice(formatUnits(royaltyInfo.unclaimed, 18))} {RESERVE_LABEL} + {plotUsd != null && ( + (≈ {formatUsdValue(Number(formatUnits(royaltyInfo.unclaimed, 18)) * plotUsd)}) + )} + claimable + )}
@@ -766,15 +774,6 @@ function StoriesTab({ ); } -function StatCell({ label, value }: { label: string; value: string }) { - return ( -
- {label} - {value} -
- ); -} - function StoryRow({ storyline, isOwnProfile, @@ -834,6 +833,7 @@ function StoryRow({ return (
+ {/* Row 1: Title + badges */}
-
- - {storyline.plot_count} {storyline.plot_count === 1 ? "plot" : "plots"} - - - {priceInfo - ? `${formatPrice(priceInfo.pricePerToken)} ${RESERVE_LABEL}${plotUsd != null ? ` (≈ ${formatUsdValue(Number(priceInfo.pricePerToken) * plotUsd)})` : ""}` - : "—"} - - - {holderCount !== undefined ? `${holderCount} holder${holderCount !== 1 ? "s" : ""}` : "—"} - - - {formatViewCount(storyline.view_count)} views - - {isOwnProfile && storyline.token_address && ( - + {/* Row 2: Key stats — inline */} +
+ {storyline.plot_count} {storyline.plot_count === 1 ? "plot" : "plots"} + · + {holderCount !== undefined ? `${holderCount} holder${holderCount !== 1 ? "s" : ""}` : "—"} + · + {formatViewCount(storyline.view_count)} views + · + {priceInfo ? ( + + {formatPrice(priceInfo.pricePerToken)} {RESERVE_LABEL} + {plotUsd != null && ( + (≈ {formatUsdValue(Number(priceInfo.pricePerToken) * plotUsd)}) + )} + + ) : ( + + )} + {storyline.block_timestamp && ( + <> + · + + {new Date(storyline.block_timestamp).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + year: "numeric", + })} + + )}
- {storyline.block_timestamp && ( -
- Created{" "} - {new Date(storyline.block_timestamp).toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: "numeric", - })} -
+ {/* Deadline countdown — own profile only, active storylines */} + {isOwnProfile && !storyline.sunset && storyline.last_plot_time && ( + )} {/* Genre prompt — own profile only, when genre not set */} @@ -899,30 +905,35 @@ function StoryRow({ /> )} - {/* Deadline countdown — own profile only, active storylines */} - {isOwnProfile && !storyline.sunset && storyline.last_plot_time && ( - - )} - - {/* Token price + TVL — visible to all */} - {storyline.token_address && ( -
- - {/* Claim royalties — own profile only */} - {isOwnProfile && ( - - )} + {/* Claim royalties — own profile only */} + {isOwnProfile && storyline.token_address && ( +
+
)} - {/* Donation history — own profile only */} - {isOwnProfile && storyline.token_address && ( - + {/* Expandable: TVL, donations, donation history */} + {storyline.token_address && ( +
+ + ▶ more details + ▼ details + +
+ + {isOwnProfile && ( + + )} + {isOwnProfile && ( + + )} +
+
)}
); @@ -1152,13 +1163,20 @@ function StoryDonationCount({ storylineId, tokenAddress }: { storylineId: number }); if (!data || data.count === 0) { - return — donations; + return
No donations
; } return ( - - {formatPrice(formatUnits(data.total, 18))} {RESERVE_LABEL}{plotUsd != null && ` (≈ ${formatUsdValue(Number(formatUnits(data.total, 18)) * plotUsd)})`} ({data.count}) - +
+ Donations + + {formatPrice(formatUnits(data.total, 18))} {RESERVE_LABEL} + + {plotUsd != null && ( + (≈ {formatUsdValue(Number(formatUnits(data.total, 18)) * plotUsd)}) + )} + ({data.count}) +
); } From 7420df4beac1475697c0d5527ba86243ba31ffa4 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Wed, 1 Apr 2026 12:10:19 +0100 Subject: [PATCH 2/2] [#699] Fix T2a review: always show donations/claimable, public donation count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Writer Stats: show donations and claimable with "—" when zero instead of hiding them entirely - StoryDonationCount visible on public profiles too (only donation history rows remain own-profile-only) Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/profile/[address]/page.tsx | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/app/profile/[address]/page.tsx b/src/app/profile/[address]/page.tsx index 078824ff..81b4965a 100644 --- a/src/app/profile/[address]/page.tsx +++ b/src/app/profile/[address]/page.tsx @@ -706,22 +706,30 @@ function StoriesTab({ · {totalHolders !== undefined ? totalHolders : "—"} holders - {totalDonations > BigInt(0) && ( + · + {totalDonations > BigInt(0) ? ( <> - · {formatPrice(formatUnits(totalDonations, 18))} {RESERVE_LABEL} {plotUsd != null && ( (≈ {formatUsdValue(Number(formatUnits(totalDonations, 18)) * plotUsd)}) )} - donated + ) : ( + )} - {isOwnProfile && royaltyInfo && royaltyInfo.unclaimed > BigInt(0) && ( + donated + {isOwnProfile && royaltyInfo && ( <> · - {formatPrice(formatUnits(royaltyInfo.unclaimed, 18))} {RESERVE_LABEL} - {plotUsd != null && ( - (≈ {formatUsdValue(Number(formatUnits(royaltyInfo.unclaimed, 18)) * plotUsd)}) + {royaltyInfo.unclaimed > BigInt(0) ? ( + <> + {formatPrice(formatUnits(royaltyInfo.unclaimed, 18))} {RESERVE_LABEL} + {plotUsd != null && ( + (≈ {formatUsdValue(Number(formatUnits(royaltyInfo.unclaimed, 18)) * plotUsd)}) + )} + + ) : ( + )} claimable @@ -926,9 +934,7 @@ function StoryRow({
- {isOwnProfile && ( - - )} + {isOwnProfile && ( )}