Files
cameleer-saas/audit/platform-ui-findings.md
hsiegeln 63c194dab7
Some checks failed
CI / build (push) Failing after 18s
CI / docker (push) Has been skipped
chore: rename cameleer3 to cameleer
Rename Java packages from net.siegeln.cameleer3 to net.siegeln.cameleer,
update all references in workflows, Docker configs, docs, and bootstrap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:28:44 +02:00

17 KiB

Cameleer SaaS Platform UI Audit Findings

Date: 2026-04-09 Auditor: Claude Opus 4.6 URL: https://desktop-fb5vgj9.siegeln.internal/ Credentials: admin/admin Browser: Playwright (Chromium)


1. Login Page (/sign-in)

Screenshot: 03-login-page.png, 04-login-error.png

What works well

  • Clean, centered card layout with consistent design system components
  • Fun rotating subtitle taglines (e.g., "No ticket, no caravan") add personality
  • Cameleer logo is displayed correctly
  • Error handling works -- "Invalid username or password" alert appears on bad credentials (red alert banner)
  • Sign in button is correctly disabled until both fields are populated
  • Loading state on button during authentication
  • Uses proper autoComplete attributes (username, current-password)

Issues found

Severity Issue Element
Important No password visibility toggle -- the Password input uses type="password" with no eye icon to reveal. Most modern login forms offer this. Password field
Important Branding says "cameleer" not "Cameleer" or "Cameleer SaaS" -- the product name on the login page is the internal repo name, not the user-facing brand .logo text content
Nice-to-have No "Forgot password" link -- even if it goes to a "contact admin" page, users expect this Below password field
Nice-to-have No Enter-key submit hint -- though Enter does work via form submit, there's no visual affordance Form area
Nice-to-have Page title is "Sign in -- cameleer" -- should match product branding ("Cameleer SaaS") <title> tag

2. Platform Dashboard (/platform/)

Screenshots: 05-platform-dashboard-loggedin.png, 15-dashboard-desktop-1280.png, 19-tenant-info-detail.png, 20-kpi-strip-detail.png

What works well

  • Clear tenant name as page heading ("Example Tenant")
  • Tier badge next to tenant name provides immediate context
  • KPI strip with Tier, Status, License cards is visually clean and well-structured
  • License KPI card shows expiry date in green "expires 8.4.2027" trend indicator
  • "Server Management" card provides clear description of what the server dashboard does

Issues found

Severity Issue Element
Critical Label/value collision in Tenant Information card -- "Slugdefault", "Created8.4.2026" have no visual separation between label and value. The source uses flex justify-between but the deployed Card component doesn't give the inner div full width, so items stack/collapse. Tenant Information card
Critical "Open Server Dashboard" appears 3 times on one page: (1) primary button in header area below tenant name, (2) "Server Management" card with secondary button, (3) sidebar footer link. This is redundant and clutters the page. Reduce to 1-2 locations max. Header area, Server Management card, sidebar footer
Important Breadcrumb is always empty -- the breadcrumb prop is passed as []. Platform pages should have breadcrumbs like "Platform > Dashboard" or "Platform > License". TopBar breadcrumb nav
Important Massive empty space below content -- the dashboard only has ~4 cards but the page extends far below with blank white/cream space. The page feels sparse and "stub-like." Below Server Management card
Important Tier badge color is misleading -- "LOW" tier uses primary (orange) color, which doesn't convey it's the lowest/cheapest tier. The tierColor() function in DashboardPage maps to enterprise=success, pro=primary, starter=warning, but the actual data uses LOW/MID/HIGH/BUSINESS tiers (defined in LicensePage). Dashboard and License pages have different tier color mappings. Tier badge
Important Status is shown redundantly -- "ACTIVE" appears in (1) KPI strip Status card, (2) Tenant Information card with badge, and (3) header area badge. This is excessive for a single piece of information. Multiple locations
Nice-to-have No tenant ID/slug in breadcrumb or subtitle -- the slug "default" only appears buried in the Tenant Information card Page header area

3. License Page (/platform/license)

Screenshots: 06-license-page.png, 07-license-token-revealed.png, 16-license-features-detail.png, 17-license-limits-detail.png, 18-license-validity-detail.png

What works well

  • Well-structured layout with logical sections (Validity, Features, Limits, License Token)
  • Tier badge in header provides context
  • Feature matrix clearly shows enabled vs disabled features
  • "Days remaining" with color-coded badge (green for healthy, warning for <30 days, red for expired)
  • Token show/hide toggle works correctly
  • Token revealed in monospace code block with appropriate styling

Issues found

Severity Issue Element
Critical Label/value collision in Validity section -- "Issued8. April 2026" and "Expires8. April 2027" have no separation. Source code uses flex items-center justify-between but the flex container seems to not be stretching to full width. Validity card rows
Critical Label/value collision in Limits section -- "Max Agents3", "Retention Days7", "Max Environments1" have labels and values mashed together. Source uses flex items-center justify-between layout but the same rendering bug prevents proper spacing. Limits card rows
Important No "Copy to clipboard" button for the license token -- users need to manually select and copy. A copy button with confirmation toast is standard UX for tokens/secrets. License Token section
Important Feature badge text mismatch -- Source code says 'Not included' for disabled features, but deployed version shows "DISABLED". This suggests the deployed build is out of sync with the source. Features card badges
Important "Disabled" badge color -- disabled features use color='auto' (which renders as a neutral/red-ish badge), while "Enabled" uses green. Consider using a muted gray for "Not included" to make it feel less like an error state. Red implies something is wrong, but a feature simply not being in the plan is not an error. Features card disabled badges
Nice-to-have Limits values are not right-aligned -- due to the label/value collision, the numeric values don't align in a column, making comparison harder Limits card
Nice-to-have No units on limits -- "Retention Days7" should be "7 days", "Max Agents3" should be "3 agents" or just "3" with clear formatting Limits card values

4. Admin Pages (/platform/admin/tenants)

No screenshot available -- page returns HTTP error

Issues found

Severity Issue Element
Critical Admin page returns HTTP error (net::ERR_HTTP_RESPONSE_CODE_FAILURE) -- navigating to /platform/admin/tenants fails with an HTTP error. The route exists in the router (AdminTenantsPage), but the admin section is not visible in the sidebar (no "Platform" item shown). Admin route
Important Admin section not visible in sidebar -- the platform:admin scope check in Layout.tsx hides the "Platform" sidebar item. Even though the user is "admin", they apparently don't have the platform:admin scope in their JWT. This may be intentional (scope not assigned) or a bug. Sidebar Platform section
Important No graceful fallback for unauthorized admin access -- if a user manually navigates to /admin/tenants without the scope, the page should show a "Not authorized" message rather than an HTTP error. Admin route error handling

5. Navigation

Screenshots: 21-sidebar-detail.png, 12-sidebar-collapsed.png

What works well

  • Clean sidebar with Cameleer SaaS branding and logo
  • "Open Server Dashboard" in sidebar footer is a good location
  • Sidebar has only 2 navigation items (Dashboard, License) which keeps it simple

Issues found

Severity Issue Element
Critical No active state on sidebar navigation items -- when on the Dashboard page, neither Dashboard nor License is highlighted/active. The sidebar uses Sidebar.Section components with open={false} as navigation links via onToggle, but Section is designed for expandable/collapsible groups, not navigation links. There is no visual indicator of the current page. Sidebar items
Important Sidebar collapse doesn't work visually -- clicking "Collapse sidebar" toggles the active state on the button but the sidebar doesn't visually collapse. The Layout component passes collapsed={false} as a hardcoded prop and onCollapseToggle={() => {}} as a no-op. Sidebar collapse button
Important No clear distinction between "platform" and "server" levels -- there's nothing in the sidebar header that says "Platform" vs "Server". The sidebar says "Cameleer SaaS" but when you switch to the server dashboard, it becomes a completely different app. A user might not understand the relationship. Sidebar header
Nice-to-have "Open Server Dashboard" opens in new tab -- window.open('/server/', '_blank', 'noopener') is used. While reasonable, there's no visual indicator (external link icon) that it will open a new tab. Sidebar footer link, dashboard buttons

6. Header Bar (TopBar)

Screenshot: 22-header-bar-detail.png

Issues found

Severity Issue Element
Critical Server-specific controls shown on platform pages -- the TopBar always renders: (1) Search (Ctrl+K), (2) Status filters (OK/Warn/Error/Running), (3) Time range pills (1h/3h/6h/Today/24h/7d), (4) Auto-refresh toggle (MANUAL/AUTO). None of these are relevant to the platform dashboard or license page. They are observability controls designed for the server's exchange/route monitoring. Entire TopBar filter area
Important Search button does nothing -- clicking "Search..." on the platform does not open a search modal. The CommandPaletteProvider is likely not configured for the platform context. Search button
Important Status filter buttons are interactive but meaningless -- clicking OK/Warn/Error/Running on platform pages toggles state (global filter provider) but has no effect on the displayed content. Status filter buttons
Important Time range selector is interactive but meaningless -- similarly, changing the time range from 1h to 7d has no effect on platform pages. Time range pills
Important Auto-refresh toggle is misleading -- shows "MANUAL" toggle on platform pages where there's nothing to auto-refresh. Auto-refresh button

7. User Menu

Screenshot: 02-user-menu-dropdown.png

What works well

  • User name "admin" and avatar initials "AD" displayed correctly
  • Dropdown appears on click with Logout option

Issues found

Severity Issue Element
Important User menu only has "Logout" -- there's no "Profile", "Settings", "About", or "Switch Tenant" option. For a SaaS platform, users should at minimum see their role and tenant context. User dropdown menu
Nice-to-have Avatar shows "AD" for "admin" -- the Avatar component appears to use first 2 characters of the name. For "admin" this produces "AD" which looks like initials for a different name. Avatar component

8. Dark Mode

Screenshots: 08-dashboard-dark-mode.png, 09-license-dark-mode.png

