Skip to content

Update the theme - #22

Merged
fulopkovacs merged 39 commits into
mainfrom
update-shadcn-theme
Dec 24, 2025
Merged

Update the theme#22
fulopkovacs merged 39 commits into
mainfrom
update-shadcn-theme

Conversation

@fulopkovacs

@fulopkovacs fulopkovacs commented Dec 23, 2025

Copy link
Copy Markdown
Owner

This is a huge visual overhaul attempting to make the whole app more appealing.

Summary by CodeRabbit

  • New Features

    • Added a scroll-shadow hook and a public three-board loading placeholder; major boards/tasks UI rework with virtualized lists, improved drag-and-drop, drop indicators, and persistent drag overlay.
  • Style & Visual Improvements

    • Default theme now light; switched to Space Grotesk; updated header branding, badges, buttons, inputs, skeletons, icons, animations, and dark-mode styles.
  • Bug Fixes / UX

    • Streamlined loading/not-found flows, removed stray console logging, tightened event propagation, and refined connection/progress indicators.
  • Documentation

    • Tech stack now specifies Tailwind CSS version (v4).

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

@coderabbitai

coderabbitai Bot commented Dec 23, 2025

Copy link
Copy Markdown

Walkthrough

Reworks the boards UI to a virtualized drag/drop surface with scroll shadows and a new loading component; adds useScrollShadow hook; switches default theme to light and font to Space Grotesk; many UI/dark-mode styling tweaks; removes export from insertTodoItem; adds CI knip step and small component updates.

Changes

Cohort / File(s) Summary
TodoBoards & drag/drop UI
src/components/TodoBoards.tsx, src/components/TaskBase.tsx, src/components/DraggableTask.tsx
Major rewrite: column-centric Virtualizer + drag/drop integration, new DropIndicator/ScrollShadow, drag-overlay skeleton & wiggle, removed projectId from TaskBase/DraggableTask/Board internals; added public TodoBoardsLoading.
Loading UI
src/components/TodoBoardsLoading.tsx
New exported loading component rendering three skeleton boards (TaskSkeleton / BoardSkeleton).
Scroll hook
src/hooks/use-scroll-shadow.ts
New exported useScrollShadow() hook returning { scrollRef, canScrollUp, canScrollDown } with scroll/resize/mutation observers and cleanup.
Theme & global styles
src/components/theme-provider.tsx, src/styles.css, src/routes/__root.tsx
Default theme changed from dark→light; font switch to Space Grotesk (preconnect + stylesheet); large CSS token refactor, new skeleton & wiggle animations, radius/shadow tokens and many variable remappings.
Design system primitives
src/components/ui/badge.tsx, src/components/ui/button.tsx, src/components/ui/dropdown-menu.tsx, src/components/ui/input.tsx, src/components/ui/skeleton.tsx
Added neutral badge variant; button variants adjusted (added empty, tutorial/destructive/outline/ghost dark-mode tweaks); dropdown dark-mode focus styles; input selection changed primary→accent; skeleton uses bg-skeleton + animate-skeleton-pulse.
Header & branding
src/components/Header.tsx
Left header reworked into compact "fuko's guide to" branding block with bordered avatar and layout adjustments; removed unused import.
Small component styling/behavior tweaks
src/components/ConfigureDB.tsx, src/components/FakeProgressIndicator.tsx, src/components/NetworkLatencyConfigurator.tsx, src/components/PriorityRating.tsx, src/components/EditableProjectDetails.tsx
Styling/class updates (badge variant, progress bg, dark-mode icon colors); PriorityRating: icon set, event propagation guards, trigger variant→empty; EditableProjectDetails: removed console.log, deleted LoadingEditableProjects, inlined loading skeletons.
API visibility change
src/collections/todoItems.ts
insertTodoItem changed from exported → internal (removed export), signature unchanged.
CI workflow
.github/workflows/main.yml
Adds "Knip" step that runs pnpm knip after type checks.
Docs
AGENTS.md
Tailwind CSS annotated to "(v4)" (documentation-only change).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Browser as Browser (UI)
  participant TodoBoards as TodoBoards component
  participant LiveDB as Live Query / DB
  participant Virtualizer as Virtualizer
  participant Sortable as SortableContext (DragLayer)

  Browser->>TodoBoards: mount(projectId)
  TodoBoards->>LiveDB: subscribe to boards & items
  LiveDB-->>TodoBoards: stream items
  TodoBoards->>Virtualizer: provide visible items & layout
  Virtualizer-->>Browser: render TaskBase items
  Browser->>Sortable: pointer down / start drag
  Sortable->>Virtualizer: request overlay render for dragged item
  Virtualizer-->>Sortable: provide overlay (TaskBase with wiggle)
  Browser->>Sortable: drop at target
  Sortable->>LiveDB: commit reorder payload
  LiveDB-->>TodoBoards: updated items stream
  TodoBoards->>Virtualizer: re-render with new order
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title "Update the theme" is vague and overly broad. While the PR does update theming (styles.css, theme variables, colors), it encompasses much more: UI component restructuring, layout changes, icon replacements, new components, and behavioral updates across multiple files. The title does not convey the scope or primary nature of the changes. Provide a more specific title that captures the main change. Consider: "Redesign UI components and theme styling" or "Refactor TodoBoards layout and update theme tokens" to better reflect the comprehensive nature of the visual overhaul.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update-shadcn-theme

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
src/components/TodoBoardsLoading.tsx (1)

28-37: Consider responsive layout for mobile viewports.

The grid-cols-3 class creates a fixed 3-column layout. On smaller screens, this may cause content to be cramped or overflow. Consider adding responsive breakpoints (e.g., grid-cols-1 md:grid-cols-2 lg:grid-cols-3) if the loading skeleton should match the responsive behavior of the actual TodoBoards component.

🔎 Suggested responsive fix
 export function TodoBoardsLoading() {
   return (
     <div className="flex-1 min-h-0">
-      <div className="grid grid-cols-3 gap-4 h-full min-h-0">
+      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 h-full min-h-0">
         <BoardSkeleton taskCount={2} />
         <BoardSkeleton taskCount={3} />
         <BoardSkeleton taskCount={2} />
       </div>
     </div>
   );
 }
src/components/Header.tsx (2)

14-37: Consider consistent rel attributes for external links.

The external links use different rel values: rel="noreferrer" on line 17 vs rel="noopener" on line 34. For consistency and security best practices, consider using rel="noopener noreferrer" on both links.

🔎 Suggested fix
         <a
           href="https://fulop.dev"
           target="_blank"
-          rel="noreferrer"
+          rel="noopener noreferrer"
           className="group/fuko-link cursor-pointer transition-colors flex items-center gap-2"
         >
         <a
           target="_blank"
           href="https://tanstack.com/db/latest/docs/overview"
           className="text-primary flex items-center cursor-pointer underline decoration-wavy hover:opacity-80"
-          rel="noopener"
+          rel="noopener noreferrer"
         >

20-24: External avatar image dependency.

The avatar is loaded directly from GitHub's CDN. While GitHub avatars are highly available, consider self-hosting the image or adding a fallback for improved reliability and faster load times.

src/components/TodoBoards.tsx (2)

53-57: Consider deriving board names from schema.

The BoardName enum hardcodes board names that likely exist in your database schema. If board names change in the schema, this enum will become stale.

Alternative approach using schema types

Consider importing board name constants from your schema or using the actual board.name values directly to maintain a single source of truth:

-enum BoardName {
-  Todo = "Todo",
-  InProgress = "In Progress",
-  Done = "Done",
-}

// In Board component
-{board.name === BoardName.Done ? (
+{board.name === "Done" ? (

Or if you have schema constants:

import { BOARD_NAMES } from "@/db/schema";

{board.name === BOARD_NAMES.Done ? (

163-170: Consider dynamic skeleton height for better drag feedback.

The skeleton placeholder uses a hardcoded h-[180px], which may not match the actual height of tasks with varying content lengths. This could cause visual jumps or inconsistent spacing during drag operations.

Alternative approach using ref measurement

Consider measuring the actual task height before drag starts:

function DraggableTask({ task }: { task: TodoItemRecord }) {
  const taskRef = useRef<HTMLDivElement>(null);
  const [taskHeight, setTaskHeight] = useState<number | null>(null);
  
  const { attributes, listeners, setNodeRef, isDragging } = useSortable({
    id: task.id,
  });

  useEffect(() => {
    if (taskRef.current) {
      setTaskHeight(taskRef.current.offsetHeight);
    }
  }, []);

  if (isDragging && taskHeight) {
    return (
      <div
        ref={setNodeRef}
        className="bg-skeleton rounded-lg mb-2 animate-skeleton-pulse"
        style={{ height: `${taskHeight}px` }}
      />
    );
  }

  return (
    <TaskBase
      task={task}
      ref={(node) => {
        setNodeRef(node);
        taskRef.current = node;
      }}
      {...attributes}
      {...listeners}
      className="cursor-grab"
    />
  );
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d7c46f1 and 63714e9.

📒 Files selected for processing (18)
  • AGENTS.md
  • src/components/ConfigureDB.tsx
  • src/components/EditableProjectDetails.tsx
  • src/components/FakeProgressIndicator.tsx
  • src/components/Header.tsx
  • src/components/NetworkLatencyConfigurator.tsx
  • src/components/PriorityRating.tsx
  • src/components/TodoBoards.tsx
  • src/components/TodoBoardsLoading.tsx
  • src/components/theme-provider.tsx
  • src/components/ui/badge.tsx
  • src/components/ui/button.tsx
  • src/components/ui/dropdown-menu.tsx
  • src/components/ui/input.tsx
  • src/components/ui/skeleton.tsx
  • src/hooks/use-scroll-shadow.ts
  • src/routes/__root.tsx
  • src/styles.css
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-19T21:20:23.301Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:20:23.301Z
Learning: Applies to src/route/__root.tsx : The root route is located at `src/route/__root.tsx` in a TanStack Start project

Applied to files:

  • src/routes/__root.tsx
  • AGENTS.md
📚 Learning: 2025-12-19T21:20:23.301Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:20:23.301Z
Learning: The project uses TanStack Start as the framework with React, TanStack Router, shadcn/ui for UI, and Tailwind CSS for styling

Applied to files:

  • AGENTS.md
🧬 Code graph analysis (9)
src/components/NetworkLatencyConfigurator.tsx (1)
src/components/mode-toggle.tsx (2)
  • ModeToggle (11-39)
  • setTheme (28-28)
src/hooks/use-scroll-shadow.ts (1)
src/components/ui/scroll-area.tsx (2)
  • ScrollArea (6-33)
  • ScrollBar (35-60)
src/components/TodoBoardsLoading.tsx (1)
src/components/ui/skeleton.tsx (1)
  • Skeleton (13-13)
src/components/FakeProgressIndicator.tsx (1)
src/components/ui/progress.tsx (1)
  • Progress (5-26)
src/components/ui/skeleton.tsx (1)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/theme-provider.tsx (1)
src/components/mode-toggle.tsx (1)
  • setTheme (28-28)
src/components/PriorityRating.tsx (2)
src/components/ui/dropdown-menu.tsx (4)
  • DropdownMenu (240-240)
  • DropdownMenuTrigger (242-242)
  • DropdownMenuContent (243-243)
  • DropdownMenuItem (246-246)
src/components/ui/button.tsx (1)
  • Button (63-63)
src/components/Header.tsx (2)
src/components/ui/sidebar.tsx (2)
  • SidebarTrigger (718-718)
  • Sidebar (160-260)
src/components/tutorial/TutorialWindow.tsx (1)
  • FloatingWindowHeader (16-32)
src/components/ConfigureDB.tsx (2)
src/components/ui/badge.tsx (1)
  • Badge (48-48)
src/lib/utils.ts (1)
  • cn (4-6)
🪛 GitHub Actions: CI/CD
src/components/EditableProjectDetails.tsx

[error] 93-93: TS6133: 'LoadingEditableProjects' is declared but its value is never read.

🔇 Additional comments (23)
src/components/ui/dropdown-menu.tsx (1)

75-75: LGTM: Dark mode focus styling enhancement.

The addition of dark:focus:bg-border and dark:focus:text-current provides proper focus state styling for dark mode, aligning with the broader theming updates in this PR.

AGENTS.md (1)

47-47: LGTM: Documentation updated to reflect Tailwind CSS v4.

The version annotation accurately reflects the Tailwind CSS version in use, helping maintain clear technical documentation.

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

11-11: LGTM: Selection styling updated to use accent tokens.

The change from selection:bg-primary to selection:bg-accent aligns with the new theming system and maintains visual consistency across the UI.

src/components/PriorityRating.tsx (2)

1-23: LGTM: Icon set updated with improved visual hierarchy.

The replacement of CircleIcon with SkullIcon and the updated icon styling (with muted/destructive colors) provides clearer visual indication of priority levels.


41-80: Event propagation blocking does not affect keyboard navigation or accessibility.

The stopPropagation() calls target pointer and click events only—not keyboard events. Radix UI's DropdownMenu (which shadcn/ui wraps) handles all keyboard navigation (Enter, Space, Arrow keys, Esc, etc.) internally and maintains full WAI-ARIA support independent of pointer/click propagation. Keyboard accessibility is unaffected.

Likely an incorrect or invalid review comment.

src/routes/__root.tsx (1)

37-49: LGTM: Font loading with performance optimizations.

The Space Grotesk font is loaded with proper preconnect hints for Google Fonts, which is a performance best practice. The Google Fonts URL includes display=swap, ensuring text remains visible during font load.

src/components/FakeProgressIndicator.tsx (1)

26-26: LGTM: Progress indicator background updated to match skeleton theming.

The change to bg-skeleton maintains visual consistency with other loading states in the application, providing a unified skeleton/loading appearance.

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

14-23: Button variants are properly implemented and in use.

The new empty and tutorial variants are actively used throughout the codebase (in PriorityRating.tsx and TutorialWindow.tsx respectively). Dark mode styling enhancements are present across multiple variants, and the styling is consistent with the broader theme.

src/components/ui/skeleton.tsx (1)

7-7: The Tailwind classes bg-skeleton and animate-skeleton-pulse are not configured and will not be generated.

While the CSS custom properties --skeleton and --animate-skeleton-pulse are defined in src/styles.css, they are not wired to Tailwind class names. Tailwind v4 requires explicit configuration in a tailwind.config.ts file to extend the theme and map custom properties to classes. Without this configuration, the classes used in line 7 (bg-skeleton animate-skeleton-pulse) will be undefined and non-functional. Either add a tailwind.config.ts file with the theme extensions, or use the CSS custom properties directly via inline styles or CSS classes.

Likely an incorrect or invalid review comment.

src/components/ui/badge.tsx (1)

20-21: LGTM!

The new neutral variant follows the established pattern of other badge variants and uses consistent design tokens (bg-muted, text-muted-foreground). The hover state is appropriately scoped to anchor elements.

src/components/ConfigureDB.tsx (1)

46-53: LGTM!

The Badge styling update using variant="outline" combined with bg-muted is a clean approach since the outline variant doesn't define a background. The added border on the indicator dot improves visual definition.

src/components/theme-provider.tsx (1)

8-8: LGTM!

The default theme change from "dark" to "light" aligns with the PR's visual overhaul objectives. The change correctly propagates through UserThemeSchema, AppThemeSchema, server-side fallbacks, and the theme script.

src/components/NetworkLatencyConfigurator.tsx (1)

56-62: LGTM!

The updated color scheme improves contrast by using more saturated colors in light mode (green-500, orange-400) while keeping lighter variants for dark mode readability. Using text-destructive for both modes correctly relies on the theme's CSS variable system.

src/components/EditableProjectDetails.tsx (1)

142-177: LGTM!

The conditional rendering logic correctly handles three states: API 404 error, no project found, and the default loading/data state. The inline skeleton approach provides smooth loading transitions.

src/hooks/use-scroll-shadow.ts (1)

15-69: LGTM!

Well-implemented scroll shadow hook with:

  • Passive scroll listener for performance
  • ResizeObserver for container size changes
  • MutationObserver for content changes
  • Proper cleanup on unmount
  • 1px threshold to handle sub-pixel rendering edge cases

The empty dependency array for updateScrollShadows is correct since it only references the stable scrollRef.

src/styles.css (4)

11-12: Font change looks good.

The switch from Clash Grotesk to Space Grotesk aligns with the PR's visual overhaul goals. Ensure the font is properly preloaded in the root route to avoid layout shifts.


23-90: OKLCH color system implementation looks correct.

The new OKLCH-based color palette with skeleton and success tokens follows Tailwind v4 conventions and supports the visual overhaul goals.


370-391: Animation definitions are well-structured.

The wiggle and skeleton-pulse animations effectively support the drag-and-drop feedback and loading state UI enhancements.


405-406: Letter spacing application looks good.

The tracking-normal token properly integrates with the new typography system.

src/components/TodoBoards.tsx (4)

22-42: Import additions support the new UI features.

The new icons, hooks, and components properly support the Card-based refactor and loading states.


267-323: Board layout structure is well-organized.

The Card-based board layout with icon mapping, scroll shadows, and drop indicators creates a cohesive drag-and-drop experience.


520-528: Loading state implementation is clean.

The conditional rendering properly shows the TodoBoardsLoading skeleton during data fetch, improving perceived performance.


530-532: Drag overlay with animation enhances UX.

The wiggle animation on the dragged task provides excellent visual feedback during drag operations.

Comment thread src/components/EditableProjectDetails.tsx Outdated
Comment thread src/components/TodoBoards.tsx
Comment thread src/components/TodoBoards.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (3)
src/collections/todoItems.ts (1)

58-63: Fix Prettier formatting to pass CI/CD.

The pipeline indicates a formatting mismatch on these lines. Run the formatter to resolve the CI/CD failure.

Run the following command to fix the formatting:

prettier --write src/collections/todoItems.ts
src/components/EditableProjectDetails.tsx (2)

76-76: Fix typo: "APi" should be "API".

🔎 Proposed fix
-          We use a service worker to simulate the backend APi. Sometimes it's
+          We use a service worker to simulate the backend API. Sometimes it's

113-113: Fix typo in comment: missing opening parenthesis.

🔎 Proposed fix
-        Sometimes typically after a hard refresh), the service worker
+        Sometimes (typically after a hard refresh), the service worker
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 63714e9 and b2d8b2a.

📒 Files selected for processing (3)
  • .github/workflows/main.yml
  • src/collections/todoItems.ts
  • src/components/EditableProjectDetails.tsx
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-12-19T21:20:23.301Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:20:23.301Z
Learning: Use `pnpm run test` for running tests

Applied to files:

  • .github/workflows/main.yml
📚 Learning: 2025-12-19T21:20:23.301Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:20:23.301Z
Learning: Use `pnpm typecheck` for type checking

Applied to files:

  • .github/workflows/main.yml
📚 Learning: 2025-12-19T21:20:23.301Z
Learnt from: CR
Repo: fulopkovacs/trytanstackdb.com PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-19T21:20:23.301Z
Learning: Use `pnpm lint` for linting code

Applied to files:

  • .github/workflows/main.yml
🧬 Code graph analysis (2)
src/collections/todoItems.ts (1)
src/components/CreateOrEditTodoItems.tsx (3)
  • newItemData (45-51)
  • newItemData (32-44)
  • project (39-43)
src/components/EditableProjectDetails.tsx (3)
src/utils/highlight-collection-related-info.tsx (1)
  • HighlightWrapper (6-28)
src/components/ui/skeleton.tsx (1)
  • Skeleton (13-13)
src/local-api/api.projects.ts (1)
  • updatedData (28-90)
🪛 GitHub Actions: CI/CD
src/collections/todoItems.ts

[error] 58-63: Prettier formatting mismatch detected. The formatter would format this file differently. Run 'prettier --write' to fix code style issues in this file (or run the full formatting check again).

🔇 Additional comments (4)
src/collections/todoItems.ts (1)

58-78: No external imports exist—this change is correct as-is.

The insertTodoItem function is appropriately scoped as internal-only. It is not imported by any files, including CreateOrEditTodoItems.tsx, and is only used internally within the todoItemsCollection's onInsert callback. Removing the export keyword is the correct design decision.

Likely an incorrect or invalid review comment.

.github/workflows/main.yml (1)

54-55: Good addition of code quality tooling.

Adding Knip to catch unused files, dependencies, and exports is a solid practice, especially for a large visual overhaul PR where refactoring may leave unused code behind. The tool is properly configured with well-defined entry points and dependency rules, and its placement in the workflow after type checking and before tests follows a logical sequence.

src/components/EditableProjectDetails.tsx (2)

18-68: LGTM! Clean form handling.

The EditProjectNamePopover component correctly handles project name updates with proper validation and popover state management.


131-166: Excellent refactoring! Clean three-branch rendering logic.

The reworked rendering flow clearly separates API errors, missing projects, and normal content display. The inline loading skeleton approach is more maintainable than the previous separate loading component. The logic correctly handles all states: API 404 errors, ready-but-no-project cases, and loading-vs-loaded states.

@github-actions

github-actions Bot commented Dec 24, 2025

Copy link
Copy Markdown

🚀 Preview Deployment

Status: ✅ Ready!

Preview URL: Open Preview

Commit: 03942e79e1de8eafdb1d0f6a1571a1c99ac34057

Built and deployed successfully

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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)
src/components/TodoBoards.tsx (2)

53-57: Consider using the enum in the type system for better type safety.

The BoardName enum is defined but not used to constrain the BoardRecord.name type. This means the string comparisons on lines 242-248 aren't type-safe, and mismatches between database values and enum values will fail silently at runtime.

Consider either:

  • Updating the schema to use the enum type: boardsTable should have name: text('name').$type<BoardName>()
  • Or adding runtime validation when loading boards to ensure names match expected enum values

157-180: Consider extracting the hardcoded height to a constant.

The skeleton height h-[180px] (line 166) is also used as itemSize={180} in the Virtualizer (line 276). If these values get out of sync, virtualization will break. Consider extracting this to a named constant at the module level:

const TASK_ITEM_HEIGHT = 180;

Then use it in both places for maintainability.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b2d8b2a and e84ec5f.

📒 Files selected for processing (2)
  • src/collections/todoItems.ts
  • src/components/TodoBoards.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/TodoBoards.tsx (9)
src/lib/utils.ts (1)
  • cn (4-6)
src/components/ui/card.tsx (5)
  • Card (85-85)
  • CardHeader (86-86)
  • CardTitle (88-88)
  • CardDescription (90-90)
  • CardFooter (87-87)
src/components/PriorityRating.tsx (1)
  • PriorityRatingPopup (25-82)
src/components/CreateOrEditTodoItems.tsx (1)
  • CreateOrEditTodoItems (19-143)
src/components/ui/button.tsx (1)
  • Button (63-63)
src/db/schema.ts (2)
  • TodoItemRecord (72-72)
  • BoardRecord (52-52)
src/hooks/use-scroll-shadow.ts (1)
  • useScrollShadow (15-70)
src/components/ui/badge.tsx (1)
  • Badge (48-48)
src/components/TodoBoardsLoading.tsx (1)
  • TodoBoardsLoading (28-38)
src/collections/todoItems.ts (1)
src/local-api/api.todo-items.ts (1)
  • TodoItemCreateDataType (16-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Deploy Preview
🔇 Additional comments (5)
src/collections/todoItems.ts (1)

58-58: No external imports of insertTodoItem exist—the export removal is safe.

Verification confirms that insertTodoItem is not imported or used by any other files in the codebase. The function is only used internally within this module (line 85 in the onInsert hook). Removing the export keyword is not a breaking change.

src/components/TodoBoards.tsx (4)

110-155: LGTM!

The refactored TaskBase component properly integrates Card components with a clean header/description/footer layout. The grip indicator, priority rating, and edit functionality are well-implemented. The event handling correctly prevents drag interference with interactive elements.


265-291: LGTM! Virtualizer implementation is correct.

The refactored Board component properly addresses the previous review feedback by using Virtualizer in a custom scroll container with a controlled ref. The callback ref pattern on lines 266-269 correctly manages both the droppable ref and the scroll shadow ref. The virtualization with drop indicators is well-implemented.


276-290: Drop indicator logic is correct.

The implementation properly shows drop indicators before items when hovering over them, and after the last item when dropping at the end of a column. The conditional logic ensures indicators only appear once and in the correct position.


493-506: LGTM!

The conditional rendering for loading states and the drag overlay implementation are well-executed. The use of TodoBoardsLoading as a dedicated loading component and the wiggle animation during drag provide a polished user experience.

Comment thread src/components/TodoBoards.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/components/TodoBoards.tsx (2)

53-57: Consider strengthening type safety for board names.

The BoardName enum is compared via string equality with board.name at runtime (lines 257-263), but there's no type-level constraint ensuring database values match the enum. If board.name doesn't match exactly, the code silently falls back to LayoutListIcon.

To prevent potential mismatches, consider either:

  1. Constraining the BoardRecord type to use the BoardName enum, or
  2. Using a mapping object instead of inline conditionals:
const BOARD_ICONS: Record<BoardName, typeof LayoutListIcon> = {
  [BoardName.Done]: CircleCheckBigIcon,
  [BoardName.InProgress]: LoaderIcon,
  [BoardName.Todo]: LayoutListIcon,
};

Then use: {React.createElement(BOARD_ICONS[board.name as BoardName] ?? LayoutListIcon)}

Also applies to: 257-263


167-171: Consider optimizing the height measurement effect.

The useEffect without a dependency array runs after every render, potentially causing unnecessary measurements. While React's state batching prevents infinite loops, this could be optimized to measure only when needed:

🔎 Suggested optimization
  useEffect(() => {
    if (taskRef.current) {
      setMeasuredHeight(taskRef.current.offsetHeight);
    }
- });
+ }, []);

Alternatively, use a ResizeObserver to remeasure only when the element's size actually changes.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3af3e08 and 6ef9504.

📒 Files selected for processing (1)
  • src/components/TodoBoards.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/components/TodoBoards.tsx
🧬 Code graph analysis (1)
src/components/TodoBoards.tsx (4)
src/components/CreateOrEditTodoItems.tsx (1)
  • CreateOrEditTodoItems (19-143)
src/db/schema.ts (2)
  • TodoItemRecord (72-72)
  • BoardRecord (52-52)
src/hooks/use-scroll-shadow.ts (1)
  • useScrollShadow (15-70)
src/components/TodoBoardsLoading.tsx (1)
  • TodoBoardsLoading (28-38)
🔇 Additional comments (5)
src/components/TodoBoards.tsx (5)

65-83: LGTM!

The ScrollShadow component correctly uses Tailwind v4's canonical gradient syntax (bg-linear-to-b, bg-linear-to-t) with smooth opacity transitions for scroll indicators.


112-157: LGTM!

The refactored TaskBase component correctly implements forwardRef, properly structures the Card with semantic sections (Header/Footer), and includes appropriate event handlers to prevent drag interference when editing.


197-323: LGTM - excellent refactor!

The Board component successfully integrates:

  • Virtualizer for efficient rendering
  • useScrollShadow for scroll indicators
  • Complex drop indicator logic handling edge cases (empty columns, end-of-list)
  • Proper ref forwarding using callback refs

The migration from the previous implementation is well-executed and addresses past feedback about VList usage.


519-527: LGTM!

The loading state is properly handled with the dedicated TodoBoardsLoading component, maintaining the same 3-column grid layout for a smooth visual transition.


529-531: The animate-wiggle class is properly defined in src/styles.css with the complete animation keyframes and CSS custom property configuration. No action needed.

@fulopkovacs
fulopkovacs merged commit 3f550af into main Dec 24, 2025
3 of 4 checks passed
@fulopkovacs
fulopkovacs deleted the update-shadcn-theme branch December 24, 2025 15:55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/components/TodoBoards.tsx (1)

167-177: Consider using ResizeObserver for height measurement.

The useEffect without dependencies runs on every render to capture height changes. While the comment explains this is intentional, it could impact performance with many tasks. A ResizeObserver would measure only when the element's size actually changes:

Alternative implementation with ResizeObserver
-  // Measure height after the element is rendered
-  useEffect(
-    () => {
-      if (taskRef.current) {
-        setMeasuredHeight(taskRef.current.offsetHeight);
-      }
-    },
-    /*
-      No dependency array: remeasures on every render
-      to capture dynamic content changes (edits, etc.)
-    */
-  );
+  // Measure height when element size changes
+  useEffect(() => {
+    const element = taskRef.current;
+    if (!element) return;
+
+    const observer = new ResizeObserver(() => {
+      setMeasuredHeight(element.offsetHeight);
+    });
+
+    observer.observe(element);
+    return () => observer.disconnect();
+  }, []);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40d91ad and 03942e7.

📒 Files selected for processing (1)
  • src/components/TodoBoards.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-24T15:25:07.106Z
Learnt from: fulopkovacs
Repo: fulopkovacs/trytanstackdb.com PR: 22
File: src/components/TodoBoards.tsx:63-81
Timestamp: 2025-12-24T15:25:07.106Z
Learning: In Tailwind CSS v4, prefer canonical classes using bg-linear-to-* (e.g., bg-linear-to-b, bg-linear-to-t, bg-linear-to-r) over the older bg-gradient-to-* syntax. This aligns with Tailwind LSP's suggestCanonicalClasses rule. Apply across TSX files (e.g., src/components/*.tsx); replace occurrences of bg-gradient-to-* with the corresponding bg-linear-to-* equivalents and verify gradients visually.

Applied to files:

  • src/components/TodoBoards.tsx
🧬 Code graph analysis (1)
src/components/TodoBoards.tsx (5)
src/components/PriorityRating.tsx (1)
  • PriorityRatingPopup (25-82)
src/components/CreateOrEditTodoItems.tsx (1)
  • CreateOrEditTodoItems (19-143)
src/db/schema.ts (2)
  • TodoItemRecord (72-72)
  • BoardRecord (52-52)
src/hooks/use-scroll-shadow.ts (1)
  • useScrollShadow (15-70)
src/components/TodoBoardsLoading.tsx (1)
  • TodoBoardsLoading (28-38)
🔇 Additional comments (3)
src/components/TodoBoards.tsx (3)

65-83: Correct use of Tailwind v4 gradient classes.

The bg-linear-to-b and bg-linear-to-t classes are the correct canonical syntax for Tailwind CSS v4, as confirmed by the Tailwind LSP's suggestCanonicalClasses rule. The ScrollShadow implementation is clean and uses proper conditional opacity transitions.

Based on learnings, Tailwind v4 prefers bg-linear-to-* over the older bg-gradient-to-* syntax.


286-292: Excellent implementation of custom scroll container.

The Board component now uses the recommended pattern with a custom scroll container (lines 286-292) and Virtualizer, addressing the previous review concern about VList not exposing its internal scroll container. The callback ref correctly sets both the droppable node and scroll ref, giving you explicit control over the scroll element for the useScrollShadow hook.


522-541: Clean drag-and-drop implementation with good UX.

The TodoBoards component orchestrates the drag-and-drop flow well:

  • Conditional rendering with TodoBoardsLoading provides good loading state UX
  • DragOverlay with the wiggle animation gives clear visual feedback
  • The paced mutations with debouncing (line 335) optimize backend calls while maintaining responsive UI

The overall architecture is solid and the visual overhaul integrates smoothly with the existing functionality.

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