Skip to content

Conversation

@kyrers
Copy link

@kyrers kyrers commented Oct 23, 2025

Resolves #88.


PR-Codex overview

This PR focuses on refactoring the codebase to replace styled-components with Tailwind CSS for styling, enhancing the overall design consistency and maintainability. It also removes unused files and updates several components to use the new styling approach.

Detailed summary

  • Removed multiple unused style files and components.
  • Replaced styled-components with Tailwind CSS in various components.
  • Updated button props from disabled to isDisabled for consistency.
  • Refactored modal and overlay components to use Tailwind CSS classes.
  • Adjusted various components to improve layout and responsiveness using Tailwind.
  • Introduced a new ThemeProvider for managing theme state.
  • Updated imports to reflect new utility functions and styles.

The following files were skipped due to too many changes: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx, web/src/layout/Header/navbar/index.tsx, web/src/layout/Header/navbar/Menu/Help.tsx, web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx, web/src/components/StatsAndFilters/Filters.tsx, web/src/components/RegistriesDisplay/RegistriesGrid.tsx, web/src/components/StyledSkeleton.tsx, web/src/layout/Header/navbar/Explore.tsx, web/src/layout/Header/navbar/DappList.tsx, web/src/layout/Header/DesktopHeader.tsx, web/src/components/StatDisplay.tsx, web/src/layout/Header/navbar/Menu/Settings/General.tsx, web/src/components/InformationCards/StatusDisplay.tsx, web/src/layout/Header/navbar/Menu/Settings/index.tsx, web/src/components/RegistryCard/StatusBanner.tsx, web/src/global.css, web/src/components/ConnectWallet/AccountDisplay.tsx, web/src/components/Search.tsx, web/src/components/InformationCards/ItemInformationCard/index.tsx, web/src/components/RegistryCard/RegistryInfo.tsx, yarn.lock

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • Chores

    • Added Tailwind tooling and utilities; upgraded UI library; removed legacy CSS-in-JS and modal packages.
  • New Features

    • New theme provider with persisted light/dark preference and a global stylesheet (scrollbar, Toastify and accessibility tweaks).
  • Refactor

    • Migrated styling app-wide from CSS-in-JS to utility/class-based (Tailwind); many components updated to className-driven markup.
  • Other

    • Added a class-merge helper; removed a deprecated link component; minor public prop/interface updates (button disabling prop, modal className, settings/tabs and some component props).

@kyrers kyrers self-assigned this Oct 23, 2025
@netlify
Copy link

netlify bot commented Oct 23, 2025

Deploy Preview for curate-v2 failed. Why did it fail? →

Name Link
🔨 Latest commit 5c38226
🔍 Latest deploy log https://app.netlify.com/projects/curate-v2/deploys/6917c43107c61100085f638b

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 23, 2025

Walkthrough

Replaces styled-components with className/Tailwind utilities across the frontend, upgrades @kleros/ui-components-library to v3, adds Tailwind tooling and global.css, swaps the styled-components provider for a DOM-class ThemeProvider, introduces cn (clsx + tailwind-merge), adds LG_BREAKPOINT, and updates many components to className-based implementations and new Button prop (isDisabled) usage.

Changes

Cohort / File(s) Change Summary
Dependencies & Build
web/package.json, web/vite.config.js
Add Tailwind tooling (@tailwindcss/vite, tailwindcss), add clsx & tailwind-merge, upgrade @kleros/ui-components-library to v3, register Tailwind plugin in Vite.
Root & Providers
New: web/src/context/ThemeProvider.tsx
Deleted: web/src/context/StyledComponentsProvider.tsx
web/src/app.tsx, web/src/index.tsx
Replace StyledComponentsProvider with ThemeProvider (localStorage + DOM "dark" class); import global.css; remove react-modal setAppElement call.
Global CSS & Types
New: web/src/global.css
web/global.d.ts
Add global Tailwind/CSS tokens, dark-mode rules and overrides; convert global.d.ts from styled-components augmentation to export {} module.
Styles removed / moved
web/src/styles/* (removed: themes.ts, global-style.ts, commonStyles.ts, customScrollbar.ts, landscapeStyle.ts)
Remove styled-components theme objects/helpers and CSS-in-JS global styles; move tokens/overrides into global.css.
Breakpoints & utils
web/src/styles/breakpoints.ts, web/src/utils/index.ts
Add LG_BREAKPOINT = 900; add cn(...inputs) helper (clsx + tailwind-merge).
Theme/hook rename
web/src/hooks/useToggleThemeContext.tsx, usages
Rename hook export useToggleThemeuseTheme (returns [theme, toggleTheme]); update consumers.
Button API changes
assorted (EnsureAuth.tsx, ActionButton/*, ConnectWallet/*, etc.)
Update Button prop usage from disabledisDisabled to match UI library v3.
Modal/Overlay/Portal changes
web/src/components/Modal.tsx, web/src/components/Overlay.tsx, web/src/components/OverlayPortal.tsx, web/src/components/ActionButton/Modal/*
Replace styled-components wrappers with plain divs/className; Modal gains optional className prop.
Component styling migration (bulk)
web/src/layout/**, web/src/components/**, web/src/pages/** (many files)
Migrate many components from styled-components to className/Tailwind-like markup (headers, navbar, menus, settings, footer, layout, skeletons, pages, cards, item fields); preserve logic; some components gained or adjusted props.
Registry / Status / UI adjustments
web/src/components/RegistryCard/*, web/src/components/StatDisplay.tsx
Replace styled-components with utility classes; IListCard adds itemId?, totalItems, status; IColors becomes explicit union; removed getStatusColor helper, moved status styles to class mappings.
API/interface tweaks
assorted (InfoCard, Modal, ItemInformationCard, AliasDisplay, NumberField, RegistriesGrid, etc.)
Add/adjust props in several components (e.g., InfoCard.className?, Modal.className?, ItemInformationCard adds className?, policyURI, registryAddress, isPreview?, NumberField props changed, RegistriesGrid props extended).
Removals
web/src/components/ExternalLink.tsx, many styled helper exports
Remove ExternalLink export and multiple styled-components-only helper files/exports.

Sequence Diagram(s)

sequenceDiagram
    participant App as App.tsx
    participant ThemeProv as ThemeProvider
    participant ToggleCtx as ToggleThemeProvider
    participant Doc as document.documentElement
    participant UI as UI Component

    App->>ThemeProv: mount <ThemeProvider>{children}
    ThemeProv->>ThemeProv: read theme from localStorage (default "dark")
    ThemeProv->>Doc: add/remove "dark" class
    ThemeProv->>ToggleCtx: provide [theme, toggleTheme]
    UI->>ToggleCtx: consume [theme, toggleTheme]
    UI->>UI: render using cn(...) classNames
    UI->>ThemeProv: user triggers toggleTheme()
    ThemeProv->>ThemeProv: persist theme and update DOM class
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • web/src/global.css — token correctness, Toastify and react-loading-skeleton overrides, scrollbar rules.
    • Type impacts from removing styled-components DefaultTheme augmentation (web/global.d.ts) and deleted themes.ts.
    • Components with changed interfaces: InfoCard, RegistryCard/index, RegistryCard/StatusBanner, ItemInformationCard.
    • Hook rename: useToggleThemeuseTheme and all consumer updates.
    • Button API changes — ensure all isDisabled usages match new UI library v3 semantics.

Possibly related issues

Possibly related PRs

Suggested labels

Package: Web, Type: Enhancement :sparkles:

Suggested reviewers

  • kemuru
  • Harman-singh-waraich
  • jaybuidl

Poem

🐇 I hopped through styles and swapped each thread,
Tailwind sprouted where old themes once spread.
The root now bears "dark", cn tidies every class,
Portals, headers, buttons — quicker than a dash.
🥕 Happy reviewing, with a carrot and sass.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: migrating from styled-components to Tailwind CSS, which is the main refactoring focus.
Linked Issues check ✅ Passed The PR successfully implements all coding objectives from #88: migrates to @kleros/ui-components-library v3, removes styled-components, integrates Tailwind into build pipeline, updates global styles, and refactors theme/breakpoint handling.
Out of Scope Changes check ✅ Passed All changes are within scope of the styled-components to Tailwind migration objective. Updates to Button props (disabled→isDisabled) are necessary for v3 library compatibility. Theme provider changes and breakpoint consolidation align with stated objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 chore/migrate-from-styled-components-to-tailwind

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

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

🧹 Nitpick comments (2)
web/src/global.css (1)

60-62: Consider reducing !important usage.

The !important declarations on lines 61 and 147 override library defaults for ReactModal and Toastify. While sometimes necessary for third-party library overrides, consider if these can be achieved through higher CSS specificity instead.

If the library CSS is loaded before your global styles, you may be able to increase specificity without !important:

/* Instead of: */
.ReactModal__Overlay {
  background-color: #1b003fcc !important;
}

/* Try: */
.ReactModal__Overlay.ReactModal__Overlay {
  background-color: #1b003fcc;
}

Also applies to: 145-148

web/src/context/ThemeProvider.tsx (1)

8-8: Improve type safety for theme values.

The theme is currently typed as string, which allows any string value. This should be constrained to the valid theme values for better type safety and developer experience.

Apply this diff to add proper typing:

+type Theme = "light" | "dark";
+
 const ThemeProvider: React.FC<{
   children: React.ReactNode;
 }> = ({ children }) => {
-  const [theme, setTheme] = useLocalStorage<string>("theme", "dark");
+  const [theme, setTheme] = useLocalStorage<Theme>("theme", "dark");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc5502a and ad2c61b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (11)
  • web/package.json (2 hunks)
  • web/src/app.tsx (3 hunks)
  • web/src/context/StyledComponentsProvider.tsx (0 hunks)
  • web/src/context/ThemeProvider.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/styles/commonStyles.ts (0 hunks)
  • web/src/styles/customScrollbar.ts (0 hunks)
  • web/src/styles/global-style.ts (0 hunks)
  • web/src/styles/landscapeStyle.ts (0 hunks)
  • web/src/styles/themes.ts (0 hunks)
  • web/vite.config.js (2 hunks)
💤 Files with no reviewable changes (6)
  • web/src/styles/global-style.ts
  • web/src/styles/landscapeStyle.ts
  • web/src/styles/themes.ts
  • web/src/styles/commonStyles.ts
  • web/src/styles/customScrollbar.ts
  • web/src/context/StyledComponentsProvider.tsx
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (6)
web/vite.config.js (1)

5-5: LGTM! Tailwind v4 Vite integration is correct.

The Tailwind CSS integration follows the standard pattern for v4 with Vite using the @tailwindcss/vite plugin.

Also applies to: 32-32

web/src/global.css (1)

1-20: LGTM! Tailwind v4 @theme directive and imports are correctly structured.

The global CSS setup follows Tailwind v4 best practices: importing the UI library theme, importing Tailwind, and defining custom design tokens via the @theme directive. The token definitions are comprehensive and well-organized.

web/package.json (2)

78-78: LGTM! Tailwind CSS dependencies are correctly added.

Both tailwindcss and @tailwindcss/vite are on the same version (4.1.16), which ensures consistency. The @tailwindcss/vite package is appropriately placed in both dependencies and devDependencies for build tooling access.

Also applies to: 107-107


73-73: Manually verify component compatibility after Tailwind migration to v3.6.0.

The upgrade to v3.6.0 involved a major migration from styled-components to Tailwind CSS. The library was migrated to Tailwind CSS, which includes changes to component styling and theming. Tailwind is already configured in the project (v4.1.16).

The codebase uses 23+ components from the library across 40+ files, including several internal components prefixed with underscore (_TimelineItem1, _IItem1). However, no public changelog documents specific breaking changes and component API modifications for v3.6.0.

Actions required:

  • Test all component usages throughout the application (run tests and manual QA)
  • Verify visual regressions from CSS token/spacing changes
  • Confirm internal components (_TimelineItem1, _IItem1) remain stable and exported in v3
  • Check for any prop renames or removed component APIs against the library's Storybook or GitHub repository
web/src/context/ThemeProvider.tsx (1)

10-22: LGTM! Dark mode implementation is correct.

The theme toggling logic and the useEffect that applies the dark class to document.documentElement correctly implements Tailwind's class-based dark mode strategy. The implementation will work seamlessly with Tailwind's dark: variant.

web/src/app.tsx (1)

4-4: LGTM! Theme provider migration is correctly implemented.

The migration from StyledComponentsProvider to the new ThemeProvider is clean and correct. The global.css import is properly placed early in the file, and the ThemeProvider correctly wraps the entire application as the outermost provider to ensure theme context is available throughout the component tree.

Also applies to: 7-7, 26-26, 59-59

Copy link
Contributor

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

🧹 Nitpick comments (2)
web/src/context/Web3Provider.tsx (1)

62-62: Consider adding the brand color to the theme system for maintainability.

The hardcoded color #4D00B4 is correct—it matches the primary brand color used throughout SVG assets. However, since the codebase has migrated to Tailwind with a theme system (defined in web/src/global.css), consider adding this color to the @theme block for consistency and easier maintenance:

/* In web/src/global.css @theme block */
--color-primary: #4D00B4;

Then reference it in Web3Provider:

"--w3m-color-mix": "var(--color-primary)",

This keeps brand colors centralized and easier to maintain across the codebase. The color itself doesn't need to change between light/dark modes—this is a brand constant, not a theme-dependent color.

web/src/layout/index.tsx (1)

22-22: Consider extracting the hardcoded spacing value.

The hardcoded pt-[70px] value appears to offset the ToastContainer from the header. For better maintainability and theme consistency, consider defining this as a CSS variable or Tailwind theme extension that matches the header height.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad2c61b and d2d2579.

📒 Files selected for processing (3)
  • web/global.d.ts (1 hunks)
  • web/src/context/Web3Provider.tsx (1 hunks)
  • web/src/layout/index.tsx (1 hunks)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/index.tsx (1)

23-23: Consider adding dark mode variant.

The background class bg-klerosUIComponentsLightBackground implies a light theme background. Based on the PR's ThemeProvider that toggles a document-level dark class, consider whether this element needs a corresponding dark mode variant (e.g., dark:bg-klerosUIComponentsDarkBackground).

web/global.d.ts (1)

1-12: LGTM!

The removal of styled-components module augmentation is appropriate for the Tailwind migration. The file correctly preserves the necessary ambient declarations for SVG and PNG imports while maintaining proper module structure with the export {} statement.

@kleros kleros deleted a comment from coderabbitai bot Oct 24, 2025
@kleros kleros deleted a comment from coderabbitai bot Oct 24, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 30, 2025
Copy link
Contributor

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

🧹 Nitpick comments (3)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1)

45-45: Consider using standard spacing scale instead of arbitrary value.

The arbitrary value mb-[10px] works correctly in Tailwind v4, but using the standard spacing scale improves consistency across the codebase. Since 10px equals 2.5rem (2.5 × 4px), consider using mb-2.5 instead.

-      <label className="flex justify-between mb-[10px]">{contactLabel}</label>
+      <label className="flex justify-between mb-2.5">{contactLabel}</label>
web/src/layout/Header/Logo.tsx (2)

8-13: Remove unnecessary whitespace literal.

The {" "} on line 9 serves no purpose and can be removed for cleaner code.

Apply this diff:

  <div className="flex flex-row items-center gap-4">
-    {" "}
    <Link to={"/"}>
      <CurateLogo className="transition duration-100 max-h-12 w-auto hover:fill-white/75" />
    </Link>
  </div>

10-12: Add accessible label for the logo link.

The logo link lacks descriptive text for screen readers. Add an aria-label to improve accessibility.

Apply this diff:

-    <Link to={"/"}>
+    <Link to={"/"} aria-label="Home">
      <CurateLogo className="transition duration-100 max-h-12 w-auto hover:fill-white/75" />
    </Link>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f638cb8 and bb0901b.

📒 Files selected for processing (23)
  • web/src/app.tsx (3 hunks)
  • web/src/components/ConnectWallet/AccountDisplay.tsx (2 hunks)
  • web/src/components/InfoCard.tsx (1 hunks)
  • web/src/components/LightButton.tsx (1 hunks)
  • web/src/components/Overlay.tsx (1 hunks)
  • web/src/components/OverlayPortal.tsx (1 hunks)
  • web/src/context/ThemeProvider.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/layout/Header/DesktopHeader.tsx (1 hunks)
  • web/src/layout/Header/Logo.tsx (1 hunks)
  • web/src/layout/Header/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (1 hunks)
  • web/src/layout/Header/navbar/Debug.tsx (2 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/General.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Product.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/context/ThemeProvider.tsx
  • web/src/app.tsx
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:29:55.971Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/context/AtlasProvider.tsx:176-193
Timestamp: 2024-11-04T13:29:55.971Z
Learning: In the `web/src/context/AtlasProvider.tsx` file of the React application, the `authoriseUser` function handles session invalidation and delegates error handling and user notifications to the functions that invoke it. Therefore, adding error notifications within `authoriseUser` is unnecessary.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
🧬 Code graph analysis (5)
web/src/layout/Header/navbar/Debug.tsx (1)
web/src/consts/index.ts (2)
  • RELEASE_VERSION (12-12)
  • GIT_URL (11-11)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (2)
web/src/components/EnsureChain.tsx (1)
  • EnsureChain (10-14)
web/src/components/ConnectWallet/AccountDisplay.tsx (3)
  • IdenticonOrAvatar (16-34)
  • AddressOrName (40-50)
  • ChainDisplay (52-56)
web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (2)
web/src/layout/Header/navbar/index.tsx (1)
  • ISettings (54-56)
web/src/components/EnsureChain.tsx (1)
  • EnsureChain (10-14)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (1)
web/src/utils/date.ts (1)
  • timeLeftUntil (43-69)
web/src/layout/Header/index.tsx (1)
web/src/utils/getGraphqlUrl.ts (1)
  • getGraphqlUrl (3-7)
🔇 Additional comments (12)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1)

45-52: Migration looks clean, but verify label-input association for accessibility.

The migration from styled-components to Tailwind classes is well-executed. However, the <label> on line 45 lacks a htmlFor attribute to associate it with the input field. If the Field component renders an input element, ensure proper label-input association for accessibility.

Consider adding a htmlFor attribute if the Field component exposes an id:

-      <label className="flex justify-between mb-[10px]">{contactLabel}</label>
+      <label htmlFor="contact-input" className="flex justify-between mb-[10px]">{contactLabel}</label>
       <Field
         className="flex flex-col items-center w-full"
+        id="contact-input"
         variant={fieldVariant}

Alternatively, if the Field component from @kleros/ui-components-library handles accessibility internally or doesn't support id props, you may disregard this suggestion.

web/src/layout/Header/navbar/DappList.tsx (1)

98-98: LGTM!

The h1 header uses standard Tailwind utility classes correctly.

web/src/layout/Header/navbar/Menu/Help.tsx (1)

52-53: The breakpoint is already properly configured—no action needed.

The custom landscape-900: breakpoint is correctly defined in web/src/global.css using Tailwind v4's @theme block with the --breakpoint-landscape-900: 900px; variable, which automatically creates the responsive modifier. The review comment incorrectly assumes traditional Tailwind configuration (JS/TS config file), which is not applicable to Tailwind v4's CSS-first approach. The code at lines 52-53 in Help.tsx correctly uses this pre-configured breakpoint.

Likely an incorrect or invalid review comment.

web/src/layout/Header/navbar/Debug.tsx (1)

5-20: LGTM!

The migration from styled-components to className-based styling is implemented correctly. The arbitrary font-family syntax font-[Roboto_Mono,monospace] is proper Tailwind v4 usage.

web/src/components/Overlay.tsx (1)

1-5: LGTM!

Clean conversion from styled-component to a functional component with Tailwind classes. The bg-black-low-opacity custom color should be defined in your theme configuration.

web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1)

36-49: LGTM!

Successful migration from styled-components to utility classes. The SVG fill and layout classes are properly applied.

web/src/global.css (2)

1-67: Well-structured Tailwind v4 integration.

The global stylesheet properly:

  • Imports the UI library theme and Tailwind v4 using the new @import syntax
  • Defines custom theme tokens via @theme directive
  • Implements accessible focus management with :focus-visible (addressing the previous review concern)

The focus styling (lines 60-67) now correctly preserves keyboard navigation accessibility while removing focus outlines for mouse users.


138-142: Verify browser support for CSS nesting.

The nested selector syntax ul { li { ... } } requires modern browsers. Based on your Tailwind v4 adoption (which targets Chrome 111+, Safari 16.4+, Firefox 128+), this should be supported, but confirm this aligns with your browser compatibility requirements.

web/src/layout/Header/index.tsx (1)

12-33: LGTM! Clean migration to Tailwind v4 syntax.

The header structure correctly uses Tailwind v4 features including advanced selector syntax for StatusBanner styling and CSS variables for theme integration. The sticky positioning and backdrop blur effects are properly configured.

web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)

20-49: LGTM! Proper use of Tailwind v4 advanced features.

The component correctly uses Tailwind v4's advanced selector syntax ([&>label], [&_label]) and pseudo-element utilities (before:content-['']) to style nested elements. The layout structure is clean and maintains the original functionality.

web/src/layout/Header/DesktopHeader.tsx (1)

43-43: LGTM! Correct Tailwind v4 important modifier syntax.

The important modifier is correctly placed at the end of the utility class (fill-white!), which is the proper Tailwind v4 syntax.

web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1)

18-30: LGTM!

The migration to Tailwind utilities is well-executed. The flexbox layout structure correctly preserves the component's intended design with proper centering and spacing.

Copy link
Contributor

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

♻️ Duplicate comments (1)
web/src/components/ConnectWallet/AccountDisplay.tsx (1)

78-80: Fix merged utility class separator.

The concatenated strings still miss a trailing space before landscape-900:hidden, so the output becomes before:ml-[3px]landscape-900:hidden and Tailwind drops both utilities. Add the separator (or switch to a template literal) so each class stays intact.

-          "before:content-[''] before:w-2 before:h-2 before:rounded-[50%] before:bg-klerosUIComponentsSuccess before:my-0 before:mr-[13px] before:ml-[3px]" +
+          "before:content-[''] before:w-2 before:h-2 before:rounded-[50%] before:bg-klerosUIComponentsSuccess before:my-0 before:mr-[13px] before:ml-[3px] " +
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb0901b and 318211a.

📒 Files selected for processing (13)
  • web/src/components/ConnectWallet/AccountDisplay.tsx (2 hunks)
  • web/src/components/InfoCard.tsx (1 hunks)
  • web/src/components/LightButton.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/layout/Header/DesktopHeader.tsx (1 hunks)
  • web/src/layout/Header/Logo.tsx (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (1 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Product.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • web/src/components/InfoCard.tsx
  • web/src/layout/Header/navbar/Explore.tsx
  • web/src/layout/Header/Logo.tsx
  • web/src/components/LightButton.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/Header/navbar/Menu/Help.tsx (1)

48-69: LGTM! Previous issues resolved.

The Tailwind utility classes are now correct, and the className concatenation includes proper spacing.

web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)

39-39: Previous issues resolved.

The invalid width-[calc(...)] utility has been corrected to w-[calc(...)].

Copy link
Contributor

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

🧹 Nitpick comments (1)
web/src/layout/Header/navbar/Product.tsx (1)

39-39: Consider removing unnecessary flex class.

The <small> element contains only text and uses text-center for alignment. The flex class appears unnecessary since text-center alone handles text alignment for inline content.

-      <small className="flex font-normal text-center leading-[19px]">{text}</small>
+      <small className="font-normal text-center leading-[19px]">{text}</small>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 318211a and dba15bb.

📒 Files selected for processing (7)
  • web/src/components/LightButton.tsx (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (1 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Product.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • web/src/layout/Header/navbar/DappList.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
  • web/src/components/LightButton.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (4)
web/src/layout/Header/navbar/Explore.tsx (2)

17-18: LGTM! Clean active route detection.

The isActive helper correctly handles both the root path (exact match) and nested routes (first segment comparison), which prevents false positives in navigation highlighting.


36-49: Custom utilities are properly configured—no changes required, but consider adding @source directive.

The className structure is correct and all custom utilities are properly defined in your Tailwind v4 setup:

  • text-klerosUIComponentsPrimaryText, text-primary-text-73, text-white-73 are configured via CSS variables in the @theme block
  • landscape-900: breakpoint is defined as --breakpoint-landscape-900: 900px
  • All utilities are actively used and functional throughout the codebase

Based on the learning context, consider adding the @source directive in web/src/global.css to explicitly tell Tailwind to scan the @kleros/ui-components-library for utility classes:

@source "../node_modules/@kleros/ui-components-library";
@import "@kleros/ui-components-library/theme.css";
@import "tailwindcss";

This ensures Tailwind can generate utilities from CSS variables in the external library, though the current setup appears to be working without it.

web/src/layout/Header/navbar/Product.tsx (1)

16-25: Previous critical issues successfully resolved!

All three issues from the previous review have been properly addressed:

  1. ✅ Security: rel="noopener noreferrer" added
  2. ✅ Styling: className construction fixed and dynamic width moved to style prop
  3. ✅ This segment demonstrates proper Tailwind v4 migration pattern
web/src/layout/Header/navbar/Menu/index.tsx (1)

37-37: Clean responsive layout structure.

The flex layout with responsive breakpoint is well-structured for converting the menu from vertical to horizontal orientation.

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 31, 2025
Copy link
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/layout/Header/navbar/index.tsx (1)

2-2: Remove unused styled-components import.

The styled import is no longer used after migrating to Tailwind utility classes.

Apply this diff to remove the unused import:

-import styled from "styled-components";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dba15bb and f3b7df3.

📒 Files selected for processing (3)
  • web/src/layout/Header/MobileHeader.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (2 hunks)
  • web/src/layout/Header/navbar/index.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/layout/Header/navbar/index.tsx (1)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)
  • DisconnectWalletButton (7-10)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/Header/navbar/index.tsx (1)

59-66: LGTM! Wallet container refactoring is correct.

The replacement of styled components with Tailwind flex utilities is appropriate, and the wrapper div for vertical alignment maintains the intended layout.

web/src/layout/Header/MobileHeader.tsx (1)

29-29: Custom breakpoint is properly configured.

The landscape-900 breakpoint is defined as a CSS variable in web/src/global.css (line 21: --breakpoint-landscape-900: 900px;) and is successfully used across the codebase in multiple files (DesktopHeader, DappList, Explore, Menu, Settings, LightButton, AccountDisplay). The consistent usage throughout the project confirms proper Tailwind integration.

However, the icon-only button on line 33 lacks accessibility attributes — add aria-label or title to the LightButton since text="":

<LightButton className="p-0 [&_.button-svg]:mr-0" text="" Icon={HamburgerIcon} onClick={toggleIsOpen} aria-label="Toggle menu" />

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 31, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 12, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 13, 2025
Copy link
Contributor

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e81424 and 077af58.

📒 Files selected for processing (2)
  • web/src/app.tsx (3 hunks)
  • web/src/layout/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/app.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/layout/index.tsx
📚 Learning: 2025-11-06T23:06:51.514Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/global.css:3-3
Timestamp: 2025-11-06T23:06:51.514Z
Learning: In Tailwind v4, you can use `import "tailwindcss" source("path")` syntax to control automatic content detection by passing the source() argument directly on the import statement. This is in addition to the standalone `source "path"` directive. Both syntaxes are valid: `import "tailwindcss" source("../../node_modules/kleros/ui-components-library");` and `source "../../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/layout/index.tsx
📚 Learning: 2025-10-31T19:54:12.499Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/Header/DesktopHeader.tsx:43-44
Timestamp: 2025-10-31T19:54:12.499Z
Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).

Applied to files:

  • web/src/layout/index.tsx
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2

Copy link
Contributor

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

🧹 Nitpick comments (1)
web/src/layout/index.tsx (1)

21-21: Consider extracting the magic number to a theme variable.

The pt-[70px] arbitrary value appears to match the header height. While functional, consider extracting this to a Tailwind theme variable (e.g., --header-height) for better maintainability if the header height changes.

Example in global.css:

@theme {
  --spacing-header-height: 70px;
}

Then use:

<ToastContainer className="p-4 pt-header-height" />
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 077af58 and 6e776cb.

📒 Files selected for processing (1)
  • web/src/layout/index.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/layout/index.tsx
📚 Learning: 2025-11-06T23:06:51.514Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/global.css:3-3
Timestamp: 2025-11-06T23:06:51.514Z
Learning: In Tailwind v4, you can use `import "tailwindcss" source("path")` syntax to control automatic content detection by passing the source() argument directly on the import statement. This is in addition to the standalone `source "path"` directive. Both syntaxes are valid: `import "tailwindcss" source("../../node_modules/kleros/ui-components-library");` and `source "../../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/layout/index.tsx
📚 Learning: 2025-10-31T19:54:12.499Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/Header/DesktopHeader.tsx:43-44
Timestamp: 2025-10-31T19:54:12.499Z
Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).

Applied to files:

  • web/src/layout/index.tsx
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/index.tsx
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (3)
web/src/layout/index.tsx (3)

14-18: LGTM! Clean migration to className-based styling.

The OverlayScrollbarsComponent setup correctly uses w-full (avoiding the potential horizontal overflow issue with w-screen discussed earlier) and maintains the original functionality with proper ref handling and overlay scrollbar options.


19-19: LGTM! Correct flex container setup.

The combination of flex flex-col min-h-full w-full properly establishes a vertical flex container that fills the available space, ensuring the footer stays at the bottom when content is short.


22-24: LGTM! Outlet container properly configured.

The flex-1 ensures the content area fills available space, and the background class correctly handles theme switching (as confirmed in previous discussions). The migration from styled-components to Tailwind is clean and maintains the original layout behavior.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 13, 2025
Copy link
Contributor

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

♻️ Duplicate comments (1)
web/src/components/RegistryCard/RegistryInfo.tsx (1)

34-47: Dynamic Tailwind grid-cols won't work; extend inline style approach.

Similar to the columnGap on line 46, the template literal syntax on line 42 (lg:grid-cols-[auto_1fr_${firstColWidthCalc}_${secondColWidthCalc}_max-content]) will not work because Tailwind cannot detect runtime variable interpolation at build time.

Since you're already using inline styles for columnGap (line 46), extend this approach to handle the grid columns as well.

Apply this diff:

       <div
         className={cn(
           "flex flex-col justify-center items-center gap-2 h-[calc(100%-45px)]",
           isListView && [
             "grid grid-cols-[21px_max-content_1fr_max-content] grid-rows-[repeat(3,min-content)] gap-y-4",
             "w-full h-max lg:h-16 p-4",
             "[&_h3]:col-span-4 [&_img]:col-span-4",
             "lg:justify-between lg:grid-rows-[1fr] lg:px-8",
-            `lg:grid-cols-[auto_1fr_${firstColWidthCalc}_${secondColWidthCalc}_max-content]`,
+            "lg:grid-cols-[var(--col-1)_var(--col-2)_var(--col-3)_var(--col-4)_var(--col-5)]",
             "lg:[&_img]:col-span-1 lg:[&_h3]:col-span-2",
           ]
         )}
-        style={{ columnGap: isListView ? responsiveSize(8, 24, 900) : undefined }}
+        style={{
+          columnGap: isListView ? responsiveSize(8, 24, 900) : undefined,
+          ...(isListView && {
+            "--col-1": "auto",
+            "--col-2": "1fr",
+            "--col-3": firstColWidthCalc,
+            "--col-4": secondColWidthCalc,
+            "--col-5": "max-content",
+          }),
+        } as React.CSSProperties}
       >

This approach keeps the responsive calculation logic using the same pattern as your columnGap while working around Tailwind's build-time limitations.

🧹 Nitpick comments (2)
web/src/components/StatDisplay.tsx (2)

1-3: Use cn consistently instead of mixing with clsx.

Both clsx and cn are imported, but cn wraps clsx with tailwind-merge for proper Tailwind class deduplication. Line 18 uses clsx while line 20 uses cn.

Apply this diff to use cn consistently:

 import React from "react";
-import clsx from "clsx";
 import { cn } from "~src/utils";

Then update line 18:

-    <div className={clsx("flex items-center gap-2 max-w-[192px]", `lg:mb-[${marginBottomCalc}]`)} {...props}>
+    <div className={cn("flex items-center gap-2 max-w-[192px]", `lg:mb-[${marginBottomCalc}]`)} {...props}>

29-29: Remove unnecessary braces.

The JSX expression braces around <Icon /> are unnecessary.

Apply this diff:

-        {<Icon />}
+        <Icon />
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e776cb and 4b9dc11.

📒 Files selected for processing (5)
  • web/src/components/RegistryCard/RegistryInfo.tsx (3 hunks)
  • web/src/components/StatDisplay.tsx (2 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (2 hunks)
  • web/src/pages/Home/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/layout/Header/navbar/DappList.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2025-10-31T20:37:01.310Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
🧬 Code graph analysis (2)
web/src/components/StatDisplay.tsx (1)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/RegistryCard/RegistryInfo.tsx (3)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/consts/index.ts (1)
  • DEFAULT_LIST_LOGO (23-23)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (3)
web/src/layout/Header/navbar/Menu/Settings/index.tsx (2)

1-19: LGTM: Clean imports and tab structure.

The migration to clsx and addition of id fields to TABS entries are appropriate changes for the Tailwind migration.


34-41: Critical: Invalid z-index utility z-1 still present.

The className on line 37 uses z-1, which is not a valid Tailwind utility. The standard z-index scale does not include z-1. Use z-[1] for an explicit z-index of 1, or a standard token like z-10.

Apply this diff:

       className={clsx(
-        "flex flex-col absolute max-h-[80vh] overflow-y-auto top-[5%] left-1/2 transform -translate-x-1/2 z-1",
+        "flex flex-col absolute max-h-[80vh] overflow-y-auto top-[5%] left-1/2 transform -translate-x-1/2 z-[1]",
         "bg-klerosUIComponentsWhiteBackground border border-solid border-klerosUIComponentsStroke rounded-[3px]",
         "lg:mt-16 lg:top-0 lg:right-0 lg:left-auto lg:transform-none lg:translate-x-0"
       )}
⛔ Skipped due to learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b
web/src/components/RegistryCard/RegistryInfo.tsx (1)

48-78: LGTM on the rendering logic.

The conditional rendering, Skeleton usage, image handling, and Button styling are well-implemented. The cn utility is used correctly for className composition, and the conditional classes properly handle the isListView variations.

Copy link
Contributor

@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

♻️ Duplicate comments (1)
web/src/components/RegistryCard/RegistryInfo.tsx (1)

21-22: Acknowledged: Complex calc expressions extracted to constants.

Extracting these responsive grid calculations to named constants improves readability compared to inline usage. While these expressions remain complex, your previous explanation about needing custom parameters for each usage justifies this approach.

🧹 Nitpick comments (4)
web/src/components/RegistryCard/RegistryInfo.tsx (2)

56-63: Consider more descriptive alt text.

The alt text "List Img" is generic. For better accessibility, consider using the title prop to provide more context, e.g., alt={title ? ${title} logo : "List logo"}.

       <img
-        className={cn("object-contain", isListView ? "w-10 h-10 mb-0" : "w-[125px] h-[125px] mb-2")}
+        className={cn("object-contain", isListView ? "w-10 h-10 mb-0" : "w-[125px] h-[125px] mb-2")}
         src={imageSrc}
-        alt="List Img"
+        alt={title ? `${title} logo` : "List logo"}
         onLoad={() => setImageLoaded(true)}
         onError={() => setImageSrc(getIpfsUrl(DEFAULT_LIST_LOGO))}
         style={{ display: imageLoaded ? "block" : "none" }}
       />

65-65: Consider using span or div instead of label.

The <label> element is semantically intended for form controls. Since this is displaying informational text, a <span> or <div> would be more semantically appropriate.

-      <label className="text-klerosUIComponentsSecondaryText">{totalItems} items</label>
+      <span className="text-klerosUIComponentsSecondaryText">{totalItems} items</span>
web/src/layout/Header/navbar/Menu/Settings/index.tsx (2)

28-36: Consider initializing tab from URL hash.

The component always initializes currentTab to 0, but the cleanup logic on line 35 suggests URL-based navigation is used (#notifications). Currently, if a user navigates directly to a URL with #notifications, the Settings panel will still open on the General tab instead of the Notifications tab.

Consider adding initialization logic:

 const Settings: React.FC<ISettings> = ({ toggleIsSettingsOpen }) => {
-  const [currentTab, setCurrentTab] = useState<number>(0);
+  const location = useLocation();
+  const [currentTab, setCurrentTab] = useState<number>(
+    location.hash.includes("#notifications") ? 1 : 0
+  );
   const containerRef = useRef(null);
-  const location = useLocation();
   const navigate = useNavigate();

47-47: Use semantic heading for Settings title.

The Settings title is currently a div. For better accessibility and document structure, use a semantic heading element like <h2>.

-      <div className="flex justify-center text-2xl mt-6 text-klerosUIComponentsPrimaryText">Settings</div>
+      <h2 className="flex justify-center text-2xl mt-6 text-klerosUIComponentsPrimaryText">Settings</h2>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b9dc11 and 573a1a2.

📒 Files selected for processing (2)
  • web/src/components/RegistryCard/RegistryInfo.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2025-10-31T20:37:01.310Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
🧬 Code graph analysis (2)
web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)
web/src/layout/Header/navbar/index.tsx (1)
  • ISettings (19-21)
web/src/components/RegistryCard/RegistryInfo.tsx (3)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/consts/index.ts (1)
  • DEFAULT_LIST_LOGO (23-23)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/components/RegistryCard/RegistryInfo.tsx (1)

34-47: Typo fixed from previous review.

The grid-cols value on line 38 now correctly uses max-content instead of the previous max.content typo. The combination of className-driven styling with inline styles for dynamic values (line 46) is appropriate here.

web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)

1-23: LGTM: Clean tab configuration and imports.

The addition of clsx and the updated TABS structure with explicit id, value, text, and content fields is appropriate for the Tailwind migration. Setting content: null correctly delegates content rendering to the conditional logic below.

Copy link
Contributor

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

♻️ Duplicate comments (4)
web/src/pages/Home/index.tsx (1)

15-20: Template literal interpolation may still prevent Tailwind from detecting the class.

While moving the class to a constant is an improvement over the previous approach, wrapping it in a template literal (${landscapeInlinePaddingCalc}) can still be unreliable for Tailwind's build-time scanner. The safest approach is to pass the string directly to clsx without template literal wrapping.

Apply this diff to pass the constant directly to clsx:

       <div
         className={clsx(
           "w-full max-w-landscape mx-auto bg-klerosUIComponentsLightBackground px-4 pt-4 pb-10",
-          `${landscapeInlinePaddingCalc} lg:pb-[60px]`
+          landscapeInlinePaddingCalc,
+          "lg:pb-[60px]"
         )}
       >

Alternatively, if Tailwind still fails to detect the class after this change, use the inline style approach suggested in the previous review comment.

web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)

48-54: Major: Missing currentValue prop breaks controlled component pattern.

The Tabs component receives a callback to update currentTab but doesn't receive the current state back via currentValue. This prevents the Tabs UI from reflecting programmatic state changes and breaks standard controlled component behavior.

Apply this diff:

       <Tabs
         className={clsx(`py-0 ${inlinePaddingCalc}`, `max-w-[660px] w-[86vw] ${landscapeWidthCalc}`)}
+        currentValue={currentTab}
         items={TABS}
         callback={(_, value: number) => {
           setCurrentTab(value);
         }}
       />
web/src/components/RegistryCard/RegistryInfo.tsx (1)

67-77: Button without onClick nested in clickable parent remains unresolved.

This Button component still has no onClick handler and is rendered inside a clickable Card parent, creating nested interactive elements that violate accessibility guidelines. The previous critical issue identified this problem and suggested replacing the Button with a non-interactive <span> or removing it entirely.

web/src/layout/Header/navbar/DappList.tsx (1)

92-103: ARIA attributes still missing—modal is inaccessible to screen readers.

This issue was previously flagged but remains unaddressed. The modal container needs role="dialog", aria-modal="true", and aria-labelledby to be properly accessible to assistive technologies.

Apply this diff to add the required ARIA attributes:

     <div
       ref={containerRef}
+      role="dialog"
+      aria-modal="true"
+      aria-labelledby="dapp-list-heading"
       className={clsx(
         "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 w-[86vw] max-w-[480px]",
         "border border-klerosUIComponentsStroke rounded-[3px]",
         "bg-klerosUIComponentsWhiteBackground shadow-[0px_2px_3px_rgba(0,0,0,0.06)]",
         "[&_svg]:visible",
         "lg:mt-16 lg:top-0 lg:left-0 lg:right-auto lg:transform-none lg:translate-x-0 lg:max-h-[80vh]",
         landscapeWidthCalc
       )}
     >
-      <h1 className="pt-6 text-2xl font-semibold leading-8">Kleros Solutions</h1>
+      <h1 id="dapp-list-heading" className="pt-6 text-2xl font-semibold leading-8">Kleros Solutions</h1>
🧹 Nitpick comments (2)
web/src/components/RegistryCard/RegistryInfo.tsx (1)

21-22: Consider using responsiveSize for grid columns to match columnGap approach.

Line 46 successfully uses responsiveSize with custom parameters in an inline style for columnGap. For consistency and improved readability, apply the same pattern to the grid columns calculation instead of the complex calc() expression in landscapeGridColsCalc.

Apply this pattern to make the responsive columns consistent with the columnGap approach:

-const landscapeGridColsCalc =
-  "lg:grid-cols-[auto_1fr_calc(80px+(100-80)*(min(max(100vw,900px),1250px)-900px)/(1250-900))_calc(100px+(150-100)*(min(max(100vw,900px),1250px)-900px)/(1250-900))_max-content]";

Then update the component style prop:

     <div
       className={cn(
         "flex flex-col justify-center items-center gap-2 h-[calc(100%-45px)]",
         isListView && [
           "grid grid-cols-[21px_max-content_1fr_max-content] grid-rows-[repeat(3,min-content)] gap-y-4",
           "w-full h-max lg:h-16 p-4",
           "[&_h3]:col-span-4 [&_img]:col-span-4",
           "lg:justify-between lg:grid-rows-[1fr] lg:px-8",
           "lg:[&_img]:col-span-1 lg:[&_h3]:col-span-2",
-          landscapeGridColsCalc,
+          "lg:grid-cols-[auto_1fr_var(--col-3)_var(--col-4)_max-content]",
         ]
       )}
-      style={{ columnGap: isListView ? responsiveSize(8, 24, 900) : undefined }}
+      style={
+        isListView
+          ? {
+              columnGap: responsiveSize(8, 24, 900),
+              "--col-3": responsiveSize(80, 100, 900, 1250),
+              "--col-4": responsiveSize(100, 150, 900, 1250),
+            }
+          : undefined
+      } as React.CSSProperties
     >

This approach keeps the custom parameters while improving maintainability.

Also applies to: 46-46

web/src/layout/Header/navbar/DappList.tsx (1)

95-95: Consolidate width controls to a single container.

Both the outer modal container (line 95: w-[86vw], max-w-[480px], landscapeWidthCalc) and the inner grid container (line 106: width: responsiveSize(300, 480), max-w-[480px], min-w-[300px]) set explicit widths. This creates redundancy and potential confusion about which container actually controls the final width.

Consider consolidating width control to the outer container and letting the inner grid inherit its width, or vice versa.

Option 1: Control width via outer container only (recommended)

       className={clsx(
-        "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 w-[86vw] max-w-[480px]",
+        "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 w-[86vw] max-w-[480px] min-w-[300px]",
         "border border-klerosUIComponentsStroke rounded-[3px]",
         "bg-klerosUIComponentsWhiteBackground shadow-[0px_2px_3px_rgba(0,0,0,0.06)]",
         "[&_svg]:visible",
         "lg:mt-16 lg:top-0 lg:left-0 lg:right-auto lg:transform-none lg:translate-x-0 lg:max-h-[80vh]",
         landscapeWidthCalc
       )}
     >
       <h1 className="pt-6 text-2xl font-semibold leading-8">Kleros Solutions</h1>
       <div
-        className="grid overflow-y-auto gap-y-2 gap-x-0.5 justify-items-center max-w-[480px] min-w-[300px] grid-cols-[repeat(auto-fit,minmax(100px,1fr))]"
+        className="grid overflow-y-auto gap-y-2 gap-x-0.5 justify-items-center w-full grid-cols-[repeat(auto-fit,minmax(100px,1fr))]"
-        style={{ padding: `4px ${responsiveSize(8, 24)} 16px`, width: responsiveSize(300, 480) }}
+        style={{ padding: `4px ${responsiveSize(8, 24)} 16px` }}
       >

Option 2: Control width via inner container only

       className={clsx(
-        "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 w-[86vw] max-w-[480px]",
+        "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-1",
         "border border-klerosUIComponentsStroke rounded-[3px]",
         "bg-klerosUIComponentsWhiteBackground shadow-[0px_2px_3px_rgba(0,0,0,0.06)]",
         "[&_svg]:visible",
-        "lg:mt-16 lg:top-0 lg:left-0 lg:right-auto lg:transform-none lg:translate-x-0 lg:max-h-[80vh]",
-        landscapeWidthCalc
+        "lg:mt-16 lg:top-0 lg:left-0 lg:right-auto lg:transform-none lg:translate-x-0 lg:max-h-[80vh]"
       )}
     >

Also applies to: 106-106

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 573a1a2 and 4e96cdc.

📒 Files selected for processing (5)
  • web/src/components/RegistryCard/RegistryInfo.tsx (3 hunks)
  • web/src/components/StatDisplay.tsx (2 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/pages/Home/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/components/StatDisplay.tsx
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-10-31T19:54:12.499Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/Header/DesktopHeader.tsx:43-44
Timestamp: 2025-10-31T19:54:12.499Z
Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).

Applied to files:

  • web/src/layout/Header/navbar/DappList.tsx
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2025-10-31T20:37:01.310Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
🧬 Code graph analysis (2)
web/src/components/RegistryCard/RegistryInfo.tsx (3)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/consts/index.ts (1)
  • DEFAULT_LIST_LOGO (23-23)
web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)
web/src/layout/Header/navbar/index.tsx (1)
  • ISettings (19-21)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (5)
web/src/layout/Header/navbar/Menu/Settings/index.tsx (4)

1-9: LGTM! Clean imports for Tailwind migration.

The addition of clsx for class name composition and the use of Tabs from the updated UI library align well with the migration objectives.


10-27: LGTM! Well-structured constants improve readability.

The TABS array structure with explicit IDs and the extracted calculation constants enhance maintainability. The constants contain complete Tailwind class strings, ensuring proper JIT compilation.


28-29: LGTM! Component signature correctly simplified.

The removal of initialTab aligns with the updated ISettings interface, and the default tab state initialization is appropriate.


39-46: Critical: Invalid z-index utility z-1.

Tailwind's default z-index scale does not include z-1. Use z-[1] for an arbitrary z-index value of 1, or a standard token like z-10.

Apply this diff:

       className={clsx(
-        "flex flex-col absolute max-h-[80vh] overflow-y-auto top-[5%] left-1/2 transform -translate-x-1/2 z-1",
+        "flex flex-col absolute max-h-[80vh] overflow-y-auto top-[5%] left-1/2 transform -translate-x-1/2 z-[1]",
         "bg-klerosUIComponentsWhiteBackground border border-solid border-klerosUIComponentsStroke rounded-[3px]",
         "lg:mt-16 lg:top-0 lg:right-0 lg:left-auto lg:transform-none lg:translate-x-0"
       )}
⛔ Skipped due to learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b
web/src/components/RegistryCard/RegistryInfo.tsx (1)

48-63: LGTM! Image loading and error handling implemented correctly.

The skeleton placeholder, image loading state management, and error fallback to DEFAULT_LIST_LOGO are well implemented.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 14, 2025
Copy link
Contributor

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

♻️ Duplicate comments (1)
web/src/components/RegistryCard/RegistryInfo.tsx (1)

67-77: “Open” Button is non-functional and may still be a nested interactive element.

Button is rendered with text="Open" and an Icon but without onClick, href, or similar, so it either:

  • Looks clickable but does nothing, or
  • Ends up as a nested interactive control if the parent card handles navigation (as in the earlier review), which is an accessibility anti-pattern.

Consider one of these instead:

  • If it should trigger navigation, wire it to the same handler as the card (or move the handler down to this Button).
  • If it’s only a visual label within a clickable card, replace it with a non-interactive element (e.g., <span> with equivalent styling, or use a non-button variant from the UI library if available) so it doesn’t appear as an inert button.

Example sketch replacing it with a non-interactive span:

-      {isListView && (
-        <Button
-          className={cn(
-            "flex-row-reverse gap-2 p-0 bg-transparent",
-            "focus:bg-transparent hover:bg-transparent",
-            "[&_.button-text]:text-klerosUIComponentsPrimaryBlue [&_.button-text]:font-normal [&_.button-svg]:fill-klerosUIComponentsSecondaryPurple"
-          )}
-          text="Open"
-          Icon={ArrowIcon}
-        />
-      )}
+      {isListView && (
+        <span
+          className={cn(
+            "flex flex-row-reverse items-center gap-2 p-0 bg-transparent",
+            "text-klerosUIComponentsPrimaryBlue font-normal"
+          )}
+        >
+          <ArrowIcon className="fill-klerosUIComponentsSecondaryPurple" />
+          <span>Open</span>
+        </span>
+      )}

Please adjust the exact classes to match your design and any constraints of @kleros/ui-components-library.

🧹 Nitpick comments (7)
web/src/components/Search.tsx (3)

39-39: Question: Is the z-0 class necessary?

The z-0 class explicitly sets z-index: 0 on this container. Unless there's a specific stacking context issue you're addressing, this might be unnecessary and could be removed for cleaner code.


48-84: Consider reducing duplication in the items array.

Each item in the DropdownSelect has both id and itemValue set to the same JSON.stringify'd value, which creates unnecessary duplication across all six items. This makes the code more verbose and harder to maintain.

Consider refactoring to derive these values dynamically:

+const filterItems = [
+  { filter: {}, text: "All Status", dot: "grey" as const },
+  { filter: List_filters.Active, text: "Active", dot: "orange" as const },
+  { filter: List_filters.Pending, text: "Pending", dot: "blue" as const },
+  { filter: List_filters.Disputed, text: "Disputed", dot: "purple" as const },
+  { filter: List_filters.Included, text: "Included", dot: "green" as const },
+  { filter: List_filters.Removed, text: "Removed", dot: "red" as const },
+].map(item => {
+  const stringified = JSON.stringify(item.filter);
+  return { ...item, id: stringified, itemValue: stringified };
+});
+
 <DropdownSelect
-  items={[
-    { id: JSON.stringify({}), text: "All Status", dot: "grey", itemValue: JSON.stringify({}) },
-    {
-      id: JSON.stringify(List_filters.Active),
-      text: "Active",
-      dot: "orange",
-      itemValue: JSON.stringify(List_filters.Active),
-    },
-    ...
-  ]}
+  items={filterItems}
   defaultSelectedKey={JSON.stringify(decodedFilter)}
   callback={(item) => handleStatusChange(item.itemValue)}
 />

31-35: Tighten the type signature for better type safety.

The value parameter is typed as string | number, but all itemValue properties in the DropdownSelect are strings (from JSON.stringify). The cast as string on line 32 confirms this.

Apply this diff to improve type precision:

-const handleStatusChange = (value: string | number) => {
-  const filter = JSON.parse(value as string);
+const handleStatusChange = (value: string) => {
+  const filter = JSON.parse(value);
   const encodedFilter = encodeListURIFilter(filter);
   navigate(`${location}/1/${order}/${encodedFilter}${keywords ? "?keywords=" + keywords : ""}`);
 };
web/src/components/RegistriesDisplay/RegistriesGrid.tsx (1)

56-56: Consider simplifying the complex grid-template-columns calculation.

The inline CSS calculation grid-cols-[repeat(auto-fill,minmax(min(100%,max(274px,(100%-16px*2)/3)),1fr))] is difficult to read and maintain. This appears to create a responsive 3-column grid with minimum card width of 274px.

Consider one of these approaches:

  1. Extract to a CSS custom property (if Tailwind v4 with @theme is in use):
/* In global.css or component CSS */
@theme {
  --grid-cols-registry: repeat(auto-fill, minmax(min(100%, max(274px, (100% - 16px * 2) / 3)), 1fr));
}
-<div className="grid grid-cols-[repeat(auto-fill,minmax(min(100%,max(274px,(100%-16px*2)/3)),1fr))] items-center gap-4">
+<div className="grid grid-cols-registry items-center gap-4">
  1. Use simpler Tailwind utilities if the complex calculation isn't critical:
-<div className="grid grid-cols-[repeat(auto-fill,minmax(min(100%,max(274px,(100%-16px*2)/3)),1fr))] items-center gap-4">
+<div className="grid grid-cols-[repeat(auto-fill,minmax(274px,1fr))] items-center gap-4">
web/src/pages/AllLists/index.tsx (1)

13-13: Simplify or document the complex padding calculation.

The landscapePaddingCalc formula is difficult to parse: lg:p-[48px_calc(0px+(132-0)*(min(max(100vw,375px),1250px)-375px)/(1250-375))_60px]. This appears to implement fluid spacing between 375px and 1250px viewport widths.

Consider one of these approaches:

  1. Add a clarifying comment:
+// Responsive padding: 48px top, fluid horizontal (0-132px for 375-1250px viewports), 60px bottom
 const landscapePaddingCalc = "lg:p-[48px_calc(0px+(132-0)*(min(max(100vw,375px),1250px)-375px)/(1250-375))_60px]";
  1. Extract to CSS custom property (if using Tailwind v4 @theme):
/* In global.css */
@theme {
  --padding-landscape: 48px calc(0px + (132 - 0) * (min(max(100vw, 375px), 1250px) - 375px) / (1250 - 375)) 60px;
}
-const landscapePaddingCalc = "lg:p-[48px_calc(0px+(132-0)*(min(max(100vw,375px),1250px)-375px)/(1250-375))_60px]";
+const landscapePaddingCalc = "lg:p-landscape";
  1. Use Tailwind's built-in fluid spacing if appropriate for your use case.
web/src/components/StatsAndFilters/Filters.tsx (1)

48-61: Remove redundant isDesktop check in ListIcon onClick handler.

Both icons are already rendered inside isDesktop && isListFilter (line 45), making the additional isDesktop check in the ListIcon's onClick handler (lines 56-58) redundant. The GridIcon doesn't have this extra guard, creating an inconsistency.

Apply this diff to simplify the ListIcon handler:

           <ListIcon
             className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100"
-            onClick={() => {
-              if (isDesktop) {
-                setIsListView(true);
-              }
-            }}
+            onClick={() => setIsListView(true)}
           />
web/src/components/RegistryCard/RegistryInfo.tsx (1)

21-47: Constant for complex grid calc helps; consider documenting intent.

Extracting the long calc() expression into landscapeGridColsCalc is a good step for readability. The formula is still non-trivial, though; a short comment (e.g., “interpolate 80→100px and 100→150px over 900–1250px viewport in list view”) above the constant would make future tweaks safer.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e96cdc and fdf4c0a.

📒 Files selected for processing (10)
  • web/src/components/RegistriesDisplay/RegistriesGrid.tsx (3 hunks)
  • web/src/components/RegistryCard/RegistryInfo.tsx (3 hunks)
  • web/src/components/RegistryCard/StatusBanner.tsx (2 hunks)
  • web/src/components/Search.tsx (2 hunks)
  • web/src/components/StatsAndFilters/Filters.tsx (1 hunks)
  • web/src/components/StatsAndFilters/Stats.tsx (1 hunks)
  • web/src/components/StatsAndFilters/index.tsx (1 hunks)
  • web/src/pages/AllLists/RegistriesFetcher.tsx (1 hunks)
  • web/src/pages/AllLists/StyledBreadcrumb.tsx (2 hunks)
  • web/src/pages/AllLists/index.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (4)
web/src/components/RegistriesDisplay/RegistriesGrid.tsx (1)
web/src/utils/index.ts (1)
  • isUndefined (5-5)
web/src/components/RegistryCard/StatusBanner.tsx (1)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/RegistryCard/RegistryInfo.tsx (3)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/utils/getIpfsUrl.ts (1)
  • getIpfsUrl (4-8)
web/src/consts/index.ts (1)
  • DEFAULT_LIST_LOGO (23-23)
web/src/components/Search.tsx (1)
web/src/consts/filters.ts (1)
  • List_filters (5-11)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (4)
web/src/components/Search.tsx (1)

85-89: LGTM!

The Button components have been successfully migrated to use direct SVG imports (PaperIcon, PlusIcon) instead of styled wrappers. The implementation is clean and the conditional rendering logic is preserved correctly.

web/src/pages/AllLists/StyledBreadcrumb.tsx (1)

37-37: LGTM! Clean migration from styled-component to Tailwind.

The HomeIcon styling correctly uses a custom fill class for theming and precise spacing with an arbitrary value.

web/src/components/StatsAndFilters/index.tsx (1)

6-9: LGTM!

The migration to Tailwind utility classes is clean and the flexbox layout is properly configured.

web/src/components/RegistryCard/StatusBanner.tsx (1)

42-71: Status-based style maps are clear and maintainable.

Splitting the status styles into borderAndBgStyles and dotAndFrontColorStyles and wiring them into cn(...) removes the nested conditionals and keeps StatusBanner styling easy to extend while preserving the existing visual behavior. Looks good.

Copy link
Contributor

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

♻️ Duplicate comments (2)
web/src/pages/AllLists/RegistriesFetcher.tsx (1)

14-14: LGTM! Magic number successfully extracted to shared constant.

The introduction of LG_BREAKPOINT addresses the DRY principle violation flagged in previous reviews. The breakpoint is now centralized and can be maintained in one location.

Also applies to: 24-24

web/src/components/RegistriesDisplay/RegistriesGrid.tsx (1)

12-12: LGTM! Magic number successfully extracted to shared constant.

The use of LG_BREAKPOINT addresses the DRY principle violation flagged in previous reviews, ensuring consistent breakpoint behavior across components.

Also applies to: 38-38

🧹 Nitpick comments (1)
web/src/components/RegistriesDisplay/RegistriesGrid.tsx (1)

57-57: Consider simplifying or extracting the complex grid layout expression.

The grid-cols arbitrary value is quite complex and may be difficult to maintain:

grid-cols-[repeat(auto-fill,minmax(min(100%,max(274px,(100%-16px*2)/3)),1fr))]

Consider one of these approaches:

  1. Extract to a custom CSS class in global.css with a semantic name like .registry-grid
  2. Use Tailwind's @apply directive to create a reusable utility
  3. Document the calculation logic with a comment explaining the responsive behavior

Example using a custom class:

/* global.css */
.registry-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, max(274px, (100% - 16px * 2) / 3)), 1fr));
  gap: 1rem;
  align-items: center;
}

Then use it as:

<div className="registry-grid">
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fdf4c0a and 62b2f36.

📒 Files selected for processing (5)
  • web/src/components/RegistriesDisplay/RegistriesGrid.tsx (4 hunks)
  • web/src/hooks/useIsDesktop.tsx (1 hunks)
  • web/src/pages/AllLists/RegistriesFetcher.tsx (2 hunks)
  • web/src/pages/AllLists/StyledBreadcrumb.tsx (2 hunks)
  • web/src/styles/breakpoints.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/pages/AllLists/StyledBreadcrumb.tsx
  • web/src/hooks/useIsDesktop.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (2)
web/src/components/RegistriesDisplay/RegistriesGrid.tsx (2)
web/src/styles/breakpoints.ts (1)
  • LG_BREAKPOINT (1-1)
web/src/utils/index.ts (1)
  • isUndefined (5-5)
web/src/pages/AllLists/RegistriesFetcher.tsx (1)
web/src/styles/breakpoints.ts (1)
  • LG_BREAKPOINT (1-1)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 14, 2025
Copy link
Contributor

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1)

17-35: Fix type signature mismatch for button click handler.

The resendVerificationEmail callback is typed to receive React.FormEvent<HTMLFormElement>, but it's being used as an onClick handler for a Button component (line 52) which provides React.MouseEvent<HTMLButtonElement>. This type mismatch should cause TypeScript errors.

Apply this diff to fix the type signature:

  const resendVerificationEmail = useCallback(
-   (e: React.FormEvent<HTMLFormElement>) => {
+   (e: React.MouseEvent<HTMLButtonElement>) => {
      e.preventDefault();
      if (!user) return;
      infoToast(`Sending verification email ...`);
      updateEmail({ newEmail: user.email })
        .then(async (res) => {
          if (res) {
            successToast("Verification email sent successfully!");
            toggleIsSettingsOpen();
          }
        })
        .catch((err) => {
          console.log(err);
          errorToast(`Failed to send verification email: ${err?.message}`);
        });
    },
    [user, updateEmail, toggleIsSettingsOpen]
  );
♻️ Duplicate comments (2)
web/src/layout/Header/navbar/DappList.tsx (2)

92-103: Add ARIA attributes for modal accessibility.

This modal container lacks proper accessibility attributes. Screen readers and assistive technologies require role="dialog", aria-modal="true", and aria-labelledby to properly identify and navigate the modal.

Apply this diff:

     <div
       ref={containerRef}
+      role="dialog"
+      aria-modal="true"
+      aria-labelledby="dapp-list-heading"
       className={clsx(
         "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 w-[86vw] max-w-[480px]",
         "border border-klerosUIComponentsStroke rounded-[3px]",
         "bg-klerosUIComponentsWhiteBackground shadow-custom",
         "[&_svg]:visible",
         "lg:mt-16 lg:top-0 lg:left-0 lg:right-auto lg:transform-none lg:translate-x-0 lg:max-h-[80vh]",
         landscapeWidthCalc
       )}
     >
-      <h1 className="pt-6 text-2xl font-semibold leading-8">Kleros Solutions</h1>
+      <h1 id="dapp-list-heading" className="pt-6 text-2xl font-semibold leading-8">Kleros Solutions</h1>

95-95: Modal z-index is too low.

Line 95 uses z-1 which sets z-index: 1—insufficient for a modal that must appear above all content. Other UI elements with higher z-indices could obscure this modal.

Apply this diff to use a proper modal z-index:

-        "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 w-[86vw] max-w-[480px]",
+        "flex flex-col items-center absolute max-h-[340px] top-[5%] left-1/2 transform -translate-x-1/2 z-50 w-[86vw] max-w-[480px]",
🧹 Nitpick comments (4)
web/src/components/ItemCard/ItemField/FileField.tsx (1)

6-10: Optional: Remove unused detailed prop.

The detailed prop is defined in the interface but never destructured or used in the component. Consider removing it for clarity.

Apply this diff:

 export interface IFileField {
   value: string;
   label: string;
-  detailed?: boolean;
 }
web/src/components/RegistryInfo/AliasDisplay.tsx (1)

24-28: Remove unnecessary &nbsp; entity.

The &nbsp; on line 26 appears redundant since the parent container (line 23) already uses gap-2 to space flex items. This entity adds extra whitespace that's likely unnecessary with Tailwind's spacing utilities.

Apply this diff to remove the unnecessary spacing:

-      {isLoading ? <Skeleton width={30} height={24} /> : <AddressOrName address={finalAddress} />}&nbsp;
+      {isLoading ? <Skeleton width={30} height={24} /> : <AddressOrName address={finalAddress} />}

Note: The arbitrary selector [&>label] on line 25 correctly targets the <label> element rendered by AddressOrName and is a valid Tailwind pattern. The custom color class text-klerosUIComponentsPrimaryText should resolve correctly if CSS variables from @kleros/ui-components-library are properly imported via the source directive in global.css. Based on learnings

web/src/components/InformationCards/ItemInformationCard/index.tsx (1)

65-72: Remove redundant styling on nested container.

The aliasContainerStyle is applied to both the outer container (line 65) and an inner div (line 68). Since the inner div only wraps AliasDisplay and doesn't need its own flex layout, the second application is redundant.

Apply this diff to simplify:

         {registerer?.id ? (
           <div className={aliasContainerStyle}>
             <small>Submitted by:</small>
             <Copiable copiableContent={registerer.id}>
-              <div className={aliasContainerStyle}>
-                <AliasDisplay address={registerer.id} />
-              </div>
+              <AliasDisplay address={registerer.id} />
             </Copiable>
           </div>
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1)

45-54: Consider refactoring brittle class targeting for text styling.

The text prop is confirmed as a valid and documented API for the Button component from @kleros/ui-components-library. However, the arbitrary selector syntax on lines 47-50 remains fragile:

[&_.button-text]:text-sm [&_.button-text]:font-normal

This targets internal component DOM structure that could change in future library updates, breaking the styling.

Suggested alternatives:

  • Check if the Button component's size prop can control text sizing instead of targeting internal classes
  • If custom text styling is necessary, consider wrapping the Button in a custom component with proper styling rather than relying on internal class names
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62b2f36 and c5b2016.

📒 Files selected for processing (27)
  • web/src/components/ActionButton/ExecuteButton.tsx (1 hunks)
  • web/src/components/ActionButton/Modal/ChallengeItemModal.tsx (2 hunks)
  • web/src/components/ActionButton/Modal/DepositRequired.tsx (1 hunks)
  • web/src/components/ActionButton/Modal/Header.tsx (1 hunks)
  • web/src/components/ActionButton/index.tsx (2 hunks)
  • web/src/components/ChainIcon.tsx (1 hunks)
  • web/src/components/ConnectWallet/index.tsx (2 hunks)
  • web/src/components/InformationCards/ItemInformationCard/FieldsDisplay.tsx (3 hunks)
  • web/src/components/InformationCards/ItemInformationCard/index.tsx (4 hunks)
  • web/src/components/InformationCards/StatusDisplay.tsx (2 hunks)
  • web/src/components/ItemCard/ItemField/AddressField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/BooleanField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/ChainField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/FileField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/ImageField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/LinkField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/LongTextField.tsx (2 hunks)
  • web/src/components/ItemCard/ItemField/NumberField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/TextField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/index.tsx (1 hunks)
  • web/src/components/Modal.tsx (2 hunks)
  • web/src/components/RegistryInfo/AliasDisplay.tsx (2 hunks)
  • web/src/components/WithHelpTooltip.tsx (2 hunks)
  • web/src/global.css (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • web/src/components/ItemCard/ItemField/BooleanField.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/layout/Header/navbar/Menu/Help.tsx
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.955Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-11-14T22:12:39.955Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.955Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.

Applied to files:

  • web/src/layout/Header/navbar/DappList.tsx
  • web/src/global.css
📚 Learning: 2025-10-31T19:54:12.499Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/Header/DesktopHeader.tsx:43-44
Timestamp: 2025-10-31T19:54:12.499Z
Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).

Applied to files:

  • web/src/layout/Header/navbar/DappList.tsx
  • web/src/global.css
📚 Learning: 2025-10-31T20:37:01.310Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b

Applied to files:

  • web/src/layout/Header/navbar/DappList.tsx
  • web/src/global.css
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.

Applied to files:

  • web/src/components/ItemCard/ItemField/LongTextField.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:42:03.737Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/components/ActionButton/Modal/EvidenceUpload.tsx:74-82
Timestamp: 2024-11-04T13:42:03.737Z
Learning: In `web/src/components/ActionButton/Modal/EvidenceUpload.tsx`, the `uploadFile` function already manages error handling and logging, so additional error handling after calling it is unnecessary.

Applied to files:

  • web/src/components/ActionButton/Modal/ChallengeItemModal.tsx
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
📚 Learning: 2025-11-06T23:06:51.514Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/global.css:3-3
Timestamp: 2025-11-06T23:06:51.514Z
Learning: In Tailwind v4, you can use `import "tailwindcss" source("path")` syntax to control automatic content detection by passing the source() argument directly on the import statement. This is in addition to the standalone `source "path"` directive. Both syntaxes are valid: `import "tailwindcss" source("../../node_modules/kleros/ui-components-library");` and `source "../../node_modules/kleros/ui-components-library";`

Applied to files:

  • web/src/global.css
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.

Applied to files:

  • web/src/components/ItemCard/ItemField/AddressField.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
🧬 Code graph analysis (6)
web/src/components/ItemCard/ItemField/LongTextField.tsx (1)
web/src/components/Overlay.tsx (1)
  • Overlay (3-5)
web/src/components/InformationCards/StatusDisplay.tsx (3)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/RegistryCard/StatusBanner.tsx (1)
  • getStatusLabel (11-26)
web/src/utils/date.ts (1)
  • secondsToDayHourMinute (10-16)
web/src/components/InformationCards/ItemInformationCard/index.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
  • Policies (74-104)
web/src/components/ActionButton/Modal/DepositRequired.tsx (1)
web/src/utils/format.ts (1)
  • formatETH (20-21)
web/src/components/RegistryInfo/AliasDisplay.tsx (2)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/ConnectWallet/AccountDisplay.tsx (2)
  • IdenticonOrAvatar (17-35)
  • AddressOrName (41-51)
web/src/components/Modal.tsx (1)
web/src/utils/index.ts (1)
  • cn (44-46)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (26)
web/src/components/ItemCard/ItemField/FileField.tsx (1)

15-18: LGTM! Clean migration to Tailwind.

The replacement of the styled Container with <Link className="flex gap-2"> is correct. The Tailwind utilities properly replicate the flexbox layout, and all functionality (routing, click handling) is preserved.

web/src/components/RegistryInfo/AliasDisplay.tsx (3)

1-11: LGTM!

The imports and interface are clean. Adding the optional className prop follows good composition patterns for reusable components.


13-21: LGTM!

The component signature correctly accepts the new className prop, and the ENS address resolution logic is preserved without modification.


23-23: LGTM!

Good use of the cn utility to merge the optional external className with the base Tailwind classes. The min-h-8 provides appropriate vertical spacing for the 24px avatar.

web/src/components/InformationCards/ItemInformationCard/FieldsDisplay.tsx (1)

6-6: LGTM! Clean migration to Tailwind.

The replacement of the styled FieldsContainer with a plain div and the fieldsContainerStyle constant is straightforward and correct. The Tailwind utilities used are standard and appropriate for the flexbox layout.

Also applies to: 41-48, 51-61, 63-67

web/src/components/InformationCards/StatusDisplay.tsx (1)

10-24: Color mappings look good.

The colorStyles and dotStyles mappings correctly cover all Status enum values and use the appropriate color variables from klerosUIComponents. The arbitrary variant syntax for pseudo-elements is valid for Tailwind v4.

web/src/components/InformationCards/ItemInformationCard/index.tsx (2)

59-62: Mixing className and inline style is acceptable here.

The hr element uses both className for border styling and an inline style prop for dynamic margins via responsiveSize. This mixing is justified since responsiveSize provides computed responsive values that can't be expressed purely in Tailwind utilities.


42-87: Overall structure migrated correctly.

The component successfully replaces styled-components with Tailwind utilities while maintaining the same layout hierarchy and functionality. The use of the cn utility for className composition is appropriate throughout.

web/src/components/ItemCard/ItemField/ChainField.tsx (1)

15-18: Clean migration to Tailwind utilities.

The conversion from styled-components to Tailwind classes is well executed. The flex layout with gap and alignment matches the typical pattern for icon-text combinations.

web/src/components/ChainIcon.tsx (1)

46-50: The custom color configuration is verified and working correctly.

The fill-klerosUIComponentsSecondaryPurple color is already successfully used throughout the codebase, including the identical [&_svg]:fill-klerosUIComponentsSecondaryPurple pattern in StatDisplay.tsx and Highlights/Header.tsx. The @source directive in global.css properly enables these colors from the @kleros/ui-components-library. The ChainIcon implementation is correct and follows established patterns.

web/src/components/ConnectWallet/index.tsx (2)

32-44: LGTM!

The isDisabled prop correctly prevents users from clicking the Connect button while the AppKit modal is already open, providing good UX.


23-28: Verify if isDisabled is needed when isLoading is set.

Both isLoading and isDisabled are set to the same value on line 25. Many UI libraries automatically disable buttons during loading states, but I cannot definitively confirm whether the @kleros/ui-components-library v3 Button component implements this behavior.

Please verify in the library's Storybook or source code whether the Button auto-disables when isLoading={true}, as setting both props to the same value may be redundant.

web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (2)

1-8: LGTM: Clean migration to Tailwind-compatible imports.

The addition of clsx on line 8 is appropriate for composing conditional class names, and the Button import from the ui-components-library aligns with the migration objectives.


38-39: Custom Tailwind color classes are properly configured.

Verification confirms the custom color utilities border-klerosUIComponentsStroke and fill-klerosUIComponentsPrimaryBlue are correctly configured:

  • global.css includes the @source directive pointing to @kleros/ui-components-library
  • global.css imports the library's theme via @import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css"
  • web/package.json lists "@kleros/ui-components-library": "^3.6.0" as a dependency
  • These colors are consistently used across 20+ files in the codebase, confirming the setup is functional

The configuration follows Tailwind v4 best practices for external library CSS variables. No action required.

web/src/components/ActionButton/Modal/Header.tsx (1)

8-8: LGTM! Clean migration to Tailwind.

The replacement of the styled component with a plain h1 element and m-0 utility class is correct and maintains the original styling intent.

web/src/components/ActionButton/index.tsx (1)

59-59: Same verification needed for isDisabled prop.

Ensure the Button component API from @kleros/ui-components-library v3 accepts isDisabled as shown here.

web/src/layout/Header/navbar/DappList.tsx (1)

104-107: Inline styles correctly handle responsive dimensions.

The use of inline style for dynamic padding and width values is the correct approach since Tailwind cannot generate utilities for runtime-computed values. The responsiveSize helper properly handles the responsive behavior.

web/src/components/ItemCard/ItemField/index.tsx (1)

84-95: LGTM! Clean Tooltip migration.

The replacement of styled components with a plain div and direct Tooltip usage is well-executed. The WarningIcon dimensions are correctly passed as props, and the layout classes properly handle the flex container.

web/src/components/WithHelpTooltip.tsx (1)

12-17: LGTM! Responsive sizing correctly implemented.

The migration from styled components to Tailwind classes is clean. The responsive sizing with the lg: breakpoint for width and height properly handles different viewport sizes.

Based on learnings

web/src/components/ItemCard/ItemField/TextField.tsx (1)

12-18: LGTM! Straightforward migration.

The replacement of the styled Container with a plain <p> element using m-0 is correct and preserves the original behavior while simplifying the component structure.

web/src/components/ItemCard/ItemField/NumberField.tsx (1)

12-20: LGTM! Clean flex layout migration.

The replacement of the styled Container with a plain <p> element using Tailwind utilities (flex gap-2 items-center m-0) is correct and maintains proper spacing and alignment.

web/src/components/Modal.tsx (1)

4-29: LGTM! Clean Tailwind migration.

The refactor from StyledModal to a plain div with Tailwind utility classes is well-executed. The cn utility correctly merges incoming className props, maintaining customization flexibility while standardizing the base modal styling.

web/src/components/ActionButton/Modal/ChallengeItemModal.tsx (1)

127-127: LGTM! Appropriate spacing adjustment.

The className="gap-8" addition provides proper vertical spacing between the modal's child sections, maintaining visual hierarchy and readability.

web/src/components/ActionButton/ExecuteButton.tsx (1)

29-29: LGTM! Correct API migration.

The prop rename to isDisabled correctly adapts to the @kleros/ui-components-library v3 Button API while maintaining backward compatibility with the component's external disabled prop.

web/src/components/ItemCard/ItemField/LongTextField.tsx (2)

5-14: LGTM! Clean refactor to Tailwind.

The migration from styled-components to Tailwind utility classes is well-executed. The TextArea component with isDisabled correctly provides a read-only full-screen view, and the Modal padding override (p-0) appropriately removes default padding for the full-height display.


27-39: LGTM! Appropriate inline styling migration.

The replacement of styled containers with plain elements and Tailwind classes maintains the same functionality and visual appearance. The "Read More" label correctly uses cursor-pointer and theme color classes for interactive styling.

Copy link
Contributor

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

♻️ Duplicate comments (1)
web/src/components/InformationCards/StatusDisplay.tsx (1)

18-24: Critical: Dot indicator still won't render - duplicate of previous review.

The dotStyles mapping uses selectors like [&_.dot::before]:bg-klerosUIComponentsPrimaryBlue that target a descendant with class .dot, but the label at lines 60-69 contains no such element. While line 63 creates a ::before pseudo-element with size and shape, it has no background color because the dotStyles selectors don't match, making the status indicator invisible.

The previous review already provided a fix. Alternatively, you could simplify by changing dotStyles to directly target the label's ::before:

 const dotStyles: Record<Status, string> = {
-  [Status.RegistrationPending]: "[&_.dot::before]:bg-klerosUIComponentsPrimaryBlue",
-  [Status.ClearingPending]: "[&_.dot::before]:bg-klerosUIComponentsPrimaryBlue",
-  [Status.Disputed]: "[&_.dot::before]:bg-klerosUIComponentsSecondaryPurple",
-  [Status.Included]: "[&_.dot::before]:bg-klerosUIComponentsSuccess",
-  [Status.Removed]: "[&_.dot::before]:bg-klerosUIComponentsError",
+  [Status.RegistrationPending]: "before:bg-klerosUIComponentsPrimaryBlue",
+  [Status.ClearingPending]: "before:bg-klerosUIComponentsPrimaryBlue",
+  [Status.Disputed]: "before:bg-klerosUIComponentsSecondaryPurple",
+  [Status.Included]: "before:bg-klerosUIComponentsSuccess",
+  [Status.Removed]: "before:bg-klerosUIComponentsError",
 };

Also applies to: 60-69

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5b2016 and 5c38226.

📒 Files selected for processing (4)
  • web/src/components/InformationCards/StatusDisplay.tsx (2 hunks)
  • web/src/components/ItemCard/ItemField/AddressField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/ImageField.tsx (1 hunks)
  • web/src/components/ItemCard/ItemField/LinkField.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/ItemCard/ItemField/ImageField.tsx
  • web/src/components/ItemCard/ItemField/AddressField.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.955Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/components/InformationCards/StatusDisplay.tsx (3)
web/src/utils/index.ts (1)
  • cn (44-46)
web/src/components/RegistryCard/StatusBanner.tsx (1)
  • getStatusLabel (11-26)
web/src/utils/date.ts (1)
  • secondsToDayHourMinute (10-16)
⏰ 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: Redirect rules - curate-v2
  • GitHub Check: Header rules - curate-v2
  • GitHub Check: Pages changed - curate-v2
🔇 Additional comments (1)
web/src/components/ItemCard/ItemField/LinkField.tsx (1)

11-20: LGTM! Previous issue resolved.

The target attribute has been corrected to target="_blank" as suggested in the previous review. The migration from styled-components to Tailwind classes is clean, and all security considerations (rel="noopener noreferrer") and functionality (onClick stopPropagation) are properly preserved.

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.

Frontend migration to the major update of @kleros/ui-components-library v3 with Tailwind

2 participants