Skip to content

UX: Clean login page — shadcn polish [STU-4020] - #1

Open
BAWES wants to merge 4 commits into
mainfrom
shadcn-polish-settings-login-header
Open

UX: Clean login page — shadcn polish [STU-4020]#1
BAWES wants to merge 4 commits into
mainfrom
shadcn-polish-settings-login-header

Conversation

@BAWES

@BAWES BAWES commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

STU-4020 — Clean Login Page Shadcn Polish

Changes Made

Login form (src/components/auth/login-form.tsx):

  • Wrapped entire form in shadcn Card component (Card → CardHeader → CardContent)
  • Replaced bare <h1> with CardTitle and <p> with CardDescription
  • Proper shadcn component hierarchy throughout

Register form (src/components/auth/register-form.tsx):

  • Same Card wrapper pattern applied for visual consistency
  • CardHeader with CardTitle + CardDescription replaces bare heading elements

Verify-email form (src/components/auth/verify-email-form.tsx):

  • Same Card wrapper pattern applied for visual consistency

Prior Changes (from last commit)

  • Settings page: raw divs replaced with shadcn Card components
  • Header: glass effects (backdrop-blur) removed, solid bg-background
  • Login form: inline spinner replaced with shared LoadingSpinner component

Design Compliance

  • ✅ Uses shadcn Card component pattern (matching settings page)
  • ✅ No arbitrary Tailwind values (p-[30px], gap-[14px], etc.)
  • ✅ No inline style blocks
  • ✅ No glass morphism / backdrop-blur / frost effects
  • ✅ Tailwind CSS only — no inline styles
  • ✅ Zendesk Coral #eb6651 accent via shadcn Button variant
  • ✅ Light mode default for landing

Notes

  • The "forgot-password" page described in the original issue does not exist in this project codebase — no route or component was found under any auth directory
  • TypeScript: tsc --noEmit completed — no new errors introduced (pre-existing errors in unrelated files unchanged)

Screen Captures

(Screenshots available when running on dev server — current dev server not active)

Closes STU-4020

Summary by CodeRabbit

  • New Features
    • Added responsive navigation with a desktop sidebar and a fixed mobile bottom nav with active-route highlighting
  • Style
    • Refreshed authentication pages (login, register, email verification) and settings page with a consistent card-based layout
    • Updated header styling and main navigation spacing/active link visuals
    • Updated global theme colors to a Zendesk-branded palette
  • Chores
    • Reorganized navigation exports for cleaner module access
  • Refactor
    • Added a useMediaQuery hook for client-side viewport matching

Coder (agent) added 2 commits June 21, 2026 01:31
- Settings page: replaced raw rounded-lg border p-4 divs with shadcn Card
  components (Card, CardHeader, CardTitle, CardDescription, CardContent)
- Header: removed backdrop-blur and backdrop-filter glass effects, solid
  bg-background instead
- Login form: replaced inline spinner div with shared LoadingSpinner
  component for consistency

All changes are Tailwind CSS only, no inline styles, no glass effects.
- Login form: wrapped in shadcn Card with CardHeader/CardContent structure,
  using CardTitle and CardDescription instead of bare h1/p
- Register form: same Card wrapper pattern applied for consistency
- Verify-email form: same Card wrapper pattern applied for consistency
- All forms now use proper shadcn component hierarchy: Card → CardHeader
  (CardTitle, CardDescription) → CardContent (form elements)
- No arbitrary Tailwind values, no inline styles, no glass effects
- Consistent visual treatment across all public auth pages

Part of STU-4020 — Clean login page shadcn polish
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Auth form components and the settings page adopt shared Card UI primitives; new Sidebar and MobileNav components provide responsive navigation; Header integrates these with simplified styling; AuthLayout adds responsive padding for desktop sidebar and mobile tab bar; design tokens and colors are updated with Zendesk branding.

Changes

Design system, navigation, and responsive layout overhaul