What works well

  • Dark mode toggle works and applies globally
  • Background transitions to dark brown/charcoal
  • Text colors adapt appropriately
  • Cards maintain visual distinction from background
  • Design system tokens handle the switch smoothly

Issues found

Severity Issue Element
Nice-to-have Dark mode is warm-toned (brown) rather than the more common cool dark gray/charcoal. This is consistent with the design system's cameleer branding but may feel unusual to users accustomed to dark mode in other apps. Global dark theme
Nice-to-have The same label/value collision issues appear in dark mode -- these are layout bugs, not color bugs, so dark mode doesn't help or hurt. Card content

9. Responsiveness

Screenshots: 13-responsive-tablet.png, 14-responsive-mobile.png

Issues found

Severity Issue Element
Critical Mobile layout is broken -- at 375px width, the sidebar overlaps the main content. The KPI strip cards are truncated ("LO...", "AC..."). The header bar overflows. Content is unreadable. Full page at mobile widths
Important Tablet layout (768px) is functional but crowded -- sidebar takes significant width, header bar items are compressed ("Se..." for Search), but content is readable. KPI strip wraps correctly. Full page at tablet widths
Important Sidebar doesn't collapse on mobile -- there's no hamburger menu or responsive sidebar behavior. The sidebar is always visible, eating screen space on narrow viewports. Sidebar

10. Cross-cutting Concerns

Loading States

  • Dashboard and License pages both show a centered Spinner during loading -- this works well.
  • EmptyState component used for "No tenant associated" and "License unavailable" -- good error handling in components.

Error States

  • Login page error handling is good (alert banner)
  • No visible error boundary for unexpected errors on platform pages
  • Admin route fails silently with HTTP error -- no user-facing error message

Toast Notifications

  • No toast notifications observed during the audit
  • License token copy should trigger a toast confirmation (if a copy button existed)

Confirmation Dialogs

  • No destructive actions available on the platform (no delete/deactivate buttons) so no confirmation dialogs needed currently

Summary of Issues by Severity

Critical (5)

  1. Label/value collision throughout Tenant Information card, License Validity, and License Limits sections -- labels and values run together without spacing
  2. "Open Server Dashboard" appears 3 times on the dashboard page -- excessive redundancy
  3. No active state on sidebar navigation items -- users can't tell which page they're on
  4. Server-specific header controls shown on platform pages -- search, status filters, time range, auto-refresh are all meaningless on platform pages
  5. Mobile layout completely broken -- sidebar overlaps content, content truncated

Important (17)

  1. No password visibility toggle on login
  2. Branding says "cameleer" instead of product name on login
  3. Breadcrumbs always empty on platform pages
  4. Massive empty space below dashboard content
  5. Tier badge color mapping inconsistent between Dashboard and License pages
  6. Status shown redundantly in 3 places on dashboard
  7. No clipboard copy button for license token
  8. Feature badge text mismatch between source and deployed build
  9. "Disabled" badge uses red-ish color (implies error, not "not in plan")
  10. Admin page returns HTTP error with no graceful fallback
  11. Admin section invisible in sidebar despite being admin user
  12. Sidebar collapse button doesn't work (no-op handler)
  13. No clear platform vs server level distinction
  14. Search button does nothing on platform
  15. Status filters and time range interactive but meaningless on platform
  16. User menu only has Logout (no profile/settings)
  17. Sidebar doesn't collapse/hide on mobile

Nice-to-have (8)

  1. No "Forgot password" link on login
  2. Login page title uses "cameleer" branding
  3. No external link icon on "Open Server Dashboard"
  4. Avatar shows "AD" for "admin"
  5. No units on limit values
  6. Dark mode warm-toned (not standard cool dark)
  7. No Enter-key submit hint
  8. No tenant ID in breadcrumb/subtitle

Overarching Assessment

The platform UI currently feels like a thin shell around the server dashboard. It has only 2 functioning pages (Dashboard and License), and both suffer from the same fundamental layout bug (label/value collision in Card components). The header bar is entirely borrowed from the server observability UI without any platform-specific adaptation, making 70% of the header controls irrelevant.

Key architectural concerns:

  1. The TopBar component from the design system is monolithic -- it always renders server-specific controls (status filters, time range, search). The platform needs either a simplified TopBar variant or the ability to hide these sections.
  2. The sidebar uses Sidebar.Section (expandable groups) as navigation links, which prevents active-state highlighting. It should use Sidebar.Link or a similar component.
  3. The platform provides very little actionable functionality -- a user can view their tenant info and license, but can't manage anything. The "Server Management" card is just a link to another app.

What works well overall:

  • Design system integration is solid (same look and feel as server)
  • Dark mode works correctly
  • Loading and error states are handled
  • Login page is clean and functional
  • KPI strip component is effective at summarizing key info

Recommended priorities:

  1. Fix the label/value collision bug (affects 3 cards across 2 pages)
  2. Hide or replace server-specific header controls on platform pages
  3. Add sidebar active state and fix the collapse behavior
  4. Add clipboard copy for license token
  5. Fix mobile responsiveness