Skip to content

feat: implement dashboard story with analytics and job sections#258

Merged
kylengn merged 4 commits intomainfrom
feat/dashboard-story
Dec 23, 2025
Merged

feat: implement dashboard story with analytics and job sections#258
kylengn merged 4 commits intomainfrom
feat/dashboard-story

Conversation

@kylengn
Copy link
Contributor

@kylengn kylengn commented Dec 22, 2025

Note

Introduces a Storybook dashboard with Analytics/Jobs tabs, animated topbar, org/user menus, plus minor UI tweaks and tests.

  • Dashboard story and layout: Adds Dashboard with sticky TopMenu tabs (analytics, jobs), scroll-aware AnimatedLogo, and Topbar (org selector, setup button, search/help/notifications, mobile menu, user profile) under components/dashboard/*; exports via components/dashboard/index.ts and Storybook dashboard.stories.tsx (fullscreen).
  • Content panes: AnalyticsContent with metric cards/placeholders; JobsContent with searchable/paginated DataTable.
  • UI components: OrganizationSelector, MobileMenu, CompleteSetupButton, UserProfile (usage gauge), TopbarButton.
  • Minor UI adjustments: avatar rounded radius set to rounded-4; SelectTrigger icon switched to expandUpDownLine; new Select story TimeSelector.
  • Visual testing: form.stories.tsx adds Argos screenshot play step for Basic story.
  • Release: Changeset adds minor bump for @shipfox/react-ui.

Written by Cursor Bugbot for commit d1f4aaa. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Introduced a comprehensive dashboard UI with tabbed Analytics and Jobs views
    • Added scroll-driven animations and visual feedback for interactive navigation
    • Implemented user profile dropdown with usage tracking and account management
    • Added mobile navigation menu and organization selector for multi-tenant support
    • Created setup flow with themed loader integration
  • Style

    • Refined avatar radius styling for improved visual consistency
    • Updated select dropdown icon for enhanced UX clarity

✏️ Tip: You can customize this high-level summary in your review settings.

@kylengn kylengn self-assigned this Dec 22, 2025
Copilot AI review requested due to automatic review settings December 22, 2025 12:27
@vercel
Copy link

vercel bot commented Dec 22, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
react-ui Ready Ready Preview, Comment Dec 22, 2025 10:25pm

@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR adds a comprehensive dashboard UI system with multiple new components for navigation, analytics/jobs content areas, user profile management, and mobile support. It also refines avatar styling and select component icons.

Changes

Cohort / File(s) Summary
Avatar styling refinement
libs/react/ui/src/components/avatar/avatar.tsx
Updated avatarVariants radius mapping: changed rounded value from 'rounded-6' to 'rounded-4'.
Dashboard core component
libs/react/ui/src/components/dashboard/dashboard.tsx
New Dashboard component with scroll-driven UI management: tracks scroll progress via Framer Motion, conditionally renders AnimatedLogo, manages Topbar collapse state, handles tab switching between Analytics/Jobs content with scroll reset, and applies dynamic styling to TopMenu based on scroll progress.
Dashboard subcomponents
libs/react/ui/src/components/dashboard/components/analytics-content.tsx, animated-logo.tsx, complete-setup-button.tsx, jobs-content.tsx, mobile-menu.tsx, organization-selector.tsx, top-menu.tsx, topbar-button.tsx, topbar.tsx, user-profile.tsx
New presentational and interactive subcomponents: AnalyticsContent (skeleton dashboard layout), AnimatedLogo (scroll-triggered logo animation), CompleteSetupButton (themed button with loader), JobsContent (searchable paginated jobs table), MobileMenu (dropdown navigation), OrganizationSelector (org selection dropdown), TopMenu (Analytics/Jobs tabs), TopbarButton (reusable icon button), Topbar (main navigation bar), UserProfile (profile dropdown with usage gauge).
Dashboard export aggregation
libs/react/ui/src/components/dashboard/index.ts
Added re-export of all dashboard exports to aggregated entrypoint.
Storybook stories
libs/react/ui/src/components/dashboard/dashboard.stories.tsx, libs/react/ui/src/components/form/form.stories.tsx, libs/react/ui/src/components/select/select.stories.tsx
Added Dashboard Storybook story with fullscreen layout; added form story interaction hook with screenshot capture; added TimeSelector and OrganizationSelector select stories.
Select component refinement
libs/react/ui/src/components/select/select.tsx
Updated SelectTrigger icon from arrowDownSLine to expandUpDownLine.

Sequence Diagram

sequenceDiagram
    participant User
    participant Dashboard as Dashboard Component
    participant ScrollTracker as Scroll Tracker
    participant AnimatedLogo
    participant Topbar
    participant TopMenu
    participant ContentArea as Content (Analytics/<br/>Jobs)

    User->>Dashboard: Render Dashboard
    Dashboard->>ScrollTracker: Initialize useScroll hook
    ScrollTracker-->>Dashboard: Initial scroll position
    Dashboard->>Topbar: Render (hidelogo=false)
    Dashboard->>ContentArea: Render active tab content

    User->>User: Scroll down
    ScrollTracker->>ScrollTracker: Compute scroll progress
    ScrollTracker->>Dashboard: Trigger useMotionValueEvent
    Dashboard->>AnimatedLogo: Update scrollProgress
    AnimatedLogo->>AnimatedLogo: Compute eased progress & animate
    AnimatedLogo-->>User: Fade in with translateY
    
    Dashboard->>Topbar: Update hidelogo=true
    Topbar->>Topbar: Reduce logo opacity
    
    Dashboard->>TopMenu: Update padding (cubic easing)
    TopMenu->>TopMenu: Apply dynamic spacing

    User->>TopMenu: Click "Jobs" tab
    TopMenu->>Dashboard: Trigger onTabChange callback
    Dashboard->>Dashboard: Reset scroll position
    Dashboard->>ScrollTracker: Reset scroll progress
    Dashboard->>ContentArea: Switch to JobsContent
    ContentArea-->>User: Render jobs table
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas requiring extra attention:

  • Dashboard component's scroll tracking, easing computations, and conditional rendering logic with scroll-driven state
  • CompleteSetupButton and MobileMenu theme resolution consistency using useResolvedTheme
  • JobsContent filtering and memoization logic for large job datasets
  • Proper integration and prop passing between Dashboard orchestrator and all subcomponents

Possibly related PRs

Suggested reviewers

  • EnzalRad
  • dvxam
  • noe-charmet

Poem

🐰✨ A dashboard blooms with many a part—
Scroll-driven magic sets it apart!
Topbars hide, logos dance with grace,
Jobs and analytics find their place.
From mobile menus to profile delight,
This rabbit crafted UI so bright! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: implementing a dashboard UI component with analytics and jobs sections, which aligns with the majority of changes in the PR.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/dashboard-story

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.

@argos-ci
Copy link

argos-ci bot commented Dec 22, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) 👍 Changes approved 8 changed, 3 added Dec 22, 2025, 10:29 PM

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a comprehensive dashboard story for Storybook with analytics and jobs sections. The implementation includes animated scroll effects, organization/time selectors, and responsive layouts.

  • Adds a new Dashboard component with tab navigation between Analytics and Jobs views
  • Updates the Select component icon from "arrowDownSLine" to "expandUpDownLine"
  • Adjusts Avatar rounded radius from rounded-6 to rounded-4
  • Adds visual regression testing to Form story with Argos screenshot integration

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
libs/react/ui/src/components/select/select.tsx Updates dropdown icon to use expand/collapse iconography
libs/react/ui/src/components/select/select.stories.tsx Adds TimeSelector and OrganizationSelector story examples
libs/react/ui/src/components/form/form.stories.tsx Integrates Argos screenshot testing for visual regression
libs/react/ui/src/components/dashboard/index.ts Exports Dashboard component
libs/react/ui/src/components/dashboard/dashboard.tsx Main dashboard with scroll animations and tab switching
libs/react/ui/src/components/dashboard/dashboard.stories.tsx Storybook story for Dashboard with fullscreen layout
libs/react/ui/src/components/dashboard/components/user-profile.tsx User profile dropdown with usage gauge and upgrade CTA
libs/react/ui/src/components/dashboard/components/topbar.tsx Top navigation bar with organization selector and utilities
libs/react/ui/src/components/dashboard/components/topbar-button.tsx Reusable button component for topbar icons
libs/react/ui/src/components/dashboard/components/top-menu.tsx Tab navigation between Analytics and Jobs sections
libs/react/ui/src/components/dashboard/components/organization-selector.tsx Dropdown for switching between organizations
libs/react/ui/src/components/dashboard/components/mobile-menu.tsx Mobile-responsive dropdown menu
libs/react/ui/src/components/dashboard/components/jobs-content.tsx Jobs table view with search and filtering
libs/react/ui/src/components/dashboard/components/complete-setup-button.tsx Animated setup completion button with loader
libs/react/ui/src/components/dashboard/components/animated-logo.tsx Logo with scroll-based reveal animation
libs/react/ui/src/components/dashboard/components/analytics-content.tsx Analytics dashboard with charts and empty states
libs/react/ui/src/components/avatar/avatar.tsx Reduces border radius for rounded variant

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@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: 2

🧹 Nitpick comments (13)
libs/react/ui/src/components/dashboard/components/jobs-content.tsx (2)

1-8: Imports from story files suggest prototype/demo code.

The component imports jobColumns and jobsData from table.stories.columns and table.stories.data, which are typically for Storybook demonstrations rather than production code. Consider moving these to a dedicated data layer or prop-drilling them if this component is intended for production use.


34-36: Button lacks an onClick handler.

The button with the "Insert column left" icon has no onClick handler. If this is a placeholder for future functionality, consider adding a TODO comment or a no-op handler to make the intent explicit.

libs/react/ui/src/components/dashboard/components/complete-setup-button.tsx (1)

7-29: Consider adding interaction handling.

The button renders with proper styling and theme-aware loader but lacks an onClick handler or asChild pattern for composability. If this is intentional (e.g., the button is meant to be wrapped or will receive handlers later), consider documenting this or accepting an optional onClick prop.

💡 Suggested enhancement
-export function CompleteSetupButton({className}: {className?: string}) {
+export function CompleteSetupButton({
+  className,
+  onClick,
+}: {
+  className?: string;
+  onClick?: () => void;
+}) {
   const resolvedTheme = useResolvedTheme();
   return (
     <Button
       type="button"
       variant="transparent"
+      onClick={onClick}
       className={cn(
libs/react/ui/src/components/dashboard/components/user-profile.tsx (2)

23-28: Static user data suggests demo/prototype implementation.

The component uses hardcoded user data (name, email, credits). For production use, consider accepting these as props or fetching from a user context/hook.

💡 Suggested enhancement
-export function UserProfile() {
-  const userName = 'Thierry Abalea';
-  const userEmail = 'thierryabalea@acme.com';
-  const creditsUsed = 3213;
-  const creditsTotal = 6000;
+export function UserProfile({
+  userName,
+  userEmail,
+  creditsUsed,
+  creditsTotal,
+}: {
+  userName: string;
+  userEmail: string;
+  creditsUsed: number;
+  creditsTotal: number;
+}) {

52-53: Menu items lack interaction handlers.

The "Getting started", "Profile settings", and "Log out" menu items don't have onClick or onSelect handlers. If this is placeholder functionality, consider adding TODO comments or accepting handlers as props.

Also applies to: 86-86

libs/react/ui/src/components/dashboard/components/animated-logo.tsx (1)

6-25: Consider using framer-motion's animate prop for consistency.

The component uses motion.div but applies animation styles manually via the style prop with template literals. While this works, using framer-motion's animate prop with motion values would be more idiomatic and potentially more performant, especially if scrollProgress is a motion value from useScroll.

💡 Alternative approach using animate prop

If scrollProgress is already a motion value, you could use:

const easedProgress = useTransform(scrollProgress, [0, 1], [0, 1], {
  ease: (v) => 1 - (1 - v) ** 3
});

return (
  <motion.div
    className="..."
    style={{
      opacity: easedProgress,
      y: useTransform(easedProgress, (v) => -LOGO_HEIGHT + v * LOGO_HEIGHT),
    }}
  />
);
libs/react/ui/src/components/dashboard/components/organization-selector.tsx (1)

15-15: Consider making defaultValue configurable.

The defaultValue is hardcoded to "stripe". If this component will be reused, consider accepting it as a prop along with an optional onChange handler.

libs/react/ui/src/components/dashboard/dashboard.stories.tsx (1)

4-13: Consider adding component to meta for autodocs.

The autodocs tag is included, but without component: Dashboard, Storybook won't generate automatic documentation with prop tables. If you intend to document props, add the component reference.

🔎 Proposed fix
+import type {Meta, StoryObj} from '@storybook/react';
+import {Dashboard} from './dashboard';

 const meta = {
   title: 'Dashboard/Example',
+  component: Dashboard,
   tags: ['autodocs'],
   parameters: {
     layout: 'fullscreen',
     viewport: {
       defaultViewport: 'extraLarge',
     },
   },
-} satisfies Meta;
+} satisfies Meta<typeof Dashboard>;
libs/react/ui/src/components/dashboard/components/top-menu.tsx (1)

3-9: Consider using a stricter type for activeTab.

Using string for both activeTab and the onTabChange callback parameter is flexible but loses type safety. A union type would catch typos at compile time.

🔎 Proposed improvement
+type TabValue = 'analytics' | 'jobs';
+
 export function TopMenu({
   activeTab,
   onTabChange,
 }: {
-  activeTab: string;
-  onTabChange: (tab: string) => void;
+  activeTab: TabValue;
+  onTabChange: (tab: TabValue) => void;
 }) {
libs/react/ui/src/components/dashboard/dashboard.tsx (2)

14-14: Unused ref: topbarRef is assigned but never read.

The topbarRef is created and attached to a div but its value is never used. If it's intended for future functionality, consider adding a comment; otherwise, remove it to reduce clutter.

🔎 If unused, remove the ref
 export function Dashboard() {
   const containerRef = useRef<HTMLDivElement>(null);
-  const topbarRef = useRef<HTMLDivElement>(null);
   const [scrollProgress, setScrollProgress] = useState(0);
   const [activeTab, setActiveTab] = useState('analytics');

And remove the ref assignment:

       <div ref={containerRef} className="flex flex-col w-full h-full overflow-auto">
-        <div ref={topbarRef}>
+        <div>
           <Topbar hidelogo={isTopbarHidden} />
         </div>

9-10: Consider documenting magic numbers or co-locating with AnimatedLogo.

LOGO_HEIGHT is also used in animated-logo.tsx. Consider extracting these constants to a shared location or adding brief comments explaining their relationship to the UI layout.

libs/react/ui/src/components/dashboard/components/mobile-menu.tsx (1)

32-45: Consider extracting the shared "Complete setup" content into a reusable component.

This ShipfoxLoader + ShinyText pattern is duplicated from CompleteSetupButton (see complete-setup-button.tsx lines 17-24). If both need to stay in sync, consider extracting the inner content into a shared component to reduce duplication and ensure consistent styling.

🔎 Example extraction

Create a shared component:

// complete-setup-content.tsx
export function CompleteSetupContent({ className }: { className?: string }) {
  const resolvedTheme = useResolvedTheme();
  return (
    <div className={cn("flex items-center gap-8", className)}>
      <ShipfoxLoader
        size={13}
        animation="circular"
        color={resolvedTheme === 'dark' ? 'white' : 'orange'}
        background={resolvedTheme === 'dark' ? 'dark' : 'light'}
      />
      <ShinyText
        text="Complete setup"
        className="flex-1 text-sm font-medium leading-20 text-foreground-neutral-base truncate text-left"
      />
    </div>
  );
}

Then use it in both CompleteSetupButton and MobileMenu.

libs/react/ui/src/components/dashboard/components/topbar.tsx (1)

8-8: Prop name should use camelCase: hideLogo instead of hidelogo.

React convention uses camelCase for prop names. This also improves consistency with standard React patterns and readability.

🔎 Proposed fix
-export function Topbar({hidelogo = false}: {hidelogo?: boolean}) {
+export function Topbar({hideLogo = false}: {hideLogo?: boolean}) {

And update line 13:

-          <div className={cn('shrink-0', hidelogo ? 'opacity-0' : 'opacity-100')}>
+          <div className={cn('shrink-0', hideLogo ? 'opacity-0' : 'opacity-100')}>
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3c145d and b193665.

📒 Files selected for processing (17)
  • libs/react/ui/src/components/avatar/avatar.tsx
  • libs/react/ui/src/components/dashboard/components/analytics-content.tsx
  • libs/react/ui/src/components/dashboard/components/animated-logo.tsx
  • libs/react/ui/src/components/dashboard/components/complete-setup-button.tsx
  • libs/react/ui/src/components/dashboard/components/jobs-content.tsx
  • libs/react/ui/src/components/dashboard/components/mobile-menu.tsx
  • libs/react/ui/src/components/dashboard/components/organization-selector.tsx
  • libs/react/ui/src/components/dashboard/components/top-menu.tsx
  • libs/react/ui/src/components/dashboard/components/topbar-button.tsx
  • libs/react/ui/src/components/dashboard/components/topbar.tsx
  • libs/react/ui/src/components/dashboard/components/user-profile.tsx
  • libs/react/ui/src/components/dashboard/dashboard.stories.tsx
  • libs/react/ui/src/components/dashboard/dashboard.tsx
  • libs/react/ui/src/components/dashboard/index.ts
  • libs/react/ui/src/components/form/form.stories.tsx
  • libs/react/ui/src/components/select/select.stories.tsx
  • libs/react/ui/src/components/select/select.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

We handle errors at the edge of our applications in most cases. Do not recommend to add error handling around every single function. We prefer them to bubble up and be handled at upper layers.

Files:

  • libs/react/ui/src/components/dashboard/components/user-profile.tsx
  • libs/react/ui/src/components/dashboard/components/complete-setup-button.tsx
  • libs/react/ui/src/components/dashboard/components/top-menu.tsx
  • libs/react/ui/src/components/select/select.stories.tsx
  • libs/react/ui/src/components/dashboard/components/organization-selector.tsx
  • libs/react/ui/src/components/dashboard/dashboard.tsx
  • libs/react/ui/src/components/dashboard/components/animated-logo.tsx
  • libs/react/ui/src/components/dashboard/components/topbar-button.tsx
  • libs/react/ui/src/components/dashboard/components/mobile-menu.tsx
  • libs/react/ui/src/components/avatar/avatar.tsx
  • libs/react/ui/src/components/dashboard/index.ts
  • libs/react/ui/src/components/dashboard/components/topbar.tsx
  • libs/react/ui/src/components/dashboard/components/analytics-content.tsx
  • libs/react/ui/src/components/form/form.stories.tsx
  • libs/react/ui/src/components/dashboard/components/jobs-content.tsx
  • libs/react/ui/src/components/dashboard/dashboard.stories.tsx
  • libs/react/ui/src/components/select/select.tsx
🧬 Code graph analysis (10)
libs/react/ui/src/components/dashboard/components/user-profile.tsx (5)
libs/react/ui/src/components/dropdown-menu/dropdown-menu.tsx (5)
  • DropdownMenu (388-388)
  • DropdownMenuTrigger (389-389)
  • DropdownMenuContent (391-391)
  • DropdownMenuSeparator (398-398)
  • DropdownMenuItem (394-394)
libs/react/ui/src/components/avatar/avatar.tsx (1)
  • Avatar (117-217)
libs/react/ui/src/components/badge/user-badge.tsx (1)
  • UserBadge (11-34)
libs/react/ui/src/components/button/button.tsx (1)
  • Button (50-91)
libs/react/ui/src/components/shiny-text/shiny-text.tsx (1)
  • ShinyText (20-20)
libs/react/ui/src/components/dashboard/components/top-menu.tsx (1)
libs/react/ui/src/components/tabs/tabs.tsx (3)
  • Tabs (368-368)
  • TabsList (369-369)
  • TabsTrigger (370-370)
libs/react/ui/src/components/dashboard/components/organization-selector.tsx (5)
libs/react/ui/src/components/select/select.stories.tsx (1)
  • OrganizationSelector (212-250)
libs/react/ui/src/components/select/select.tsx (6)
  • Select (207-207)
  • SelectTrigger (210-210)
  • SelectValue (209-209)
  • SelectContent (211-211)
  • SelectItem (213-213)
  • SelectSeparator (214-214)
libs/react/ui/src/components/avatar/avatar.tsx (1)
  • Avatar (117-217)
libs/react/ui/src/components/button/button.tsx (1)
  • Button (50-91)
libs/react/ui/src/components/icon/icon.tsx (1)
  • Icon (86-90)
libs/react/ui/src/components/dashboard/dashboard.tsx (5)
libs/react/ui/src/components/dashboard/components/animated-logo.tsx (1)
  • AnimatedLogo (6-25)
libs/react/ui/src/components/dashboard/components/topbar.tsx (1)
  • Topbar (8-40)
libs/react/ui/src/components/dashboard/components/top-menu.tsx (1)
  • TopMenu (3-26)
libs/react/ui/src/components/dashboard/components/analytics-content.tsx (1)
  • AnalyticsContent (5-102)
libs/react/ui/src/components/dashboard/components/jobs-content.tsx (1)
  • JobsContent (10-51)
libs/react/ui/src/components/dashboard/components/animated-logo.tsx (1)
libs/react/ui/src/components/icon/icon.tsx (1)
  • Icon (86-90)
libs/react/ui/src/components/dashboard/components/topbar-button.tsx (2)
libs/react/ui/src/components/icon/icon.tsx (2)
  • IconName (77-77)
  • Icon (86-90)
libs/react/ui/src/components/button/button.tsx (1)
  • Button (50-91)
libs/react/ui/src/components/dashboard/components/topbar.tsx (6)
libs/react/ui/src/components/dashboard/components/topbar-button.tsx (1)
  • TopbarButton (5-30)
libs/react/ui/src/components/dashboard/components/organization-selector.tsx (1)
  • OrganizationSelector (13-51)
libs/react/ui/src/components/select/select.stories.tsx (1)
  • OrganizationSelector (212-250)
libs/react/ui/src/components/dashboard/components/complete-setup-button.tsx (1)
  • CompleteSetupButton (7-30)
libs/react/ui/src/components/dashboard/components/mobile-menu.tsx (1)
  • MobileMenu (14-53)
libs/react/ui/src/components/dashboard/components/user-profile.tsx (1)
  • UserProfile (23-90)
libs/react/ui/src/components/dashboard/components/analytics-content.tsx (3)
libs/react/ui/src/components/skeleton/skeleton.tsx (1)
  • Skeleton (6-14)
libs/react/ui/src/components/icon/icon.tsx (1)
  • Icon (86-90)
libs/react/ui/src/components/typography/text.tsx (1)
  • Text (27-50)
libs/react/ui/src/components/dashboard/dashboard.stories.tsx (2)
libs/react/ui/src/components/select/select.stories.tsx (1)
  • Default (27-40)
libs/react/ui/src/components/dashboard/dashboard.tsx (1)
  • Dashboard (12-61)
libs/react/ui/src/components/select/select.tsx (1)
libs/react/ui/src/components/icon/icon.tsx (1)
  • Icon (86-90)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Upload results
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Continuous integration
🔇 Additional comments (20)
libs/react/ui/src/components/form/form.stories.tsx (1)

1-1: Verify that the Argos CI package is correctly installed.

The import pattern import { argosScreenshot } from "@argos-ci/storybook/vitest" is correct and matches official Argos documentation for capturing screenshots in Storybook play functions. Ensure the @argos-ci/storybook package is listed in dependencies and compatible with the project's Storybook and Vitest versions.

libs/react/ui/src/components/select/select.tsx (1)

60-60: LGTM! Icon change improves semantic clarity.

The replacement of arrowDownSLine with expandUpDownLine better represents the bidirectional nature of a select dropdown, where users can navigate both up and down through options.

libs/react/ui/src/components/avatar/avatar.tsx (1)

14-14: LGTM! Styling refinement aligns with design system updates.

The border radius reduction from rounded-6 to rounded-4 is consistent with the broader UI styling refinements in this PR.

libs/react/ui/src/components/dashboard/components/user-profile.tsx (1)

13-21: LGTM! Safe percentage calculation with overflow protection.

The UsageGauge component correctly uses Math.min to cap the percentage at 100%, preventing visual overflow issues.

libs/react/ui/src/components/dashboard/index.ts (1)

1-1: LGTM! Standard barrel export pattern.

The barrel export provides a clean public API for the dashboard module, allowing consumers to import from a single entry point.

libs/react/ui/src/components/dashboard/components/organization-selector.tsx (2)

16-16: Verify the specific breakpoint min-[321px] is intentional.

The SelectTrigger uses a very specific responsive breakpoint of 321px for the right border. This is unusual compared to standard Tailwind breakpoints (sm: 640px, md: 768px, etc.). Ensure this precise value aligns with design requirements.


41-47: Verify Button behavior inside SelectContent.

Placing a Button inside SelectContent is an unusual pattern. Ensure that:

  1. The Button's click handler doesn't conflict with Radix Select's item selection logic
  2. The select dropdown closes appropriately when the button is clicked
  3. Consider using asChild on a SelectItem instead if you need custom styling

You may want to test this interaction or check Radix UI documentation for recommended patterns for action items in select dropdowns.

libs/react/ui/src/components/dashboard/components/jobs-content.tsx (1)

13-16: The code is type-safe. The JobData type explicitly requires name as a non-nullable string, so the filter operation cannot fail due to null/undefined values. No additional error handling is needed.

Likely an incorrect or invalid review comment.

libs/react/ui/src/components/dashboard/dashboard.stories.tsx (1)

19-25: LGTM!

The Default story is correctly structured with a full-height container appropriate for the fullscreen layout parameter.

libs/react/ui/src/components/select/select.stories.tsx (3)

2-5: LGTM!

New imports are correctly added for the additional components used in the new stories.


168-210: LGTM!

The TimeSelector story effectively demonstrates using Kbd components inside select items to show keyboard shortcuts, which is a useful pattern for documentation.


240-246: Verify Button accessibility within SelectContent.

The Button is placed inside SelectContent but outside of SelectItem elements. While this is a common pattern for "add new" actions, ensure it's keyboard-accessible and doesn't interfere with the Select's native keyboard navigation (arrow keys, enter selection).

libs/react/ui/src/components/dashboard/components/top-menu.tsx (1)

10-25: LGTM!

The Tabs implementation is clean, with proper controlled state management and responsive styling.

libs/react/ui/src/components/dashboard/dashboard.tsx (3)

18-25: LGTM!

The scroll tracking implementation with framer-motion is well-structured. The progress is correctly clamped between 0 and 1.


27-33: LGTM!

The handleTabChange callback is properly memoized with useCallback and correctly resets both scroll position and progress state when switching tabs.


37-60: LGTM!

The overall component structure is clean with proper separation of concerns. The dynamic padding calculation using cubic easing provides smooth animation, and conditional rendering of tab content is straightforward.

libs/react/ui/src/components/dashboard/components/mobile-menu.tsx (1)

14-53: LGTM!

The component is well-structured, follows existing patterns (theme-aware loader, dropdown composition), and correctly handles responsive display via the md:hidden class on the trigger button.

libs/react/ui/src/components/dashboard/components/topbar.tsx (1)

9-39: LGTM!

The Topbar composition is clean with good responsive handling. The use of opacity-0 for hiding the logo (rather than conditional rendering) correctly preserves layout space, which appears intentional for the dashboard structure.

libs/react/ui/src/components/dashboard/components/analytics-content.tsx (2)

5-102: LGTM!

The skeleton-based placeholder UI is well-structured with:

  • Proper responsive design using md: breakpoints
  • Consistent styling patterns
  • Clean iteration for repeated elements (metrics cards, extra blocks)
  • Good use of semantic Text component with size variants

This provides a solid foundation for replacing with real data.


69-74: This usage is correct. The color prop is explicitly supported by the ShipfoxLogo component, which the Icon component renders when name="shipfox". The Icon wrapper passes all additional props through to the underlying icon component via spread operator, allowing the color prop to flow through properly and be applied to the SVG's fill attribute. No changes needed.

Likely an incorrect or invalid review comment.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on January 19

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

dvxam
dvxam previously approved these changes Dec 22, 2025
@kylengn kylengn merged commit 9bd4839 into main Dec 23, 2025
6 checks passed
@kylengn kylengn deleted the feat/dashboard-story branch December 23, 2025 08:59
@coderabbitai coderabbitai bot mentioned this pull request Dec 24, 2025
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