Skip to content

Conversation

@lukevella
Copy link
Owner

@lukevella lukevella commented Dec 11, 2025

Summary by CodeRabbit

  • New Features

    • Dialog component rebuilt with richer layout, header/footer/title slots and optional close control.
    • Form pattern consolidated with per-field messaging and a VoteSummary display.
  • Style Updates

    • Introduced centralized shared Tailwind styles and new global CSS; removed legacy app style files.
    • Wide visual refinements: shadows, radii, gradients, spacing, masks, width tokens and focus outline behavior.
  • Bug Fixes

    • Modal cancel/close action wired to trigger reliably.

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


Note

Upgrades the repo to Tailwind v4 with a shared Tailwind package, migrates global/postcss configs, and refactors UI components and forms to the new class/Focus patterns, alongside minor Next config and dependency updates.

  • Styling/Build:
    • Upgrade to Tailwind CSS v4 across apps; introduce shared package @rallly/tailwind-config (shared-styles.css, postcss.config.mjs).
    • Replace app-level style.css/tailwind.config.js with globals.css; switch PostCSS to @tailwindcss/postcss.
    • Update utilities to v4 syntax (e.g., bg-linear-to-*, mask-*, width tokens) with shadow/radius tweaks.
  • UI Library (packages/ui):
    • Refactor components (Button, Input, Dialog, Dropdown, Select, Tabs, Card, Sidebar, etc.) for new focus/outline, sizing, and aria states; export ./style.css.
    • Dialog API: explicit DialogOverlay/Portal, showCloseButton, Header/Footer/Title/Description components.
  • Apps (landing/web):
    • Migrate forms to FormControl pattern; remove per-input error props; add aria-invalid; numerous visual polish updates (shadows, gradients, masks).
    • Move layouts to import ./globals.css; tweak redirects (e.g., landing /profile).
    • Rewrite calendar CSS overrides using CSS vars instead of @apply.
  • Config:
    • Convert Next configs to typed ESM; update bundle analyzer usage; preserve Sentry integration.
  • Dependencies:
    • Bump/install tailwindcss@^4.1.18, @tailwindcss/postcss; update @next/env; remove legacy Tailwind/postcss deps; lockfile refresh.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Note

Other AI code review bot(s) detected

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

Walkthrough

Convert Next.js configs to ESM with types, centralize PostCSS/Tailwind via a new ESM tailwind-config, remove per-app Tailwind configs/styles, migrate many Tailwind utility/selector tokens, and refactor core UI primitives (Dialog, Input, Form) and consumer form usages.

Changes

Cohort / File(s) Summary
Next.js config (ESM migration)
apps/landing/next.config.ts, apps/web/next.config.ts
Migrate Next configs from CommonJS to ES modules, add NextConfig typing, use createBundleAnalyzer and export default ESM wiring.
PostCSS ESM re-exports
packages/tailwind-config/postcss.config.mjs, apps/landing/postcss.config.mjs, apps/web/postcss.config.mjs
Add ESM PostCSS modules that export a shared postcssConfig from @rallly/tailwind-config.
Removed legacy PostCSS files
apps/landing/postcss.config.js, apps/web/postcss.config.js
Delete CommonJS PostCSS config files that previously exported plugin maps.
Package manifests & deps
apps/landing/package.json, apps/web/package.json, packages/tailwind-config/package.json, packages/ui/package.json
Update Tailwind/PostCSS deps, convert packages/tailwind-config to ESM with an exports map, and change packages/ui public export mapping.
Tailwind config files removed
apps/landing/tailwind.config.js, apps/web/tailwind.config.js, packages/ui/tailwind.config.js, packages/tailwind-config/tailwind.config.js
Remove per-app and shared CommonJS Tailwind config re-exports; no replacement CommonJS configs provided.
Shared Tailwind partials added
packages/tailwind-config/shared-styles.css
Add a shared Tailwind CSS partial defining theme variables, utilities, plugins, and base styles.
Global CSS added / legacy styles removed
apps/landing/src/app/[locale]/globals.css, apps/web/src/app/[locale]/globals.css, apps/web/src/globals.css, apps/landing/src/style.css (removed), apps/web/src/style.css (removed)
Add lightweight per-app globals importing Tailwind/shared config; remove large legacy src/style.css files.
PostCSS / Tailwind wiring in apps
apps/landing/postcss.config.mjs, apps/web/postcss.config.mjs, apps/landing/package.json
Wire apps to shared PostCSS config and add Tailwind dependency to landing.
Tailwind utility & selector migrations
many apps/..., many packages/ui/src/**/*.tsx
Mass classname/token updates: gradient tokens, shadow/rounded/backdrop adjustments, arbitrary token syntax changes, outline-noneoutline-hidden, data-selector normalization, and variable-width token forms.
Dialog API & implementation refactor
packages/ui/src/dialog.tsx, apps/web/src/components/modal/modal.tsx
Replace prior Dialog alias with explicit exported Dialog components/types (Dialog, DialogTrigger, DialogPortal, DialogContent, DialogOverlay, DialogClose, DialogHeader, DialogFooter, DialogTitle, DialogDescription) and update modal usage to DialogClose asChild.
Input & Form refactor; form consumer migrations
packages/ui/src/input.tsx, packages/ui/src/form.tsx, apps/web/src/components/new-participant-modal.tsx, many apps/web/src/app/...
Replace forwardRef Input with a plain function component and variant API, change InputProps typing, switch FormItem layout to grid/gap, adopt unified Form/FormField/FormItem pattern and remove many inputs' inline error props.
React Big Calendar overrides → explicit CSS
apps/web/src/components/forms/poll-options-form/rbc-overrides.css
Replace Tailwind @apply directives with explicit CSS properties using variables and color-mix.
Layout & small UI tweaks
many apps/..., many packages/ui/src/**/*.tsx
Adjust viewport/fill strategies (absolute inset-0h-dvh + overscroll-none), responsive token renames (sm:flex-shrink-0sm:shrink-0), and many shadow/rounded/mask/token tweaks across components.
Removed small modules
apps/web/src/components/description-list.tsx
Delete DescriptionList, DescriptionTerm, DescriptionDetails components (module removed).

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant App
  participant DialogRoot as Dialog
  participant Portal
  participant Overlay
  participant Content as DialogContent

  User->>App: click DialogTrigger
  App->>DialogRoot: set open=true
  DialogRoot->>Portal: mount
  Portal->>Overlay: render backdrop
  Portal->>Content: render DialogContent (size, showCloseButton)
  User->>Content: click close button (DialogClose asChild)
  Content->>DialogRoot: request close
  DialogRoot->>App: set open=false
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

  • Focus areas:
    • packages/ui/src/dialog.tsx — extensive public API additions, DialogContent props and conditional close-button behavior.
    • packages/ui/src/input.tsx — component reimplementation, prop/type changes, and variant behavior.
    • packages/tailwind-config/* & package.json updates — ESM/exports and PostCSS re-export correctness.
    • Removal of per-app src/style.css and tailwind.config files — risk of missing utilities and visual regressions.
    • Broad classname/selector migrations — verify compiled classes and data-selector correctness across components (sidebar, select, dropdowns).

Possibly related PRs

Poem

🐇
I hopped from CJS to ESM bright and clean,
stitched shared styles where globals had been,
dialogs sprouted names and close buttons too,
inputs learned new forms and forms lined in a queue,
a rabbit nudged classes — and the app felt keen.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '⬆️ Upgrade to Tailwind 4' clearly and concisely summarizes the main objective of this pull request.
✨ 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 tailwind-4

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 687cac0 and 12250f0.

📒 Files selected for processing (1)
  • apps/web/src/components/description-list.tsx (0 hunks)
💤 Files with no reviewable changes (1)
  • apps/web/src/components/description-list.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). (2)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Integration tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@vercel
Copy link

vercel bot commented Dec 11, 2025

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

Project Deployment Review Updated (UTC)
app Ready Ready Preview, Comment Dec 18, 2025 8:32am
1 Skipped Deployment
Project Deployment Review Updated (UTC)
landing Skipped Skipped Dec 18, 2025 8:32am

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

Caution

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

⚠️ Outside diff range comments (6)
packages/ui/src/billing-plan.tsx (1)

38-45: discount prop is declared but never rendered

BillingPlanPrice accepts a discount prop, but it’s not used anywhere in the JSX. That’s either dead API surface or a missing part of the UI.

Consider either:

  • Wiring discount into the markup (e.g. showing a struck-through old price or a “Save X%” label), or
  • Removing the discount prop from the type if it’s not needed.

Example (if you want to display a discount label inline):

-export const BillingPlanPrice = ({
-  children,
-}: React.PropsWithChildren<{ discount?: React.ReactNode }>) => {
+export const BillingPlanPrice = ({
+  children,
+  discount,
+}: React.PropsWithChildren<{ discount?: React.ReactNode }>) => {
   return (
-    <div className="flex items-center gap-4">
-      <span className="font-bold text-3xl">{children}</span>
-    </div>
+    <div className="flex items-center gap-4">
+      <span className="font-bold text-3xl">{children}</span>
+      {discount ? <span className="text-muted-foreground text-sm">{discount}</span> : null}
+    </div>
   );
 };
apps/web/src/components/vote-summary-progress-bar.tsx (1)

23-70: Guard against total === 0 to avoid invalid progress widths

The switch to rounded-sm on the container is a harmless visual tweak.

However, the width calculations:

width: `${(props.yes.length / props.total) * 100}%`;
// ... same pattern for ifNeedBe and no

will yield NaN%/Infinity% if props.total is 0, which results in invalid CSS and unpredictable bar rendering.

Consider normalizing total before using it:

-export const VoteSummaryProgressBar = (props: {
-  total: number;
-  yes: string[];
-  ifNeedBe: string[];
-  no: string[];
-}) => {
-  return (
-    <div className="flex h-1.5 grow overflow-hidden rounded-sm bg-slate-100">
+export const VoteSummaryProgressBar = (props: {
+  total: number;
+  yes: string[];
+  ifNeedBe: string[];
+  no: string[];
+}) => {
+  const total = props.total || 1;
+
+  return (
+    <div className="flex h-1.5 grow overflow-hidden rounded-sm bg-slate-100">
       {/* ... */}
-          style={{
-            width: `${(props.yes.length / props.total) * 100}%`,
-          }}
+          style={{
+            width: `${(props.yes.length / total) * 100}%`,
+          }}
       {/* repeat the same change for ifNeedBe and no */}

This keeps behavior identical for valid totals while ensuring a safe fallback (empty bar) when total happens to be 0.

apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1)

159-163: Duration calculation likely incorrect (always 0 minutes)

Here:

const newEvent: DateTimeOption = {
  type: "timeSlot",
  start: formatDateWithoutTz(startDate),
  duration: dayjs(endDate).diff(endDate, "minutes"),
  end: formatDateWithoutTz(endDate),
};

dayjs(endDate).diff(endDate, "minutes") will always be 0. This looks like it was meant to be the minutes between startDate and endDate.

Consider:

-    duration: dayjs(endDate).diff(endDate, "minutes"),
+    duration: dayjs(endDate).diff(startDate, "minutes"),

so duration correctly reflects the selected slot length.

apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (1)

125-201: Calendar day cell styling is fine; fix Biome’s class‑order complaint

The shadow / border / focus tweaks on the day cells and selection overlay look good and are consistent with the rest of the Tailwind 4 visual polish.

Biome is currently flagging the class list on the inner <span> (line 190) as unsorted, which will cause biome check to fail. You can either reorder the classes manually or just run the project’s autofix script to let Biome handle it:

#!/bin/bash
# Let Biome fix Tailwind class ordering and other style nits
pnpm --filter @rallly/web biome check . --write || pnpm biome check . --write

(Based on static analysis hints for this file.)

apps/landing/package.json (1)

5-43: ESM switch requires converting CommonJS config files

Adding "type": "module" changes how .js files are parsed. Found CommonJS in config files that will break:

  • apps/landing/i18next-scanner.config.js uses require() and module.exports – convert to ESM syntax
  • apps/landing/next.config.ts uses module.exports – verify Next.js handles this correctly with ESM mode, or migrate to ESM syntax
packages/ui/src/sidebar.tsx (1)

513-528: Sort classes in sidebarMenuButtonVariants to satisfy Biome

Biome is flagging the base class string and the size.lg variant in sidebarMenuButtonVariants for unsorted classes (lint/nursery/useSortedClasses). To keep CI green and align with the configured style rules, run Biome with --fix (or equivalent) on this file so those class lists are automatically reordered.

🧹 Nitpick comments (6)
packages/ui/src/button.tsx (1)

21-21: Tailwind v4 migration looks good, but consider enhancing the focus state.

The shadow-2xs utility and opacity slash syntax (bg-destructive/90) are correct for Tailwind v4.

However, the destructive variant has focus-visible:ring-offset-1 without an actual ring, which means keyboard users won't see a visible focus indicator. The primary variant (line 19) correctly includes both ring-2 and ring-gray-300, providing a clear focus state.

Consider applying this diff to add a visible focus ring:

-          "border-destructive bg-destructive text-destructive-foreground shadow-2xs hover:bg-destructive/90 focus-visible:ring-offset-1 active:bg-destructive",
+          "border-destructive bg-destructive text-destructive-foreground shadow-2xs hover:bg-destructive/90 focus-visible:ring-2 focus-visible:ring-red-300 focus-visible:ring-offset-1 active:bg-destructive",

Note: The default and secondary variants (lines 22-25) have the same focus state issue and may benefit from a similar enhancement.

packages/ui/src/billing-plan.tsx (1)

56-69: Prefer wrapping CheckCircle2Icon with <Icon> from @rallly/ui/icon

