Skip to content

refactor(hub): redesign Home & Spawn UI with unified design system#56

Open
KerwinTsaiii wants to merge 14 commits intodevelopfrom
refactor/user-interface
Open

refactor(hub): redesign Home & Spawn UI with unified design system#56
KerwinTsaiii wants to merge 14 commits intodevelopfrom
refactor/user-interface

Conversation

@KerwinTsaiii
Copy link
Copy Markdown
Collaborator

@KerwinTsaiii KerwinTsaiii commented Apr 1, 2026

Summary

Replaces the stock JupyterHub home page with a branded Home landing page and redesigns the Spawn page with a unified design system, then applies a series of bug-fixes and hardening on top.

New Home Page (feat + fix commits)

  • Landing page with platform content: quick-start guide, resource cards from API, documentation links, news/announcement section, and a floating launch bar
  • Team-based resource filtering — respects AVAILABLE_RESOURCES so users only see permitted resources
  • Error handling — shows a visible warning when resource loading fails instead of silent "No resources available"
  • XSS prevention — renders announcement as plain text instead of dangerouslySetInnerHTML
  • Server stop feedback — displays a red error message in the launch bar when stop fails
  • Launch bar reactivity — converts server_active to React state so the bar re-renders after stop/start
  • Scoped .container width — no longer relies on external Bootstrap CSS
  • Correct server_url fallback — points to /hub/user/<username>/ instead of /hub/spawn
  • TypeScript strict fix — nullish coalescing for optional jhdata.base_url
  • Copyright year updated to 2025-2026

Spawn Page Redesign

  • Two-column layout with resource picker (left) and sticky config sidebar (right)
  • Removed duplicate GPU/Git controls that appeared on mobile viewport

Infrastructure / Config

  • Dockerfile — builds the new Home frontend app alongside Spawn
  • values.yaml — sets redirect_to_server=false so users land on Home first; updates announcement
  • Auto-login redirect changed from /hub/spawn/hub/home

Changed Files (18 files, +1865 / −1023)

Area Files
Home app (new) apps/home/{App.tsx, main.tsx, styles.css, vite.config.ts, …}
Spawn app apps/spawn/src/{App.tsx, styles.css}
Hub template frontend/templates/home.html
Build dockerfiles/Hub/Dockerfile, frontend/package.json, pnpm-lock.yaml
Config runtime/values.yaml
Auth core/authenticators/auto_login.py

Test Plan

  • Verify Home page loads with correct resource cards, quick-start, docs, and news sections
  • Confirm team-based filtering hides unauthorized resources on Home
  • Test server start/stop from the Home launch bar; verify error messages display on failure
  • Confirm Spawn page two-column layout renders correctly on desktop and mobile
  • Verify no duplicate GPU/Git controls on mobile
  • Check announcement renders as plain text (no XSS via HTML injection)
  • Validate auto-login redirects to /hub/home

Made with Cursor

Replace the stock JupyterHub home page with a branded landing page
that shows platform info, quick-start guide, available courses,
documentation links, and news. The spawner is accessible via a
prominent "Start My Server" button in a floating launch bar.

Also redirect auto-login users to /hub/home instead of /hub/spawn.

Made-with: Cursor
- Convert server_active from a static module variable to React state
  so the launch bar (icon, badge, description, buttons) re-renders
  after stopping the server via DELETE API call
- Point "Start My Server" href to /hub/spawn instead of /hub/user/
  so users go directly to the spawner rather than the "server not
  running" interstitial page
- Remove legacy require(["home"]) from template to prevent the
  JupyterHub home.js from conflicting with React's stop handler
- Remove debug logging panel

Made-with: Cursor
- Home: dynamic resource cards from API, launch bar, quick-start strip,
  docs/news sections with shared --home-* design tokens
- Spawn: two-column layout with resource picker and sticky config sidebar
- values.yaml: set redirect_to_server=false so users land on Home first

Made-with: Cursor
Home page now respects window.AVAILABLE_RESOURCES (injected by Hub
based on user team membership), matching the same filtering logic
used in the Spawn page's useResources hook. Without this, users
could see resources on Home they don't have permission to launch.

Made-with: Cursor
…trap

Home page used .container class without defining it, depending entirely
on Hub's Bootstrap CSS. This adds an explicit scoped rule under
.home-page matching the 1120px max-width used by Spawn's #spawn-root.

Made-with: Cursor
Previously getResources() errors were silently swallowed, leaving
users with a confusing "No resources available" message. Now captures
the error and displays a visible warning box with a fallback link
to the Spawner page.

Made-with: Cursor
The fallback server_url incorrectly pointed to /hub/spawn instead of
the user's running server at /hub/user/<username>/. When HOME_DATA
is not injected by the Hub template, the "My Server" button now
navigates to the correct destination.

Made-with: Cursor
The mobile CSS re-showed inline .gpu-selection panels while the
sidebar remained visible (just non-sticky), causing GPU selection
and Git input to appear twice. The sidebar handles all configuration
on both desktop and mobile, so the inline fallback is removed.

Made-with: Cursor
JHData.base_url is typed as optional in the shared package. Add
nullish coalescing fallbacks for base_url and user to satisfy
strict TypeScript checks, and reorder declarations so baseUrl
is available when computing the homeData fallback.

Made-with: Cursor
Replace dangerouslySetInnerHTML with safe text rendering for the
announcement content. HTML announcements are already rendered
server-side by the Jinja template; the React News section does
not need to support raw HTML injection.

Made-with: Cursor
Previously, stop failures (HTTP errors or network errors) were
silently logged to console. Now displays a visible red error
message in the launch bar so users know the stop action failed.
The error clears on the next stop attempt.

Made-with: Cursor
@KerwinTsaiii KerwinTsaiii requested a review from MioYuuIH April 1, 2026 17:27
@KerwinTsaiii
Copy link
Copy Markdown
Collaborator Author

@MioYuuIH Please comfirm team-based filtering hides unauthorized resources on Home working properly at internal testing site.

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