Skip to content

feat(favorites): add folder item limit and folder picker for organizi…#45

Merged
creatorcluster merged 2 commits intocreatorcluster:mainfrom
Coder-soft:main
Mar 1, 2026
Merged

feat(favorites): add folder item limit and folder picker for organizi…#45
creatorcluster merged 2 commits intocreatorcluster:mainfrom
Coder-soft:main

Conversation

@Coder-soft
Copy link

@Coder-soft Coder-soft commented Mar 1, 2026

…ng favorites

Add MAX_FOLDER_ITEMS constant (40) to enforce folder capacity limits. Implement visual indicators showing folder item counts with warning icons when folders are full. Add FolderPickerPopover component to allow users to select a folder when favoriting a resource. Block drag operations and folder assignments when limits are reached with user-friendly error messages.

Summary by CodeRabbit

New Features

  • Display folder item counts with alert indicators when folders reach maximum capacity
  • Select target folders when favoriting resources via an interactive folder picker
  • Create new folders directly from the favorites interface
  • Prevent adding resources to full folders with error notifications

…ng favorites

Add MAX_FOLDER_ITEMS constant (40) to enforce folder capacity limits. Implement visual indicators showing folder item counts with warning icons when folders are full. Add FolderPickerPopover component to allow users to select a folder when favoriting a resource. Block drag operations and folder assignments when limits are reached with user-friendly error messages.
@vercel
Copy link

vercel bot commented Mar 1, 2026

@Coder-soft is attempting to deploy a commit to the yamura3's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3a6918 and eb22bbe.

📒 Files selected for processing (6)
  • src/components/resources/FavoritesSidebar.tsx
  • src/components/resources/FavoritesTab.tsx
  • src/components/resources/FolderPickerPopover.tsx
  • src/components/resources/ResourceCard.tsx
  • src/hooks/useHeartedResources.ts
  • src/hooks/useUserFavorites.ts

📝 Walkthrough

Walkthrough

This pull request introduces folder capacity management for favorites, adding a 40-item limit per folder (MAX_FOLDER_ITEMS). It includes a new FolderPickerPopover component for selecting or creating folders when favoriting resources, displays folder item counts and capacity alerts in the sidebar, and enforces capacity checks during drag-drop and folder assignment operations. The toggleHeart hook method now returns a Promise to support asynchronous folder-picker workflows.

Changes

Cohort / File(s) Summary
Folder Capacity Enforcement
src/hooks/useUserFavorites.ts
Exports MAX_FOLDER_ITEMS constant (40); adds addFavoriteToFolder and getFolderItemCount helper functions with folder-full validation; updates toggleFavorite to return Promise<{action}> and strengthens type casting for favorites data.
Folder Selection UI
src/components/resources/FolderPickerPopover.tsx
New component with positioned popover anchored to element, folder list with per-folder item counts, capacity state indicators, folder creation via FolderDialog, outside-click and Escape-key dismissal, and selection blocking when folders are full.
Sidebar & Tab Integration
src/components/resources/FavoritesSidebar.tsx, src/components/resources/FavoritesTab.tsx
FavoritesSidebar displays folder item count badges and AlertTriangle icon when at capacity via new folderItemCount prop; FavoritesTab passes favoritesData prop and adds guard to block drop operations into full folders.
Favorite Action Flows
src/hooks/useHeartedResources.ts, src/components/resources/ResourceCard.tsx
useHeartedResources exposes folder-related methods (moveFavorite, addFavoriteToFolder, getFolderItemCount, folders) and converts toggleHeart to async; ResourceCard anchors FolderPickerPopover to heart button and opens picker post-favorite for folder assignment.

Sequence Diagram

sequenceDiagram
    actor User
    participant ResourceCard
    participant useHeartedResources
    participant FolderPickerPopover
    participant useUserFavorites
    participant Database

    User->>ResourceCard: Click heart icon
    activate ResourceCard
    ResourceCard->>useHeartedResources: toggleHeart(resource)
    activate useHeartedResources
    useHeartedResources->>useUserFavorites: toggleFavorite(resourceUrl)
    activate useUserFavorites
    useUserFavorites->>Database: Add to favorites
    Database-->>useUserFavorites: Success, returns action: 'added'
    useUserFavorites-->>useHeartedResources: Promise resolves
    deactivate useUserFavorites
    useHeartedResources-->>ResourceCard: Promise resolves
    deactivate useHeartedResources
    
    alt Folders exist
        ResourceCard->>ResourceCard: setShowFolderPicker(true)
        ResourceCard->>FolderPickerPopover: Open picker anchored to heart button
        activate FolderPickerPopover
        User->>FolderPickerPopover: Select folder
        FolderPickerPopover->>useUserFavorites: getFolderItemCount(folderId)
        useUserFavorites-->>FolderPickerPopover: Item count < MAX_FOLDER_ITEMS?
        
        alt Folder has capacity
            FolderPickerPopover->>useHeartedResources: handleFolderSelect(folderId)
            useHeartedResources->>useUserFavorites: addFavoriteToFolder(resourceUrl, folderId)
            activate useUserFavorites
            useUserFavorites->>Database: Update favorite with folder_id
            Database-->>useUserFavorites: Success
            deactivate useUserFavorites
            FolderPickerPopover->>ResourceCard: Close picker
            deactivate FolderPickerPopover
        else Folder is full
            FolderPickerPopover->>User: Show disabled state for folder
        end
    end
    
    deactivate ResourceCard
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰 With whiskers twitching, baskets fill to forty strong,
A picker blooms when hearts say "stay and sing along!"
No folder overflows—our warnings guard the way,
Organization hops with joy throughout the day! 🥕✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@creatorcluster creatorcluster merged commit 4a65dfb into creatorcluster:main Mar 1, 2026
1 check failed
@greptile-apps
Copy link

greptile-apps bot commented Mar 1, 2026

Greptile Summary

Added 40-item folder capacity limits with visual indicators and enforcement across the favorites system. Implemented FolderPickerPopover component that appears when favoriting resources, allowing users to organize items into folders immediately. Drag-and-drop operations now validate folder capacity before allowing moves.

Key changes:

  • Added MAX_FOLDER_ITEMS constant and folder count displays with warning icons when folders approach/reach capacity
  • Created new FolderPickerPopover component for selecting folders when favoriting
  • Integrated folder limit validation in drag-and-drop and folder assignment operations
  • Updated hooks to expose folder-related methods and return action types from toggle operations

Issues found:

  • Critical bug: nested folders always display 0/40 count instead of actual item count
  • Folder picker only shows root folders, preventing selection of nested folders
  • Minor: potential race condition in folder count validation using client-side data

Confidence Score: 3/5

  • This PR has a critical display bug and a logic limitation that should be fixed before merging
  • The folder capacity feature is well-implemented with good UX, but contains a critical bug where nested folders show incorrect item counts (always 0). The folder picker also only displays root folders, limiting functionality. These issues should be resolved before merge.
  • Pay close attention to src/components/resources/FavoritesSidebar.tsx (nested folder count bug) and src/components/resources/FolderPickerPopover.tsx (nested folder selection limitation)

Important Files Changed

Filename Overview
src/components/resources/FavoritesSidebar.tsx Added folder item count display with warning indicators, but child folders hardcoded to show 0 items (line 145)
src/components/resources/FavoritesTab.tsx Added folder capacity validation for drag-and-drop operations with user-friendly error messages
src/components/resources/FolderPickerPopover.tsx New component for folder selection when favoriting, only shows root folders (excludes nested folders), minor positioning inconsistency
src/components/resources/ResourceCard.tsx Integrated folder picker popover that appears after favoriting when folders exist
src/hooks/useHeartedResources.ts Updated to expose folder-related methods and changed toggleHeart to return Promise with action type
src/hooks/useUserFavorites.ts Added MAX_FOLDER_ITEMS constant and folder capacity validation, potential race condition in count checks, TypeScript suppression

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User clicks heart on ResourceCard] --> B{toggleHeart}
    B --> C{Added or Removed?}
    C -->|Removed| D[Remove from favorites]
    C -->|Added| E{Folders exist?}
    E -->|No| F[Add to favorites without folder]
    E -->|Yes| G[Show FolderPickerPopover]
    G --> H{User selects folder}
    H -->|No folder| I[Add without folder_id]
    H -->|Select folder| J{Check folder count}
    J -->|Full| K[Block & show error]
    J -->|Available space| L[addFavoriteToFolder]
    L --> M[Update DB with folder_id]
    
    N[User drags resource to folder] --> O{Check folder count}
    O -->|Full| P[Block drag & toast error]
    O -->|Available space| Q[moveFavorite]
    Q --> R[Update folder_id in DB]
    
    S[FavoritesSidebar renders] --> T[getFolderItemCount]
    T --> U{Count >= 40?}
    U -->|Yes| V[Show warning icon]
    U -->|No| W[Show normal count]
Loading

Last reviewed commit: eb22bbe

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

6 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

onDelete={onDelete}
onDownload={onDownload}
getChildren={getChildren}
folderItemCount={0}
Copy link

Choose a reason for hiding this comment

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

child folders always show 0/40 regardless of actual item count

Suggested change
folderItemCount={0}
folderItemCount={getFolderItemCount(child.id)}


if (!isOpen) return null;

const rootFolders = folders.filter(f => !f.parent_id);
Copy link

Choose a reason for hiding this comment

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

only root folders are shown in picker - nested folders can't be selected when favoriting a resource

Comment on lines +94 to +98
// Check folder limit
const folderCount = favoritesData.filter(f => f.folder_id === folderId).length;
if (folderCount >= MAX_FOLDER_ITEMS) {
throw new Error('FOLDER_FULL');
}
Copy link

Choose a reason for hiding this comment

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

race condition: favoritesData could be stale between count check and DB operation, allowing folder limit to be exceeded by concurrent requests


const { error } = await supabase
.from('user_favorites')
// @ts-ignore -- folder_id column exists in DB but generated types are stale
Copy link

Choose a reason for hiding this comment

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

regenerate types instead of suppressing TypeScript warnings

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +40 to +41
const popoverWidth = 220;
const popoverHeight = 300;
Copy link

Choose a reason for hiding this comment

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

popoverHeight is 300 but maxHeight on line 132 is 340 - inconsistent values may cause positioning issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants