Skip to content

Integrate the shell for desktop#4676

Merged
ncarazon merged 9 commits intofeat/question-page-redesign-1st-iterationfrom
feat/integrate-the-shell-widen-the-main-column-strip-old-layouts
May 1, 2026
Merged

Integrate the shell for desktop#4676
ncarazon merged 9 commits intofeat/question-page-redesign-1st-iterationfrom
feat/integrate-the-shell-widen-the-main-column-strip-old-layouts

Conversation

@ncarazon
Copy link
Copy Markdown
Contributor

@ncarazon ncarazon commented Apr 29, 2026

This PR wires all previously built shell pieces into a single top-level
QuestionPageShell that owns full page rendering for both variants, widens
the main column to the new design width, and removes all now-unreachable code.

Implemented features & fixes:

  • Created question_page_shell/index.tsx with ForecasterShell and
    ConsumerShell as named exports - composing MetaRow, TitleRow, ActionRow,
    body content, TabBar, and active tab panel in one place
  • Wired QuestionTimeline (chart) into ConsumerShell alongside the
    prediction block in a side-by-side flex row on desktop
  • Passed mobile sidebar as a ReactNode prop to avoid a server/client
    boundary issue with next/headers
  • Widened the main column from the old value to w-[59rem]
  • Updated page_component.tsx to mount QuestionPageShell directly,
    removing the old QuestionLayout / QuestionView tree
  • Deleted 10 dead files: QuestionLayout, QuestionSection, QuestionInfo,
    ForecasterQuestionLayout, ConsumerQuestionLayout, ConsumerTabs,
    QuestionView, ForecasterQuestionView, QuestionHeader,
    ConsumerQuestionView
  • Migrated all 10 Storybook question-page stories to import
    ConsumerShell / ForecasterShell from the new shell
  • Moved CommunityDisclaimer (mobile standalone variant) inside both shells
    so it renders within the card section rather than outside it; added
    relative z-10 to the section so it correctly layers above the desktop
    inline disclaimer
  • Replaced direct DOM comment scrolling with context-based navigation for more reliable cross-tab behavior
  • Updated key factors overlay and related actions to switch to the comments tab before scrolling to the target comment
  • Refined question page and comment feed styling, spacing, and layout
  • Stacked comment created date below author nickname on question page; aligned date and vote score typography
  • Added My Scores tab to the consumer tab bar (conditionally when scores exist) - renders ParticipationSummarySection + Peer Score + Baseline Score cards via PostScoreData
  • Fixed duplicate comments appearing when switching away from and back to the comments tab
  • Deduplicated post score routing logic in utils.ts with a shared someQuestionIn helper
  • Added shouldPostShowUserScores alongside the existing score check so the My Scores tab only appears when the user has personal scores, not just community ones

Demo videos

  • Consumer view
consumer.view.mp4
  • Forecaster view
forecaster.view.mp4
  • Check key factors overlay behavior and scrolling to the correct comment
key.factors.mp4
  • My Scores tab and dropdown section for consumer and forecaster views
my-scores.mp4

Summary by CodeRabbit

Release Notes

  • New Features

    • Added "My Scores" tab for viewing your personal forecast scores on questions.
    • Improved comment navigation—clicking comments from overlays or sections now smoothly scrolls to the correct position.
  • Bug Fixes

    • Fixed comment feed filtering to reset pagination when applying new filters.
  • Style

    • Updated comment styling with improved spacing and typography.
    • Refined comment author information layout for better readability.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 29478f2f-16de-4daa-a1a4-2106fc15d4f1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/integrate-the-shell-widen-the-main-column-strip-old-layouts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Cleanup: Preview Environment Removed

The preview environment for this PR has been destroyed.

Resource Status
🌐 Preview App Deleted
🗄️ PostgreSQL Branch Deleted
⚡ Redis Database Deleted
🔧 GitHub Deployments Removed
📦 Docker Image Retained (auto-cleanup via GHCR policies)

Cleanup triggered by PR close at 2026-05-01T10:41:01Z

@ncarazon ncarazon marked this pull request as ready for review April 30, 2026 14:50
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (1)
front_end/src/stories/question_page/binary_group/fan_chart.stories.tsx (1)

46-46: ⚡ Quick win

Align Storybook container width with the new shell width.

Line 46 still constrains the story to 703px, which no longer matches the desktop shell width update (59rem) described in this PR. Keeping this in sync avoids misleading Storybook visual baselines.

