feat: Implement project management features#42
Conversation
…lete functionality
|
Warning Review limit reached
More reviews will be available in 38 minutes and 57 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughIntroduces a new projects management dashboard with category-based organization, drag-and-drop reordering, and full CRUD operations. Features include editable project cards with SVG logo upload, role-based server actions for persistence, optimistic state management with rollback on errors, and integration into the sidebar navigation. ChangesWeb Projects Dashboard
Possibly Related PRs
Suggested Labels
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@package.json`:
- Line 18: The package.json was updated to add the dependency "`@dnd-kit/react`"
but the pnpm lockfile wasn't regenerated, causing CI to fail with a frozen
lockfile; run pnpm install (or pnpm install --lockfile-only) locally to update
pnpm-lock.yaml, verify the lockfile includes the new "`@dnd-kit/react`" specifier,
and commit the updated pnpm-lock.yaml alongside the package.json change so CI
can install with the frozen lockfile.
In `@src/app/dashboard/`(active)/telegram/users/[id]/page.tsx:
- Around line 13-14: The route currently uses parseInt(id, 10) which accepts
partial numeric strings like "123abc"; instead, first validate the full route
param string (id) matches a whole-integer pattern (e.g. /^\d+$/ for positive
Telegram IDs) and if it fails call notFound(); only after that convert the
validated id to a number (used by parsedInt / getUserDetails) and proceed so
partially numeric inputs are rejected.
In `@src/app/dashboard/`(active)/web/projects/card-project.tsx:
- Around line 35-39: The uploaded SVG is read as raw text in handleIconUpload
and later injected via dangerouslySetInnerHTML (card rendering code around the
setLogo/dangerouslySetInnerHTML use), creating a stored XSS sink; fix by
validating and normalizing the upload and never persisting or rendering raw SVG
markup: on upload in handleIconUpload, verify the file MIME/type (e.g.,
image/svg+xml), sanitize the SVG server-side (remove <script>, event-*
attributes, foreignObject, external resources) before saving to the project logo
field, or convert/store the file as a static blob/asset and persist only a
vetted URL/reference; additionally, before rendering, do not use
dangerouslySetInnerHTML with raw SVG—either render an <img> pointing to the
sanitized asset URL or re-sanitize the markup client-side with a strict
sanitizer library to ensure no executable attributes remain.
- Around line 122-126: The title and link inputs are missing accessible names;
update the <Input> for the editable title (value={title}, onChange={(event) =>
setTitle(event.target.value)}) and the link input (the input rendered around
lines 185-193) to include programmatic labels by either adding a <label
htmlFor="..."> paired with an id on each Input or by adding an explicit
aria-label on each Input (e.g., id="project-title" + <label
htmlFor="project-title">Title</label>, and id="project-link" + <label
htmlFor="project-link">Link</label>), ensuring the id strings match the Input
components so screen readers can associate the labels with the controls.
In `@src/app/dashboard/`(active)/web/projects/projects-view.tsx:
- Around line 31-44: The current handleProjectsReorder increments a local guard
(reorderRequestId) but still fires reorderProjects({ projectIds }) without any
version/cancellation token, allowing out-of-order backend commits; modify
persistProjectOrder (and the backend call reorderProjects) to accept the
requestId (or a version/AbortSignal) and include that id in the outgoing
request, then make persistProjectOrder ignore responses whose requestId is older
than the latest reorderRequestId.current (or cancel prior inflight requests via
AbortController), and ensure the UI-path that calls persistProjectOrder (in
handleProjectsReorder and the similar block around lines 61-76) either
awaits/queues the previous persist call or uses the requestId check so only the
newest reorder is applied server-side.
- Around line 187-190: When moving a project between categories, the current
code only computes and persists the destination category order via
getPersistedProjectIds(...) and persistProjectOrder(...), but it must also
persist the source category order because removing the item changes that bucket;
update the flow around getPersistedProjectIds, savedProjects and
project.category to compute both the source and destination category ID arrays
(e.g., sourceProjectIds and destProjectIds) and persist them together—either by
calling persistProjectOrder for both categories back-to-back with the same
requestId or, preferably, add/use a backend method that accepts both category id
lists in one operation to avoid races/stale state. Ensure you reference the same
requestId and savedProjects when generating both lists so the backend receives
consistent ordering for both the source and destination categories.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 41946934-4a1d-4b22-920c-8c88f86ef61f
📒 Files selected for processing (14)
package.jsonsrc/app/dashboard/(active)/telegram/users/[id]/page.tsxsrc/app/dashboard/(active)/web/projects/card-project.tsxsrc/app/dashboard/(active)/web/projects/category-menu.tsxsrc/app/dashboard/(active)/web/projects/constants.tssrc/app/dashboard/(active)/web/projects/page.tsxsrc/app/dashboard/(active)/web/projects/projects-drag.tsxsrc/app/dashboard/(active)/web/projects/projects-view.tsxsrc/app/dashboard/(active)/web/projects/types.tssrc/components/dashboard-sidebar/data.tsxsrc/components/delete-dialog.tsxsrc/components/ui/button.tsxsrc/components/web-header.tsxsrc/server/actions/projects.ts
Blocked by PoliNetworkOrg/backend#37