Layer / File(s) Summary
Auth forms and settings refactored to Card layout
src/components/auth/login-form.tsx, src/components/auth/register-form.tsx, src/components/auth/verify-email-form.tsx, src/app/(auth)/settings/page.tsx
LoginForm, RegisterForm, VerifyEmailForm, and the settings page replace div/h1/p structures with Card, CardHeader, CardTitle, CardDescription, and CardContent primitives. LoginForm replaces inline spinner markup with a LoadingSpinner component. Form logic and field behavior remain unchanged.
New Sidebar and MobileNav components for responsive navigation
src/components/navigation/sidebar.tsx, src/components/navigation/mobile-nav.tsx
Sidebar renders a fixed desktop navigation bar using a navItems array; applies active-state styling via usePathname() and shows a footer branding line. MobileNav renders a fixed bottom navigation bar for mobile using the same navItems and usePathname() approach; both are responsive-hidden via Tailwind classes.
Header restructured with Sidebar and MobileNav integration
src/components/navigation/header.tsx
Header removes bg-background/95, backdrop-blur, and supports-[backdrop-filter] classes, using plain bg-background instead. Brand label changes from BAWES ERP to BAWES; MainNav receives hidden lg:flex styling. Header component now renders Sidebar and MobileNav alongside the top header within a fragment.
MainNav link styling with active route detection
src/components/navigation/main-nav.tsx
Imports usePathname and updates nav container from space-x-* to flex with gap-1. Each link computes isActive per route and uses cn to select between active/inactive class sets with distinct background, text, and hover styling.
Navigation module exports
src/components/navigation/index.ts
Adds Sidebar and MobileNav exports alongside the repositioned UserNav export.
AuthLayout responsive padding and spacing
src/app/(auth)/layout.tsx
JSDoc expands to document responsive sidebar spacing (desktop) and tab bar padding (mobile). Layout JSX restructures main to include flex growth plus desktop left padding and mobile bottom padding; children are wrapped in a separate centered container.
Design tokens and Zendesk branding
src/app/globals.css, tailwind.config.ts
globals.css light theme (:root) replaces primary, muted, accent, ring, and chart tokens with Zendesk-branded values; dark theme (.dark) updates primary, accent, and ring tokens to match. tailwind.config.ts adds Coral and Slack design token color definitions with hex values for defaults, hovers, and variant roles.
useMediaQuery hook for responsive logic
src/hooks/use-media-query.ts
New hook provides SSR-safe media query matching: checks window availability to prevent hydration mismatches, uses window.matchMedia(query).matches for initial state, subscribes to 'change' events, and cleans up listeners on unmount or query change.

Sequence Diagram

sequenceDiagram
  participant User
  participant Header
  participant Sidebar
  participant MobileNav
  participant usePathname
  
  User->>Header: Load page
  Header->>usePathname: Read current route
  usePathname-->>Header: Return pathname
  Header->>Sidebar: Render (desktop)
  Header->>MobileNav: Render (mobile)
  Sidebar->>usePathname: Check active route
  usePathname-->>Sidebar: Return pathname
  Sidebar-->>Sidebar: Apply active styling
  MobileNav->>usePathname: Check active route
  usePathname-->>MobileNav: Return pathname
  MobileNav-->>MobileNav: Apply active styling
  Sidebar-->>User: Display desktop nav
  MobileNav-->>User: Display mobile nav
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 The rabbit hops through cards and nav,
A sidebar gleams, mobile gets pav,
Zendesk blues and Slack-hued schemes,
Responsive dreams in responsive streams,
The warren glows with design's grace,
A modern, spacious, branded space! 🎨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: refactoring authentication pages with shadcn Card components for visual polish, which is the primary focus of the PR across login, register, verify-email forms, and settings pages.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch shadcn-polish-settings-login-header

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/app/globals.css

Parsing error: This experimental syntax requires enabling one of the following parser plugin(s): "decorators", "decorators-legacy". (1:0)


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.

Coder (agent) added 2 commits June 21, 2026 05:37
…okens

Core changes:
- Added Zendesk Coral (#eb6651) and Slack design tokens to tailwind.config.ts
- Set Zendesk Blue (#1f73b7) as primary color and Coral (#eb6651) as accent in globals.css
- Created Sidebar component (shadcn clean links, no borders, hover bg, blue active)
- Created MobileNav component (fixed bottom tab bar with icon+label at <=760px)
- Created useMediaQuery hook for responsive breakpoints
- Updated MainNav with shadcn button-like link styles (rounded, bg on active/hover)
- Updated Header to integrate sidebar + mobile nav
- Updated auth layout with sidebar padding (lg:pl-60) and mobile bottom padding (pb-16)
- Exported all new components from navigation index

Design: Zendesk blue #1f73b7 primary, coral #eb6651 accent, Slack-inspired sidebar.
No glass effects. Tailwind CSS only, no inline styles.
Changes:
- header.tsx: Removed backdrop-blur glass effect (violates 'no glass' rule).
  Solid bg-background instead of semi-transparent + blur.
- sidebar.tsx: Use bg-slack-sidebar (#f4f2ef) for Slack-inspired warm
  sidebar background instead of pure white bg-background.
- mobile-nav.tsx: Add pb-[env(safe-area-inset-bottom)] for proper
  safe-area padding on notched phones.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/components/navigation/sidebar.tsx (1)

53-71: ⚡ Quick win

Expose active link state to assistive tech.

When isActive is true, add aria-current="page" on the <Link> so screen readers can identify the current location.

Suggested patch
           <Link
             key={item.href}
             href={item.href}
+            aria-current={isActive ? 'page' : undefined}
             className={cn(
               'group flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/navigation/sidebar.tsx` around lines 53 - 71, The Link
component in the sidebar navigation does not expose the active page state to
assistive technologies. Add the aria-current attribute to the Link element and
set it to "page" when isActive is true to help screen readers identify the
current page location. This can be done by adding aria-current={isActive ?
"page" : undefined} as a prop on the Link component or by conditionally
including the attribute only when isActive evaluates to true.
src/components/navigation/main-nav.tsx (1)

15-32: ⚡ Quick win

Centralize navigation items shared across desktop/mobile/header navs.

This route list duplicates navItems in sidebar.tsx and mobile-nav.tsx; extract one shared source (e.g., src/components/navigation/nav-items.ts) to prevent cross-view drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/navigation/main-nav.tsx` around lines 15 - 32, The `links`
array in main-nav.tsx is duplicated across sidebar.tsx and mobile-nav.tsx,
creating a single source of truth problem. Extract this navigation items array
into a new shared file at `src/components/navigation/nav-items.ts`, export it as
a constant, and then update all three components (main-nav.tsx, sidebar.tsx, and
mobile-nav.tsx) to import and use this shared export instead of maintaining
their own copies.
src/components/navigation/mobile-nav.tsx (1)

46-58: ⚡ Quick win

Add aria-current on active mobile tab link.

Set aria-current="page" for the active tab to improve navigation context for screen readers.

Suggested patch
           <Link
             key={item.href}
             href={item.href}
+            aria-current={isActive ? 'page' : undefined}
             className={cn(
               'flex flex-col items-center gap-1 px-3 py-2 text-xs font-medium transition-colors',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/navigation/mobile-nav.tsx` around lines 46 - 58, The Link
component in the mobile navigation does not include the aria-current attribute
for accessibility purposes. Add an aria-current attribute to the Link component
that is set to "page" when isActive is true, and undefined or omitted when
isActive is false. This will provide proper navigation context to screen readers
when a mobile tab is active. Reference the isActive variable that is already
being used to conditionally apply the active styling to determine when to set
aria-current.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/globals.css`:
- Around line 25-26: The --accent-foreground color variables on lines 26 and 53
are set to white (0 0% 100%), which creates insufficient contrast when used as
text color on the bright coral --accent background colors. To meet WCAG AA
contrast requirements, adjust the --accent-foreground values on both lines 26
and 53 from white to a significantly darker shade that provides adequate
contrast for normal-sized text against the accent background. Consider using a
dark color such as black or near-black to ensure the contrast ratio meets the
WCAG AA standard of at least 4.5:1 for normal text.

In `@src/components/navigation/sidebar.tsx`:
- Line 1: The ESLint configuration in the repository is missing rule definitions
for TypeScript ESLint rules, causing `@typescript-eslint/no-unused-vars` and
`@typescript-eslint/no-explicit-any` to be reported as unknown rules. Update the
repository's ESLint configuration file (typically .eslintrc.json, .eslintrc.js,
or eslint.config.js) to include proper rule definitions for these two TypeScript
ESLint rules by ensuring they are properly configured with appropriate severity
levels (error, warn, or off) so that static analysis can correctly detect and
report violations.

---

Nitpick comments:
In `@src/components/navigation/main-nav.tsx`:
- Around line 15-32: The `links` array in main-nav.tsx is duplicated across
sidebar.tsx and mobile-nav.tsx, creating a single source of truth problem.
Extract this navigation items array into a new shared file at
`src/components/navigation/nav-items.ts`, export it as a constant, and then
update all three components (main-nav.tsx, sidebar.tsx, and mobile-nav.tsx) to
import and use this shared export instead of maintaining their own copies.

In `@src/components/navigation/mobile-nav.tsx`:
- Around line 46-58: The Link component in the mobile navigation does not
include the aria-current attribute for accessibility purposes. Add an
aria-current attribute to the Link component that is set to "page" when isActive
is true, and undefined or omitted when isActive is false. This will provide
proper navigation context to screen readers when a mobile tab is active.
Reference the isActive variable that is already being used to conditionally
apply the active styling to determine when to set aria-current.

In `@src/components/navigation/sidebar.tsx`:
- Around line 53-71: The Link component in the sidebar navigation does not
expose the active page state to assistive technologies. Add the aria-current
attribute to the Link element and set it to "page" when isActive is true to help
screen readers identify the current page location. This can be done by adding
aria-current={isActive ? "page" : undefined} as a prop on the Link component or
by conditionally including the attribute only when isActive evaluates to true.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2015aea6-31fc-4668-910c-aaf26dd64597

📥 Commits

Reviewing files that changed from the base of the PR and between fffdc35 and b3b5b11.

📒 Files selected for processing (9)
  • src/app/(auth)/layout.tsx
  • src/app/globals.css
  • src/components/navigation/header.tsx
  • src/components/navigation/index.ts
  • src/components/navigation/main-nav.tsx
  • src/components/navigation/mobile-nav.tsx
  • src/components/navigation/sidebar.tsx
  • src/hooks/use-media-query.ts
  • tailwind.config.ts
✅ Files skipped from review due to trivial changes (2)
  • src/components/navigation/index.ts
  • tailwind.config.ts

Comment thread src/app/globals.css
Comment on lines +25 to +26
--accent: 10 79% 62%;
--accent-foreground: 0 0% 100%;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Accent text contrast is likely below WCAG AA.

On Line 26 and Line 53, --accent-foreground is white while accent shades on Line 25 and Line 52 are relatively bright coral; this can produce insufficient contrast for normal-sized text in bg-accent text-accent-foreground surfaces.

Suggested token adjustment
-    --accent-foreground: 0 0% 100%;
+    --accent-foreground: 0 0% 5%;
...
-    --accent-foreground: 0 0% 100%;
+    --accent-foreground: 0 0% 5%;

Also applies to: 52-53

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/globals.css` around lines 25 - 26, The --accent-foreground color
variables on lines 26 and 53 are set to white (0 0% 100%), which creates
insufficient contrast when used as text color on the bright coral --accent
background colors. To meet WCAG AA contrast requirements, adjust the
--accent-foreground values on both lines 26 and 53 from white to a significantly
darker shade that provides adequate contrast for normal-sized text against the
accent background. Consider using a dark color such as black or near-black to
ensure the contrast ratio meets the WCAG AA standard of at least 4.5:1 for
normal text.

@@ -0,0 +1,82 @@
'use client';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix missing ESLint rule definitions in repo lint config.

Static analysis reports @typescript-eslint/no-unused-vars and @typescript-eslint/no-explicit-any as unknown rules, which means linting is currently misconfigured and can miss real regressions.

🧰 Tools
🪛 ESLint

[error] 1-1: Definition for rule '@typescript-eslint/no-unused-vars' was not found.

(@typescript-eslint/no-unused-vars)


[error] 1-1: Definition for rule '@typescript-eslint/no-explicit-any' was not found.

(@typescript-eslint/no-explicit-any)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/navigation/sidebar.tsx` at line 1, The ESLint configuration in
the repository is missing rule definitions for TypeScript ESLint rules, causing
`@typescript-eslint/no-unused-vars` and `@typescript-eslint/no-explicit-any` to
be reported as unknown rules. Update the repository's ESLint configuration file
(typically .eslintrc.json, .eslintrc.js, or eslint.config.js) to include proper
rule definitions for these two TypeScript ESLint rules by ensuring they are
properly configured with appropriate severity levels (error, warn, or off) so
that static analysis can correctly detect and report violations.

Source: Linters/SAST tools

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