Suggested change
-              <div style={{ margin: "0 auto", maxWidth: "703px" }}>
+              <div style={{ margin: "0 auto", maxWidth: "59rem" }}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@front_end/src/stories/question_page/binary_group/fan_chart.stories.tsx` at
line 46, Storybook wrapper div hard-codes maxWidth: "703px", which no longer
matches the updated desktop shell width (59rem); update the inline style on the
div (the JSX element with style {{ margin: "0 auto", maxWidth: "703px" }}) to
use maxWidth: "59rem" (or a matching pixel value) so the story container matches
the new shell width.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@front_end/src/app/`(main)/questions/[id]/components/question_page_shell/index.tsx:
- Around line 58-64: The effect that shows the translated banner (useEffect
referencing postData.is_current_content_translated, setTimeout and
setBannerIsVisible) can leave a pending timeout or stale visible state across
navigation; update the effect to always reset the banner on dependency changes
by calling setBannerIsVisible(false) immediately, then if
postData.is_current_content_translated schedule a timeout to
setBannerIsVisible(true), store the timer id and clear it in the effect cleanup
(clearTimeout(timerId)) so no stale timer can show the banner on the next page.
- Around line 121-123: Consumer variant is not receiving the mobileSidebar prop
causing the sidebar to be dropped; thread the mobileSidebar prop from where
QuestionVariantComposer chooses the Consumer variant down into ConsumerShell and
then pass it into QuestionPageShell so it gets forwarded to ForecasterShell
(mirror how ForecasterShell receives mobileSidebar). Update the ConsumerShell
component signature (ConsumerShell: FC<{ postData: PostWithForecasts;
mobileSidebar?: ReactNode }>) and ensure the call sites in
QuestionVariantComposer (where the consumer branch is returned) pass the
mobileSidebar prop through to ConsumerShell and from ConsumerShell into
QuestionPageShell (same prop name mobileSidebar) so the sidebar is rendered for
consumer variant too.

In
`@front_end/src/app/`(main)/questions/[id]/components/question_page_shell/tab_bar.tsx:
- Line 17: The hash-based tab restoration is still checking for the old "scores"
key so links to the new TabKey "my-scores" fall back to "comments"; update the
whitelist/allowed-keys logic in question_layout_context (the code that validates
persisted hash/tab keys) to include "my-scores" (and replace any checks that
specifically look for "scores" to accept "my-scores"), and apply the same change
to the other related checks referenced (the occurrences around the 69-71 area)
so hash-based activation correctly restores the My Scores tab instead of falling
back.

In `@front_end/src/components/comment_feed/comment.tsx`:
- Line 1081: The menu button's aria-label is hardcoded as "menu"; update the JSX
in the Comment component to call useTranslations() (or reuse an existing t
variable from useTranslations()) and replace aria-label="menu" with
aria-label={t('commentFeed.menuLabel')} (or another descriptive i18n key), add
the new i18n key to the translations files, and ensure the t variable is
imported/available where the menu button is rendered.

In `@front_end/src/components/comment_feed/index.tsx`:
- Around line 432-434: The hardcoded fallback string "sort" should be replaced
with a localized translation key; update the component to import/use
useTranslations (e.g., call const t = useTranslations(...) in this component)
and replace the fallback with t('sort') or a namespaced key like
t('commentFeed.sort') so the expression becomes menuItems.find((item) => item.id
=== feedFilters.sort)?.name ?? t('commentFeed.sort'); ensure the chosen
translation key is added to the i18n resource files and that useTranslations is
imported where menuItems and feedFilters.sort are used.

In
`@front_end/src/stories/question_page/continuous_question/continuous_question.stories.tsx`:
- Around line 45-50: The story wrapper is still fixed to the legacy 703px max
width (the inline style on the div wrapping
MockCommentsFeedProvider/QuestionLayoutProvider/Story), preventing the migrated
story from rendering the new desktop shell; update that inline style to use the
new widened shell width (replace "703px" with the project's desktop shell max
width constant or CSS variable, or the new pixel value used across the app) so
the component tree (MockCommentsFeedProvider, QuestionLayoutProvider, Story)
renders at the correct width in Storybook.

In `@front_end/src/stories/question_page/date_question/date_question.stories.tsx`:
- Around line 45-50: The story wrapper currently constrains the preview with an
inline style maxWidth: "703px" so the story never exercises the new desktop
layout; remove or update that constraint around the Story (the div wrapping
MockCommentsFeedProvider / QuestionLayoutProvider / Story) so it no longer
clamps to 703px—either remove the inline style entirely or replace it with a
width class/config that allows the new w-[59rem] desktop layout to be rendered
and tested (target the div containing QuestionLayoutProvider and Story).

---

Nitpick comments:
In `@front_end/src/stories/question_page/binary_group/fan_chart.stories.tsx`:
- Line 46: Storybook wrapper div hard-codes maxWidth: "703px", which no longer
matches the updated desktop shell width (59rem); update the inline style on the
div (the JSX element with style {{ margin: "0 auto", maxWidth: "703px" }}) to
use maxWidth: "59rem" (or a matching pixel value) so the story container matches
the new shell width.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c096fbcb-cdaf-4150-bf17-6bcdc65b13b2

📥 Commits

Reviewing files that changed from the base of the PR and between 6b4cd20 and 405ad3c.

📒 Files selected for processing (41)
  • front_end/src/app/(main)/components/comments_feed_provider.tsx
  • front_end/src/app/(main)/questions/[id]/[[...slug]]/page_component.tsx
  • front_end/src/app/(main)/questions/[id]/components/key_factors/item_view/more_panel.tsx
  • front_end/src/app/(main)/questions/[id]/components/key_factors/key_factor_detail_overlay.tsx
  • front_end/src/app/(main)/questions/[id]/components/post_score_data/single_question_score_data.tsx
  • front_end/src/app/(main)/questions/[id]/components/post_score_data/utils.ts
  • front_end/src/app/(main)/questions/[id]/components/question_layout/consumer_question_layout/consumer_tabs.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/consumer_question_layout/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/forecaster_question_layout/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/question_info.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/question_layout_context.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/question_section.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_page_shell/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_page_shell/tab_bar.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_page_shell/tabs.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_page_shell/tabs/comments.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_page_shell/tabs/my_scores.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/consumer_question_view/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/consumer_question_view/timeline/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/forecaster_question_view/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/forecaster_question_view/question_header/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/index.tsx
  • front_end/src/components/comment_feed/comment.tsx
  • front_end/src/components/comment_feed/comment_card.tsx
  • front_end/src/components/comment_feed/comment_date.tsx
  • front_end/src/components/comment_feed/comment_voter.tsx
  • front_end/src/components/comment_feed/comment_wrapper.tsx
  • front_end/src/components/comment_feed/index.tsx
  • front_end/src/components/detailed_question_card/detailed_question_card/index.tsx
  • front_end/src/components/voter.tsx
  • front_end/src/stories/question_page/binary_group/binary_group_timeline.stories.tsx
  • front_end/src/stories/question_page/binary_group/fan_chart.stories.tsx
  • front_end/src/stories/question_page/binary_question/binary_question.stories.tsx
  • front_end/src/stories/question_page/continuous_question/continuous_question.stories.tsx
  • front_end/src/stories/question_page/date_group/date_group_timeline.stories.tsx
  • front_end/src/stories/question_page/date_group/fan_chart.stories.tsx
  • front_end/src/stories/question_page/date_question/date_question.stories.tsx
  • front_end/src/stories/question_page/mc_question/mc_question.stories.tsx
  • front_end/src/stories/question_page/numeric_group/numeric_fan_chart.stories.tsx
  • front_end/src/stories/question_page/numeric_group/numeric_group_timeline.stories.tsx
💤 Files with no reviewable changes (10)
  • front_end/src/app/(main)/questions/[id]/components/question_view/forecaster_question_view/question_header/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/consumer_question_layout/consumer_tabs.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/forecaster_question_view/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/consumer_question_layout/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_view/consumer_question_view/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/question_section.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/index.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/question_info.tsx
  • front_end/src/app/(main)/questions/[id]/components/question_layout/forecaster_question_layout/index.tsx

Comment thread front_end/src/app/(main)/questions/[id]/components/question_page_shell/index.tsx Outdated
Comment thread front_end/src/app/(main)/questions/[id]/components/question_page_shell/index.tsx Outdated
Comment thread front_end/src/components/comment_feed/comment.tsx
Comment thread front_end/src/components/comment_feed/index.tsx
ncarazon added 9 commits May 1, 2026 13:25
…ion, improve cross-tab comment access, and refine consumer shell layout handling for different question types
…ter shell with Resolution Criteria and Background Info, and fix duplicate comments on tab re-entry
…ondition into named vars, and deduplicate post score routing logic
…mer cleanup, update my-scores hash key, and widen Storybook story wrappers to 59rem
@ncarazon ncarazon force-pushed the feat/integrate-the-shell-widen-the-main-column-strip-old-layouts branch from 6285beb to 31e3be1 Compare May 1, 2026 10:29
@ncarazon ncarazon merged commit 282a591 into feat/question-page-redesign-1st-iteration May 1, 2026
7 checks passed
@ncarazon ncarazon deleted the feat/integrate-the-shell-widen-the-main-column-strip-old-layouts branch May 1, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants