Skip to content

improve project view#307

Merged
InfinityBowman merged 6 commits into
mainfrom
306-improve-project-view
Jan 18, 2026
Merged

improve project view#307
InfinityBowman merged 6 commits into
mainfrom
306-improve-project-view

Conversation

@InfinityBowman
Copy link
Copy Markdown
Owner

@InfinityBowman InfinityBowman commented Jan 18, 2026

Summary by CodeRabbit

  • New Features

    • New Profile & Settings pages with Profile, Persona, Academic Info, Delete Account, and Integrations screens
    • Create Project modal for streamlined project creation
  • Updates

    • Avatar-based reviewer display with tooltips and role badges
    • Compact project header with inline name/description editing and sticky tab navigation
    • Refreshed overview, team members, settings, and dashboard visual styles
  • Removed

    • Legacy standalone Profile page, General settings page, and old progress card component

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

@InfinityBowman InfinityBowman linked an issue Jan 18, 2026 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 18, 2026

Warning

Rate limit exceeded

@InfinityBowman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 18 minutes and 12 seconds before requesting another review.

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

📥 Commits

Reviewing files that changed from the base of the PR and between d807f59 and 140154f.

📒 Files selected for processing (4)
  • packages/web/src/components/settings/pages/AcademicInfoSection.jsx
  • packages/web/src/components/settings/pages/PersonaSection.jsx
  • packages/web/src/components/settings/shared/SettingField.jsx
  • packages/workers/src/durable-objects/ProjectDoc.ts
📝 Walkthrough

Walkthrough

Added ProjectContext.getMember(userId) and switched components to use it; reworked ProjectHeader/ProjectView to a sticky, compact header with inline description editing; swapped reviewer badges for avatar + tooltip UI; redesigned Overview and several settings pages; removed legacy ProfilePage; introduced CreateProjectModal and other modal/setting components; various typing/parameter-name cleanups.

Changes

Cohort / File(s) Summary
Project Context
\packages/web/src/components/project/ProjectContext.jsx``
Added getMember(userId) helper and exposed it on the ProjectContext value.
Project Header & View
\packages/web/src/components/project/ProjectHeader.jsx`, `packages/web/src/components/project/ProjectView.jsx``
Replaced back icon, moved to a compact sticky header; changed description editing to inline Save flow; separated tabs navigation into the header.
All Studies / Study Card Flow
\packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx`, `packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx`, `packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx``
Replaced getAssigneeName usage with getMember; StudyCard/StudyCardHeader now accept getMember; reviewer badges replaced by avatar + tooltip UI with avatar helpers and color classes.
Create Project (Dashboard / Panels)
\packages/web/src/components/dashboard/ProjectsSection.jsx`, `packages/web/src/components/dashboard/ProjectsPanel.jsx`, `packages/web/src/components/project/CreateProjectModal.jsx``
Replaced inline create form with new CreateProjectModal and swapped showCreateForm → createModalOpen prop/state; modal handles create API call, validation, cache invalidation and navigation.
Overview Tab & Dashboard UI
\packages/web/src/components/project/overview-tab/OverviewTab.jsx`, `packages/web/src/components/dashboard/ProgressCard.jsx` (removed), `packages/web/src/components/dashboard/Dashboard.jsx``
Large visual restyle to slate palette and updated layout; ProgressCard removed and related UI adjusted.
Profile / Settings Surface
\packages/web/src/components/profile/ProfilePage.jsx` (removed), `packages/web/src/components/settings/index.js`, `packages/web/src/components/settings/SettingsSidebar.jsx`, `packages/web/src/components/settings/SettingsIndex.jsx`, `packages/web/src/components/settings/pages/*.jsx``
Removed legacy ProfilePage; added ProfileSettings and subpages/components (ProfileInfoSection, PersonaSection, AcademicInfoSection, DeleteAccountSection, IntegrationsSettings); updated settings exports, routing and sidebar entries (Profile, Integrations).
Settings Shared UI
\packages/web/src/components/settings/shared/SettingField.jsx``
New reusable SettingField component for view/edit patterns.
Navbar / Layout / Routes
\packages/web/src/components/Navbar.jsx`, `packages/web/src/Layout.jsx`, `packages/web/src/Routes.jsx``
Conditional avatar render in Navbar; profile no longer hides sidebar; settings routes updated (profile/integrations added, general removed); dropdown link changed to /settings/profile.
Tabs Indicator
\packages/web/src/components/ui/tabs.tsx``
TabsIndicator now accepts and applies inline style prop for width/left/transition positioning.
Workers / Types / Naming Cleanups
\packages/workers/src/**` (email.ts, durable-objects/ProjectDoc.ts, billing handlers/types, webhooks, orgs, subscription, portal, dev-handlers, escapeHtml, etc.)`
Many parameter identifiers renamed to underscore-prefixed names (typing/unused-param cosmetic); Durable Object members sync now updates existing member metadata (image/name/displayName).
ESLint / Docs / Style Guide
\eslint.config.js`, `packages/docs/guides/style-guide.md``
ESLint ignore patterns added; large style-guide palette and component pattern overhaul (gray → slate/emerald/amber, typography, component tokens).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • Improve project view #306 — Implements ProjectHeader/ProjectView and StudyCard changes referenced by that issue (layout, sticky header, tabs, reviewer/member rendering).

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'improve project view' is vague and generic, using non-descriptive language that fails to convey the specific, substantial changes made across the codebase. Revise the title to be more specific and descriptive. Consider: 'Refactor project layout with sticky header and update settings/profile architecture' or a similarly detailed phrase that reflects the main changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Jan 18, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
corates 140154f Commit Preview URL Jan 18 2026, 10:25 PM

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx`:
- Around line 26-36: The outer StudyCard container uses the slate palette
(border-slate-200) while the inner CollapsibleContent uses border-gray-100;
update the inner div inside the CollapsibleContent (the element rendered with
<CollapsibleContent> where the class currently contains "border-gray-100") to
use "border-slate-100" so the StudyCard component's borders are consistent
(refer to StudyCard.jsx and the CollapsibleContent wrapper around
StudyCardHeader/children).
🧹 Nitpick comments (2)
packages/web/src/components/project/overview-tab/OverviewTab.jsx (1)

336-340: Consider using Tailwind for alternating row colors.

The inline style attribute with conditional background works, but using odd:bg-slate-50 or even:bg-slate-50 Tailwind utilities would be more consistent with the rest of the codebase.

Suggested change
                 return (
                   <div
-                    class='flex items-center justify-between rounded-lg p-3 transition-colors'
-                    style={{ background: index() % 2 === 0 ? '#f8fafc' : 'transparent' }}
+                    class='flex items-center justify-between rounded-lg p-3 transition-colors even:bg-slate-50'
                   >
packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx (1)

37-37: Prefer intent-focused comments over narrating ones.
These new inline comments mostly restate what the code does. Consider removing or rephrasing to capture the rationale only. As per coding guidelines, keep comments focused on intent.

Also applies to: 56-56, 66-66, 81-81, 85-85, 174-174

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a8b5138 and a385991.

📒 Files selected for processing (8)
  • .mcp/memory.db-shm
  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
🧰 Additional context used
📓 Path-based instructions (14)
packages/web/src/**/*.{js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/form-state.mdc)

packages/web/src/**/*.{js,jsx}: Save form state to IndexedDB before initiating OAuth redirects (Google Drive, ORCID) using saveFormState() with form type ('createProject' or 'addStudies') and serializable state only
Only save serializable data to IndexedDB—exclude File objects, ArrayBuffers, functions, and other non-serializable objects from form state persistence
Restore form state after OAuth redirects by checking URL restore params with getRestoreParamsFromUrl(), retrieving saved state with getFormState(), restoring to form, clearing saved state with clearFormState(), and clearing URL params with clearRestoreParamsFromUrl()
For temporary File object storage during OAuth flows (e.g., pending PDFs), use projectStore.setPendingProjectData() instead of IndexedDB, as File objects cannot be serialized
Add restore parameters to the URL after OAuth redirects in the format '?restore=&projectId=' to signal form state restoration on mount
Clear URL restore parameters after form state restoration by calling clearRestoreParamsFromUrl() to prevent stale restoration attempts on subsequent navigation
Form state persistence library functions (saveFormState, getFormState, clearFormState, getRestoreParamsFromUrl, clearRestoreParamsFromUrl) are implemented in packages/web/src/lib/formStatePersistence.js and should be imported from @/lib/formStatePersistence.js

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

packages/web/src/**/*.{js,jsx,ts,tsx}: Always use uploadPdf from @api/pdf-api.js for uploading PDF files. Pass object with projectId, studyId, tag ('primary' or 'supplementary'), and fileName
Validate PDF files on frontend by checking file.type includes 'pdf' and file.size is within MAX_PDF_SIZE limit (full validation is done on backend)
Use cachePdf and getCachedPdf from @primitives/pdfCache.js for caching PDF data in IndexedDB
Implement PDF caching strategy: check cache first, download from server if not cached, then cache the downloaded PDF
Store only PDF metadata in Yjs (id, name, size, tag, uploadedAt, uploadedBy), never store PDF binary data in Yjs as it is too large
Use importFromGoogleDrive from @api/google-drive.js for importing PDFs from Google Drive. Pass fileId, projectId, studyId, and tag
Save form state using saveFormState from @/lib/formStatePersistence.js before triggering OAuth redirects for Google Drive
Use addPdfToStudy operation from useProject hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy
Use removePdfFromStudy operation from useProject hook to remove PDFs from a study
Use pdfPreviewStore from @/stores/pdfPreviewStore.js for managing PDF preview state (openPreview, closePreview, getPreview methods)
Use downloadPdf from @api/pdf-api.js to download PDFs from server, then cache the result using cachePdf
Always cache PDFs after download and check cache before downloading to avoid redundant downloads
Use PDF operations from useProject hook instead of bypassing through direct API calls

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

Use PdfViewer component from @/components/checklist-ui/pdf/PdfViewer.jsx for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}: NEVER destructure props in SolidJS components - access props directly or wrap in functions to maintain reactivity
Use external stores in packages/web/src/stores/ for shared/cross-feature state instead of prop-drilling
Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities
Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components
Use Solid's Show component for conditional rendering instead of ternary operators
Use Solid's For component for rendering lists instead of Array.map()
Use the children helper when manipulating props.children in SolidJS components

Use Show and For components for conditional and list rendering in SolidJS

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: Use createSignal for simple reactive values in SolidJS components
Use createStore for complex objects and arrays that need granular reactivity in SolidJS
Use createMemo for computed/derived values that depend on reactive state in SolidJS
Always clean up SolidJS effects that create subscriptions or timers using onCleanup
Import stores directly in components and use store read/write action pattern - read from store, write via actions store
Prefer derived state with createMemo or signals over effects whenever possible
Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: NEVER destructure props in SolidJS components - it breaks reactivity. Access props directly (e.g., props.name) or wrap in a function (e.g., () => props.name)
Store imports should access store data directly from external stores (packages/web/src/stores/) rather than receiving store data via props
Use createSignal for simple, reactive values in SolidJS
Use createStore for complex objects and nested state in SolidJS, with nested updates using setState pattern (e.g., setState('items', items => [...items, newItem]))
Use createMemo for derived/computed values in SolidJS to maintain reactivity
Use local createSignal or createStore for local component state
Components should receive at most 1-5 props for local configuration only
Move business logic to stores, utilities, or SolidJS primitives rather than keeping it in component code

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/yjs-sync.mdc)

**/*.{js,jsx,ts,tsx}: Use the useProject hook for managing Yjs connections with reference counting instead of creating Y.Doc instances directly
Never create Y.Doc instances directly; always use the connection registry managed by useProject
Access Y.Doc connection state via projectStore.getConnectionState(projectId) instead of checking connection state directly
Read Yjs-synced data from projectStore (using getStudies, getChecklist, etc.) rather than accessing Y.Doc maps/arrays directly
Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc
Don't store Y.Doc references in component state; always retrieve the connection through useProject
Handle connection cleanup via onCleanup() in Solid.js components or equivalent cleanup patterns, calling disconnect() when the component unmounts

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
packages/web/src/**

📄 CodeRabbit inference engine (.cursor/rules/organizations.mdc)

packages/web/src/**: Use human-readable slug in frontend URLs: /orgs/:orgSlug/...
Use orgId (UUID) for API calls, not orgSlug, when making fetch requests to backend endpoints

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
packages/web/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/web/**/*.{js,ts,jsx,tsx}: Use apiFetch for all frontend API calls instead of raw fetch to automatically handle JSON parsing, errors, and toast notifications
Use handleFetchError for wrapping legacy raw fetch calls in frontend code (legacy pattern, prefer apiFetch)
Use error utility functions like isErrorCode from error-utils to check specific error types instead of direct string comparisons

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
packages/web/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

Use createFormErrorSignals for form error handling in frontend forms to manage field-level and global error states

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
packages/{web,workers}/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

Never throw string literals; always throw Error objects or return domain errors from API routes

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
{packages/web/src/stores/**/*.{js,jsx,ts,tsx},packages/web/src/**/*.{js,jsx,ts,tsx}}

📄 CodeRabbit inference engine (.github/instructions/solidjs.instructions.md)

Shared or cross-feature state should use external stores located in packages/web/src/stores/

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

**/*.{js,ts,jsx,tsx}: Prefer modern ES6+ syntax and features
Comments should explain why something is being done, not what the code is doing
Reserve comments for explaining intent, context, workarounds, assumptions, edge cases, or limitations
Use TODO(agent): prefix for incomplete work or flagged items with brief description and relevant doc references

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Never use emojis or unicode symbols anywhere in code, comments, documentation, plan files, commit messages, or examples

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
packages/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/**/*.{ts,tsx,js,jsx}: Prefer modern ES6+ syntax and features
Prefer config files over hardcoding values
Keep files small, focused, and modular - extract large files into sub-modules or separate utilities
Each file should handle one coherent responsibility
Comments should explain WHY something is being done or provide context, not repeat what the code is saying
Do NOT narrate what code is doing, don't duplicate function/variable names in comments, and don't leave stale comments that contradict the code
Use the Agent TODO convention // TODO(agent): Brief description for incomplete work, flagging items for future attention, known limitations, and documentation section references

Use TODO(agent) convention with brief description and relevant doc section references for incomplete work or flagged issues

Files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
🧠 Learnings (32)
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure

Applied to files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to packages/workers/src/durable-objects/ProjectDoc.js, packages/web/src/primitives/useProject/** : Y.Doc structure in ProjectDoc follows a specific hierarchy: meta (Map), members (Map), reviews (Map containing studies with checklists, pdfs, and reconciliation)

Applied to files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/ProjectView.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Read Yjs-synced data from projectStore (using getStudies, getChecklist, etc.) rather than accessing Y.Doc maps/arrays directly

Applied to files:

  • packages/web/src/components/project/ProjectContext.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Use getChecklistStatus utility from `@/lib/checklist-domain.js` to determine current checklist status before performing operations

Applied to files:

  • packages/web/src/components/project/ProjectContext.jsx
📚 Learning: 2026-01-01T23:32:23.488Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/workers.mdc:0-0
Timestamp: 2026-01-01T23:32:23.488Z
Learning: Applies to packages/workers/src/routes/orgs/**/*.{js,ts,jsx,tsx} : Use `requireOrgMembership` and `requireProjectAccess` middleware instead of manual membership checks for org-scoped routes

Applied to files:

  • packages/web/src/components/project/ProjectContext.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc

Applied to files:

  • packages/web/src/components/project/ProjectContext.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `addPdfToStudy` operation from `useProject` hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy

Applied to files:

  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `removePdfFromStudy` operation from `useProject` hook to remove PDFs from a study

Applied to files:

  • packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx
  • packages/web/src/components/project/ProjectView.jsx
  • packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx
  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
📚 Learning: 2025-12-27T03:01:35.601Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/durable-objects.mdc:0-0
Timestamp: 2025-12-27T03:01:35.601Z
Learning: Applies to packages/workers/src/durable-objects/**/ProjectDoc.{js,ts} : Structure ProjectDoc Y.Doc with meta (Map), members (Map), and reviews (Map) containing checklists (Map), pdfs (Array), and reconciliation (Map)

Applied to files:

  • packages/web/src/components/project/ProjectView.jsx
📚 Learning: 2025-12-27T03:01:54.727Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.727Z
Learning: Applies to packages/web/src/components/project-ui/**/*.{js,jsx} : Form state should include serializable metadata when handling files (name, size, type) and use the store's pendingPdfs pattern for actual File objects that persist across redirects

Applied to files:

  • packages/web/src/components/project/ProjectView.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use PDF operations from `useProject` hook instead of bypassing through direct API calls

Applied to files:

  • packages/web/src/components/project/ProjectView.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Use `PdfViewer` component from `@/components/checklist-ui/pdf/PdfViewer.jsx` for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Applied to files:

  • packages/web/src/components/project/ProjectView.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Solid's Show component for conditional rendering instead of ternary operators

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2026-01-17T00:25:12.507Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.507Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Show and For components for conditional and list rendering in SolidJS

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createSignal for simple reactive values in SolidJS components

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2026-01-17T00:25:12.507Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.507Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createSignal for simple, reactive values in SolidJS

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createMemo for computed/derived values that depend on reactive state in SolidJS

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2026-01-17T16:09:36.904Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-17T16:09:36.904Z
Learning: Applies to packages/{web,landing}/src/**/*.{ts,tsx} : Use `createMemo` for derived values in SolidJS

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2026-01-17T00:25:12.507Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.507Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createMemo for derived/computed values in SolidJS to maintain reactivity

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2026-01-17T00:25:12.507Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.507Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use local createSignal or createStore for local component state

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2026-01-17T00:25:35.702Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/corates.mdc:0-0
Timestamp: 2026-01-17T00:25:35.702Z
Learning: Applies to packages/web/src/**/*.{ts,tsx} : Use `createMemo` for derived values in SolidJS

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Prefer derived state with createMemo or signals over effects whenever possible

Applied to files:

  • packages/web/src/components/project/ProjectHeader.jsx
📚 Learning: 2026-01-01T23:32:17.698Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/organizations.mdc:0-0
Timestamp: 2026-01-01T23:32:17.698Z
Learning: Applies to packages/web/src/primitives/useOrg* : Use useOrgProjectContext hook to combine org and project context, providing basePath and path builder functions (getStudyPath, getChecklistPath)

Applied to files:

  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
📚 Learning: 2025-12-27T03:01:54.727Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.727Z
Learning: Applies to packages/web/src/**/*.{js,jsx} : Save form state to IndexedDB before initiating OAuth redirects (Google Drive, ORCID) using saveFormState() with form type ('createProject' or 'addStudies') and serializable state only

Applied to files:

  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `importFromGoogleDrive` from `api/google-drive.js` for importing PDFs from Google Drive. Pass fileId, projectId, studyId, and tag

Applied to files:

  • packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx
📚 Learning: 2026-01-17T00:25:35.702Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/corates.mdc:0-0
Timestamp: 2026-01-17T00:25:35.702Z
Learning: Applies to packages/workers/src/**/*.{ts,tsx} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2026-01-17T16:09:36.904Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-17T16:09:36.904Z
Learning: Applies to packages/workers/src/**/*.ts : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components

Applied to files:

  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

Applied to files:

  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2026-01-17T16:10:07.519Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-17T16:10:07.519Z
Learning: Use required libraries for specific functionality: Zod for validation, Drizzle for database, Better-Auth for authentication, Ark UI for components

Applied to files:

  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities

Applied to files:

  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js} : Store reconciliation progress metadata (IDs and optional currentPage) in the study's Y.Map reconciliation property

Applied to files:

  • packages/web/src/components/project/overview-tab/OverviewTab.jsx
🧬 Code graph analysis (6)
packages/web/src/components/project/ProjectContext.jsx (1)
packages/web/src/primitives/useProject/index.js (1)
  • members (154-154)
packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx (1)
packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx (1)
  • StudyCardHeader (51-225)
packages/web/src/components/project/ProjectView.jsx (2)
packages/web/src/components/ui/tabs.tsx (4)
  • Tabs (132-132)
  • TabsList (132-132)
  • TabsTrigger (132-132)
  • TabsContent (132-132)
packages/web/src/components/project/ProjectHeader.jsx (1)
  • ProjectHeader (7-142)
packages/web/src/components/project/ProjectHeader.jsx (3)
packages/web/src/components/ui/editable.tsx (1)
  • SimpleEditable (241-241)
packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx (1)
  • handleNameChange (99-103)
packages/web/src/components/project/ProjectContext.jsx (1)
  • userRole (34-39)
packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx (4)
packages/web/src/components/project/ProjectHeader.jsx (1)
  • name (14-14)
packages/web/src/components/ui/tooltip.tsx (4)
  • Tooltip (136-136)
  • TooltipTrigger (137-137)
  • TooltipPositioner (138-138)
  • TooltipContent (139-139)
packages/web/src/components/ui/avatar.tsx (3)
  • Avatar (125-125)
  • AvatarImage (125-125)
  • AvatarFallback (125-125)
packages/web/src/components/ui/menu.tsx (2)
  • Menu (195-195)
  • MenuTrigger (196-196)
packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx (1)
packages/web/src/components/project/ProjectContext.jsx (2)
  • useProjectContext (83-89)
  • getMember (49-52)
⏰ 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: Workers Builds: corates
🔇 Additional comments (9)
packages/web/src/components/project/ProjectContext.jsx (1)

49-52: LGTM!

The getMember helper is well-implemented with proper null handling for missing userId and unfound members. The pattern is consistent with the existing getAssigneeName helper.

packages/web/src/components/project/ProjectHeader.jsx (1)

65-141: LGTM!

The restructured header layout is clean with proper use of Show components for conditional rendering. The inline description editing flow with save/cancel actions and loading states is well-implemented.

packages/web/src/components/project/overview-tab/OverviewTab.jsx (1)

218-296: LGTM!

The Project Progress section is well-structured with the circular progress visualization and stats grid. The slate color palette is consistently applied throughout.

packages/web/src/components/project/all-studies-tab/AllStudiesTab.jsx (2)

25-25: LGTM!

The switch from getAssigneeName to getMember aligns correctly with the new ProjectContext API.


160-167: LGTM!

The getMember prop is correctly passed to StudyCard, enabling avatar-based reviewer display in StudyCardHeader.

packages/web/src/components/project/ProjectView.jsx (2)

291-357: Clean sticky header layout implementation.

The restructured layout with a sticky header containing ProjectHeader and TabsList, followed by the main content area, is well-organized. The use of SectionErrorBoundary around each tab content is good defensive practice.


316-320: Verify that data-[selected] styling works on the badge span child element.

The data-[selected]:bg-blue-100 data-[selected]:text-blue-700 classes are applied to the <span> child element, but data-[selected] is typically set only on the TabsTrigger parent. Tailwind's data-[*] selectors only match elements that directly have the attribute. Confirm whether the TabsTrigger implementation passes the attribute to children or if alternative styling (group pattern, Show component, or conditional className) is needed.

packages/web/src/components/project/all-studies-tab/study-card/StudyCardHeader.jsx (2)

27-49: Avatar reviewer rendering looks solid.
The helper utilities and fallbacks keep the avatar and tooltip UI resilient when member data is partial.

Also applies to: 69-91, 175-194


155-156: Styling updates are consistent with the slate palette.
The chevron, text, and menu trigger adjustments align with the updated theme.

Also applies to: 166-170, 201-201, 206-206

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +26 to 36
<div class='rounded-lg border border-slate-200 bg-white transition-colors hover:border-slate-300'>
<Collapsible open={props.expanded}>
<StudyCardHeader
study={props.study}
expanded={props.expanded}
onToggle={() => props.onToggleExpanded?.()}
onAssignReviewers={() => props.onAssignReviewers?.(props.study)}
getAssigneeName={props.getAssigneeName}
getMember={props.getMember}
/>
<CollapsibleContent>
<div class='border-t border-gray-100'>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent border color palette.

The outer container uses border-slate-200 (line 26) but the inner CollapsibleContent border uses border-gray-100 (line 36). Consider updating to border-slate-100 for consistency with the slate palette used elsewhere in this PR.

Suggested fix
         <CollapsibleContent>
-          <div class='border-t border-gray-100'>
+          <div class='border-t border-slate-100'>
             <StudyPdfSection
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div class='rounded-lg border border-slate-200 bg-white transition-colors hover:border-slate-300'>
<Collapsible open={props.expanded}>
<StudyCardHeader
study={props.study}
expanded={props.expanded}
onToggle={() => props.onToggleExpanded?.()}
onAssignReviewers={() => props.onAssignReviewers?.(props.study)}
getAssigneeName={props.getAssigneeName}
getMember={props.getMember}
/>
<CollapsibleContent>
<div class='border-t border-gray-100'>
<div class='rounded-lg border border-slate-200 bg-white transition-colors hover:border-slate-300'>
<Collapsible open={props.expanded}>
<StudyCardHeader
study={props.study}
expanded={props.expanded}
onToggle={() => props.onToggleExpanded?.()}
onAssignReviewers={() => props.onAssignReviewers?.(props.study)}
getMember={props.getMember}
/>
<CollapsibleContent>
<div class='border-t border-slate-100'>
🤖 Prompt for AI Agents
In `@packages/web/src/components/project/all-studies-tab/study-card/StudyCard.jsx`
around lines 26 - 36, The outer StudyCard container uses the slate palette
(border-slate-200) while the inner CollapsibleContent uses border-gray-100;
update the inner div inside the CollapsibleContent (the element rendered with
<CollapsibleContent> where the class currently contains "border-gray-100") to
use "border-slate-100" so the StudyCard component's borders are consistent
(refer to StudyCard.jsx and the CollapsibleContent wrapper around
StudyCardHeader/children).

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@packages/web/src/components/settings/pages/AcademicInfoSection.jsx`:
- Around line 14-23: Replace the raw fetch in syncProfileToProjects with the
shared apiFetch helper: import apiFetch from '@lib/apiFetch.js', call await
apiFetch('/api/users/sync-profile', { method: 'POST', credentials: 'include' })
inside the syncProfileToProjects function so JSON parsing, error handling and
toasts are applied, remove the try/catch console.error (apiFetch will surface
errors) and drop the API_BASE import if it’s no longer used elsewhere in the
file.

In `@packages/web/src/components/settings/pages/PersonaSection.jsx`:
- Around line 27-35: The function syncProfileToProjects currently calls fetch
directly (bypassing shared error/toast handling); replace the raw fetch call
with the shared apiFetch utility (or wrap the request with handleFetchError) to
ensure consistent frontend API handling — call
apiFetch(`${API_BASE}/api/users/sync-profile`, { method: 'POST', credentials:
'include' }) inside syncProfileToProjects and remove the direct fetch usage so
errors and toasts flow through the common handlers.

In `@packages/web/src/components/settings/shared/SettingField.jsx`:
- Around line 29-33: The fallback display uses a boolean OR that hides valid
falsy values: in the Show fallback JSX where it currently renders {props.value
|| 'Not set'} (inside the Show when={props.editing} fallback block in
SettingField.jsx), change the operator to nullish coalescing so it reads
{props.value ?? 'Not set'} so only null/undefined trigger the "Not set" fallback
and values like 0, false, or '' are rendered correctly.
- Around line 39-58: The Edit, Save and Cancel buttons in SettingField.jsx (the
button elements that call props.onEdit, props.onSave?.(), and props.onCancel?.()
and respect props.saving) lack an explicit type and will act as form submits;
update each of those button elements to include type="button" to prevent
unintended form submission while preserving their current onClick, disabled, and
class attributes.

In `@packages/workers/src/durable-objects/ProjectDoc.ts`:
- Around line 550-576: The image update logic in initializeDoc/membersMap
handling only sets existingMember.image when userImage is truthy, which prevents
clearing avatars; change the comparison to update when userImage !== storedImage
(including null) and call existingMember.set('image', userImage) when they
differ so removals clear the stored value; update the code in the block that
references initializeDoc, membersMap, existingMember and the
storedImage/userImage variables accordingly.
🧹 Nitpick comments (6)
packages/web/src/components/project/ProjectView.jsx (1)

238-264: Consider memoizing or extracting tabDefinitions to avoid recreating JSX icons on every render.

The tabDefinitions array with inline JSX icons is recreated on each render. While SolidJS handles this efficiently, extracting the static parts outside the component or memoizing could slightly improve performance.

Optional: Extract icon components or memoize definitions
+// Outside component - static icon components
+const TabIcons = {
+  overview: () => <BiRegularHome class='h-4 w-4' />,
+  'all-studies': () => <AiOutlineBook class='h-4 w-4' />,
+  todo: () => <BsListTask class='h-4 w-4' />,
+  reconcile: () => <CgArrowsExchange class='h-4 w-4' />,
+  completed: () => <AiFillCheckCircle class='h-4 w-4' />,
+};

 export default function ProjectView(props) {
   // ...
   
   // Tab configuration
-  const tabDefinitions = [
-    { value: 'overview', label: 'Overview', icon: <BiRegularHome class='h-4 w-4' /> },
+  const tabDefinitions = [
+    { value: 'overview', label: 'Overview', Icon: TabIcons.overview },
     // ... etc
   ];

Then in the render: <tab.Icon /> instead of {tab.icon}

packages/web/src/components/settings/pages/IntegrationsSettings.jsx (2)

57-62: Add rel="noopener noreferrer" to external link.

The anchor opens in a new context (implied by linking to an external URL). Adding rel="noopener noreferrer" prevents the linked page from accessing window.opener and mitigates tabnapping risks.

Suggested fix
               <p class='pt-2'>
                 <a
                   href={LANDING_URL}
+                  target='_blank'
+                  rel='noopener noreferrer'
                   class='text-blue-600 transition-colors hover:text-blue-700 hover:underline'
                 >
                   Visit our website
                 </a>
               </p>

55-55: Consider centralizing version information.

The hardcoded version 1.0.0 will need manual updates. Consider importing from a central config or package.json if automatic versioning is desired.

packages/web/src/components/settings/pages/AcademicInfoSection.jsx (2)

24-36: Move imports to the top of the file.

The Select-related imports are placed after the syncProfileToProjects function definition. Conventional JavaScript/ES6 style groups all imports at the top for better readability.

Suggested reordering

Move lines 24-36 to after line 9 (after the other imports).


98-99: Consider awaiting syncProfileToProjects or adjusting success messaging.

Currently the success toast shows before the sync completes. If the sync fails, users believe their changes propagated to projects when they didn't. Either await the sync or clarify the toast message indicates local profile was updated.

packages/web/src/components/settings/pages/ProfileInfoSection.jsx (1)

21-30: Use apiFetch instead of raw fetch for API calls.

Per coding guidelines, all frontend API calls should use apiFetch to automatically handle JSON parsing, errors, and toast notifications. The current implementation silently swallows errors which may hide sync failures from users.

Suggested fix
+import { apiFetch } from '@/lib/api-fetch.js';
+
 /**
  * Sync profile changes to all projects the user is a member of
  */
 async function syncProfileToProjects() {
   try {
-    await fetch(`${API_BASE}/api/users/sync-profile`, {
-      method: 'POST',
-      credentials: 'include',
-    });
+    await apiFetch('/api/users/sync-profile', { method: 'POST' });
   } catch (err) {
     console.error('Failed to sync profile to projects:', err);
   }
 }

Comment thread packages/web/src/components/settings/pages/AcademicInfoSection.jsx
Comment thread packages/web/src/components/settings/pages/PersonaSection.jsx Outdated
Comment thread packages/web/src/components/settings/shared/SettingField.jsx
Comment thread packages/web/src/components/settings/shared/SettingField.jsx
Comment thread packages/workers/src/durable-objects/ProjectDoc.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/docs/guides/style-guide.md`:
- Line 183: Replace the invalid Tailwind class name used in the div element's
class list: change "bg-linear-to-r" to the correct Tailwind utility
"bg-gradient-to-r" in the element that currently has the class string "border-b
border-slate-100 bg-linear-to-r from-slate-50 to-white px-6 py-4" so the
gradient utilities (from-slate-50 to-white) work as intended.
- Line 333: Replace the invalid Tailwind class used on the div element (the
class string containing "bg-linear-to-br") with the correct Tailwind gradient
class "bg-gradient-to-br"; locate the div that includes "flex h-20 w-20
items-center justify-center rounded-full bg-linear-to-br ..." and update that
class token to "bg-gradient-to-br" so the gradient utility resolves correctly.
🧹 Nitpick comments (3)
packages/web/src/components/project/ProjectsPanel.jsx (1)

98-108: Consider using apiFetch for the DELETE request.

This pre-existing code uses raw fetch for the delete operation. Per coding guidelines, apiFetch should be used for all frontend API calls to get automatic JSON parsing, error handling, and toast notifications.

Suggested refactor
-      const response = await fetch(
-        `${API_BASE}/api/orgs/${project.orgId}/projects/${targetProjectId}`,
-        {
-          method: 'DELETE',
-          credentials: 'include',
-        },
-      );
-      if (!response.ok) {
-        const data = await response.json().catch(() => ({}));
-        throw new Error(data.error || 'Failed to delete project');
-      }
+      await apiFetch(`/api/orgs/${project.orgId}/projects/${targetProjectId}`, {
+        method: 'DELETE',
+      });

Note: You would also need to import apiFetch from @lib/apiFetch.js.

packages/web/src/components/dashboard/Dashboard.jsx (1)

160-168: Consider removing commented code if permanently deprecated.

The StatsRow component and related code are commented out. If this removal is permanent (as suggested by the PR summary), consider deleting the commented code to reduce noise. If it's temporary, a brief comment explaining why it's disabled would help future maintainers.

packages/web/src/components/dashboard/ProjectsSection.jsx (1)

90-91: Consider simplifying prop accessor wrappers.

These local functions wrap the prop accessors but add an extra layer of indirection. While functionally correct, you could access props.createModalOpen() and props.setCreateModalOpen(val) directly in the JSX for simplicity.

However, if this pattern is used for consistency with other components or to allow future local state fallback, it's acceptable.

Simplified alternative (if no local state fallback needed)
-  const createModalOpen = () => props.createModalOpen();
-  const setCreateModalOpen = val => props.setCreateModalOpen(val);

Then use directly in JSX:

<CreateProjectModal open={props.createModalOpen()} onOpenChange={props.setCreateModalOpen} />
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d5c3de and d807f59.

📒 Files selected for processing (7)
  • packages/docs/guides/style-guide.md
  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProgressCard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/dashboard/index.js
  • packages/web/src/components/project/CreateProjectModal.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
💤 Files with no reviewable changes (2)
  • packages/web/src/components/dashboard/ProgressCard.jsx
  • packages/web/src/components/dashboard/index.js
🧰 Additional context used
📓 Path-based instructions (14)
packages/web/src/**/*.{js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/form-state.mdc)

packages/web/src/**/*.{js,jsx}: Save form state to IndexedDB before initiating OAuth redirects (Google Drive, ORCID) using saveFormState() with form type ('createProject' or 'addStudies') and serializable state only
Only save serializable data to IndexedDB—exclude File objects, ArrayBuffers, functions, and other non-serializable objects from form state persistence
Restore form state after OAuth redirects by checking URL restore params with getRestoreParamsFromUrl(), retrieving saved state with getFormState(), restoring to form, clearing saved state with clearFormState(), and clearing URL params with clearRestoreParamsFromUrl()
For temporary File object storage during OAuth flows (e.g., pending PDFs), use projectStore.setPendingProjectData() instead of IndexedDB, as File objects cannot be serialized
Add restore parameters to the URL after OAuth redirects in the format '?restore=&projectId=' to signal form state restoration on mount
Clear URL restore parameters after form state restoration by calling clearRestoreParamsFromUrl() to prevent stale restoration attempts on subsequent navigation
Form state persistence library functions (saveFormState, getFormState, clearFormState, getRestoreParamsFromUrl, clearRestoreParamsFromUrl) are implemented in packages/web/src/lib/formStatePersistence.js and should be imported from @/lib/formStatePersistence.js

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

packages/web/src/**/*.{js,jsx,ts,tsx}: Always use uploadPdf from @api/pdf-api.js for uploading PDF files. Pass object with projectId, studyId, tag ('primary' or 'supplementary'), and fileName
Validate PDF files on frontend by checking file.type includes 'pdf' and file.size is within MAX_PDF_SIZE limit (full validation is done on backend)
Use cachePdf and getCachedPdf from @primitives/pdfCache.js for caching PDF data in IndexedDB
Implement PDF caching strategy: check cache first, download from server if not cached, then cache the downloaded PDF
Store only PDF metadata in Yjs (id, name, size, tag, uploadedAt, uploadedBy), never store PDF binary data in Yjs as it is too large
Use importFromGoogleDrive from @api/google-drive.js for importing PDFs from Google Drive. Pass fileId, projectId, studyId, and tag
Save form state using saveFormState from @/lib/formStatePersistence.js before triggering OAuth redirects for Google Drive
Use addPdfToStudy operation from useProject hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy
Use removePdfFromStudy operation from useProject hook to remove PDFs from a study
Use pdfPreviewStore from @/stores/pdfPreviewStore.js for managing PDF preview state (openPreview, closePreview, getPreview methods)
Use downloadPdf from @api/pdf-api.js to download PDFs from server, then cache the result using cachePdf
Always cache PDFs after download and check cache before downloading to avoid redundant downloads
Use PDF operations from useProject hook instead of bypassing through direct API calls

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

Use PdfViewer component from @/components/checklist-ui/pdf/PdfViewer.jsx for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}: NEVER destructure props in SolidJS components - access props directly or wrap in functions to maintain reactivity
Use external stores in packages/web/src/stores/ for shared/cross-feature state instead of prop-drilling
Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities
Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components
Use Solid's Show component for conditional rendering instead of ternary operators
Use Solid's For component for rendering lists instead of Array.map()
Use the children helper when manipulating props.children in SolidJS components

Use Show and For components for conditional and list rendering in SolidJS

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: Use createSignal for simple reactive values in SolidJS components
Use createStore for complex objects and arrays that need granular reactivity in SolidJS
Use createMemo for computed/derived values that depend on reactive state in SolidJS
Always clean up SolidJS effects that create subscriptions or timers using onCleanup
Import stores directly in components and use store read/write action pattern - read from store, write via actions store
Prefer derived state with createMemo or signals over effects whenever possible
Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: NEVER destructure props in SolidJS components - it breaks reactivity. Access props directly (e.g., props.name) or wrap in a function (e.g., () => props.name)
Store imports should access store data directly from external stores (packages/web/src/stores/) rather than receiving store data via props
Use createSignal for simple, reactive values in SolidJS
Use createStore for complex objects and nested state in SolidJS, with nested updates using setState pattern (e.g., setState('items', items => [...items, newItem]))
Use createMemo for derived/computed values in SolidJS to maintain reactivity
Use local createSignal or createStore for local component state
Components should receive at most 1-5 props for local configuration only
Move business logic to stores, utilities, or SolidJS primitives rather than keeping it in component code

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/yjs-sync.mdc)

**/*.{js,jsx,ts,tsx}: Use the useProject hook for managing Yjs connections with reference counting instead of creating Y.Doc instances directly
Never create Y.Doc instances directly; always use the connection registry managed by useProject
Access Y.Doc connection state via projectStore.getConnectionState(projectId) instead of checking connection state directly
Read Yjs-synced data from projectStore (using getStudies, getChecklist, etc.) rather than accessing Y.Doc maps/arrays directly
Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc
Don't store Y.Doc references in component state; always retrieve the connection through useProject
Handle connection cleanup via onCleanup() in Solid.js components or equivalent cleanup patterns, calling disconnect() when the component unmounts

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
packages/web/src/**

📄 CodeRabbit inference engine (.cursor/rules/organizations.mdc)

packages/web/src/**: Use human-readable slug in frontend URLs: /orgs/:orgSlug/...
Use orgId (UUID) for API calls, not orgSlug, when making fetch requests to backend endpoints

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
packages/web/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/web/**/*.{js,ts,jsx,tsx}: Use apiFetch for all frontend API calls instead of raw fetch to automatically handle JSON parsing, errors, and toast notifications
Use handleFetchError for wrapping legacy raw fetch calls in frontend code (legacy pattern, prefer apiFetch)
Use error utility functions like isErrorCode from error-utils to check specific error types instead of direct string comparisons

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
packages/web/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

Use createFormErrorSignals for form error handling in frontend forms to manage field-level and global error states

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
packages/{web,workers}/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

Never throw string literals; always throw Error objects or return domain errors from API routes

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
{packages/web/src/stores/**/*.{js,jsx,ts,tsx},packages/web/src/**/*.{js,jsx,ts,tsx}}

📄 CodeRabbit inference engine (.github/instructions/solidjs.instructions.md)

Shared or cross-feature state should use external stores located in packages/web/src/stores/

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

**/*.{js,ts,jsx,tsx}: Prefer modern ES6+ syntax and features
Comments should explain why something is being done, not what the code is doing
Reserve comments for explaining intent, context, workarounds, assumptions, edge cases, or limitations
Use TODO(agent): prefix for incomplete work or flagged items with brief description and relevant doc references

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Never use emojis or unicode symbols anywhere in code, comments, documentation, plan files, commit messages, or examples

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
  • packages/docs/guides/style-guide.md
packages/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/**/*.{ts,tsx,js,jsx}: Prefer modern ES6+ syntax and features
Prefer config files over hardcoding values
Keep files small, focused, and modular - extract large files into sub-modules or separate utilities
Each file should handle one coherent responsibility
Comments should explain WHY something is being done or provide context, not repeat what the code is saying
Do NOT narrate what code is doing, don't duplicate function/variable names in comments, and don't leave stale comments that contradict the code
Use the Agent TODO convention // TODO(agent): Brief description for incomplete work, flagging items for future attention, known limitations, and documentation section references

Use TODO(agent) convention with brief description and relevant doc section references for incomplete work or flagged issues

Files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
🧠 Learnings (22)
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Prefer derived state with createMemo or signals over effects whenever possible

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
📚 Learning: 2025-12-27T03:01:54.727Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.727Z
Learning: Applies to packages/web/src/components/project-ui/**/*.{js,jsx} : Form state should include serializable metadata when handling files (name, size, type) and use the store's pendingPdfs pattern for actual File objects that persist across redirects

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
📚 Learning: 2025-12-27T03:01:54.727Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.727Z
Learning: Applies to packages/web/src/**/*.{js,jsx} : Save form state to IndexedDB before initiating OAuth redirects (Google Drive, ORCID) using saveFormState() with form type ('createProject' or 'addStudies') and serializable state only

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/web/src/components/project/CreateProjectModal.jsx
📚 Learning: 2026-01-17T00:25:12.507Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.507Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use local createSignal or createStore for local component state

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2026-01-17T00:25:12.507Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.507Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Show and For components for conditional and list rendering in SolidJS

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
  • packages/docs/guides/style-guide.md
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Solid's Show component for conditional rendering instead of ternary operators

Applied to files:

  • packages/web/src/components/dashboard/Dashboard.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use PDF operations from `useProject` hook instead of bypassing through direct API calls

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't store Y.Doc references in component state; always retrieve the connection through useProject

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to packages/web/src/primitives/useProject/**, packages/web/src/stores/projectStore.js : IndexedDB persistence is set up automatically by useProject with database name 'corates-project-${projectId}'; don't manually create IndexedDB providers

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/docs/guides/style-guide.md
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Never create Y.Doc instances directly; always use the connection registry managed by useProject

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to packages/web/src/primitives/useProject/**, packages/web/src/stores/projectStore.js : Local projects (with IDs starting with 'local-') use IndexedDB persistence only and skip WebSocket connection, but still use Y.Doc structure and sync to store normally

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to packages/web/src/primitives/useProject/**, packages/web/src/stores/projectStore.js : When access is denied (user removed or project deleted), the connection automatically triggers cleanup: IndexedDB data cleared, connection closed, store cleared, and user redirected

Applied to files:

  • packages/web/src/components/dashboard/ProjectsSection.jsx
  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2025-12-27T03:01:54.727Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.727Z
Learning: Applies to packages/web/src/**/*.{js,jsx} : Add restore parameters to the URL after OAuth redirects in the format '?restore=<formType>&projectId=<projectId>' to signal form state restoration on mount

Applied to files:

  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createSignal for simple reactive values in SolidJS components

Applied to files:

  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2026-01-17T00:25:12.507Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.507Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createSignal for simple, reactive values in SolidJS

Applied to files:

  • packages/web/src/components/project/ProjectsPanel.jsx
📚 Learning: 2026-01-17T16:09:36.904Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-17T16:09:36.904Z
Learning: Applies to packages/{web,landing}/src/**/*.{ts,tsx} : Use Ark UI components from `ark-ui/solid` for UI components

Applied to files:

  • packages/docs/guides/style-guide.md
📚 Learning: 2026-01-17T00:25:35.702Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/corates.mdc:0-0
Timestamp: 2026-01-17T00:25:35.702Z
Learning: Applies to packages/web/src/**/*.{ts,tsx} : Use Ark UI component library (`ark-ui/solid`) for UI components

Applied to files:

  • packages/docs/guides/style-guide.md
🧬 Code graph analysis (2)
packages/web/src/components/dashboard/Dashboard.jsx (2)
packages/web/src/components/dashboard/ProjectsSection.jsx (2)
  • createModalOpen (90-90)
  • setCreateModalOpen (91-91)
packages/web/src/components/project/ProjectsPanel.jsx (1)
  • createModalOpen (59-59)
packages/web/src/components/dashboard/ProjectsSection.jsx (3)
packages/web/src/components/dashboard/Dashboard.jsx (1)
  • createModalOpen (120-120)
packages/web/src/components/project/ProjectsPanel.jsx (1)
  • createModalOpen (59-59)
packages/web/src/components/project/CreateProjectModal.jsx (1)
  • CreateProjectModal (39-225)
⏰ 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: Workers Builds: corates
🔇 Additional comments (18)
packages/web/src/components/project/CreateProjectModal.jsx (4)

1-33: LGTM - Well-structured imports and documentation.

The imports are properly organized and the JSDoc header clearly describes the component's purpose and scope.


39-77: LGTM - Correct SolidJS reactivity patterns.

Form state management is well-implemented:

  • Local signals for form fields
  • createMemo for derived resolvedOrgId correctly handles single vs. multiple org scenarios
  • Reset effect properly cleans up when dialog closes

80-130: LGTM - Robust submission handling with comprehensive error handling.

The submit handler correctly:

  • Prevents double-submission via isSubmitting state
  • Uses apiFetch per coding guidelines
  • Handles specific FORBIDDEN error reasons (entitlement, quota) with user-friendly messages
  • Falls back to generic error handler for other cases
  • Invalidates cache and navigates on success

132-224: LGTM - Clean modal UI with proper accessibility.

The JSX follows SolidJS guidelines with proper use of Show for conditional rendering, and maintains accessibility with correctly linked labels and inputs.

packages/web/src/components/project/ProjectsPanel.jsx (5)

31-31: LGTM - Import updated for modal pattern.

The import change correctly reflects the refactor from inline form to modal-based project creation.


59-59: LGTM - Signal renamed to match modal pattern.

The rename from showCreateForm to createModalOpen accurately reflects the new modal-based UI.


147-147: LGTM - Button handler updated.

The click handler correctly opens the modal instead of toggling an inline form.


157-158: LGTM - Modal integration is correct.

The CreateProjectModal is properly wired with open and onOpenChange props for controlled dialog state.


197-197: LGTM - Empty state button correctly opens modal.

The fallback "Create your first project" button correctly triggers the modal.

packages/web/src/components/dashboard/Dashboard.jsx (3)

116-120: LGTM - State management updated for modal pattern.

The stats is correctly commented out since the StatsRow is no longer rendered. The createModalOpen signal appropriately manages modal visibility at the dashboard level.


122-124: LGTM - Handler simplified for modal.

The handleCreateProject now simply opens the modal, with all creation logic encapsulated in CreateProjectModal.


177-180: LGTM - Props correctly passed to ProjectsSection.

The signal accessor and setter are passed as props, allowing ProjectsSection to control the modal state while keeping the source of truth in Dashboard.

packages/web/src/components/dashboard/ProjectsSection.jsx (3)

35-35: LGTM - Import updated for modal component.

Correctly imports the new CreateProjectModal component.


151-157: LGTM - Create click handler correctly opens modal.

The handler properly delegates to props.onCreateClick if provided, otherwise opens the modal directly.


194-195: LGTM - Modal correctly integrated.

The CreateProjectModal is properly wired with controlled open and onOpenChange props.

packages/docs/guides/style-guide.md (3)

1-497: Comprehensive style guide update looks good overall.

The systematic transition from gray-based neutrals to the slate/emerald/amber design system is well-documented. The guide provides clear examples for all major UI patterns, properly references Ark UI components, and maintains consistency throughout. The typography, spacing, and component sections are thorough and practical.


460-462: Verify color contrast ratio claims.

The specific contrast ratios listed (slate-900: 15.4:1, slate-500: 5.6:1, blue-600: 4.5:1) should be verified against the actual color values defined in the palette section to ensure accuracy for WCAG compliance guidance.


420-420: Verify Tailwind CSS version before applying this fix.

The class bg-linear-to-br is actually the correct name in Tailwind CSS v4, where background gradient utilities were renamed from bg-gradient-to-* to bg-linear-to-*. If this project uses Tailwind v1–v3, then bg-gradient-to-br is correct. Confirm the project's Tailwind version before treating this as an error.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

<div class="text-center p-8 rounded-2xl bg-white shadow-lg hover:shadow-xl transition-shadow duration-300 border border-gray-100">
<div class='overflow-hidden rounded-xl border border-slate-200/60 bg-white shadow-sm transition-shadow duration-200 hover:shadow-md'>
{/* Header */}
<div class='border-b border-slate-100 bg-linear-to-r from-slate-50 to-white px-6 py-4'>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix invalid Tailwind CSS class.

The class bg-linear-to-r is not a valid Tailwind CSS class. It should be bg-gradient-to-r.

Proposed fix
-  <div class='border-b border-slate-100 bg-linear-to-r from-slate-50 to-white px-6 py-4'>
+  <div class='border-b border-slate-100 bg-gradient-to-r from-slate-50 to-white px-6 py-4'>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div class='border-b border-slate-100 bg-linear-to-r from-slate-50 to-white px-6 py-4'>
<div class='border-b border-slate-100 bg-gradient-to-r from-slate-50 to-white px-6 py-4'>
🤖 Prompt for AI Agents
In `@packages/docs/guides/style-guide.md` at line 183, Replace the invalid
Tailwind class name used in the div element's class list: change
"bg-linear-to-r" to the correct Tailwind utility "bg-gradient-to-r" in the
element that currently has the class string "border-b border-slate-100
bg-linear-to-r from-slate-50 to-white px-6 py-4" so the gradient utilities
(from-slate-50 to-white) work as intended.

#### Avatar Fallback (Initials)

```jsx
<div class='flex h-20 w-20 items-center justify-center rounded-full bg-linear-to-br from-blue-500 to-blue-600 text-xl font-semibold text-white shadow-md'>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix invalid Tailwind CSS class.

The class bg-linear-to-br is not a valid Tailwind CSS class. It should be bg-gradient-to-br.

Proposed fix
-<div class='flex h-20 w-20 items-center justify-center rounded-full bg-linear-to-br from-blue-500 to-blue-600 text-xl font-semibold text-white shadow-md'>
+<div class='flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-blue-600 text-xl font-semibold text-white shadow-md'>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div class='flex h-20 w-20 items-center justify-center rounded-full bg-linear-to-br from-blue-500 to-blue-600 text-xl font-semibold text-white shadow-md'>
<div class='flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-blue-600 text-xl font-semibold text-white shadow-md'>
🤖 Prompt for AI Agents
In `@packages/docs/guides/style-guide.md` at line 333, Replace the invalid
Tailwind class used on the div element (the class string containing
"bg-linear-to-br") with the correct Tailwind gradient class "bg-gradient-to-br";
locate the div that includes "flex h-20 w-20 items-center justify-center
rounded-full bg-linear-to-br ..." and update that class token to
"bg-gradient-to-br" so the gradient utility resolves correctly.

@InfinityBowman InfinityBowman merged commit 5ea7692 into main Jan 18, 2026
4 checks passed
@InfinityBowman InfinityBowman deleted the 306-improve-project-view branch January 18, 2026 22:25
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.

Improve project view

1 participant