Add ForecastNeedle gauge and use it in the forecast cards#135
Merged
Conversation
A cartoon-styled semicircle "needle" gauge (à la the NYT election needle) for visualizing forecast probabilities. Supports one or more independently colored needles on the same half-wheel, e.g. a user's forecast alongside a community-average baseline. - Red -> white -> green gradient arc with a dark outline and blocky needles - `color` accepts any CSS color string (Tailwind var, chart token, or hex); defaults to the theme --primary - Smooth sweep-in animation; 0% / 100% axis labels - Per-needle label + percentage surfaced in a hover/tap tooltip - Pure, exported geometry helpers with unit tests; Storybook stories Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Cartoon styling: red -> white -> green gradient, blocky pencil needle and hub, dark ink outline - Sub-semicircle sweep (140deg) so the gauge is taller and less wide - Render the band as a horizontally-sliced ring (filled + single outline) so the ends are flat and parallel to the x-axis with a continuous outline - Per-needle labels moved into the hover/tap tooltip; axis labels trimmed to 0% / 100% and enlarged - Geometry parameterized via SWEEP_DEGREES; tests updated accordingly Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the arbitrary `needles` array with a required `forecast` and an optional `baseline`, matching the only two real use cases. Styling is now fixed by role rather than caller-controlled: - forecast: solid primary needle with an ink outline - baseline: lighter outline-only "ghost" needle in muted gray, drawn behind Tooltip labels default to "You" / "Avg" and stay overridable for non-average baselines. Stories updated to the new API. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stories cover the default (has-forecast), empty, low/high probability, and long-text states. The slider and percent input are interactive. To render a component that module-imports server actions, alias @/lib/db_actions and @/lib/db_actions/props to success-returning stubs in Storybook only, so the Postgres client and next/cache stay out of the bundle. Shared mock data lives in forecast-card.fixtures.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stories cover the color scale, the you-vs-avg comparison bar (including the identical and label-collision cases), the no-forecast placeholder, status badges, and markdown/long-text rendering. ForecastCard imports next/link, whose app-router internals trip a circular-import TDZ under Vite's dev transform. Mock next/link to a plain anchor in Storybook (as @storybook/nextjs does) to render it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Throwaway mockups exploring how to fold the ForecastNeedle into the forecast card: NeedleRight (compact needle as a right-hand summary), NeedleHero (needle as the left hero panel), and NeedleTile (centered redesign). Shown side by side in a Storybook gallery for picking a direction. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the NeedleHero and NeedleTile mockups; keep only NeedleRight, the chosen direction. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the colored % box and the you/avg comparison bar with the needle
layout chosen from the experiments: the user's forecast as the primary needle
with the community average as a muted ghost needle, a bold % readout, and an
"Average: NN%" line. The whole card is now a link to the prop details (the
external-link button is gone), and the badges sit top-left.
Same { prop, showCommunityAvg } API, so call sites are unchanged. Delete the
throwaway needle-experiments files; drop the comparison-bar collision stories.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Throwaway mock for folding the ForecastNeedle into the editable forecast card: the needle (live preview + community-average ghost) on the right with a number box as the input, an inline edit pencil beside the prop text, and the unsaved-changes ring + Save/Cancel. Local state only — saving is faked. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Notes used `truncate` (nowrap) and spilled off the side; switch to wrapping. Add LongPropText and LongNotes stories to exercise overflow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the colored % box and slider with the needle layout: the user's
forecast as the primary needle plus the community average as a muted ghost
needle, with a number-entry box (type 0–100, Enter/blur to commit) as the
input. The admin edit pencil now sits inline beside the prop text, and notes
wrap instead of truncating.
Real save logic (createForecast/updateForecast via useServerAction), admin
gating, and PropEditDialog are unchanged; same { prop, onForecastUpdate } API,
so the call site is untouched. Delete the throwaway needle experiments.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Set outputFileTracingRoot and turbopack.root to this project so Next/Turbopack don't infer a parent directory as the workspace root. On a nested checkout that mis-rooting poisoned the build/cache and made webpack (via @sentry/nextjs) try to resolve `tailwindcss` from the parent folder, breaking `next dev`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a cartoon-styled half-wheel needle gauge for visualizing forecast probabilities, and wires it into both forecast cards.
What's new
ForecastNeedle(components/ui/forecast-needle.tsx) — an SVG gauge with a red→white→green arc and a blocky outlined needle. API isforecast(0–1, primary needle) plus an optionalbaseline(drawn as a muted "ghost" needle). Hovering/tapping a needle reveals its%; it animates in on mount. Pure geometry helpers are unit-tested.ForecastCard(display) — replaces the colored%box and the you/avg comparison bar with the needle (forecast + community-average ghost) and a small%/Average: NN%readout. The whole card is now a link to the prop details.EditableForecastCard— replaces the%box and slider with the needle plus a number-entry box (type 0–100, Enter/blur to commit). The admin edit pencil now sits inline beside the prop text, and long notes wrap. Real save logic (createForecast/updateForecast), admin gating, andPropEditDialogare unchanged..storybook/mocks/) for the server actions andnext/linkso the Next.js-coupled cards render in the react-vite Storybook without pulling in the DB client.Both card components keep their existing props, so call sites are untouched.
Behavior changes worth noting
Testing
npm run lint— 0 errorsnpx tsc --noEmit— cleannpm run test— 203 passednpm run build-storybook— passes🤖 Generated with Claude Code