Guidelines say icon size/colour should be controlled via the shared <Icon> component rather than per‑icon Tailwind classes. Here CheckCircle2Icon is styled directly with className.

Consider refactoring along these lines:

-import { CheckCircle2Icon } from "lucide-react";
+import { CheckCircle2Icon } from "lucide-react";
+import { Icon } from "@rallly/ui/icon";

      <CheckCircle2Icon
-        className={cn(
-          "mt-0.5 size-4 shrink-0",
-          !pro ? "text-gray-500" : "text-primary",
-        )}
+        // or wrap:
+        // <Icon asChild className={cn("mt-0.5 shrink-0", !pro ? "text-gray-500" : "text-primary")}>
+        //   <CheckCircle2Icon />
+        // </Icon>
       />

Adjust the exact pattern to match how <Icon> is used elsewhere in @rallly/ui.

As per coding guidelines, icons’ size and colour should be provided via the shared <Icon> component.

packages/ui/src/breadcrumb.tsx (1)

22-22: Breadcrumb text wrapping change is good; sort classes to satisfy Biome

The updated class list on Line 22 keeps the existing layout while switching to the new word-wrapping utility, which fits the Tailwind 4 upgrade. Biome is flagging only the class order, so you can auto-fix or apply a small manual tweak.

For example:

-      "flex flex-wrap items-center gap-1.5 wrap-break-word text-muted-foreground text-sm sm:gap-2.5",
+      "flex flex-wrap gap-1.5 items-center sm:gap-2.5 text-muted-foreground text-sm wrap-break-word",

As per coding guidelines, Biome should be the source of truth for formatting, so letting it auto-sort these is also fine.

apps/web/src/components/cookie-consent.tsx (1)

36-59: Shadow change is fine; consider localizing the cookie consent copy

The update from shadow-sm to shadow-xs on the OK button is a straightforward visual refinement and looks good.

However, the surrounding text ("Your privacy is important to us...", "Privacy Policy", and "OK") is currently hard-coded. Given the project’s guidelines that all UI text should be translatable (via the <Trans> component or useTranslation), consider refactoring this component to use <Trans> from @/components/trans with defaults strings so it can be localized in the same way as the rest of the app.

If you’d like, I can sketch a concrete refactor using <Trans> for these three strings.

apps/web/src/components/maintenance.tsx (1)

5-14: Card shadow tweak is fine; maintenance copy could be made translatable later

The change from shadow-sm to shadow-xs on the maintenance card is a harmless visual adjustment and matches the PR-wide move to lighter shadows.

As a future improvement (not blocking this PR), you may want to move the title and body text into your i18n system using <Trans>/useTranslation, so this maintenance screen respects locale like the rest of the app.

packages/tailwind-config/shared-styles.css (1)

124-160: Base border-color compatibility and utilities fit the Tailwind 4 migration

The base-layer compatibility rule restoring the pre-v4 border color default, plus the text-link and bg-diagonal-lines utilities and the global body/html styles, provide a coherent, token-driven base for all apps. As a small optional improvement, you could swap the hard-coded grays in bg-diagonal-lines for the gray design tokens to keep everything fully theme-based.

Based on learnings, this aligns shared styling with the Tailwind + custom design system strategy.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 102e5d2 and 411139c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (72)
  • apps/landing/next.config.ts (2 hunks)
  • apps/landing/package.json (2 hunks)
  • apps/landing/postcss.config.js (1 hunks)
  • apps/landing/src/app/[locale]/(main)/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx (1 hunks)
  • apps/landing/src/app/[locale]/globals.css (1 hunks)
  • apps/landing/src/app/[locale]/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1 hunks)
  • apps/landing/src/components/home/bonus-item.tsx (1 hunks)
  • apps/landing/src/style.css (0 hunks)
  • apps/landing/tailwind.config.js (0 hunks)
  • apps/web/.cursor/rules/better-auth.md (3 hunks)
  • apps/web/next.config.ts (1 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.js (1 hunks)
  • apps/web/src/app/[locale]/(auth)/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/globals.css (1 hunks)
  • apps/web/src/app/[locale]/layout.tsx (1 hunks)
  • apps/web/src/app/components/page-layout.tsx (1 hunks)
  • apps/web/src/components/cookie-consent.tsx (1 hunks)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/discussion/discussion.tsx (1 hunks)
  • apps/web/src/components/empty-state.tsx (1 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1 hunks)
  • apps/web/src/components/full-width-layout.tsx (1 hunks)
  • apps/web/src/components/maintenance.tsx (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (1 hunks)
  • apps/web/src/components/poll/desktop-poll.tsx (2 hunks)
  • apps/web/src/components/poll/scheduled-event.tsx (1 hunks)
  • apps/web/src/components/skeleton.tsx (1 hunks)
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx (1 hunks)
  • apps/web/src/components/vote-summary-progress-bar.tsx (1 hunks)
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx (2 hunks)
  • apps/web/src/features/space/components/space-dropdown.tsx (1 hunks)
  • apps/web/src/globals.css (1 hunks)
  • apps/web/src/style.css (0 hunks)
  • apps/web/tailwind.config.js (0 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.js (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/tailwind-config/tailwind.config.d.ts (0 hunks)
  • packages/tailwind-config/tailwind.config.js (0 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/alert.tsx (1 hunks)
  • packages/ui/src/avatar.tsx (1 hunks)
  • packages/ui/src/badge.tsx (1 hunks)
  • packages/ui/src/billing-plan.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/button.tsx (1 hunks)
  • packages/ui/src/card.tsx (1 hunks)
  • packages/ui/src/checkbox.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/dropdown-menu.tsx (5 hunks)
  • packages/ui/src/page-tabs.tsx (2 hunks)
  • packages/ui/src/popover.tsx (1 hunks)
  • packages/ui/src/progress.tsx (1 hunks)
  • packages/ui/src/radio-group.tsx (1 hunks)
  • packages/ui/src/select.tsx (3 hunks)
  • packages/ui/src/separator.tsx (1 hunks)
  • packages/ui/src/sheet.tsx (1 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
  • packages/ui/src/switch.tsx (1 hunks)
  • packages/ui/src/table.tsx (2 hunks)
  • packages/ui/src/tabs.tsx (2 hunks)
  • packages/ui/src/textarea.tsx (1 hunks)
  • packages/ui/src/toast.tsx (4 hunks)
  • packages/ui/src/tooltip.tsx (1 hunks)
💤 Files with no reviewable changes (6)
  • packages/tailwind-config/tailwind.config.d.ts
  • apps/web/tailwind.config.js
  • apps/landing/tailwind.config.js
  • apps/web/src/style.css
  • packages/tailwind-config/tailwind.config.js
  • apps/landing/src/style.css
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/globals.css
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/package.json
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/package.json
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/globals.css
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • apps/landing/postcss.config.js
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/package.json
  • apps/web/postcss.config.js
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/tailwind-config/postcss.config.js
  • packages/ui/src/radio-group.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • apps/landing/postcss.config.js
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/postcss.config.js
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/tailwind-config/postcss.config.js
  • packages/ui/src/radio-group.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/maintenance.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/components/description-list.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/components/maintenance.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/postcss.config.js
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/button.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/tooltip.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/textarea.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/progress.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
apps/web/src/app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js App Router conventions for route handlers

Files:

  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
apps/web/src/features/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize features in apps/web/src/features/[feature]/ directory structure

Files:

  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
**/*.ts

📄 CodeRabbit inference engine (.cursorrules)

On the server use the getTranslations function from @/i18n/server to get the translations

Files:

  • apps/landing/next.config.ts
  • apps/web/next.config.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • apps/web/src/components/maintenance.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • apps/web/src/globals.css
  • packages/ui/src/progress.tsx
  • apps/landing/postcss.config.js
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/package.json
  • apps/web/postcss.config.js
  • packages/tailwind-config/postcss.config.js
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/tabs.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/card.tsx
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/components/description-list.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • apps/web/src/components/skeleton.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/globals.css
  • packages/ui/src/textarea.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/globals.css
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • apps/web/src/components/vote-summary-progress-bar.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/app/components/page-layout.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • apps/landing/src/app/[locale]/globals.css
  • packages/tailwind-config/package.json
  • apps/web/src/globals.css
  • apps/web/package.json
  • apps/landing/src/app/[locale]/(main)/layout.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/tabs.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/progress.tsx
  • packages/ui/src/card.tsx
  • packages/ui/package.json
  • apps/landing/src/components/home/bonus-item.tsx
  • packages/ui/src/table.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • packages/tailwind-config/shared-styles.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • apps/web/src/globals.css
  • packages/ui/src/progress.tsx
  • apps/landing/postcss.config.js
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/package.json
  • apps/web/postcss.config.js
  • packages/tailwind-config/postcss.config.js
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/tooltip.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • packages/ui/src/avatar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translatable

Applied to files:

  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/table.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
📚 Learning: 2025-09-12T21:37:47.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1951
File: packages/ui/src/dialog.tsx:23-25
Timestamp: 2025-09-12T21:37:47.353Z
Learning: React.ElementRef is deprecated and has been replaced by React.ComponentRef for TypeScript ref typing in React components, including Radix UI forwardRef components.

Applied to files:

  • packages/ui/src/switch.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Always use the `useDialog` hook from `rallly/ui/dialog` for managing dialog state instead of manual `useState` for open/close state

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use the <Trans> component in client components from @/components/trans with the `defaults` prop to provide the default text

Applied to files:

  • packages/ui/src/select.tsx
  • packages/ui/src/table.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx,json} : i18n keys are in camelCase

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Create separate import statements for types

Applied to files:

  • packages/ui/package.json
  • apps/landing/next.config.ts
  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers

Applied to files:

  • apps/landing/next.config.ts
  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translated using either the Trans component or the useTranslation hook

Applied to files:

  • packages/ui/src/table.tsx
🧬 Code graph analysis (5)
apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1)
apps/landing/src/i18n/client/link.tsx (1)
  • LinkBase (7-26)
apps/web/src/components/new-participant-modal.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/web/src/components/time-zone-picker/time-zone-select.tsx (1)
packages/ui/src/command.tsx (1)
  • CommandList (192-192)
apps/web/postcss.config.js (1)
packages/tailwind-config/postcss.config.js (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
apps/landing/src/app/[locale]/(main)/layout.tsx (1)
apps/landing/src/i18n/client/link.tsx (1)
  • LinkBase (7-26)
🪛 Biome (2.1.2)
packages/ui/src/breadcrumb.tsx

[error] 22-22: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

packages/ui/src/command.tsx

[error] 39-39: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

packages/ui/src/sidebar.tsx

[error] 513-513: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 527-527: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx

[error] 190-190: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

apps/web/src/components/description-list.tsx

[error] 42-42: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

⏰ 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). (1)
  • GitHub Check: Integration tests

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 411139c and 380e868.

📒 Files selected for processing (7)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/components/description-list.tsx
  • packages/ui/src/command.tsx
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • packages/ui/src/breadcrumb.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • packages/ui/src/breadcrumb.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • packages/ui/src/sidebar.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). (1)
  • GitHub Check: Integration tests
🔇 Additional comments (1)
packages/ui/src/sidebar.tsx (1)

136-136: All Tailwind 4 syntax changes are correct and valid.

The conversions from Tailwind v3 to v4 follow proper syntax:

  • CSS variables use the new parentheses shorthand: w-(--sidebar-width) (v4 introduced (--var) as shorthand for [var(--var)])
  • outline-hidden is a valid v4 utility that hides the default browser focus outline while preserving high-contrast mode support
  • Shadow tokens shadow-xs and shadow-2xs are new v4 utilities with defined default values
  • Selector variants has-data-[variant=inset] and in-data-[side=left] are valid composable data variants in v4

No changes needed.

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 380e868 and 08ef4b9.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/landing/package.json (1 hunks)
  • apps/landing/postcss.config.mjs (1 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.mjs (1 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/package.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/tailwind-config/postcss.config.mjs
  • apps/web/postcss.config.mjs
  • apps/landing/postcss.config.mjs
  • packages/tailwind-config/package.json
  • apps/landing/package.json
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/tailwind-config/package.json
  • apps/landing/package.json
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • packages/tailwind-config/postcss.config.mjs
  • apps/web/postcss.config.mjs
  • apps/landing/postcss.config.mjs
  • packages/tailwind-config/package.json
  • apps/landing/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • packages/tailwind-config/postcss.config.mjs
  • apps/web/postcss.config.mjs
  • apps/landing/postcss.config.mjs
  • packages/tailwind-config/package.json
  • apps/landing/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • packages/tailwind-config/package.json
  • apps/landing/package.json
🧬 Code graph analysis (2)
apps/web/postcss.config.mjs (1)
packages/tailwind-config/postcss.config.mjs (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
apps/landing/postcss.config.mjs (1)
packages/tailwind-config/postcss.config.mjs (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
⏰ 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). (1)
  • GitHub Check: Integration tests
🔇 Additional comments (5)
packages/tailwind-config/package.json (1)

5-9: ESM package type and exports map look appropriate for the shared Tailwind config.

Marking the package as ESM and exporting "." to shared-styles.css plus "./postcss" to postcss.config.mjs matches how the apps import from @rallly/tailwind-config/postcss and consume shared styles.

packages/tailwind-config/postcss.config.mjs (1)

1-6: Shared PostCSS config is minimal and aligned with Tailwind 4 usage.

Centralizing the PostCSS plugins into postcssConfig with @tailwindcss/postcss keeps app-level configs thin and consistent; structure looks good.

apps/web/postcss.config.mjs (1)

1-3: Re-exporting the shared PostCSS config keeps web app setup DRY.

Importing { postcssConfig } from @rallly/tailwind-config/postcss and exporting it as default cleanly wires the web app into the centralized Tailwind/PostCSS pipeline.

apps/landing/postcss.config.mjs (1)

1-3: Landing app correctly reuses the centralized PostCSS config.

Mirroring the web app’s postcss.config.mjs keeps Tailwind/PostCSS behavior consistent across apps and avoids local config drift.

apps/landing/package.json (1)

40-41: Tailwind dependency addition is consistent across the monorepo.

Adding tailwindcss ^4.1.18 here aligns with the versions used in apps/web/package.json and packages/tailwind-config/package.json. No version skew in the workspace.

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

♻️ Duplicate comments (3)
packages/tailwind-config/package.json (2)

5-9: Exports map: ensure no remaining imports reference the removed @rallly/tailwind-config/tailwind.config path
This was already flagged in prior review comments; still worth confirming given the new "exports" map.

#!/bin/bash
set -euo pipefail

# Expectation: no remaining imports of the removed entrypoint.
rg -nP --glob '*.{js,jsx,ts,tsx}' '\b@rallly/tailwind-config/tailwind\.config\b' -C2 || true

# Also check other possible deep imports.
rg -nP --glob '*.{js,jsx,ts,tsx}' '\b@rallly/tailwind-config/(?!postcss\b)[^"\s]+' -C2 || true

10-13: Declare @tailwindcss/postcss in this package (exported config references it)
packages/tailwind-config/postcss.config.mjs uses @tailwindcss/postcss; without declaring it here, consumers can break depending on hoisting.

 {
@@
   "dependencies": {
+    "@tailwindcss/postcss": "^4.1.18",
     "postcss": "^8.5.6",
     "tailwindcss": "^4.1.18"
   },
For Tailwind CSS v4.1.x, is `@tailwindcss/postcss` required as a direct dependency of packages exporting a PostCSS config that references it?
packages/tailwind-config/shared-styles.css (1)

103-113: Remove invalid translate-y property (ignored by browsers)
This matches the existing prior review note on this PR.

 @keyframes popIn {
@@
   100% {
     transform: scale(1) translateY(0px);
     opacity: 1;
-    translate-y: 0;
   }
 }
🧹 Nitpick comments (7)
packages/ui/src/switch.tsx (1)

14-18: Tailwind v4 outline-hidden change is good; consider updating React.ElementRef -> React.ComponentRef. Aligns this component with the newer ref-typing pattern already used elsewhere (e.g. command.tsx).

-const Switch = React.forwardRef<
-  React.ElementRef<typeof SwitchPrimitives.Root>,
+const Switch = React.forwardRef<
+  React.ComponentRef<typeof SwitchPrimitives.Root>,
   React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> & {
     icon?: React.ReactNode;
   }
 >(({ className, ...props }, ref) => (
packages/ui/src/tabs.tsx (2)

30-34: TabsTrigger outline-hidden change is fine; consider ElementRef -> ComponentRef for consistency.


44-49: TabsContent outline-hidden change is fine; consider ElementRef -> ComponentRef for consistency.

packages/ui/src/radio-group.tsx (1)

28-33: RadioGroupItem focus outline migration looks correct; consider ElementRef -> ComponentRef.

packages/ui/src/page-tabs.tsx (2)

26-32: Page TabsTrigger outline-hidden change is good; consider ElementRef -> ComponentRef for consistency.


42-47: Page TabsContent outline-hidden change is good; consider ElementRef -> ComponentRef for consistency.

apps/landing/next.config.ts (1)

16-18: Remove redundant JSDoc type now that nextConfig is typed
Line 16 is unnecessary once you have const nextConfig: NextConfig = ... (Line 17).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08ef4b9 and 91f47e3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (75)
  • apps/landing/next.config.ts (2 hunks)
  • apps/landing/package.json (1 hunks)
  • apps/landing/postcss.config.js (0 hunks)
  • apps/landing/postcss.config.mjs (1 hunks)
  • apps/landing/src/app/[locale]/(main)/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx (1 hunks)
  • apps/landing/src/app/[locale]/globals.css (1 hunks)
  • apps/landing/src/app/[locale]/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1 hunks)
  • apps/landing/src/components/home/bonus-item.tsx (1 hunks)
  • apps/landing/src/style.css (0 hunks)
  • apps/landing/tailwind.config.js (0 hunks)
  • apps/web/.cursor/rules/better-auth.md (3 hunks)
  • apps/web/next.config.ts (1 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.js (0 hunks)
  • apps/web/postcss.config.mjs (1 hunks)
  • apps/web/src/app/[locale]/(auth)/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/globals.css (1 hunks)
  • apps/web/src/app/[locale]/layout.tsx (1 hunks)
  • apps/web/src/app/components/page-layout.tsx (1 hunks)
  • apps/web/src/components/cookie-consent.tsx (1 hunks)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/discussion/discussion.tsx (1 hunks)
  • apps/web/src/components/empty-state.tsx (1 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1 hunks)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1 hunks)
  • apps/web/src/components/full-width-layout.tsx (1 hunks)
  • apps/web/src/components/maintenance.tsx (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (1 hunks)
  • apps/web/src/components/poll/desktop-poll.tsx (2 hunks)
  • apps/web/src/components/poll/scheduled-event.tsx (1 hunks)
  • apps/web/src/components/skeleton.tsx (1 hunks)
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx (1 hunks)
  • apps/web/src/components/vote-summary-progress-bar.tsx (1 hunks)
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx (2 hunks)
  • apps/web/src/features/space/components/space-dropdown.tsx (1 hunks)
  • apps/web/src/globals.css (1 hunks)
  • apps/web/src/style.css (0 hunks)
  • apps/web/tailwind.config.js (0 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.mjs (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/tailwind-config/tailwind.config.d.ts (0 hunks)
  • packages/tailwind-config/tailwind.config.js (0 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/alert.tsx (1 hunks)
  • packages/ui/src/avatar.tsx (1 hunks)
  • packages/ui/src/badge.tsx (1 hunks)
  • packages/ui/src/billing-plan.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/button.tsx (1 hunks)
  • packages/ui/src/card.tsx (1 hunks)
  • packages/ui/src/checkbox.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/dropdown-menu.tsx (5 hunks)
  • packages/ui/src/page-tabs.tsx (2 hunks)
  • packages/ui/src/popover.tsx (1 hunks)
  • packages/ui/src/progress.tsx (1 hunks)
  • packages/ui/src/radio-group.tsx (1 hunks)
  • packages/ui/src/select.tsx (3 hunks)
  • packages/ui/src/separator.tsx (1 hunks)
  • packages/ui/src/sheet.tsx (1 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
  • packages/ui/src/switch.tsx (1 hunks)
  • packages/ui/src/table.tsx (2 hunks)
  • packages/ui/src/tabs.tsx (2 hunks)
  • packages/ui/src/textarea.tsx (1 hunks)
  • packages/ui/src/toast.tsx (4 hunks)
  • packages/ui/src/tooltip.tsx (1 hunks)
💤 Files with no reviewable changes (8)
  • apps/web/src/style.css
  • packages/tailwind-config/tailwind.config.d.ts
  • apps/landing/src/style.css
  • packages/tailwind-config/tailwind.config.js
  • apps/landing/tailwind.config.js
  • apps/web/postcss.config.js
  • apps/web/tailwind.config.js
  • apps/landing/postcss.config.js
✅ Files skipped from review due to trivial changes (1)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
🚧 Files skipped from review as they are similar to previous changes (45)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/select.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/badge.tsx
  • packages/ui/src/card.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/package.json
  • packages/ui/src/tooltip.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/package.json
  • apps/web/src/globals.css
  • apps/web/src/components/empty-state.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/progress.tsx
  • apps/web/postcss.config.mjs
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/app/[locale]/globals.css
  • packages/tailwind-config/postcss.config.mjs
  • apps/web/next.config.ts
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • apps/web/src/components/full-width-layout.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/separator.tsx
  • apps/landing/src/app/[locale]/globals.css
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
  • packages/tailwind-config/package.json
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/radio-group.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/postcss.config.mjs
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
  • packages/tailwind-config/package.json
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
apps/web/src/features/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize features in apps/web/src/features/[feature]/ directory structure

Files:

  • apps/web/src/features/space/components/space-dropdown.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
apps/web/src/app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js App Router conventions for route handlers

Files:

  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
**/*.ts

📄 CodeRabbit inference engine (.cursorrules)

On the server use the getTranslations function from @/i18n/server to get the translations

Files:

  • apps/landing/next.config.ts
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/tabs.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/switch.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-09-12T21:37:47.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1951
File: packages/ui/src/dialog.tsx:23-25
Timestamp: 2025-09-12T21:37:47.353Z
Learning: React.ElementRef is deprecated and has been replaced by React.ComponentRef for TypeScript ref typing in React components, including Radix UI forwardRef components.

Applied to files:

  • packages/ui/src/switch.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/postcss.config.mjs
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/postcss.config.mjs
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • apps/landing/package.json
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use Biome for code formatting with indent of 2 spaces and double quotes

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers

Applied to files:

  • apps/landing/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Create separate import statements for types

Applied to files:

  • apps/landing/next.config.ts
🧬 Code graph analysis (1)
apps/landing/postcss.config.mjs (1)
packages/tailwind-config/postcss.config.mjs (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
⏰ 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). (1)
  • GitHub Check: Integration tests
🔇 Additional comments (26)
apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1)

11-11: Tailwind v4 shadow-xs swap looks safe. This is a purely visual change and should align with the broader v4 migration.

apps/web/src/components/poll/scheduled-event.tsx (1)

71-74: Looks good; verify shadow-xs is available in your Tailwind v4 theme output.

If shadows are customized via your shared tokens/theme, make sure shadow-xs compiles and matches the intended visual.

apps/web/src/features/space/components/space-dropdown.tsx (1)

82-82: LGTM! Correct Tailwind v4 CSS variable syntax.

The change correctly migrates the CSS variable syntax from Tailwind v3 (min-w-[var(--...)]) to Tailwind v4 (min-w-(--...)). The var() wrapper is no longer needed and parentheses replace square brackets for arbitrary CSS variable values.

apps/web/src/app/[locale]/(auth)/layout.tsx (1)

37-37: LGTM! Correct Tailwind v4 arbitrary value syntax.

The change from arbitrary CSS property syntax [mask-image:radial-gradient(...)] to the standard arbitrary value syntax mask-[radial-gradient(...)] is the correct approach for Tailwind v4. This aligns with Tailwind's conventions for applying arbitrary values to utilities.

apps/web/.cursor/rules/better-auth.md (1)

24706-24706: Replace invalid variant "outline-solid" with a valid Button variant.

The Button component does not support variant="outline-solid". Valid variants are: primary, destructive, default, secondary, ghost, actionBar, and link.

For the outlined appearance shown in these examples, use variant="ghost" or variant="secondary" instead at lines 24706, 24720, and 24733.

packages/ui/src/checkbox.tsx (1)

16-19: Tailwind v4 focus outline migration looks correct (outline-hidden). Keeps the focus affordance via focus-visible:ring-1, so accessibility shouldn’t regress.

packages/ui/src/popover.tsx (1)

22-25: PopoverContent outline-none -> outline-hidden is a safe Tailwind v4 alignment. No behavior impact expected.

packages/ui/src/command.tsx (5)

39-41: Selector/class updates on CommandDialog look consistent with Tailwind v4 + cmdk patterns. No functional impact expected.


60-63: CommandInput outline-hidden migration is consistent with the rest of the UI kit.


103-106: CommandGroup selector updates look fine; keeps styling localized to cmdk attributes.


131-134: CommandItem focus outline change is fine (outline-hidden).


147-150: CommandItemShortcut focus outline change is fine (outline-hidden).

packages/ui/src/toast.tsx (4)

18-18: Correct Tailwind v4 migration for z-index.

The change from z-[100] to z-100 correctly applies Tailwind v4's dynamic utility value syntax.


27-27: Correct Tailwind v4 CSS variable syntax migration.

The changes from translate-x-[--radix-toast-swipe-*-x] to translate-x-(--radix-toast-swipe-*-x) correctly implement Tailwind v4's breaking change requiring parentheses for CSS variables instead of brackets.


64-64: Correct Tailwind v4 outline utility migration.

The change from focus:outline-none to focus:outline-hidden correctly implements Tailwind v4's breaking change where outline-none now only removes outline style, and outline-hidden must be used to completely remove the outline.


79-79: Correct Tailwind v4 outline utility migration.

The change from focus:outline-none to focus:outline-hidden correctly implements Tailwind v4's breaking change, consistent with the ToastAction component.

apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (2)

177-177: LGTM: More explicit focus rounding.

The change from focus:rounded to focus:rounded-sm makes the border radius size more explicit, improving code clarity.


190-192: LGTM: Z-index cleanup.

The change from -z-0 to z-0 removes a redundant negative sign (since negative zero equals zero). The shadow-xs change is consistent with line 125 and covered in the previous verification request.

apps/landing/next.config.ts (1)

74-76: Redirect destination fix for /profile looks correct
Passing an explicit subpath to createAppUrl("/profile") is clearer/safer than relying on an implicit default.

apps/landing/postcss.config.mjs (1)

1-3: Clean re-export of shared PostCSS config
Keeps PostCSS config centralized and avoids drift across apps.

packages/ui/src/button.tsx (1)

21-21: LGTM! Shadow utility correctly updated for Tailwind v4.

The migration from shadow-sm to shadow-2xs aligns with Tailwind v4's refined shadow scale, maintaining consistent visual depth across the design system.

packages/ui/src/sidebar.tsx (5)

176-176: CSS variable syntax correctly migrated to Tailwind v4.

The migration from bracket syntax w-[--sidebar-width] to parentheses syntax w-(--sidebar-width) is correct per Tailwind v4 requirements. All CSS variable references have been consistently updated throughout the component.

Also applies to: 193-193, 223-223, 228-228, 233-233, 240-240, 673-673


513-513: Important modifier syntax correctly updated for Tailwind v4.

The important modifier placement has been correctly migrated from prefix (!size-8) to suffix (size-8!) as required by Tailwind v4.

Also applies to: 527-527


440-440: Outline utilities correctly migrated to Tailwind v4.

The migration from outline-none to outline-hidden is correct. In Tailwind v4, outline-none only removes the outline style, while outline-hidden removes the outline completely.

Also applies to: 461-461, 610-610, 726-726


136-136: Data attribute selectors correctly migrated to Tailwind v4.

The migration to new data attribute selector syntax is correct:

  • has-data-[variant=inset] for parent selectors
  • in-data-[side=left] for ancestor state targeting
  • peer-data-[...] for peer relationships

All align with Tailwind v4's enhanced data attribute handling.

Also applies to: 302-302, 324-324


247-247: Shadow utility correctly updated for Tailwind v4.

The shadow-xs utility aligns with Tailwind v4's refined shadow scale, maintaining consistent visual depth for the floating sidebar variant.

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

Caution

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

⚠️ Outside diff range comments (6)
apps/web/src/components/cookie-consent.tsx (2)

1-1: Add "use client" directive.

This component uses client-side JavaScript features (React.useState, createPortal, Cookies.set, animations), but is missing the "use client" directive required for Next.js 15 App Router.

As per coding guidelines, add the directive at the top of the file:

+"use client";
+
 import Cookies from "js-cookie";

40-48: Make UI text translatable.

The component contains hardcoded English text that violates the coding guidelines requirement that "All text in the UI should be translated using either the Trans component or the useTranslation hook."

As per coding guidelines, wrap the text with the Trans component from @/components/trans:

<Trans defaults="Your privacy is important to us. We only use cookies to improve the browsing experience on this website." />

And for the link text:

<Trans defaults="Privacy Policy" />
packages/ui/src/table.tsx (1)

69-82: [[role=checkbox]]:*:translate-y-[2px] may be invalid Tailwind syntax + may over-apply styles

I’m not confident Tailwind will parse [[role=checkbox]]:*:translate-y-[2px] as intended (and the *: risks translating checkbox children too). If the goal is “translate any descendant checkbox element”, consider using the standard descendant form:

-      "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [[role=checkbox]]:*:translate-y-[2px]",
+      "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&_[role=checkbox]]:translate-y-[2px]",
-      "p-2 align-middle [&:has([role=checkbox])]:pr-0 [[role=checkbox]]:*:translate-y-[2px]",
+      "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&_[role=checkbox]]:translate-y-[2px]",

To verify usage/consistency across the repo:

#!/bin/bash
rg -n --type=tsx --type=css '\[\[role=checkbox\]\]|\[&_\[role=checkbox\]\]'

Also applies to: 84-97

packages/ui/src/sidebar.tsx (1)

302-307: Migrate [[data-..._&]] arbitrary variant syntax to Tailwind v4 compatible patterns. The syntax on lines 303, 305–306 combining data attributes with the nesting placeholder in a single bracket is not reliably supported in Tailwind v4. Rewrite using either:

  • Separate selectors (e.g., data-[side=left]:data-[state=collapsed]:cursor-e-resize)
  • Custom variants via @plugin if complex chaining is needed
  • Or define explicit arbitrary variants that conform to v4's nesting rules

Reference the Tailwind v4 arbitrary variants documentation for the updated syntax patterns.

packages/ui/src/tabs.tsx (1)

10-13: Replace React.ElementRef with React.ComponentRef for ref typing consistency.

The codebase has already migrated several components to use React.ComponentRef (dialog.tsx, dropdown-menu.tsx, select.tsx, command.tsx, avatar.tsx, action-bar.tsx). Standardize tabs.tsx to match this pattern across all three forwardRef declarations: TabsList, TabsTrigger, and TabsContent.

-const TabsList = React.forwardRef<
-  React.ElementRef<typeof TabsPrimitive.List>,
+const TabsList = React.forwardRef<
+  React.ComponentRef<typeof TabsPrimitive.List>,
   React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
 >(({ className, ...props }, ref) => (
-const TabsTrigger = React.forwardRef<
-  React.ElementRef<typeof TabsPrimitive.Trigger>,
+const TabsTrigger = React.forwardRef<
+  React.ComponentRef<typeof TabsPrimitive.Trigger>,
   React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
 >(({ className, ...props }, ref) => (
-const TabsContent = React.forwardRef<
-  React.ElementRef<typeof TabsPrimitive.Content>,
+const TabsContent = React.forwardRef<
+  React.ComponentRef<typeof TabsPrimitive.Content>,
   React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
 >(({ className, ...props }, ref) => (
packages/ui/src/toast.tsx (1)

11-23: Use z-[100] instead of z-100—the latter is not defined in Tailwind's default zIndex scale and will not apply any z-index styling.

Tailwind v4's default zIndex utilities are limited to z-0, z-10, z-20, z-30, z-40, z-50, and z-auto. Since your shared-styles.css doesn't define a custom zIndex scale, z-100 will be silently ignored, potentially causing the toast viewport to render behind other elements. Revert to the arbitrary value syntax:

-      "fixed top-0 z-100 flex max-h-screen w-full flex-col-reverse p-4 sm:top-auto sm:right-4 sm:bottom-4 sm:flex-col md:max-w-[420px]",
+      "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:top-auto sm:right-4 sm:bottom-4 sm:flex-col md:max-w-[420px]",
♻️ Duplicate comments (5)
apps/web/src/components/forms/poll-options-form/rbc-overrides.css (3)

29-31: Good: uses design-system variable instead of hardcoded hex.


61-64: Good: aligns with design system via CSS variables.


11-13: Conflicting duplicate selector: later rule overrides earlier. Pick one. Right now .rbc-time-content > * + * > * sets --color-gray-200 (Line 12) but is later overwritten by --color-gray-100 (Line 73), so one of these is wrong/dead.

 .rbc-time-content > * + * > * {
-  border-color: var(--color-gray-200);
+  border-color: var(--color-gray-100); /* or --color-gray-200: choose one */
 }
@@
-.rbc-time-content > * + * > * {
-  border-color: var(--color-gray-100);
-}

Also applies to: 72-74

packages/tailwind-config/package.json (1)

5-13: Note existing comments about exports and dependencies.

The migration to "type": "module" and the new exports map are correct for Tailwind v4. However, there are existing comments flagging:

  1. A broken import path for "tailwind.config" used by packages/ui
  2. Missing @tailwindcss/postcss dependency that postcss.config.mjs requires

Please address those comments to ensure the package is self-contained.

packages/ui/src/sidebar.tsx (1)

176-178: Fix invalid calc() token: (--spacing(4)) is not valid CSS/Tailwind v4.

This still uses the broken (--spacing(4)) pattern (Line 227, Line 239). It should reference the CSS custom property with var(--spacing) (and then multiply), consistent with Tailwind v4 arbitrary values.

- ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
+ ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+calc(var(--spacing)*4))]"
  : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)",

- ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
+ ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+calc(var(--spacing)*4)+2px)]"
  : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",

Also applies to: 193-199, 223-229, 233-240

🧹 Nitpick comments (5)
apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1)

81-92: Avoid leaving the UI “pending” forever on sign-out failures.
If signOut() throws, setIsPending(true) is never reverted, and the loading indicator can get stuck. Consider try/finally (and optionally disable the item while pending).

           <DropdownMenuItem
             onClick={async () => {
               setIsPending(true);
-              await signOut();
-              posthog?.reset();
+              try {
+                await signOut();
+                posthog?.reset();
+              } finally {
+                setIsPending(false);
+              }
             }}
           >
packages/ui/src/sheet.tsx (1)

68-71: Tailwind v4 outline change looks right; please verify rounded-xs token exists

focus:outline-hidden is the correct v4 replacement, but rounded-xs isn’t a Tailwind default—please confirm it’s defined in your theme/design tokens and actually generated for packages/ui builds. Also consider whether the hardcoded sr-only “Close” label should be localizable or injectable (e.g., via prop / aria-label) per repo i18n guidelines.

apps/web/next.config.ts (1)

122-125: Consider using export default for full ESM consistency.

Similar to the landing config, the file uses ESM imports but retains CommonJS module.exports. For full ESM consistency in next.config.ts, consider using export default:

-module.exports =
+export default
   process.env.NEXT_PUBLIC_SELF_HOSTED === "true"
     ? withBundleAnalyzerConfig
     : withSentryConfig(withBundleAnalyzerConfig, sentryWebpackPluginOptions);
packages/ui/src/switch.tsx (1)

8-13: Consider switching React.ElementRefReact.ComponentRef for consistency + reported deprecation.

 const Switch = React.forwardRef<
-  React.ElementRef<typeof SwitchPrimitives.Root>,
+  React.ComponentRef<typeof SwitchPrimitives.Root>,
   React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> & {
     icon?: React.ReactNode;
   }
 >(({ className, ...props }, ref) => (
packages/ui/src/toast.tsx (1)

11-14: Standardize forwardRef typings from React.ElementRef to React.ComponentRef.

React.ElementRef is deprecated. Other UI components (select.tsx, dropdown-menu.tsx, command.tsx, avatar.tsx, dialog.tsx) already use React.ComponentRef for consistency. Update all six forwardRef declarations in toast.tsx (lines 12, 43, 58, 73, 91, 103).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28b424c and 265ef9a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (76)
  • apps/landing/next.config.ts (2 hunks)
  • apps/landing/package.json (1 hunks)
  • apps/landing/postcss.config.js (0 hunks)
  • apps/landing/postcss.config.mjs (1 hunks)
  • apps/landing/src/app/[locale]/(main)/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx (1 hunks)
  • apps/landing/src/app/[locale]/globals.css (1 hunks)
  • apps/landing/src/app/[locale]/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1 hunks)
  • apps/landing/src/components/home/bonus-item.tsx (1 hunks)
  • apps/landing/src/style.css (0 hunks)
  • apps/landing/tailwind.config.js (0 hunks)
  • apps/web/next.config.ts (1 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.js (0 hunks)
  • apps/web/postcss.config.mjs (1 hunks)
  • apps/web/src/app/[locale]/(auth)/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/globals.css (1 hunks)
  • apps/web/src/app/[locale]/layout.tsx (1 hunks)
  • apps/web/src/app/components/page-layout.tsx (1 hunks)
  • apps/web/src/components/cookie-consent.tsx (1 hunks)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/discussion/discussion.tsx (1 hunks)
  • apps/web/src/components/empty-state.tsx (1 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1 hunks)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1 hunks)
  • apps/web/src/components/full-width-layout.tsx (1 hunks)
  • apps/web/src/components/maintenance.tsx (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (1 hunks)
  • apps/web/src/components/poll/desktop-poll.tsx (2 hunks)
  • apps/web/src/components/poll/scheduled-event.tsx (1 hunks)
  • apps/web/src/components/skeleton.tsx (1 hunks)
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx (1 hunks)
  • apps/web/src/components/vote-summary-progress-bar.tsx (1 hunks)
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx (2 hunks)
  • apps/web/src/features/space/components/space-dropdown.tsx (1 hunks)
  • apps/web/src/globals.css (1 hunks)
  • apps/web/src/style.css (0 hunks)
  • apps/web/tailwind.config.js (0 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.mjs (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/tailwind-config/tailwind.config.d.ts (0 hunks)
  • packages/tailwind-config/tailwind.config.js (0 hunks)
  • packages/ui/components.json (0 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/alert.tsx (1 hunks)
  • packages/ui/src/avatar.tsx (1 hunks)
  • packages/ui/src/badge.tsx (1 hunks)
  • packages/ui/src/billing-plan.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/button.tsx (1 hunks)
  • packages/ui/src/card.tsx (1 hunks)
  • packages/ui/src/checkbox.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/dropdown-menu.tsx (5 hunks)
  • packages/ui/src/page-tabs.tsx (2 hunks)
  • packages/ui/src/popover.tsx (1 hunks)
  • packages/ui/src/progress.tsx (1 hunks)
  • packages/ui/src/radio-group.tsx (1 hunks)
  • packages/ui/src/select.tsx (3 hunks)
  • packages/ui/src/separator.tsx (1 hunks)
  • packages/ui/src/sheet.tsx (1 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
  • packages/ui/src/switch.tsx (1 hunks)
  • packages/ui/src/table.tsx (2 hunks)
  • packages/ui/src/tabs.tsx (2 hunks)
  • packages/ui/src/textarea.tsx (1 hunks)
  • packages/ui/src/toast.tsx (4 hunks)
  • packages/ui/src/tooltip.tsx (1 hunks)
  • packages/ui/tailwind.config.js (0 hunks)
💤 Files with no reviewable changes (10)
  • packages/ui/tailwind.config.js
  • apps/landing/src/style.css
  • apps/web/postcss.config.js
  • apps/landing/postcss.config.js
  • apps/web/src/style.css
  • apps/web/tailwind.config.js
  • packages/ui/components.json
  • packages/tailwind-config/tailwind.config.js
  • packages/tailwind-config/tailwind.config.d.ts
  • apps/landing/tailwind.config.js
✅ Files skipped from review due to trivial changes (3)
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/app/[locale]/globals.css
🚧 Files skipped from review as they are similar to previous changes (34)
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/landing/postcss.config.mjs
  • apps/landing/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/package.json
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • packages/ui/src/checkbox.tsx
  • packages/tailwind-config/postcss.config.mjs
  • packages/ui/src/alert.tsx
  • packages/ui/src/progress.tsx
  • packages/ui/package.json
  • packages/ui/src/page-tabs.tsx
  • apps/web/postcss.config.mjs
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/select.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/badge.tsx
  • packages/ui/src/avatar.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/radio-group.tsx
  • apps/landing/package.json
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/web/src/components/maintenance.tsx
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/card.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/card.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/table.tsx
  • apps/landing/src/app/[locale]/globals.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/next.config.ts
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/globals.css
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/switch.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/card.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/card.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/switch.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/breadcrumb.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/card.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/table.tsx
  • apps/landing/src/app/[locale]/globals.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/next.config.ts
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/globals.css
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/switch.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/breadcrumb.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/card.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/card.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/breadcrumb.tsx
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/card.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/textarea.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/breadcrumb.tsx
apps/web/src/app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js App Router conventions for route handlers

Files:

  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
**/*.ts

📄 CodeRabbit inference engine (.cursorrules)

On the server use the getTranslations function from @/i18n/server to get the translations

Files:

  • apps/landing/next.config.ts
  • apps/web/next.config.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/landing/src/app/[locale]/globals.css
  • apps/web/src/globals.css
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/card.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/card.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/switch.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • packages/ui/src/card.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/globals.css
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/separator.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Always use the `useDialog` hook from `rallly/ui/dialog` for managing dialog state instead of manual `useState` for open/close state

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use Biome for code formatting with indent of 2 spaces and double quotes

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • apps/web/src/components/empty-state.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/shared-styles.css
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translatable

Applied to files:

  • packages/ui/src/table.tsx
  • apps/web/src/app/[locale]/layout.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translated using either the Trans component or the useTranslation hook

Applied to files:

  • packages/ui/src/table.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • apps/landing/src/app/[locale]/globals.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/globals.css
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • apps/landing/src/app/[locale]/globals.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/globals.css
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Create separate import statements for types

Applied to files:

  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/next.config.ts
  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers

Applied to files:

  • apps/landing/next.config.ts
📚 Learning: 2025-08-08T11:21:25.231Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1890
File: apps/web/src/app/[locale]/(space)/(dashboard)/events/page.tsx:105-113
Timestamp: 2025-08-08T11:21:25.231Z
Learning: In this repository’s Next.js App Router pages, `params` and `searchParams` are typed as Promises per Async Request APIs, and should be awaited in server components (e.g., apps/web/src/app/[locale]/(space)/(dashboard)/events/page.tsx).

Applied to files:

  • apps/landing/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)

Applied to files:

  • apps/landing/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Prefer implicit return values over explicit return values

Applied to files:

  • apps/landing/next.config.ts
📚 Learning: 2025-09-12T21:37:47.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1951
File: packages/ui/src/dialog.tsx:23-25
Timestamp: 2025-09-12T21:37:47.353Z
Learning: React.ElementRef is deprecated and has been replaced by React.ComponentRef for TypeScript ref typing in React components, including Radix UI forwardRef components.

Applied to files:

  • packages/ui/src/switch.tsx
🧬 Code graph analysis (1)
apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1)
apps/landing/src/i18n/client/link.tsx (1)
  • LinkBase (7-26)
⏰ 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). (1)
  • GitHub Check: Integration tests
🔇 Additional comments (51)
packages/ui/src/breadcrumb.tsx (1)

21-24: Tailwind v4 word-wrap class update looks correct.

Switching to wrap-break-word matches Tailwind v4 naming and should preserve prior breadcrumb wrapping behavior.

packages/ui/src/textarea.tsx (1)

13-13: LGTM! Correct Tailwind v4 migration.

The change from outline-none to outline-hidden correctly follows the Tailwind v4 breaking change where outline-none now only removes the outline style, while outline-hidden completely removes the outline. This maintains the intended behavior of hiding the focus outline.

apps/web/src/components/forms/poll-options-form/rbc-overrides.css (13)

1-5: Looks good; explicit borders are clear and consistent.


7-9: color-mix() is fine, but ensure your supported browsers match this usage. If you support older browsers than Tailwind v4’s baseline, this may need a fallback.


15-19: Good conversion to design-system border color.


21-23: Looks fine; relies on RBC border defaults (intentional).


25-27: LGTM.


33-35: LGTM.


37-40: LGTM (spacing matches prior Tailwind values).


42-44: LGTM.


46-49: Check that dashed borders render as expected with RBC defaults. You set border-style/border-color but not width; if RBC changes widths, this may vary.


51-53: LGTM.


55-59: color-mix() usage is consistent with the new style; verify contrast/readability in selection state.


66-70: Confirm pointer-events: none doesn’t break expected keyboard/mouse interactions. If this is meant to prevent navigation but still allow focus/ARIA interactions, consider a different approach.


76-78: LGTM.

packages/ui/src/separator.tsx (1)

22-22: LGTM! Improved use of standard Tailwind utilities.

Replacing arbitrary values h-[1px] and w-[1px] with the standard h-px and w-px utilities is a best practice improvement. The semantics remain identical while making the code more idiomatic.

apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1)

56-60: Tailwind v4 CSS variable width syntax looks correct.
w-(--radix-dropdown-menu-trigger-width) matches the v4 “CSS variables use parentheses” rule and should keep the dropdown width aligned with the trigger.

apps/web/src/components/empty-state.tsx (1)

25-25: Tailwind v4 gradient syntax is correct. The bg-linear-to-b from-gray-50 to-white pattern follows the v4 naming convention for linear gradients with color stops.

apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1)

15-15: LGTM! Design refinement applied consistently.

The change from rounded to rounded-sm reduces the border radius for a subtler visual appearance. While not required by Tailwind v4, this intentional design refinement is valid and aligns with similar updates across the codebase.

apps/web/src/components/cookie-consent.tsx (1)

56-56: LGTM! Shadow utility updated for Tailwind v4.

The change from shadow-sm to shadow-xs aligns with the broader design system update across the codebase. The opacity syntax (hover:bg-primary-600/90) correctly uses Tailwind v4's slash notation.

apps/web/src/app/[locale]/(auth)/layout.tsx (1)

37-37: LGTM! Correct Tailwind v4 mask utility syntax.

The migration from arbitrary property syntax [mask-image:...] to utility-based syntax mask-[...] is correct for Tailwind v4. The mask utility is supported in v4, and this change will produce identical visual results while following modern Tailwind conventions.

apps/web/src/components/discussion/discussion.tsx (1)

259-259: LGTM! Tailwind v4 migration applied correctly.

The className changes align with Tailwind v4 requirements:

  • outline-noneoutline-hidden is the correct migration path, as v4 changed the behavior of outline-none to only remove the outline style rather than hiding it completely.
  • roundedrounded-sm standardizes border radius across the UI.
  • Accessibility is preserved: the custom focus ring (focus-visible:ring-2 with offset) provides a clear focus indicator.
packages/ui/src/card.tsx (1)

12-12: LGTM! Shadow utility updated for Tailwind v4.

The change from shadow-sm to shadow-2xs aligns with Tailwind v4's refined shadow scale, making the card's drop shadow more subtle. The syntax and approach are correct for the migration.

packages/ui/src/command.tsx (5)

39-39: Tailwind v4 selector syntax migration looks correct.

The migration from [&_[cmdk-group-heading]]: to [[cmdk-group-heading]]:**: correctly adopts Tailwind v4's arbitrary selector syntax combined with the new :** descendant combinator.


61-61: Correct Tailwind v4 outline utility migration.

The change from outline-none to outline-hidden is required for Tailwind v4, where outline-none now only removes the outline style rather than hiding it completely.


104-104: Tailwind v4 selector syntax applied consistently.

The [[cmdk-group-heading]]:**: pattern is correctly applied here, matching the migration pattern used throughout the file.


132-132: Correct Tailwind v4 outline utility migration.

Consistently applies the outline-hidden change required for Tailwind v4 compatibility.


148-148: Tailwind v4 outline utility migration complete.

Final outline-none to outline-hidden change completes the consistent migration across all command components.

packages/ui/src/billing-plan.tsx (1)

12-12: No changes needed. Both shadow-2xs and backdrop-blur-xs are valid Tailwind v4 utilities according to official documentation.

apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3)

177-177: Focus state border radius updated for consistency.

The focus state has been made more explicit with focus:rounded-sm. This reduces the border radius from the default rounded to rounded-sm, making it consistent with the overall calendar cell styling.


190-190: Good catch on the z-index utility correction.

The change from -z-0 to z-0 is correct. Tailwind doesn't have a standard -z-0 utility, and z-0 is the proper way to explicitly set z-index: 0 for the selection indicator to layer correctly behind the day number.


125-125: [rewritten comment]
[classification tag]

apps/landing/src/app/[locale]/(main)/pricing/page.tsx (1)

154-154: LGTM! Tailwind v4 gradient and shadow syntax correctly applied.

The changes correctly migrate to Tailwind v4 syntax: bg-gradient-to-bbg-linear-to-b for gradients and shadow-smshadow-xs for the updated shadow scale.

apps/landing/src/app/[locale]/globals.css (1)

1-8: LGTM! Tailwind v4 import structure correctly implemented.

The new globals file uses the correct Tailwind v4 import syntax with @import "tailwindcss"; and properly references the shared configuration.

apps/landing/next.config.ts (1)

1-7: ES module imports correctly applied for Tailwind v4 migration.

The migration to ES module imports (import type { NextConfig } and import createBundleAnalyzer) is correct. Note that there's an existing comment about replacing module.exports with export default at line 129 for full ESM consistency.

packages/tailwind-config/shared-styles.css (3)

4-102: LGTM! Comprehensive Tailwind v4 theme configuration.

The @theme block correctly defines design tokens using CSS custom properties, keyframes, and follows v4 conventions. The wiggle animation is properly structured.


112-120: Well-documented v4 compatibility layer.

The border-color compatibility styles are clearly documented and provide a smooth transition path. The comment correctly explains that these can be removed once explicit border utilities are added throughout the codebase.


122-124: Correct use of outline-hidden for Tailwind v4.

The text-link utility correctly uses outline-hidden instead of the deprecated approach, aligning with Tailwind v4 where outline-none only removes the outline style rather than completely hiding it.

apps/web/next.config.ts (1)

5-11: ES module imports correctly applied.

The migration to ES module syntax with proper type imports and createBundleAnalyzer initialization is correct and consistent with Next.js 15 conventions.

apps/web/src/globals.css (1)

1-4: LGTM! Tailwind v4 imports correctly configured.

The new globals file properly uses Tailwind v4's import syntax and references the shared configuration package.

apps/web/src/app/[locale]/layout.tsx (1)

1-1: LGTM! CSS import updated for new globals location.

The import path correctly references the new locale-specific globals.css file introduced in this Tailwind v4 migration.

packages/ui/src/sidebar.tsx (2)

136-138: Nice Tailwind v4 selector migration (has-data-[...]).


440-444: Tailwind v4 class updates look consistent (outline-hidden, important modifier at end, CSS-var parens).

Also applies to: 461-466, 513-528, 673-680, 726-732

packages/ui/src/tabs.tsx (2)

25-37: Focus outline change looks correct for Tailwind v4 (outline-none → outline-hidden).


40-52: Focus outline change looks correct for Tailwind v4 (outline-none → outline-hidden).

packages/ui/src/switch.tsx (1)

8-20: Tailwind v4 focus outline update is fine.

packages/ui/src/toast.tsx (2)

26-40: CSS variable parentheses syntax for Tailwind v4 looks right; please sanity-check swipe behavior.


57-86: Outline-none → outline-hidden updates look consistent with Tailwind v4.

packages/ui/src/dropdown-menu.tsx (3)

35-53: Tailwind v4 selector/outline updates look good; verify Radix emits data-disabled for these nodes.


57-69: min-w-32 seems fine (8rem); should be a safe replacement for min-w-[8rem].


91-105: data-[disabled]data-disabled variant migration is reasonable; validate disabled styling still applies in UI.

Also applies to: 126-148, 152-173

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

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

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

Caution

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

⚠️ Outside diff range comments (1)
packages/ui/src/dialog.tsx (1)

76-108: Remove the redundant data-slot prop from <DialogPortal> call

DialogPortal already renders data-slot="dialog-portal" internally, so passing it at the call site is redundant:

-    <DialogPortal data-slot="dialog-portal">
+    <DialogPortal>
       <DialogOverlay />

All other Dialog component wrappers follow the same pattern where data-slot is set internally, not at the call site.

🧹 Nitpick comments (3)
packages/ui/src/input.tsx (1)

19-21: The error variant duplicates the aria-invalid styling already defined in base classes.

Lines 10 applies destructive styling via aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40. The error: true variant repeats the same classes. Consider whether this variant is necessary, or if setting aria-invalid="true" on the input would suffice.

apps/web/src/components/new-participant-modal.tsx (1)

184-190: VoteSummary is wrapped in FormItem/FormControl without a corresponding form field.

The VoteSummary is display-only and not connected to any form field via FormField. The FormMessage here will never display anything since there's no field context. Consider using a plain container instead of form primitives for this read-only display.

-        <FormItem>
-          <FormLabel>{t("response")}</FormLabel>
-          <FormControl>
-            <VoteSummary votes={props.votes} />
-          </FormControl>
-          <FormMessage />
-        </FormItem>
+        <div className="grid gap-1.5">
+          <Label>{t("response")}</Label>
+          <VoteSummary votes={props.votes} />
+        </div>

Note: This would require importing Label from @rallly/ui/label.

packages/ui/src/dialog.tsx (1)

12-37: Wrapper components drop ref support; consider using React.forwardRef for frequently-accessed elements

The current wrapper components (Dialog, DialogTrigger, DialogPortal, DialogClose, DialogHeader, DialogFooter, DialogTitle, DialogDescription) are plain function components and don't forward refs. While no current usage of refs on these components was found in the codebase, converting frequently-accessed ones (e.g., DialogContent, DialogTitle, DialogDescription) to React.forwardRef would align with shadcn-ui patterns and enable ref access if needed.

If adding forwardRef support, use React.ComponentRef instead of the deprecated React.ElementRef:

-function DialogTitle({
-  className,
-  ...props
-}: React.ComponentProps<typeof DialogPrimitive.Title>) {
-  return (
-    <DialogPrimitive.Title
-      data-slot="dialog-title"
-      className={cn("font-semibold text-lg leading-none", className)}
-      {...props}
-    />
-  );
-}
+const DialogTitle = React.forwardRef<
+  React.ComponentRef<typeof DialogPrimitive.Title>,
+  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
+>(({ className, ...props }, ref) => (
+  <DialogPrimitive.Title
+    ref={ref}
+    data-slot="dialog-title"
+    className={cn("font-semibold text-lg leading-none", className)}
+    {...props}
+  />
+));
+DialogTitle.displayName = DialogPrimitive.Title.displayName;

Also applies to: 110-131, 133-157, 189-200

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 265ef9a and 15c6d07.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • apps/landing/next.config.ts (3 hunks)
  • apps/web/next.config.ts (2 hunks)
  • apps/web/package.json (3 hunks)
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1 hunks)
  • apps/web/src/components/layouts/poll-layout.tsx (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (4 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/dialog.tsx (4 hunks)
  • packages/ui/src/form.tsx (1 hunks)
  • packages/ui/src/input.tsx (1 hunks)
  • packages/ui/src/textarea.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/ui/src/textarea.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/next.config.ts
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/next.config.ts
  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/next.config.ts
  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/package.json
  • apps/web/next.config.ts
  • packages/ui/src/form.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/package.json
  • apps/web/next.config.ts
  • packages/ui/src/form.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/next.config.ts
  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/next.config.ts
  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/src/components/new-participant-modal.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/next.config.ts
  • apps/web/src/components/new-participant-modal.tsx
**/*.ts

📄 CodeRabbit inference engine (.cursorrules)

On the server use the getTranslations function from @/i18n/server to get the translations

Files:

  • apps/web/next.config.ts
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • packages/ui/src/dialog.tsx
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • apps/web/package.json
  • packages/tailwind-config/package.json
  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • apps/web/package.json
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • apps/web/package.json
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Create separate import statements for types

Applied to files:

  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • packages/ui/src/form.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use react-hook-form for form handling

Applied to files:

  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/tailwind-config/package.json
📚 Learning: 2025-09-12T21:37:47.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1951
File: packages/ui/src/dialog.tsx:23-25
Timestamp: 2025-09-12T21:37:47.353Z
Learning: React.ElementRef is deprecated and has been replaced by React.ComponentRef for TypeScript ref typing in React components, including Radix UI forwardRef components.

Applied to files:

  • packages/ui/src/input.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Prefer inline prop types over named interfaces for simple component props (e.g., `function Component({ prop }: { prop: string })` instead of defining a separate interface)

Applied to files:

  • packages/ui/src/input.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/input.tsx
  • packages/ui/src/dialog.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use react-hook-form with Zod validation for form state management

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Use zod for form validation

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use React Context for client state (auth, preferences, etc.)

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Always use the `useDialog` hook from `rallly/ui/dialog` for managing dialog state instead of manual `useState` for open/close state

Applied to files:

  • packages/ui/src/dialog.tsx
🧬 Code graph analysis (3)
packages/ui/src/form.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
packages/ui/src/input.tsx (2)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
packages/ui/src/index.ts (1)
  • cn (1-1)
packages/ui/src/dialog.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
⏰ 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). (2)
  • GitHub Check: Integration tests
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (11)
apps/web/src/components/layouts/poll-layout.tsx (1)

31-31: The positioning change is correct. The switch from absolute inset-0 to h-dvh is appropriate for this layout component, which has no positioned parent container in its usage context. The parent layout hierarchy only applies providers without any positioning setup. Using h-dvh with overscroll-none is the right modernization and aligns with the component's actual role as a full-page layout container.

Likely an incorrect or invalid review comment.

apps/web/next.config.ts (1)

5-7: LGTM! Clean ESM migration with proper TypeScript typing.

The migration from CommonJS to ESM is well-executed:

  • Type imports properly separated (line 5) per coding guidelines
  • Explicit NextConfig type annotation for type safety
  • Bundle analyzer correctly initialized with createBundleAnalyzer
  • Default export pattern maintains existing functionality

The config structure and behavior remain unchanged while modernizing to ESM syntax compatible with Next.js 15.

Also applies to: 9-11, 13-13, 122-125

packages/tailwind-config/package.json (1)

5-17: LGTM! Package restructuring successfully addresses previous concerns.

The package has been properly migrated to ESM with a clean exports structure:

  • "type": "module" enables ES modules
  • Exports map correctly exposes shared styles and PostCSS config
  • @tailwindcss/postcss is now declared as a dependency (line 11), resolving the previous review concern about the missing dependency
  • All Tailwind v4 dependencies are present with compatible versions

The exported PostCSS config is now self-contained and will resolve reliably for consuming packages.

packages/ui/src/form.tsx (1)

75-75: LGTM!

The layout change from vertical stack (space-y-2.5) to grid (grid gap-1.5) is appropriate for Tailwind v4 and provides consistent spacing between form item children.

packages/ui/src/input.tsx (1)

47-49: LGTM!

Deriving InputProps from React.ComponentProps<typeof Input> is a clean pattern that keeps the type in sync with the actual component signature.

apps/web/src/components/new-participant-modal.tsx (3)

26-35: LGTM!

The schema consolidation with conditional email validation via .refine() is clean. Using z.email().optional() with a refinement for conditional requirement is the idiomatic Zod 4 approach.


45-91: LGTM!

The VoteSummary component styling aligns with Tailwind v4 conventions and uses cn() appropriately for class composition.


101-114: LGTM!

Form initialization properly integrates zodResolver with the consolidated schema and handles default values for both logged-in and guest users.

packages/ui/src/dialog.tsx (3)

7-7: React default import + module APIs are appropriate here

Importing React as a default export matches your use of React.useState, React.useRef, and React.ComponentProps in this file and aligns with the guideline to prefer the React module APIs over standalone hooks. No changes needed.

As per coding guidelines, this matches the preferred React usage style.

Also applies to: 159-186


38-52: Dialog overlay styles and slot usage look consistent

DialogOverlay correctly wraps the Radix overlay, applies data-slot="dialog-overlay", and uses Tailwind 4-friendly classes (slash opacity, data-[state=*] variants) with cn() for composition. This aligns with the shared styling approach and looks good.


54-74: dialogVariants size handling is coherent and extensible

The dialogVariants cva setup, including the new "6xl" and "7xl" size variants and the base content positioning/animation classes, is consistent with the rest of the API and works cleanly with the size prop on DialogContent. No changes needed.

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)
packages/ui/src/form.tsx (1)

19-21: Strengthen context safety in useFormField (guards currently ineffective)

FormFieldContext and FormItemContext are initialized with {} as ..., so useFormField’s if (!fieldContext) check can never fire, and getFieldState(fieldContext.name, formState) is called before any guard. If someone accidentally calls useFormField outside <FormField> / <FormItem>, this will fail in a non-obvious way.

Consider typing the contexts as possibly undefined and guarding before using them:

-const FormFieldContext = React.createContext<FormFieldContextValue>(
-  {} as FormFieldContextValue,
-);
+const FormFieldContext = React.createContext<FormFieldContextValue | undefined>(
+  undefined,
+);

-const FormItemContext = React.createContext<FormItemContextValue>(
-  {} as FormItemContextValue,
-);
+const FormItemContext = React.createContext<FormItemContextValue | undefined>(
+  undefined,
+);

 const useFormField = () => {
   const fieldContext = React.useContext(FormFieldContext);
   const itemContext = React.useContext(FormItemContext);
-  const { getFieldState, formState } = useFormContext();
-
-  const fieldState = getFieldState(fieldContext.name, formState);
-
-  if (!fieldContext) {
-    throw new Error("useFormField should be used within <FormField>");
-  }
-
-  const { id } = itemContext;
+  if (!fieldContext) {
+    throw new Error("useFormField should be used within <FormField>");
+  }
+  if (!itemContext) {
+    throw new Error("useFormField should be used within <FormItem>");
+  }
+
+  const { getFieldState, formState } = useFormContext();
+  const fieldState = getFieldState(fieldContext.name, formState);
+  const { id } = itemContext;

   return {
     id,

This keeps the public API the same but makes misuse fail fast with clear errors.

Also applies to: 36-48, 59-65

packages/ui/src/button.tsx (1)

26-26: Consider using a semantic color token for consistency.

The ghost variant uses the hard-coded text-gray-800 class, while other variants use semantic tokens (e.g., text-destructive-foreground, text-white). For better maintainability and consistency with the design system, consider defining and using a semantic token like text-muted-foreground or similar.

Example:

-        "border-transparent bg-transparent text-gray-800 hover:bg-gray-500/10 active:bg-gray-500/20 data-[state=open]:bg-gray-500/20",
+        "border-transparent bg-transparent text-foreground hover:bg-gray-500/10 active:bg-gray-500/20 data-[state=open]:bg-gray-500/20",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15c6d07 and db49992.

📒 Files selected for processing (3)
  • apps/web/src/components/time-format-picker.tsx (1 hunks)
  • packages/ui/src/button.tsx (1 hunks)
  • packages/ui/src/form.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/web/src/components/time-format-picker.tsx
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • packages/ui/src/form.tsx
  • packages/ui/src/button.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • packages/ui/src/form.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use react-hook-form for form handling

Applied to files:

  • packages/ui/src/form.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/button.tsx
🧬 Code graph analysis (1)
packages/ui/src/form.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
⏰ 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). (2)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Integration tests
🔇 Additional comments (2)
packages/ui/src/form.tsx (1)

75-79: FormItem layout change looks consistent with the new design system

Switching to flex flex-col items-start space-y-1.5 tightens vertical spacing and makes alignment explicit while still allowing consumers to override via className (thanks to cn). This should be a safe visual-only change.

packages/ui/src/button.tsx (1)

12-12: LGTM! Comprehensive base button styling.

The expanded base styles provide robust styling with proper focus management, accessibility states, and sophisticated SVG child handling. The outline-none paired with focus-visible:ring ensures proper keyboard navigation visibility while avoiding unwanted focus rings on mouse clicks.

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)
apps/web/src/components/discussion/discussion.tsx (1)

110-125: Add visible error messages for validation feedback.

The shift from error prop to aria-invalid improves accessibility, but users now have no visual feedback when validation fails. Consider wrapping the Input with FormItem/FormField/FormMessage or displaying formState.errors.authorName?.message to inform users why form submission is blocked.

Apply this diff to add error message display:

        <Controller
          name="authorName"
          key={user?.id}
          control={control}
          rules={{ validate: requiredString }}
          render={({ field }) => (
-            <Input
-              placeholder={t("yourName")}
-              className="lg:w-48"
-              data-1p-ignore="true"
-              aria-invalid={!!formState.errors.authorName}
-              {...field}
-            />
+            <>
+              <Input
+                placeholder={t("yourName")}
+                className="lg:w-48"
+                data-1p-ignore="true"
+                aria-invalid={!!formState.errors.authorName}
+                {...field}
+              />
+              {formState.errors.authorName && (
+                <p className="text-destructive text-sm mt-1">
+                  {t("fieldRequired")}
+                </p>
+              )}
+            </>
          )}
        />

Note: The same issue affects the content Textarea at line 97-103.

♻️ Duplicate comments (8)
packages/ui/src/billing-plan.tsx (1)

38-40: Remove unused discount prop.

The discount?: React.ReactNode prop is declared but never used in the component body. This was previously flagged and should be removed.

packages/ui/src/form.tsx (1)

75-79: Explicit flex layout is a good structural improvement.

The flex flex-col items-start addition makes the layout behavior explicit rather than relying on implicit block stacking. The items-start alignment ensures form elements don't stretch unexpectedly.

The spacing reduction concern has already been flagged in a previous review.

apps/web/src/components/new-participant-modal.tsx (1)

134-140: Non-TRPC error handling gap already flagged.

This concern has been raised in previous reviews.

apps/landing/next.config.ts (1)

9-14: Add validation for NEXT_PUBLIC_APP_BASE_URL to fail fast with a clear error.

new URL(subpath, appBaseUrl) throws a TypeError if appBaseUrl is undefined. Adding early validation provides a clearer error message during build.

 const appBaseUrl = process.env.NEXT_PUBLIC_APP_BASE_URL;

 function createAppUrl(subpath: string) {
+  if (!appBaseUrl) {
+    throw new Error("NEXT_PUBLIC_APP_BASE_URL is required for redirects");
+  }
   const url = new URL(subpath, appBaseUrl);
   return url.href;
 }
apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1)

29-31: Undefined CSS variables --color-rose-400 and --color-rose-600.

These variables are not defined in the theme. Tailwind's default rose-600 is #e11d48, which matches the project's --color-destructive, but rose-400 (#fb7185) has no equivalent in the current design system.

Recommended approach: Add the rose color variables to packages/tailwind-config/shared-styles.css:

@theme {
  --color-destructive: #e11d48;
  --color-destructive-background: #fff1f2;
  --color-destructive-foreground: #fff1f2;
+
+  --color-rose-400: #fb7185;
+  --color-rose-600: #e11d48;

Alternatively, use --color-destructive only for the rose-600 reference:

 .rbc-header.rbc-today {
   background-color: var(--color-background);
-  color: var(--color-rose-600);
+  color: var(--color-destructive);
 }

For rose-400, either add the variable to the theme or use a different existing color if semantically appropriate.

packages/ui/src/table.tsx (1)

76-76: Incorrect variant order in checkbox selector migration.

The selector migration from [&>[role=checkbox]] to [[role=checkbox]]:*: has the variant order backwards. The new syntax means "if this element has role=checkbox, apply to all children", but the original targeted "direct children that have role=checkbox". The correct Tailwind v4 syntax should be *:[[role=checkbox]]: to first select children then filter by the attribute.

Apply this diff to fix the selector order:

-      "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [[role=checkbox]]:*:translate-y-[2px]",
+      "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 *:[[role=checkbox]]:translate-y-[2px]",

And for TableCell:

-      "p-2 align-middle [&:has([role=checkbox])]:pr-0 [[role=checkbox]]:*:translate-y-[2px]",
+      "p-2 align-middle [&:has([role=checkbox])]:pr-0 *:[[role=checkbox]]:translate-y-[2px]",

Also applies to: 91-91

packages/ui/src/command.tsx (1)

33-34: Command dialog now renders centered instead of top-positioned.

The removal of position="top" (which was dropped from DialogContent entirely) changes the UX of the command palette. Command palettes conventionally appear near the top of the screen for quick access. If this is intentional, consider documenting the change; otherwise, the top positioning can be restored via custom className.

The Tailwind v4 selector syntax updates ([[cmdk-*]]:**:) and showCloseButton={false} prop alignment look correct.

packages/ui/src/button.tsx (1)

19-24: Destructive and secondary variants are missing border width class.

The border-destructive and border-secondary classes only set border color. Without the border class for width, these variants will have no visible border.

Apply this diff to fix:

         destructive:
-          "border-destructive bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-destructive",
+          "border border-destructive bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-destructive",
         default:
           "border bg-white shadow-xs hover:bg-gray-50 active:bg-gray-100",
         secondary:
-          "border-secondary bg-secondary text-secondary-foreground hover:bg-secondary/80 focus-visible:ring-offset-1",
+          "border border-secondary bg-secondary text-secondary-foreground hover:bg-secondary/80 focus-visible:ring-offset-1",
🧹 Nitpick comments (1)
apps/web/src/components/new-participant-modal.tsx (1)

194-203: Action button layout is clean.

The button group properly handles cancel/submit with loading state on the submit button. Consider wrapping the cancel Button with type="button" to explicitly prevent form submission on click, though the current behavior may work due to the default type being "button" for non-submit buttons.

         <div className="mt-6 flex gap-2">
-          <Button onClick={props.onCancel}>{t("cancel")}</Button>
+          <Button type="button" onClick={props.onCancel}>{t("cancel")}</Button>
           <Button
             type="submit"
             variant="primary"
             loading={formState.isSubmitting}
           >
             {t("submit")}
           </Button>
         </div>
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8cae50 and a66f9dd.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (90)
  • apps/landing/next.config.ts (3 hunks)
  • apps/landing/package.json (1 hunks)
  • apps/landing/postcss.config.js (0 hunks)
  • apps/landing/postcss.config.mjs (1 hunks)
  • apps/landing/src/app/[locale]/(main)/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx (1 hunks)
  • apps/landing/src/app/[locale]/globals.css (1 hunks)
  • apps/landing/src/app/[locale]/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1 hunks)
  • apps/landing/src/components/home/bonus-item.tsx (1 hunks)
  • apps/landing/src/style.css (0 hunks)
  • apps/landing/tailwind.config.js (0 hunks)
  • apps/web/next.config.ts (2 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.js (0 hunks)
  • apps/web/postcss.config.mjs (1 hunks)
  • apps/web/src/app/[locale]/(auth)/forgot-password/components/forgot-password-form.tsx (0 hunks)
  • apps/web/src/app/[locale]/(auth)/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/(auth)/login/components/login-email-form.tsx (0 hunks)
  • apps/web/src/app/[locale]/(auth)/reset-password/components/reset-password-form.tsx (0 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/settings/general/components/delete-space-button.tsx (0 hunks)
  • apps/web/src/app/[locale]/(space)/settings/general/components/leave-space-button.tsx (0 hunks)
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/settings/profile/delete-account-dialog.tsx (0 hunks)
  • apps/web/src/app/[locale]/(space)/settings/security/components/change-password-form.tsx (0 hunks)
  • apps/web/src/app/[locale]/(space)/settings/spaces/components/leave-space-dialog.tsx (0 hunks)
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/globals.css (1 hunks)
  • apps/web/src/app/[locale]/layout.tsx (1 hunks)
  • apps/web/src/app/components/page-layout.tsx (1 hunks)
  • apps/web/src/components/cookie-consent.tsx (1 hunks)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/discussion/discussion.tsx (2 hunks)
  • apps/web/src/components/empty-state.tsx (1 hunks)
  • apps/web/src/components/forms/poll-details-form.tsx (0 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1 hunks)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1 hunks)
  • apps/web/src/components/full-width-layout.tsx (1 hunks)
  • apps/web/src/components/layouts/poll-layout.tsx (1 hunks)
  • apps/web/src/components/maintenance.tsx (1 hunks)
  • apps/web/src/components/modal/modal.tsx (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (3 hunks)
  • apps/web/src/components/poll/desktop-poll.tsx (2 hunks)
  • apps/web/src/components/poll/scheduled-event.tsx (1 hunks)
  • apps/web/src/components/skeleton.tsx (1 hunks)
  • apps/web/src/components/time-format-picker.tsx (1 hunks)
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx (1 hunks)
  • apps/web/src/components/vote-summary-progress-bar.tsx (1 hunks)
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx (4 hunks)
  • apps/web/src/globals.css (1 hunks)
  • apps/web/src/style.css (0 hunks)
  • apps/web/tailwind.config.js (0 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.mjs (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/tailwind-config/tailwind.config.d.ts (0 hunks)
  • packages/tailwind-config/tailwind.config.js (0 hunks)
  • packages/ui/components.json (0 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/alert.tsx (1 hunks)
  • packages/ui/src/avatar.tsx (1 hunks)
  • packages/ui/src/badge.tsx (1 hunks)
  • packages/ui/src/billing-plan.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/button.tsx (1 hunks)
  • packages/ui/src/card.tsx (1 hunks)
  • packages/ui/src/checkbox.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/dialog.tsx (3 hunks)
  • packages/ui/src/dropdown-menu.tsx (5 hunks)
  • packages/ui/src/form.tsx (1 hunks)
  • packages/ui/src/input.tsx (1 hunks)
  • packages/ui/src/page-tabs.tsx (2 hunks)
  • packages/ui/src/popover.tsx (1 hunks)
  • packages/ui/src/progress.tsx (1 hunks)
  • packages/ui/src/radio-group.tsx (1 hunks)
  • packages/ui/src/select.tsx (3 hunks)
  • packages/ui/src/separator.tsx (1 hunks)
  • packages/ui/src/sheet.tsx (1 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
  • packages/ui/src/switch.tsx (1 hunks)
  • packages/ui/src/table.tsx (2 hunks)
  • packages/ui/src/tabs.tsx (2 hunks)
  • packages/ui/src/textarea.tsx (1 hunks)
  • packages/ui/src/toast.tsx (4 hunks)
  • packages/ui/src/tooltip.tsx (1 hunks)
  • packages/ui/tailwind.config.js (0 hunks)
💤 Files with no reviewable changes (19)
  • apps/web/src/components/forms/poll-details-form.tsx
  • apps/web/src/app/[locale]/(auth)/reset-password/components/reset-password-form.tsx
  • apps/web/src/app/[locale]/(space)/settings/profile/delete-account-dialog.tsx
  • apps/landing/postcss.config.js
  • packages/tailwind-config/tailwind.config.d.ts
  • apps/web/src/app/[locale]/(space)/settings/security/components/change-password-form.tsx
  • apps/web/src/app/[locale]/(space)/settings/general/components/leave-space-button.tsx
  • apps/web/src/app/[locale]/(space)/settings/spaces/components/leave-space-dialog.tsx
  • apps/web/src/app/[locale]/(auth)/forgot-password/components/forgot-password-form.tsx
  • packages/ui/components.json
  • apps/web/src/app/[locale]/(space)/settings/general/components/delete-space-button.tsx
  • apps/web/src/style.css
  • apps/landing/tailwind.config.js
  • apps/web/tailwind.config.js
  • apps/web/src/app/[locale]/(auth)/login/components/login-email-form.tsx
  • packages/tailwind-config/tailwind.config.js
  • apps/landing/src/style.css
  • packages/ui/tailwind.config.js
  • apps/web/postcss.config.js
✅ Files skipped from review due to trivial changes (2)
  • apps/web/src/globals.css
  • apps/landing/src/components/home/bonus-item.tsx
🚧 Files skipped from review as they are similar to previous changes (35)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/progress.tsx
  • apps/landing/package.json
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/alert.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/layouts/poll-layout.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/postcss.config.mjs
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • apps/landing/postcss.config.mjs
  • packages/ui/src/sheet.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/components/modal/modal.tsx
  • packages/ui/src/popover.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/toast.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/globals.css
  • packages/ui/src/checkbox.tsx
  • apps/web/package.json
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/card.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/web/src/app/[locale]/layout.tsx
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/form.tsx
  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/next.config.ts
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/form.tsx
  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/next.config.ts
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/form.tsx
  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/form.tsx
  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/package.json
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/tailwind-config/package.json
  • apps/landing/next.config.ts
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/next.config.ts
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/form.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • packages/ui/src/textarea.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/form.tsx
  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/package.json
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • packages/tailwind-config/postcss.config.mjs
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/tailwind-config/package.json
  • apps/landing/next.config.ts
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/next.config.ts
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/form.tsx
  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/next.config.ts
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/form.tsx
  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/radio-group.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/input.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/next.config.ts
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/dialog.tsx
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/components/new-participant-modal.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/components/time-format-picker.tsx
  • apps/web/src/components/maintenance.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/next.config.ts
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • apps/web/src/components/new-participant-modal.tsx
apps/web/src/app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js App Router conventions for route handlers

Files:

  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
**/*.ts

📄 CodeRabbit inference engine (.cursorrules)

On the server use the getTranslations function from @/i18n/server to get the translations

Files:

  • apps/landing/next.config.ts
  • apps/web/next.config.ts
apps/web/src/features/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize features in apps/web/src/features/[feature]/ directory structure

Files:

  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
🧠 Learnings (30)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use react-hook-form for form handling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use React Context for client state (auth, preferences, etc.)
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • packages/ui/src/separator.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/badge.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/input.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Use dayjs for date handling

Applied to files:

  • apps/web/src/components/time-format-picker.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/package.json
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • packages/tailwind-config/postcss.config.mjs
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/package.json
  • apps/web/src/app/components/page-layout.tsx
  • packages/tailwind-config/postcss.config.mjs
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/package.json
  • packages/tailwind-config/package.json
  • packages/ui/src/command.tsx
  • packages/ui/src/textarea.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • packages/ui/src/form.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • packages/ui/src/dropdown-menu.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use react-hook-form for form handling

Applied to files:

  • packages/ui/src/form.tsx
  • packages/ui/src/input.tsx
  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • packages/ui/src/form.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • apps/web/src/components/full-width-layout.tsx
  • packages/ui/package.json
  • apps/web/src/app/components/page-layout.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/input.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/textarea.tsx
  • packages/ui/src/dialog.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx,json} : i18n keys are in camelCase

Applied to files:

  • packages/ui/package.json
  • apps/landing/src/app/[locale]/layout.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Create separate import statements for types

Applied to files:

  • packages/ui/package.json
  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translatable

Applied to files:

  • packages/ui/src/table.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/textarea.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translated using either the Trans component or the useTranslation hook

Applied to files:

  • packages/ui/src/table.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use the <Trans> component in client components from @/components/trans with the `defaults` prop to provide the default text

Applied to files:

  • packages/ui/src/table.tsx
  • apps/landing/src/app/[locale]/layout.tsx
📚 Learning: 2024-10-23T17:08:22.079Z
Learnt from: smncd
Repo: lukevella/rallly PR: 1408
File: apps/web/src/components/poll/mobile-poll/time-slot-option.tsx:3-3
Timestamp: 2024-10-23T17:08:22.079Z
Learning: The project does not use CSS modules, so suggestions should avoid introducing them.

Applied to files:

  • apps/landing/src/app/[locale]/layout.tsx
📚 Learning: 2025-02-12T04:21:35.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1557
File: packages/emails/src/templates/abandoned-checkout.tsx:0-0
Timestamp: 2025-02-12T04:21:35.353Z
Learning: In React components that display discount values in email templates, make the discount configurable through props with a default value to improve maintainability and reduce duplication.

Applied to files:

  • packages/ui/src/billing-plan.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it

Applied to files:

  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/input.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • packages/tailwind-config/package.json
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers

Applied to files:

  • apps/landing/next.config.ts
  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)

Applied to files:

  • apps/landing/next.config.ts
  • packages/ui/src/input.tsx
📚 Learning: 2025-09-12T21:37:47.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1951
File: packages/ui/src/dialog.tsx:23-25
Timestamp: 2025-09-12T21:37:47.353Z
Learning: React.ElementRef is deprecated and has been replaced by React.ComponentRef for TypeScript ref typing in React components, including Radix UI forwardRef components.

Applied to files:

  • packages/ui/src/input.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Prefer inline prop types over named interfaces for simple component props (e.g., `function Component({ prop }: { prop: string })` instead of defining a separate interface)

Applied to files:

  • packages/ui/src/input.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Always use the `useDialog` hook from `rallly/ui/dialog` for managing dialog state instead of manual `useState` for open/close state

Applied to files:

  • packages/ui/src/input.tsx
  • packages/ui/src/command.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/dialog.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use Biome for code formatting with indent of 2 spaces and double quotes

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use react-hook-form with Zod validation for form state management

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-06-14T16:32:39.967Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1776
File: apps/web/src/auth/adapters/prisma.ts:40-60
Timestamp: 2025-06-14T16:32:39.967Z
Learning: In the Rallly codebase, optional user fields like timeZone, weekStart, timeFormat, and locale correspond to nullable database columns, so passing undefined values won't cause insert failures.

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use React Context for client state (auth, preferences, etc.)

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Use zod for form validation

Applied to files:

  • apps/web/src/components/new-participant-modal.tsx
🧬 Code graph analysis (6)
apps/web/src/components/time-format-picker.tsx (1)
packages/ui/src/radio-group.tsx (1)
  • RadioGroupItem (44-44)
packages/ui/src/form.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
packages/ui/src/input.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
packages/ui/src/command.tsx (1)
packages/ui/src/dialog.tsx (1)
  • DialogContent (186-186)
apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1)
apps/landing/src/i18n/client/link.tsx (1)
  • LinkBase (7-26)
packages/ui/src/dialog.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
⏰ 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). (2)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Integration tests

}) {
return (
<header className="sticky top-0 z-10 rounded-t-lg border-b bg-background/90 px-3 py-4 backdrop-blur-sm md:px-6">
<header className="sticky top-0 z-10 rounded-t-lg border-b bg-background/90 px-3 py-4 backdrop-blur-xs md:px-6">
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for backdrop-blur-xs definition in theme config and codebase

echo "=== Checking tailwind-config for backdrop-blur definitions ==="
fd -type f \( -name "*.ts" -o -name "*.js" -o -name "*.json" \) packages/tailwind-config 2>/dev/null | xargs cat 2>/dev/null | grep -i "backdrop" -C 3

echo -e "\n=== All backdrop-blur usages in web app ==="
rg -n "backdrop-blur" apps/web --type-list 2>/dev/null | head -20

echo -e "\n=== Searching for backdrop-blur-xs specifically ==="
rg "backdrop-blur-xs" apps/web

echo -e "\n=== Checking theme configuration files ==="
fd theme -type f \( -name "*.ts" -o -name "*.js" -o -name "*.json" \) packages/tailwind-config 2>/dev/null

Repository: lukevella/rallly

Length of output: 589


🏁 Script executed:

#!/bin/bash
# List tailwind-config directory structure
echo "=== Tailwind config directory structure ==="
find packages/tailwind-config -type f -name "*.ts" -o -name "*.js" -o -name "*.json" | head -20

echo -e "\n=== Contents of main tailwind config files ==="
find packages/tailwind-config -maxdepth 2 -type f \( -name "*.ts" -o -name "index.ts" \) -exec sh -c 'echo "File: $1"; cat "$1"' _ {} \;

Repository: lukevella/rallly

Length of output: 189


🏁 Script executed:

#!/bin/bash
# Find tailwind config files
echo "=== Finding tailwind config files ==="
find . -maxdepth 3 -name "tailwind.config.*" -type f

echo -e "\n=== Checking package.json for tailwind version ==="
rg "tailwind" package.json apps/web/package.json

echo -e "\n=== Looking for theme customization in tailwind config ==="
rg -A 50 "theme\s*:" tailwind.config.* 2>/dev/null | head -100

echo -e "\n=== Check if backdrop-blur-xs exists in generated CSS or theme ==="
rg "backdrop-blur" packages/ --type-list 2>/dev/null

echo -e "\n=== List package.json for tailwind-config ==="
cat packages/tailwind-config/package.json

Repository: lukevella/rallly

Length of output: 931


🏁 Script executed:

#!/bin/bash
# Check the actual CSS theme configuration
echo "=== Contents of shared-styles.css ==="
cat packages/tailwind-config/shared-styles.css

echo -e "\n=== Contents of postcss.config.mjs ==="
cat packages/tailwind-config/postcss.config.mjs

Repository: lukevella/rallly

Length of output: 4081


Replace backdrop-blur-xs with valid Tailwind v4 backdrop-blur utility.

backdrop-blur-xs is not a valid Tailwind CSS v4 utility. The standard backdrop-blur scale includes: none, sm, (base), md, lg, xl, 2xl, 3xl. No custom definition exists in the project's theme configuration. Update to backdrop-blur-sm (smallest standard option) or backdrop-blur (base option) in:

  • apps/web/src/components/full-width-layout.tsx (line 13)
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
🤖 Prompt for AI Agents
In apps/web/src/components/full-width-layout.tsx around line 13 and in
apps/web/src/app/[locale]/(space)/settings/layout.tsx (search for
backdrop-blur-xs), replace the invalid Tailwind v4 utility "backdrop-blur-xs"
with a valid utility such as "backdrop-blur-sm" (or "backdrop-blur" if you
prefer the base option); update the className strings accordingly so they use
the supported backdrop-blur value.

@vercel vercel bot temporarily deployed to Preview – landing December 17, 2025 16:00 Inactive
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 (1)
packages/ui/src/command.tsx (1)

99-99: Migrate CommandGroup selectors to Tailwind 4 syntax for consistency.

Line 99 still uses the Tailwind 3 selector pattern [&_[cmdk-group-heading]]:, while Line 34 (CommandDialog) has been migrated to the Tailwind 4 pattern [[cmdk-group-heading]]:**:. For consistency with the v4 upgrade, update this line to match the new syntax.

Apply this diff to align with the Tailwind 4 migration:

-      "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:text-xs",
+      "overflow-hidden p-1 text-foreground [[cmdk-group-heading]]:**:px-2 [[cmdk-group-heading]]:**:py-1.5 [[cmdk-group-heading]]:**:font-medium [[cmdk-group-heading]]:**:text-muted-foreground [[cmdk-group-heading]]:**:text-xs",
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 232ae4f and 687cac0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx (4 hunks)
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx (2 hunks)
  • packages/ui/src/command.tsx (5 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • packages/ui/src/command.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • packages/ui/src/command.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • packages/ui/src/command.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/ui/src/command.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/command.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/ui/src/command.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • packages/ui/src/command.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • packages/ui/src/command.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
apps/web/src/app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js App Router conventions for route handlers

Files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use React Context for client state (auth, preferences, etc.)
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use react-hook-form for form handling
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Always use the `useDialog` hook from `rallly/ui/dialog` for managing dialog state instead of manual `useState` for open/close state

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use Biome for code formatting with indent of 2 spaces and double quotes

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Use dayjs for date handling

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
📚 Learning: 2025-09-02T11:43:51.643Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1927
File: apps/web/src/utils/ics.ts:100-100
Timestamp: 2025-09-02T11:43:51.643Z
Learning: In the Rallly application (lukevella/rallly), for non-all-day ICS events when timeZone is not set, the code intentionally uses UTC date components (getUTC*) with startInputType: "local" to create floating time events. This ensures all users see the exact same time regardless of their timezone, as the application stores times in UTC and wants consistent display for floating events.

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use react-hook-form with Zod validation for form state management

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Use zod for form validation

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use react-hook-form for form handling

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translatable

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translated using either the Trans component or the useTranslation hook

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use the <Trans> component in client components from @/components/trans with the `defaults` prop to provide the default text

Applied to files:

  • apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx
🧬 Code graph analysis (3)
packages/ui/src/command.tsx (1)
packages/ui/src/dialog.tsx (1)
  • DialogContent (186-186)
apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx (3)
packages/ui/src/form.tsx (1)
  • FormControl (164-164)
apps/web/src/components/time-format-picker.tsx (1)
  • TimeFormatPicker (39-39)
packages/ui/src/select.tsx (1)
  • SelectTrigger (135-135)
apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx (2)
packages/ui/src/form.tsx (1)
  • FormControl (164-164)
apps/web/src/components/poll/language-selector.tsx (1)
  • LanguageSelect (12-34)
⏰ 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). (2)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Integration tests
🔇 Additional comments (7)
packages/ui/src/command.tsx (2)

30-40: DialogContent refactor looks good; position change already noted.

The updates to DialogContent (explicit close button control, size, and padding) align with the Dialog API refactor described in the PR objectives. The new Command className uses Tailwind 4's [[selector]]:**: syntax for descendant matching, which is appropriate for the v4 upgrade.

Note: The position behavior change (centered instead of top-aligned) has already been flagged in a previous comment.


56-56: This change is correct and follows Tailwind CSS v4 migration requirements.

The replacement of outline-none with outline-hidden at lines 56, 127, and 143 is part of the official Tailwind CSS v3-to-v4 upgrade path. In v4, outline-none has been renamed to outline-hidden, making these changes consistent with the framework's latest standards.

apps/web/src/app/[locale]/(space)/settings/preferences/components/language-preference.tsx (2)

3-9: LGTM: FormControl import added correctly.

The import addition is necessary for the FormControl wrapper usage below and follows the existing import pattern.


54-60: LGTM: FormControl wrapper and width constraint applied correctly.

The FormControl wrapper provides proper form field context, and the w-fit utility appropriately constrains the select width for the preferences layout. The field wiring remains intact.

apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx (3)

3-9: LGTM: FormControl import added correctly.

The import addition is necessary for the FormControl wrapper introduced later in the file.


86-91: LGTM: TimeFormatPicker properly wrapped with FormControl.

The FormControl wrapper provides appropriate form field context for the custom TimeFormatPicker component, consistent with the pattern applied to LanguageSelect.


111-111: LGTM: Width constraint applied to SelectTrigger.

The w-fit utility appropriately constrains the select width for better layout in the preferences form.

Comment on lines 68 to 72
<TimeZoneSelect
className="w-fit"
value={field.value}
onValueChange={field.onChange}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find TimeZoneSelect component definition
find . -type f -name "*.tsx" -o -name "*.ts" | xargs rg -l "TimeZoneSelect" | head -20

Repository: lukevella/rallly

Length of output: 253


🏁 Script executed:

# Look at the date-time-preferences.tsx file around lines 68-72
cat -n apps/web/src/app/\[locale\]/\(space\)/settings/preferences/components/date-time-preferences.tsx | sed -n '60,85p'

Repository: lukevella/rallly

Length of output: 1043


🏁 Script executed:

# Find LanguageSelect usage in language-preference.tsx
find . -type f -name "language-preference.tsx" -exec cat -n {} \;

Repository: lukevella/rallly

Length of output: 3091


🏁 Script executed:

# Search for TimeFormatPicker usage to see if it's wrapped with FormControl
rg -B 5 -A 5 "TimeFormatPicker" apps/web/src/app/\[locale\]/\(space\)/settings/preferences/components/date-time-preferences.tsx

Repository: lukevella/rallly

Length of output: 862


🏁 Script executed:

# Find and examine TimeZoneSelect component definition
find . -type f \( -name "*.tsx" -o -name "*.ts" \) -exec grep -l "export.*TimeZoneSelect" {} \;

Repository: lukevella/rallly

Length of output: 123


🏁 Script executed:

cat -n apps/web/src/components/time-zone-picker/time-zone-select.tsx

Repository: lukevella/rallly

Length of output: 3942


Wrap TimeZoneSelect with FormControl for consistency.

TimeZoneSelect should be wrapped with FormControl to match the pattern used for LanguageSelect (in language-preference.tsx) and TimeFormatPicker (elsewhere in this file). All three components follow the same FormField/render pattern with value and onValueChange props, so they should all be consistently wrapped.

Change:

<FormItem>
  <FormLabel>
    <Trans i18nKey="timeZone" />
  </FormLabel>
  <TimeZoneSelect
    className="w-fit"
    value={field.value}
    onValueChange={field.onChange}
  />
</FormItem>

To:

<FormItem>
  <FormLabel>
    <Trans i18nKey="timeZone" />
  </FormLabel>
  <FormControl>
    <TimeZoneSelect
      className="w-fit"
      value={field.value}
      onValueChange={field.onChange}
    />
  </FormControl>
</FormItem>
🤖 Prompt for AI Agents
In
apps/web/src/app/[locale]/(space)/settings/preferences/components/date-time-preferences.tsx
around lines 68-72, wrap the existing TimeZoneSelect with a FormControl element
so it matches the FormField pattern used elsewhere: place a FormControl directly
around TimeZoneSelect (keeping className, value and
onValueChange={field.onChange} unchanged) inside the FormItem, and add an import
for FormControl if it’s not already imported.

error={!!form.formState.errors.spaceName}
placeholder={spaceName}
{...field}
/>
Copy link

Choose a reason for hiding this comment

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

Bug: Missing error styling on inputs after removing error prop

The error prop was removed from these Input components but no alternative was added for error styling. The new Input component uses aria-invalid for error states. Other files in this PR either wrap inputs in FormControl (which auto-sets aria-invalid) or explicitly add aria-invalid like in discussion.tsx. These inputs lack both approaches, so validation errors won't show the red border styling - only the error message will appear.

Additional Locations (2)

Fix in Cursor Fix in Web

@lukevella lukevella merged commit 20d2806 into main Dec 18, 2025
17 of 18 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants