Skip to content

refactor ui components#72

Merged
Israeltheminer merged 5 commits into
mainfrom
update-ui
Jan 3, 2026
Merged

refactor ui components#72
Israeltheminer merged 5 commits into
mainfrom
update-ui

Conversation

@Israeltheminer

@Israeltheminer Israeltheminer commented Jan 3, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added date range picker component for selecting date ranges with an improved calendar interface.
    • Enhanced input component with password visibility toggle, error messaging, and required field indicators.
  • Improvements

    • Reorganized conversations UI with a clearer two-panel layout for better content organization.
    • Added tooltips to conversation headers for better user context.
    • Improved keyboard accessibility for automation name editing (Enter/Space key support).
    • Strengthened email preview security with inline style sanitization.
    • Enhanced session management with automatic token refresh for more reliable authentication.

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

@coderabbitai

coderabbitai Bot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces date-picker component upgrades, authentication improvements, navigation routing updates, and significant UI refactoring. It adds react-datepicker and date-fns dependencies (package.json, globals.css), completely rewrites the date-range-picker component with a new CSS module and ReactDatePicker-based implementation, and updates auth logic in auth-server.ts and Convex RLS files to use centralized authComponent. Navigation links transition from /dashboard/{id} to /dashboard/{id}/chat across multiple files, with deletion of the [id]/route.ts handler. Conversations layout undergoes major DOM restructuring to separate left and right panels. Input component adds new public props (passwordToggle, errorMessage, label, required). Email preview gains inline-style sanitization, and various UI styling adjustments are applied throughout.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • talecorp/poc2#166: Directly modifies authentication integration codepaths, replacing/renaming authComponent and updating related Convex auth files alongside package.json dependency changes.
  • tale-project/poc2#416: Updates navigation routing to /dashboard/{id}/chat and removes the dashboard [id] route handler, aligning with this PR's routing migration.
  • tale-project/poc2#235: Modifies the same conversations layout and DOM structure (conversations.tsx, conversation-header.tsx, layout.tsx) with overlapping panel restructuring changes.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (13)
services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx (2)

47-47: Replace hardcoded color with semantic design token.

The hardcoded text-gray-500 should be replaced with text-muted-foreground to maintain consistency with the design system and the refactoring effort on line 56.

🔎 Proposed fix
-        <div className="mt-4 text-gray-500 text-center">
+        <div className="mt-4 text-muted-foreground text-center">

Based on learnings: Never use hardcoded Tailwind gray/black/white color utilities; use semantic colors like text-muted-foreground for secondary text.


52-52: Replace hardcoded error color with semantic design token.

The hardcoded text-red-500 should be replaced with text-destructive to maintain consistency with the design system.

🔎 Proposed fix
-        <div className="mt-4 text-red-500 text-center">{error}</div>
+        <div className="mt-4 text-destructive text-center">{error}</div>

Based on learnings: Never use hardcoded Tailwind color utilities; use semantic design-system colors for all UI states including errors.

services/platform/lib/auth/auth-server.ts (1)

177-177: Remove debug log statement.

This console.log({ isHttps, siteUrl }) appears to be leftover debug code. It logs environment configuration on every token retrieval attempt, which clutters logs in production and may expose configuration details unnecessarily.

🔎 Proposed fix
-    console.log({ isHttps, siteUrl });
services/platform/components/ui/email-preview.tsx (1)

366-373: Hardcoded user-facing text should use translation functions.

Per coding guidelines, user-facing UI text should not be hardcoded. The button labels "Hide"/"Show" and "quoted text" should use translation hooks/functions for i18n support.

🔎 Suggested approach
-            <span>{showQuoted ? 'Hide' : 'Show'} quoted text</span>
+            <span>{showQuoted ? t('email.hideQuotedText') : t('email.showQuotedText')}</span>

Import and use the appropriate translation hook (e.g., useTranslations or t function) based on your i18n setup.

services/platform/app/(app)/dashboard/[id]/automations/layout.tsx (4)

75-91: Consider adding optimistic updates for better UX.

The updateWorkflow mutation at line 85 updates the automation name. Per coding guidelines, consider using withOptimisticUpdate for immediate UI feedback while the mutation processes.

Also note line 86 uses type casting (params.amId as Id<'wfDefinitions'>), which violates the guidelines mentioned in the previous comment.


98-108: Use semantic <button> element instead of <span role="button">.

For better semantics and built-in accessibility, replace the <span> with a <button> element. This also applies to lines 110-121 below.

🔎 Proposed fix using semantic button
-            <span
-              role="button"
-              tabIndex={0}
-              onClick={handleClickAutomation}
-              className={cn(
-                'text-foreground',
-                automation?.name && 'text-muted-foreground cursor-pointer',
-              )}
-            >
+            <button
+              type="button"
+              onClick={handleClickAutomation}
+              className={cn(
+                'text-foreground bg-transparent border-0 p-0',
+                automation?.name && 'text-muted-foreground cursor-pointer',
+              )}
+            >
               {t('title')}&nbsp;&nbsp;
-            </span>
+            </button>

71-73: Optional: Consider memoizing handlers with useCallback.

The event handlers handleClickAutomation and handleSubmitAutomationName could be wrapped in useCallback for stability across re-renders, though this is a minor optimization since they're used with DOM elements.

Also applies to: 75-91


34-41: Remove type casting and add runtime type checks instead.

Lines 38, 47, and 86 use as type assertions, which violates the project's TypeScript guidelines. Since useParams() returns an untyped Record<string, string | string[]>, use runtime type checks to narrow the types before using them. For example, check with typeof params.id === 'string' before passing to API calls that expect specific types.

services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx (3)

214-223: Avoid type casting where possible.

Multiple as casts are used throughout (Lines 222-223, 294, 336). Per coding guidelines, prefer avoiding type casting. Consider using type guards or improving type inference.

🔎 Example for businessId
+  // Early validation with type guard
+  if (!businessId || typeof businessId !== 'string') {
+    return; // or handle error
+  }
+  // Now businessId is narrowed to string
+
   const handleSendMessages = async () => {
-    if (!businessId || typeof businessId !== 'string') {
-      toast({
-        title: tCommon('errors.organizationNotFound'),
-        variant: 'destructive',
-      });
-      return;
-    }
     // ...
-    organizationId: businessId as string,
+    organizationId: businessId,

For Convex Id<> types, consider creating a type-safe helper or ensuring the source data is properly typed upstream.


224-225: Address TODO placeholders for sender and message content.

The bulk message sending uses hardcoded placeholder values. Based on learnings, this is acceptable as a temporary placeholder until proper user context/profile features are added.

Would you like me to open an issue to track implementing proper user context for the sender field and adding message content input to the BulkSendMessagesDialog?


170-184: Fix id vs _id mismatch in selection state filter.

Line 173 filters using c._id, but selectedIds is populated with c.id values (line 113 and throughout handleConversationCheck). Since ConversationItem has both a Convex-internal _id field and a separate computed id string field, this mismatch will cause the filter to never match, breaking the "select all" checkbox logic. Change line 173 to use c.id instead:

Diff
-      const selectedInFilteredCount = filteredConversations.filter((c) =>
-        selectedIds.has(c._id),
+      const selectedInFilteredCount = filteredConversations.filter((c) =>
+        selectedIds.has(c.id),
services/platform/components/ui/input.tsx (2)

65-144: Consider consistent styling between password and non-password inputs.

The password toggle branch (lines 74-88) and non-password branch (lines 122-136) apply different focus ring styles:

  • Password inputs: Use only the base focus-visible:ring-2 ring-ring styling
  • Non-password inputs: Add ring-1 ring-border focus-visible:ring-primary for additional visual treatment

This creates visual inconsistency between input types. Unless this is an intentional design decision, consider applying consistent focus styling across both branches.

🔎 Suggested approach for consistency

Option 1: Apply the same additional ring styling to password inputs:

            <input
              id={id}
              type={inputType}
              autoComplete={resolvedAutoComplete}
              className={cn(
                inputVariants({ size }),
                'pr-10',
+               'ring-1 ring-border focus-visible:ring-primary',
                errorClassName,
                className,
              )}
              ref={ref}
              required={required}
              aria-invalid={hasError}
              {...props}
            />

Option 2: Remove the additional styling from non-password inputs to match password inputs (if the base styling is sufficient).


105-110: Inconsistent error icons: XCircle vs Info.

Password inputs display errors with XCircle icon (line 107), while non-password inputs use Info icon (line 139). This creates inconsistent error messaging across input types.

Unless the distinction is intentional (e.g., password errors are more critical), consider using the same icon for consistency.

🔎 Suggested fix for consistency

Use the same icon for both branches. For example, standardize on XCircle:

          {errorMessage && (
            <p className="text-sm text-destructive flex items-center gap-1.5">
-             <Info className="size-4" />
+             <XCircle className="size-4" />
              {errorMessage}
            </p>
          )}

Or standardize on Info for both if you prefer a less emphatic approach.

Also applies to: 137-142

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between e49f32c and 50d0a2b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (23)
  • package.json
  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/layout.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx
  • services/platform/app/(app)/dashboard/[id]/route.ts
  • services/platform/app/(app)/globals.css
  • services/platform/components/ui/button.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/components/ui/date-range-picker.module.css
  • services/platform/components/ui/date-range-picker.tsx
  • services/platform/components/ui/email-preview.tsx
  • services/platform/components/ui/input.tsx
  • services/platform/components/ui/navigation/mobile-navigation.tsx
  • services/platform/components/ui/navigation/navigation.tsx
  • services/platform/components/ui/navigation/tab-navigation.tsx
  • services/platform/components/ui/radio-group.tsx
  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
  • services/platform/convex/lib/rls/organization/get_organization_member.ts
  • services/platform/lib/auth/auth-server.ts
💤 Files with no reviewable changes (1)
  • services/platform/app/(app)/dashboard/[id]/route.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: USE implicit typing whenever possible in TypeScript
DO NOT use type casting. Avoid any, and unknown whenever possible in TypeScript

Files:

  • services/platform/components/ui/navigation/mobile-navigation.tsx
  • services/platform/components/ui/navigation/tab-navigation.tsx
  • services/platform/convex/lib/rls/organization/get_organization_member.ts
  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx
  • services/platform/lib/auth/auth-server.ts
  • services/platform/app/(app)/dashboard/[id]/automations/layout.tsx
  • services/platform/components/ui/navigation/navigation.tsx
  • services/platform/components/ui/date-range-picker.tsx
  • services/platform/components/ui/button.tsx
  • services/platform/components/ui/radio-group.tsx
  • services/platform/components/ui/email-preview.tsx
  • services/platform/components/ui/input.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: ALWAYS put imports at the top and exports at the bottom. Keep them sorted correctly
PREFER named exports. AVOID default exports (only if needed)

Files:

  • services/platform/components/ui/navigation/mobile-navigation.tsx
  • services/platform/components/ui/navigation/tab-navigation.tsx
  • services/platform/convex/lib/rls/organization/get_organization_member.ts
  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx
  • services/platform/lib/auth/auth-server.ts
  • services/platform/app/(app)/dashboard/[id]/automations/layout.tsx
  • services/platform/components/ui/navigation/navigation.tsx
  • services/platform/components/ui/date-range-picker.tsx
  • services/platform/components/ui/button.tsx
  • services/platform/components/ui/radio-group.tsx
  • services/platform/components/ui/email-preview.tsx
  • services/platform/components/ui/input.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,jsx}: Do NOT hardcode text, use the translation hooks/functions instead for user-facing UI in React/Next.js
CONSIDER ALWAYS TO add optimistic updates with withOptimisticUpdate for useMutation. If you decide to NOT add a optimistic update you need to provide a good reason why and comment the hook
USE useMemo, useCallback and memo at the right moment in React/Next.js
DO NOT overuse useEffect in React/Next.js
USE cva if a component has multiple variants in React/Next.js
AVOID router.refresh() in Next.js
CONSIDER TO preload queries with preloadQuery and usePreloadedQuery in React with Convex

Files:

  • services/platform/components/ui/navigation/mobile-navigation.tsx
  • services/platform/components/ui/navigation/tab-navigation.tsx
  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/layout.tsx
  • services/platform/components/ui/navigation/navigation.tsx
  • services/platform/components/ui/date-range-picker.tsx
  • services/platform/components/ui/button.tsx
  • services/platform/components/ui/radio-group.tsx
  • services/platform/components/ui/email-preview.tsx
  • services/platform/components/ui/input.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
**/convex/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/convex/**/*.{ts,tsx}: CONSIDER TO use rate limiting and action caching in Convex
DO NOT use .collect(), use for await (const ... of ...) instead in Convex

Files:

  • services/platform/convex/lib/rls/organization/get_organization_member.ts
  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
🧠 Learnings (45)
📚 Learning: 2025-07-03T08:43:49.346Z
Learnt from: CR
Repo: talecorp/poc PR: 0
File: .cursor/rules/next-best-practice.mdc:0-0
Timestamp: 2025-07-03T08:43:49.346Z
Learning: Applies to **/*.{tsx,jsx} : Use proper navigation with `useRouter` and `Link` components

Applied to files:

  • services/platform/components/ui/navigation/mobile-navigation.tsx
  • services/platform/components/ui/navigation/tab-navigation.tsx
  • services/platform/components/ui/navigation/navigation.tsx
📚 Learning: 2025-12-26T02:23:20.245Z
Learnt from: larryro
Repo: tale-project/tale PR: 35
File: services/platform/app/(app)/dashboard/[id]/chat/components/integration-approval-card.tsx:58-90
Timestamp: 2025-12-26T02:23:20.245Z
Learning: In services/platform/app/(app)/dashboard/[id]/chat/components/integration-approval-card.tsx, prefer reading the approving user from the authenticated session context rather than passing a userId from the frontend. The hardcoded 'user' string can be acceptable only as a temporary placeholder during the initial implementation until a user profile feature is added; plan to replace with proper user identity via session context or user service once backend supports it.

Applied to files:

  • services/platform/components/ui/navigation/mobile-navigation.tsx
  • services/platform/components/ui/navigation/tab-navigation.tsx
  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/layout.tsx
  • services/platform/components/ui/navigation/navigation.tsx
  • services/platform/components/ui/date-range-picker.tsx
  • services/platform/components/ui/button.tsx
  • services/platform/components/ui/radio-group.tsx
  • services/platform/components/ui/email-preview.tsx
  • services/platform/components/ui/input.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-07-19T15:30:05.600Z
Learnt from: CR
Repo: talecorp/poc PR: 0
File: .cursor/rules/figma.mdc:0-0
Timestamp: 2025-07-19T15:30:05.600Z
Learning: Applies to **/*.tsx : DO NOT import/add new icon packages, all the assets should be in the Figma payload

Applied to files:

  • services/platform/app/(app)/globals.css
📚 Learning: 2025-08-21T15:01:09.762Z
Learnt from: CR
Repo: talecorp/lanserhof PR: 0
File: .cursor/rules/figma.mdc:0-0
Timestamp: 2025-08-21T15:01:09.762Z
Learning: Applies to **/*.tsx : Do not import or add new icon packages; all icon assets must come from the Figma payload

Applied to files:

  • services/platform/app/(app)/globals.css
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Never use hardcoded Tailwind gray/black/white color utilities (e.g., text-gray-500, bg-gray-100, border-gray-200, text-black)

Applied to files:

  • services/platform/components/ui/date-range-picker.module.css
  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
📚 Learning: 2025-11-25T04:37:44.394Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-11-25T04:37:44.394Z
Learning: Applies to **/*.{tsx,jsx} : NEVER use hardcoded colors like `text-gray-500`, `bg-gray-100`, `border-gray-200`; ALWAYS use design system semantic colors: `text-foreground` for primary text, `text-muted-foreground` for secondary text, `bg-background` for main backgrounds, `bg-muted` for subtle backgrounds and hover states, `border-border` for borders

Applied to files:

  • services/platform/components/ui/date-range-picker.module.css
  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Use border-border for borders instead of border-gray-200 or border-gray-300

Applied to files:

  • services/platform/components/ui/date-range-picker.module.css
📚 Learning: 2025-12-26T03:04:07.995Z
Learnt from: larryro
Repo: tale-project/tale PR: 35
File: services/platform/convex/approvals.ts:51-62
Timestamp: 2025-12-26T03:04:07.995Z
Learning: In Convex approvals API (services/platform/convex/approvals.ts), continue the pattern of maintaining separate internalQuery functions for internal vs public API access (e.g., getApprovalInternal vs getApprovalById) even if implementations are identical. This separation preserves the ability to diverge access control patterns in the future without breaking call sites. Apply this guideline broadly to the Convex-related API files under services/platform/convex/, using the pattern services/platform/convex/**/*.ts to cover similar modules. Ensure new or refactored internal/public wrappers follow this convention and document intent where access rules may evolve.

Applied to files:

  • services/platform/convex/lib/rls/organization/get_organization_member.ts
  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
📚 Learning: 2025-12-30T03:24:33.770Z
Learnt from: larryro
Repo: tale-project/tale PR: 36
File: services/platform/convex/wf_step_defs.ts:33-39
Timestamp: 2025-12-30T03:24:33.770Z
Learning: In Convex API files under services/platform/convex (e.g., wf_step_defs.ts and peers) refrain from delegating trivial single-line database calls like ctx.db.get(id) to model helpers. Use direct calls for simple operations with no extra business logic. Reserve model helpers for complex tasks (ordering, filtering, validation, transformation). This guideline applies to all .ts files in this Convex API area.

Applied to files:

  • services/platform/convex/lib/rls/organization/get_organization_member.ts
  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
📚 Learning: 2025-12-30T06:21:13.183Z
Learnt from: larryro
Repo: tale-project/tale PR: 37
File: services/platform/convex/model/documents/validators.ts:89-102
Timestamp: 2025-12-30T06:21:13.183Z
Learning: Do not flag a missing trailing newline for TypeScript files in code reviews. POSIX text files should end with a trailing newline and Prettier (or your formatter) will enforce this. Treat the trailing newline as a non-issue in reviews for all TS files.

Applied to files:

  • services/platform/convex/lib/rls/organization/get_organization_member.ts
  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
  • services/platform/lib/auth/auth-server.ts
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Use bg-background for main backgrounds instead of bg-white

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Use text-foreground for primary text instead of text-gray-950 or text-black

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Use semantic design-system colors for all text and backgrounds within tables

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Use bg-muted for subtle backgrounds and hover states instead of bg-gray-100 or bg-gray-50

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Replace text-[20px] with text-xl

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Use text-muted-foreground for secondary text instead of text-gray-500 or text-gray-600

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : Use `ctx.runQuery` to call a query from a query, mutation, or action; use `ctx.runMutation` to call a mutation from a mutation or action; use `ctx.runAction` to call an action from an action

Applied to files:

  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
📚 Learning: 2025-10-03T11:34:20.628Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to convex/**/*.{ts,js} : Use ctx.runQuery to call queries, ctx.runMutation for mutations, and ctx.runAction for actions

Applied to files:

  • services/platform/convex/lib/rls/auth/require_authenticated_user.ts
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-11-30T12:29:39.745Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/workspace_rules.mdc:0-0
Timestamp: 2025-11-30T12:29:39.745Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use descriptive message as toast `title` (never generic 'Error'), with optional `description` only for additional context

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
📚 Learning: 2025-11-25T04:37:44.394Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-11-25T04:37:44.394Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use the Table component (`Table`, `TableHeader`, `TableBody`, `TableRow`, `TableHead`, `TableCell`) instead of custom flex layouts; apply proper column widths using rem units and use semantic colors for all text and backgrounds

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx
  • services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Always use the Table component instead of custom flex layouts for tabular data

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx
  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2024-11-10T16:03:41.557Z
Learnt from: Israeltheminer
Repo: talecorp/tale PR: 1599
File: apps/web/app/[locale]/(public)/(resources)/careers/[id]/page.tsx:12-13
Timestamp: 2024-11-10T16:03:41.557Z
Learning: In Next.js 15, when working with dynamic routes in Next.js, the `params` object is asynchronous and should be awaited before destructuring its properties.

Applied to files:

  • services/platform/lib/auth/auth-server.ts
📚 Learning: 2026-01-03T04:03:44.197Z
Learnt from: CR
Repo: tale-project/tale PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T04:03:44.197Z
Learning: Applies to **/*.{tsx,jsx} : AVOID `router.refresh()` in Next.js

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/layout.tsx
📚 Learning: 2025-10-03T11:34:20.628Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to package.json : Add types/node when using Node.js built-in modules

Applied to files:

  • package.json
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to package.json : Always add `types/node` to `package.json` when using any Node.js built-in modules in Convex functions

Applied to files:

  • package.json
📚 Learning: 2026-01-03T04:03:44.197Z
Learnt from: CR
Repo: tale-project/tale PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T04:03:44.197Z
Learning: Applies to **/*.{tsx,jsx} : USE `useMemo`, `useCallback` and `memo` at the right moment in React/Next.js

Applied to files:

  • services/platform/components/ui/date-range-picker.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Replace m-[8px] with m-2

Applied to files:

  • services/platform/components/ui/button.tsx
📚 Learning: 2026-01-03T04:03:44.197Z
Learnt from: CR
Repo: tale-project/tale PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T04:03:44.197Z
Learning: Applies to **/*.{tsx,jsx} : USE `cva` if a component has multiple variants in React/Next.js

Applied to files:

  • services/platform/components/ui/button.tsx
  • services/platform/components/ui/input.tsx
📚 Learning: 2025-11-25T04:37:44.394Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-11-25T04:37:44.394Z
Learning: Applies to **/*.{tsx,jsx} : Use standard font size classes instead of arbitrary values: `text-xs` for 12px, `text-sm` for 14px, `text-base` for 16px, `text-lg` for 18px, `text-xl` for 20px, `text-2xl` for 24px

Applied to files:

  • services/platform/components/ui/button.tsx
📚 Learning: 2025-08-21T15:01:09.405Z
Learnt from: CR
Repo: talecorp/lanserhof PR: 0
File: .cursor/rules/core-rules.mdc:0-0
Timestamp: 2025-08-21T15:01:09.405Z
Learning: Applies to **/*.{tsx} : Define a Props interface/type and use it in the exported component signature

Applied to files:

  • services/platform/components/ui/button.tsx
  • services/platform/components/ui/radio-group.tsx
  • services/platform/components/ui/input.tsx
📚 Learning: 2024-10-12T14:46:53.945Z
Learnt from: Israeltheminer
Repo: talecorp/tale PR: 1321
File: apps/web/app/[locale]/(public)/merchants/(home)/pricing-section.tsx:12-15
Timestamp: 2024-10-12T14:46:53.945Z
Learning: React components should be function declarations, except when creating a component that uses a forwarded ref.

Applied to files:

  • services/platform/components/ui/button.tsx
📚 Learning: 2025-07-19T15:30:00.886Z
Learnt from: CR
Repo: talecorp/poc PR: 0
File: .cursor/rules/core-rules.mdc:0-0
Timestamp: 2025-07-19T15:30:00.886Z
Learning: Applies to **/*.{tsx,jsx} : Follow the required React component structure: 'use client' (when needed), imports, Props interface, function definition, hooks, effects, event handlers, and render in order

Applied to files:

  • services/platform/components/ui/radio-group.tsx
📚 Learning: 2025-10-11T11:46:02.452Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursorrules:0-0
Timestamp: 2025-10-11T11:46:02.452Z
Learning: Applies to **/*.tsx : Follow the required client component structure: imports, Props interface, hooks, effects, handlers, and render order; include 'use client' only when needed

Applied to files:

  • services/platform/components/ui/radio-group.tsx
📚 Learning: 2025-12-30T06:20:46.309Z
Learnt from: larryro
Repo: tale-project/tale PR: 37
File: services/platform/convex/model/conversations/validators.ts:106-139
Timestamp: 2025-12-30T06:20:46.309Z
Learning: In services/platform/convex/model/conversations/validators.ts, conversationItemValidator and conversationWithMessagesValidator are intentionally kept as separate validators despite having identical structures. This separation serves different semantic purposes: conversationItemValidator is for list responses while conversationWithMessagesValidator is for single conversation detail views. The duplication allows future divergence when list views might need different fields than detail views for performance or feature reasons.

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx
📚 Learning: 2025-10-01T17:12:39.508Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/figma_rules.mdc:0-0
Timestamp: 2025-10-01T17:12:39.508Z
Learning: Applies to **/*.tsx : Use Table, TableHeader, TableBody, TableRow, TableHead, and TableCell components for tables

Applied to files:

  • services/platform/components/ui/data-table/data-table-empty-state.tsx
  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-07-19T15:30:00.886Z
Learnt from: CR
Repo: talecorp/poc PR: 0
File: .cursor/rules/core-rules.mdc:0-0
Timestamp: 2025-07-19T15:30:00.886Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Extract reusable functions, add comprehensive error handling, improve naming and documentation, and remove temporary debug code during optimization

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2026-01-03T04:03:44.197Z
Learnt from: CR
Repo: tale-project/tale PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T04:03:44.197Z
Learning: Applies to **/*.{tsx,jsx} : CONSIDER TO preload queries with `preloadQuery` and `usePreloadedQuery` in React with Convex

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : Use the `api` object from `convex/_generated/api.ts` to call public functions registered with `query`, `mutation`, or `action`

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-10-03T11:34:20.628Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to convex/**/*.{ts,js} : Register internal functions with internalQuery, internalMutation, and internalAction (imported from ./_generated/server)

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : Use the `internal` object from `convex/_generated/api.ts` to call internal functions registered with `internalQuery`, `internalMutation`, or `internalAction`

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-10-03T11:34:20.628Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to convex/schema.ts : Import schema helpers (defineSchema, defineTable) from convex/server

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : When using async iteration on queries, use `for await (const row of query)` syntax instead of `.collect()` or `.take(n)`

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : Always use the new Convex function syntax with `query`, `mutation`, `internalQuery`, `internalMutation`, `action`, or `internalAction` with explicit `args`, `returns`, and `handler` properties

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-10-03T11:34:20.628Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to convex/**/*.{ts,js} : Register public functions with query, mutation, and action; do not use these for sensitive internal logic

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : Try to use as few calls from actions to queries and mutations as possible to avoid race conditions, since queries and mutations are transactions

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx
🧬 Code graph analysis (6)
services/platform/convex/lib/rls/auth/require_authenticated_user.ts (1)
services/platform/convex/auth.ts (1)
  • authComponent (218-225)
services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx (1)
services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx (1)
  • ExecutionsTable (169-454)
services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx (1)
services/platform/components/layout/content-wrapper.tsx (1)
  • ContentWrapper (15-21)
services/platform/lib/auth/auth-server.ts (2)
services/platform/scripts/dev.mjs (1)
  • siteUrl (285-285)
services/platform/lib/convex-next-server.ts (1)
  • fetchQuery (53-72)
services/platform/components/ui/date-range-picker.tsx (1)
services/platform/components/ui/button.tsx (1)
  • Button (134-134)
services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx (3)
services/platform/app/(app)/dashboard/[id]/conversations/components/filter-dropdown.tsx (1)
  • FilterDropdown (61-172)
services/platform/app/(app)/dashboard/[id]/conversations/components/filter-status-indicator.tsx (1)
  • FilterStatusIndicator (23-99)
services/platform/app/(app)/dashboard/[id]/conversations/components/conversations-list.tsx (1)
  • ConversationsList (188-337)
🪛 ast-grep (0.40.3)
services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx

[warning] 56-56: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 Biome (2.1.2)
services/platform/app/(app)/dashboard/[id]/automations/layout.tsx

[error] 111-111: The elements with this role can be changed to the following elements:

For examples and more information, see WAI-ARIA Roles

(lint/a11y/useSemanticElements)

⏰ 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: Build Docker Image
🔇 Additional comments (47)
services/platform/app/(app)/dashboard/[id]/(knowledge)/documents/components/document-preview-docx.tsx (2)

56-56: Good refactoring: hardcoded colors removed.

Removing bg-white and text-gray-800 aligns with the design system guidelines. The component now properly inherits theme-aware styling.

Based on learnings: Always use semantic design-system colors instead of hardcoded Tailwind color utilities.


29-29: Static analysis false positive: XSS protection is properly implemented.

The dangerouslySetInnerHTML usage is safe here because the HTML content is sanitized with DOMPurify on line 29 before rendering. This is the correct pattern for displaying untrusted HTML content.

Also applies to: 57-57

services/platform/components/ui/button.tsx (2)

10-10: LGTM - Enhanced focus state styling.

Adding ring-offset-background improves the visual appearance of focus states by providing a background color for the ring offset. This is a good accessibility enhancement.


17-17: Verify removal of rounded corners from icon button variant.

The rounded-md class was removed from the icon size variant. This means icon-only buttons will now use the base rounded-lg rounding instead of the more subtle rounded-md (8px) rounding.

Note that the sm size variant still uses rounded-md, creating an inconsistency. Please verify this change aligns with your design system specifications.

Based on learnings, Figma rules and design system consistency are important considerations for UI components.

services/platform/convex/lib/rls/auth/require_authenticated_user.ts (2)

12-12: LGTM!

The switch from a direct API call to the centralized authComponent.getAuthUser(ctx) is a clean refactor that improves maintainability by consolidating authentication logic in one place.


21-31: LGTM!

The authentication retrieval and error handling logic is correct. The null coalescing to undefined for optional email and name fields ensures type consistency with the AuthenticatedUser type.

services/platform/lib/auth/auth-server.ts (3)

96-119: Verify: Refreshed token is used only once, not persisted.

The refreshed JWT token is used for the immediate retry but isn't cached or persisted. If getCurrentUser() is called multiple times in the same request lifecycle after the original token expires, each call will attempt to refresh the token independently. This could lead to redundant refresh calls.

Is this the intended behavior, or should the refreshed token be stored (e.g., in a request-scoped cache) for reuse within the same request?


187-198: LGTM!

The addition of AbortController with a 10-second timeout is a good defensive measure to prevent hanging requests to the token endpoint.


200-213: LGTM!

Good improvement to treat 401 responses as expected "no valid session" cases rather than errors. This reduces noise in logs for normal authentication flow scenarios.

services/platform/components/ui/email-preview.tsx (5)

90-178: Well-structured CSS property allowlist.

Good security approach using an allowlist (safer than blocklist). The categorization comments improve maintainability, and using a Set provides efficient O(1) lookups.


184-217: Solid CSS sanitization with defense-in-depth approach.

The property allowlist + dangerous value blocking is a good combination. The redundant checks for behavior: and -moz-binding in values (lines 207-208) add defense-in-depth since these properties are already excluded from the allowlist and url( is blocked.

One edge case to consider: CSS unicode escapes like \0065xpression() could theoretically bypass string matching. However, since expression() is only relevant to legacy IE and the property allowlist restricts which properties can even reach this check, the practical risk is minimal.


230-251: Good integration of CSS sanitization with DOMPurify.

The hook properly chains the custom CSS sanitizer with DOMPurify's attribute processing. The type guard on line 232 and the cleanup on line 259 are good practices.

Minor note: DOMPurify hooks are global. If sanitizePreviewHtml is ever called concurrently, the add/remove pattern could have race conditions. For this client-side component with useMemo, concurrent calls are unlikely, but consider using a DOMPurify instance via DOMPurify.default.isSupported && DOMPurify() if this function is ever reused elsewhere.


297-298: LGTM!

Good use of cn utility for className composition. The min-w-0 class is a common fix for flexbox containers to prevent content overflow.


309-317: Reasonable default styling for email content.

The white background with black text provides a sensible baseline for emails without explicit styling. The overflow handling and max-width constraints properly contain content within the preview area.

services/platform/components/ui/navigation/mobile-navigation.tsx (2)

65-67: LGTM!

The multi-line formatting of the ternary operator improves readability while maintaining the same conditional logic.


139-139: Chat route configuration is properly set up and navigation is consistently updated.

The chat route exists at services/platform/app/(app)/dashboard/[id]/chat/[threadId]/ and all navigation entry points have been correctly updated:

  • Logo link in mobile navigation (line 139): /dashboard/${businessId}/chat
  • Logo link in desktop navigation: /dashboard/${businessId}/chat
  • Navigation menu items in useNavigationItems hook: First item correctly points to /dashboard/${businessId}/chat

All navigation references follow the consistent /dashboard/${businessId}/... pattern.

services/platform/components/ui/navigation/tab-navigation.tsx (2)

86-96: LGTM! Correct fix for active state detection.

The query parameter stripping logic properly handles the fact that pathname from usePathname() does not include query parameters. This ensures accurate active state detection when hrefs contain query strings.


146-146: LGTM!

Adding relative positioning to both the nav container and link items enables proper positioning of the absolute-positioned active indicator at the bottom of the navigation.

Also applies to: 165-165

services/platform/components/ui/navigation/navigation.tsx (2)

55-63: LGTM!

The explicit line breaks in the linkProps object improve readability while maintaining the same conditional logic for external versus internal links.


113-113: Verify the chat route configuration.

The header logo link now navigates to /dashboard/${businessId}/chat instead of /dashboard/${businessId}, consistent with the same change in mobile-navigation.tsx. This aligns with the navigation refactoring objectives.

Please run the verification script provided in the review comment for mobile-navigation.tsx (line 139) to confirm the chat route is properly configured across all navigation entry points.

services/platform/app/(app)/dashboard/[id]/automations/layout.tsx (2)

1-19: LGTM: Imports are well-organized.

The imports follow best practices with named imports and proper organization.


55-59: LGTM: Redirect path updated correctly.

The redirect to /dashboard/${params.id}/chat aligns with the broader navigation routing updates in this PR.

services/platform/app/(app)/dashboard/[id]/conversations/layout.tsx (1)

30-32: LGTM!

The flex layout configuration properly overrides the base flex-col with flex-row for the two-panel conversations layout. The size-full and max-h-full constraints ensure proper containment within the viewport.

services/platform/app/(app)/dashboard/[id]/conversations/components/conversation-header.tsx (1)

167-169: LGTM!

The native title attribute tooltip is a nice accessibility improvement for truncated titles. The max-w-xl cap ensures consistent title width across the UI.

services/platform/app/(app)/dashboard/[id]/conversations/components/conversations.tsx (4)

377-391: LGTM!

The responsive panel visibility logic is well-implemented. The hidden md:flex / flex pattern correctly handles mobile vs desktop behavior based on selection state.


430-463: LGTM!

The search and filter UI is well-structured with proper loading state handling. The pointer-events-none during filter loading prevents conflicting user interactions.


493-504: LGTM!

The right panel visibility logic correctly complements the left panel, providing a good mobile UX where only one panel is visible at a time. The min-w-0 prevents overflow issues.


76-78: No action needed. The hooks already comply with coding guidelines by including comments that explain why optimistic updates are not implemented. Per guidelines, when optimistic updates are not used, the hooks must document the reason—which these do: bulk operations with complex selection and complex nested array insertion are valid reasons to defer optimistic updates.

Likely an incorrect or invalid review comment.

services/platform/components/ui/input.tsx (1)

27-33: Enhanced public API improves component flexibility.

The new optional props (passwordToggle, errorMessage, label, required) significantly enhance the component's capabilities while maintaining backward compatibility. The implementation integrates these props cleanly with proper TypeScript typing and sensible defaults.

Note: The passwordToggle prop defaults to true (line 40), which will enable the visibility toggle for all password inputs by default. Verify this aligns with the intended behavior across the application.

As per coding guidelines, the component properly defines a Props interface (BaseProps) and uses it in the component signature.

services/platform/convex/lib/rls/organization/get_organization_member.ts (2)

22-42: LGTM: Refactoring supports fallback pattern.

The change from inline return to storing the query result enables the fallback logic. Using let is appropriate since result is reassigned in the fallback path, and implicit typing is correctly applied.


70-76: LGTM: Cleaner conditional and return logic.

The refactoring from !result?.page?.[0] to !member improves readability and is consistent with the extracted member variable pattern. The error handling remains unchanged.

services/platform/components/ui/data-table/data-table-empty-state.tsx (3)

58-66: LGTM!

The multi-line formatting improves readability while preserving the conditional margin logic.


83-83: LGTM!

Adding an explicit default value for stickyLayout improves API clarity and makes the component's behavior more predictable.


98-110: No layout issues with the Fragment return structure.

The parent DataTable component is explicitly designed to handle the Fragment's two children: the first child (div with flex-shrink-0 pb-4) stays at natural height, while the second (Center with flex-1 min-h-0) fills available space. The complementary flex properties demonstrate intentional design. When stickyLayout is false, the space-y-4 spacing applies correctly to both Fragment children. This is a valid React pattern with no layout breakage.

Likely an incorrect or invalid review comment.

services/platform/app/(app)/globals.css (1)

2-2: LGTM!

The CSS import for react-datepicker is correctly placed and aligns with the new dependency added in package.json.

services/platform/components/ui/radio-group.tsx (2)

5-10: LGTM!

The import formatting change improves readability without affecting functionality. Import ordering is correct.


15-19: LGTM!

The interface definition reformatting improves readability. No behavioral changes.

Also applies to: 47-51

services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/page.tsx (1)

64-66: Verify layout consistency between skeleton and actual content.

The wrapper div with padding was removed from ExecutionsContent (line 65), but ExecutionsSkeleton (lines 22-26) still has the wrapper div with py-6 px-4. While the padding is now on the DataTable component itself (as seen in executions-table.tsx line 409), this creates a structural difference between the skeleton and the actual content.

This may cause a subtle layout shift during the Suspense boundary transition when the skeleton is replaced with the actual table.

Consider ensuring the skeleton structure matches the final rendered structure:

🔎 Suggested alignment

Option 1: Remove the wrapper from ExecutionsSkeleton to match the new structure:

 function ExecutionsSkeleton() {
-  return (
-    <div className="py-6 px-4">
-      <ExecutionsTableSkeleton />
-    </div>
-  );
+  return <ExecutionsTableSkeleton />;
 }

Option 2: Add the padding to ExecutionsTableSkeleton component itself to match the DataTable's className.

services/platform/app/(app)/dashboard/[id]/automations/[amId]/executions/components/executions-table.tsx (6)

7-7: LGTM!

The addition of date-fns utilities (parseISO and formatISO) is appropriate for handling ISO date strings in the date range filtering functionality.


180-186: LGTM!

The reformatting of the destructuring assignment improves readability without changing functionality.


232-236: LGTM!

The sortOrder ternary reformatting improves readability while maintaining the same logic.


396-402: LGTM!

Using formatISO with { representation: 'date' } correctly formats dates as YYYY-MM-DD strings, which is the appropriate format for date-only values in ISO 8601.


409-409: LGTM!

The padding classes have been moved from the page wrapper to the DataTable component itself, which better encapsulates the styling within the table component.


429-434: LGTM!

Using parseISO to parse ISO date strings is more robust and semantically correct than using the Date constructor. This is the recommended approach when working with ISO 8601 formatted date strings.

package.json (1)

2-8: All package versions exist and have no known security vulnerabilities.

Verification confirms:

  • date-fns@4.1.0: ✓ Exists (latest version), no known CVEs
  • react-datepicker@9.1.0: ✓ Exists (latest version), no known CVEs
  • @types/react-datepicker@6.2.0: ✓ Exists (version 7.0.0 available if upgrading), no known CVEs

Per Snyk and GitHub security advisories, no vulnerabilities affect these versions.

services/platform/components/ui/date-range-picker.module.css (1)

1-242: LGTM! Excellent use of semantic color tokens.

The CSS module correctly uses design system semantic colors throughout (e.g., hsl(var(--foreground)), hsl(var(--primary)), hsl(var(--accent)), text-muted-foreground, bg-popover, border-border) with no hardcoded gray/black/white utilities. The dark mode overrides maintain the same semantic approach.

Based on learnings, this aligns perfectly with the project's design system standards.

services/platform/components/ui/date-range-picker.tsx (1)

144-160: LGTM! Proper use of useCallback and optimistic updates.

The date change handler correctly:

  • Uses useCallback to memoize the function
  • Implements optimistic UI updates by setting local state immediately
  • Only calls onChange when both dates are selected or both are cleared

Comment thread services/platform/app/(app)/dashboard/[id]/automations/layout.tsx
Comment thread services/platform/components/ui/date-range-picker.tsx Outdated
Comment thread services/platform/components/ui/email-preview.tsx
Comment thread services/platform/components/ui/input.tsx
Comment thread services/platform/convex/lib/rls/organization/get_organization_member.ts Outdated
Comment thread services/platform/lib/auth/auth-server.ts
@Israeltheminer Israeltheminer merged commit 6181276 into main Jan 3, 2026
2 checks passed
@Israeltheminer Israeltheminer deleted the update-ui branch January 3, 2026 22:56
yannickmonney pushed a commit that referenced this pull request Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant