Skip to content

merge activity into projects: card grid + per-project detail#6

Merged
Dan-Cleary merged 2 commits into
mainfrom
feat/projects-merge
May 8, 2026
Merged

merge activity into projects: card grid + per-project detail#6
Dan-Cleary merged 2 commits into
mainfrom
feat/projects-merge

Conversation

@Dan-Cleary
Copy link
Copy Markdown
Owner

@Dan-Cleary Dan-Cleary commented May 8, 2026

Summary

  • Activity tab is gone. Everything you used to see in Activity now lives inside a project — open a project to see its items, draft PRs, and a prompt to install the widget if no events have flowed yet.
  • New `Projects` tab is two views:
    • Grid: team stats + clickable project cards (items / 7d / drafts) with a "no widget yet" badge for projects that haven't received an event.
    • Detail: per-project stats + items table + edit/delete form. Click a project card to enter; back button to return.
  • "+ new project" CTA on the grid opens an inline form; on save, you land directly on the new project's detail page so the install pointer is one click away.

Nav

Before: `Activity · Projects · Repos · Settings`
After: `Projects · Repos · Settings`

Test plan

  • Land on a fresh team → Settings (wizard) opens
  • Complete required steps → Projects becomes the natural landing
  • Click "+ new project", create one, confirm auto-routes to detail
  • Detail page shows "no widget yet" install prompt
  • Drop a widget event for that project → install prompt disappears, items table populates
  • Edit project from detail page; delete returns you to the grid

Deferred

  • Real URL routing (`/project/`) — view state is in-component today; bolt on react-router when shareable links matter.
  • Backend per-project rollup query — items filtered client-side from `recentItems(limit: 200)`. Fine until projects scale.

🤖 Generated with Claude Code


Note

Medium Risk
Moderate UI/UX refactor that removes the Activity tab and rewires navigation/default tab behavior; risk is mainly regressions in project creation/edit flows and item filtering/visibility (now client-side from recentItems).

Overview
Activity is removed from top-level navigation and the default tab/first-load logic now assumes projects (still auto-routes fresh teams to settings onboarding when setup is incomplete).

Projects is redesigned into a two-view experience: a grid of clickable project cards (team-wide stats + per-project counts/badges) and a detail view that shows per-project stats, recent items, and an inline edit/delete form, plus a minimal “new project” modal that creates then auto-opens the new project.

Adds new CSS for the project card grid and a generic modal (.project-grid, .project-card, .modal-*) to support the updated UI.

Reviewed by Cursor Bugbot for commit 6b33cbf. Bugbot is set up for automated code reviews on this repo. Configure here.

product flow: create project → install widget for that project → see its
activity at /project/<id>. activity tab disappears; everything reads from
within a project.

projects tab (rewritten):
- grid view: team-wide stats (items / drafts / queued) + project cards
  with mini-rollup (items, 7d, drafts) + "no widget yet" badge when a
  project has zero events
- detail view (state-based, no router yet): per-project stats, items
  table filtered by projectId, install-snippet pointer when noEventsYet,
  inline edit/delete form
- "+ new project" CTA opens the inline form; saving auto-routes to the
  new project's detail page so the install snippet is one click away

nav: Projects · Repos · Settings (Activity tab removed)
- AuditTab.tsx deleted
- App.tsx: default lastTab now "projects"; first-signin redirect still
  routes setup.done === 0 users to settings (wizard) when landing
  default would have been projects

styles: new .project-grid + .project-card (clickable buttons, hover +
focus-visible).

deferred: real URL routing (/project/<id>) — view state lives in
component state today; wire react-router when shareable links matter.
backend per-project rollup: items currently filtered client-side from
the existing recentItems(limit: 200) query. fine until projects scale.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Warning

Rate limit exceeded

@Dan-Cleary has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 31 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15af584a-b255-4216-8d97-6b4344ae78dd

📥 Commits

Reviewing files that changed from the base of the PR and between a1ee0ba and 6b33cbf.

📒 Files selected for processing (4)
  • app/src/App.tsx
  • app/src/styles.css
  • app/src/tabs/AuditTab.tsx
  • app/src/tabs/ProjectsTab.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/projects-merge

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.

create flow:
- new project = modal (esc to close, click backdrop to close, enter to
  submit), name-only field. slug auto-derives. on success, lands on
  the new project's detail view so the install pointer is one click.
- everything else (url patterns, primary repo, description, enabled)
  configurable in the in-project edit form.

setup banner:
- moved above the tab strip so the "you haven't connected X yet"
  warning is the first thing in the dashboard chrome instead of
  buried under tabs.

new .modal-backdrop / .modal-panel styles.

deferred: per-project widget snippet (would let us drop url patterns
entirely from project setup; currently widget events route to a
project by URL pattern matching).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Dan-Cleary Dan-Cleary merged commit 4fe2f48 into main May 8, 2026
4 checks passed
@Dan-Cleary Dan-Cleary deleted the feat/projects-merge branch May 8, 2026 15:48
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

Reviewed by Cursor Bugbot for commit 6b33cbf. Configure here.

{projects ? "project not found." : "loading…"}
</p>
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Brief "project not found" flash after creation

Medium Severity

After CreateProjectModal successfully creates a project, onCreated(id) immediately navigates to the detail view for that new project ID. The detail view looks up the project in the projects query result, but this reactive subscription may not have incorporated the newly-inserted project yet. Since projects is already defined (previously loaded), the fallback shows "project not found." instead of "loading…", causing a confusing flash on the creation happy path before the subscription catches up.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6b33cbf. Configure here.

};
window.addEventListener("keydown", onKey);
return () => window.removeEventListener("keydown", onKey);
}, [onClose]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Escape key bypasses busy guard during creation

Medium Severity

The Escape key handler unconditionally calls onClose() without checking the busy state, even though the cancel button is explicitly disabled={busy}. If the user presses Escape while the upsert mutation is in flight, the modal unmounts, but the async onCreate function continues. When the mutation resolves, onCreated(id) still fires via the parent's closure, unexpectedly navigating the user to the detail view of a project they thought they cancelled.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6b33cbf. Configure here.

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