diff --git a/src/app/story/[storylineId]/page.tsx b/src/app/story/[storylineId]/page.tsx index e9d80e78..a08ef80d 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 { RatingSummary } from "../../../components/RatingSummary"; +import { RatingSummaryWithSeparator } from "../../../components/RatingSummaryWithSeparator"; import { ShareButtons } from "../../../components/ShareButtons"; import { StoryContent } from "../../../components/StoryContent"; import { ReadingModeWrapper } from "../../../components/ReadingModeWrapper"; @@ -260,47 +260,83 @@ function StoryHeader({ }) { return (
- {/* Title */} -

- {storyline.title} -

- - {/* Writer */} -
- Writer - {truncateAddress(storyline.writer_address)}}> - - - {storyline.writer_type === 1 && } -
+ {/* Moleskine cover + Info panel */} +
+ {/* Moleskine book cover */} +
+
+
+
+ + {storyline.genre || "Uncategorized"} + +
+
+ + {storyline.title} + +
+
+ + {storyline.plot_count} {storyline.plot_count === 1 ? "plot" : "plots"} + +
+
+
- {/* Stats */} -
- {storyline.plot_count} {storyline.plot_count === 1 ? "plot" : "plots"} - -
+ {/* Info panel */} +
+ {/* Title */} +

+ {storyline.title} +

+ + {/* Rating + Views */} +
+ + +
- {/* Badges */} - {(storyline.genre || (storyline.language && storyline.language !== "English")) && ( -
- {storyline.genre && ( - - {storyline.genre} - - )} - {storyline.language && storyline.language !== "English" && ( - - {storyline.language} - - )} + {/* Info rows */} +
+
+ Writer + {truncateAddress(storyline.writer_address)}}> + + + {storyline.writer_type === 1 && } +
+
+ Plots + + {storyline.plot_count} {storyline.plot_count === 1 ? "plot" : "plots"} + +
+
+ Genre + + {storyline.genre || "Uncategorized"} + {storyline.language && storyline.language !== "English" && ( + · {storyline.language} + )} + +
+
- )} - - {/* Rating */} -
-
+ {/* Market stats */} {priceInfo && (
diff --git a/src/components/RatingSummaryWithSeparator.tsx b/src/components/RatingSummaryWithSeparator.tsx new file mode 100644 index 00000000..f1f467e7 --- /dev/null +++ b/src/components/RatingSummaryWithSeparator.tsx @@ -0,0 +1,38 @@ +"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}) + + + · + + ); +}