Skip to content

Shared and core UI shell (migration 3/8) - #691

Open
charityquinn-cognition wants to merge 2 commits into
devin/react-migration-2-core-logicfrom
devin/react-migration-3-ui-shell
Open

Shared and core UI shell (migration 3/8)#691
charityquinn-cognition wants to merge 2 commits into
devin/react-migration-2-core-logicfrom
devin/react-migration-3-ui-shell

Conversation

@charityquinn-cognition

@charityquinn-cognition charityquinn-cognition commented Aug 25, 2026

Copy link
Copy Markdown

Summary

Stacked on #690. Ports the app shell — loader, error-message, header, footer, settings — as function components, plus the global stylesheets. The router outlet is a placeholder until PR4 adds the feeds.

  • Markup, class names and copy are reproduced from the Angular templates; each component imports the original .scss verbatim, and src/styles.scss + the _media / _themes / _theme_variables partials are copied under src-react/.
  • Asset references become root-absolute (/assets/images/logo.svg) because Vite serves public/ at the root, where Angular resolved them relative to base href="/".
  • Header uses NavLink for the feed tabs (routerLinkActive -> active via NavLink's default) and keeps the scroll-to-top-on-click behavior.
  • settings.component is wired to useSettings() from PR2; the inputs stay controlled and the font/spacing fields keep their key-up semantics, so behavior is identical to the Angular [(ngModel)] + (keyup) pair. The theme radios use onChange rather than onClick — with checked set, onClick alone makes React treat them as read-only controlled inputs and warn.
  • The Angular styles.scss .app-loader / #root:empty + .app-loader rules are dropped rather than carried over: Angular's index.html held that spinner markup and the framework replaced the host element's content on boot, whereas React mounts into the container, so an :empty-driven overlay would never be hidden again.
  • App.tsx becomes the shell from app.component.html with the theme class bound to settings.theme; main.tsx wraps it in BrowserRouter + SettingsProvider.

No dangerouslySetInnerHTML here — the only [innerHTML] bindings are API-provided comment/about HTML, which arrive in PR5/PR6.

Verified: yarn react:build passes; header/footer/settings render and theme + font-size + spacing changes apply and persist across reload, with no controlled-input warning in the console.

Devin-Org: engineering

Link to Devin session: https://app.devin.ai/sessions/1ff25c6cf2f949458f82cc596fc79c65
Requested by: @charityquinn-cognition


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Devin Review (Staging)
Open in Devin Review

Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 3 new potential issues.

Open in Devin Review

return (
<header>
<div id="header">
<NavLink className="home-link" to="/news/1" onClick={scrollTop}>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: NavLink active class relies on v6 string-append behavior

NavLink with a static string className="home-link" reproduces Angular's routerLinkActive="active" only because react-router-dom v6 appends active to string classNames when active. Confirmed against ^6.26.2 in package.json, so the port is faithful.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +89 to +102
name="theme"
type="number"
onChange={changeTitleFont}
onKeyUp={changeTitleFont}
/>
</label>
</div>
<div>
<label>
List spacing:
<input
min="0"
value={settings.listSpacing}
name="theme"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Number inputs carry stray name="theme"

The font-size and list-spacing number inputs both keep name="theme", copied verbatim from the Angular template. The attribute is inert for number inputs in React, so behavior is unaffected, but the naming is misleading.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verbatim from the Angular template, and inert as you say — leaving it so the markup diffs cleanly against the original. Worth a cleanup pass once the stack lands.

Comment on lines +51 to +75
onChange={() => setTheme('default')}
/>
{' Default'}
</label>
</div>
<div>
<label>
<input
name="theme"
type="radio"
value="night"
checked={settings.theme === 'night'}
onChange={() => setTheme('night')}
/>
{' Night'}
</label>
</div>
<div>
<label>
<input
name="theme"
type="radio"
value="amoledblack"
checked={settings.theme === 'amoledblack'}
onChange={() => setTheme('amoledblack')}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Theme radios switched from click to change

Angular selected a theme on (click); the port uses onChange on the controlled radios. This is idiomatic for React and also fires on keyboard selection, so there is no user-facing regression.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant