Skip to content

feat: Implement project management features#42

Open
BIA3IA wants to merge 42 commits into
mainfrom
web/projects
Open

feat: Implement project management features#42
BIA3IA wants to merge 42 commits into
mainfrom
web/projects

Conversation

@BIA3IA

@BIA3IA BIA3IA commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@BIA3IA, we couldn't start this review because you've reached your PR review rate limit.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6aa4cb5e-f39e-43f4-8c10-3551f365c1c6

📥 Commits

Reviewing files that changed from the base of the PR and between c152b14 and 44466f3.

📒 Files selected for processing (1)
  • src/app/dashboard/(active)/web/projects/projects-view.tsx

Walkthrough

Introduces 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.

Changes

Web Projects Dashboard

Layer / File(s) Summary
Projects data contracts and constants
src/app/dashboard/(active)/web/projects/types.ts, src/app/dashboard/(active)/web/projects/constants.ts
ProjectCategory, Project, ProjectsDragProps, and CardProjectProps types are defined; PROJECT_CATEGORY enum, PROJECT_CATEGORIES UI configuration, and DEFAULT_PROJECT template are exported.
Server-side project mutations with authorization
src/server/actions/projects.ts
Four server actions (createProject, editProject, deleteProject, reorderProjects) enforce role-based access via requireRole, auto-inject createdBy/modifiedBy from caller telegramId, and handle TRPC mutation errors.
Supporting UI components
src/components/ui/button.tsx, src/components/web-header.tsx, src/app/dashboard/(active)/web/projects/category-menu.tsx, src/components/delete-dialog.tsx
New success and error button variants; WebHeader component for page titles with optional actions; ProjectCategoryMenu dropdown for category selection; DeleteDialog confirmation with async callback and pending state.
Project card component with drag and edit
src/app/dashboard/(active)/web/projects/card-project.tsx
Client component renders editable project cards with useSortable drag integration, controlled title/description/link inputs, SVG logo upload and rendering, and async save flow. Edit mode shows save/close buttons; read-only mode shows edit/delete/category actions. Supports draft cancellation via onCancelCreate.
Drag-and-drop list orchestration by category
src/app/dashboard/(active)/web/projects/projects-drag.tsx
Client component implements per-category project list rendering with drag-and-drop. moveProjectInCategory helper validates indices, performs category-scoped reordering, and reconstructs full project array. Drag-end handler calls onReorder with new order and previousProjects for rollback.
Projects view with CRUD state management
src/app/dashboard/(active)/web/projects/projects-view.tsx
Client component manages all state: active category, editing/draft flags, and optimistic CRUD. Reordering uses reorderRequestId to discard stale responses. Deletion/category-change are optimistic with rollback on errors. Save distinguishes draft creation vs editing, injects server action calls, updates local projects, shows error/success toasts, and triggers router refresh.
Page setup and sidebar navigation
src/app/dashboard/(active)/web/projects/page.tsx, src/components/dashboard-sidebar/data.tsx
Server page (WebProjectsIndex) fetches projects via trpc.web.projects.getAllProjects and renders ProjectsView. Sidebar navigation extended with "Web" category containing "Projects" link to /dashboard/web/projects.
Development environment updates
package.json
Added @dnd-kit/react ^0.4.0 dependency; removed --turbo flag from next dev script.

Possibly Related PRs

  • PoliNetworkOrg/admin#39: Updates dashboard sidebar navigation configuration to extend mainNav with new Web Projects route.

Suggested Labels

area: frontend, status: needs review

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'feat: Implement project management features' accurately summarizes the main objective of the changeset. The PR adds comprehensive project management functionality including create/edit/delete operations, drag-and-drop reordering, category management, and related UI components across multiple files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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.

❤️ Share

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

@BIA3IA BIA3IA added the status: blocked Work cannot proceed until another issue is resolved label Jun 11, 2026
@BIA3IA BIA3IA marked this pull request as ready for review June 12, 2026 08:43

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

📥 Commits

Reviewing files that changed from the base of the PR and between 05f48c8 and c152b14.

📒 Files selected for processing (14)
  • package.json
  • src/app/dashboard/(active)/telegram/users/[id]/page.tsx
  • src/app/dashboard/(active)/web/projects/card-project.tsx
  • src/app/dashboard/(active)/web/projects/category-menu.tsx
  • src/app/dashboard/(active)/web/projects/constants.ts
  • src/app/dashboard/(active)/web/projects/page.tsx
  • src/app/dashboard/(active)/web/projects/projects-drag.tsx
  • src/app/dashboard/(active)/web/projects/projects-view.tsx
  • src/app/dashboard/(active)/web/projects/types.ts
  • src/components/dashboard-sidebar/data.tsx
  • src/components/delete-dialog.tsx
  • src/components/ui/button.tsx
  • src/components/web-header.tsx
  • src/server/actions/projects.ts

Comment thread package.json
Comment thread src/app/dashboard/(active)/telegram/users/[id]/page.tsx
Comment thread src/app/dashboard/(active)/web/projects/card-project.tsx
Comment thread src/app/dashboard/(active)/web/projects/card-project.tsx
Comment thread src/app/dashboard/(active)/web/projects/projects-view.tsx
Comment thread src/app/dashboard/(active)/web/projects/projects-view.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: blocked Work cannot proceed until another issue is resolved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants