Skip to content

feat: Add Team Members & Organization Directory page#88

Merged
imuniqueshiv merged 2 commits into
imuniqueshiv:mainfrom
mrunmayeekokitkar:build-pages
Jul 7, 2026
Merged

feat: Add Team Members & Organization Directory page#88
imuniqueshiv merged 2 commits into
imuniqueshiv:mainfrom
mrunmayeekokitkar:build-pages

Conversation

@mrunmayeekokitkar

@mrunmayeekokitkar mrunmayeekokitkar commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Pull Request

Description

Implements a dedicated Team Members & Organization Directory page for MeetOnMemory, allowing users to browse organization members, search and filter the directory, view member details, and quickly copy contact information. This update also adds the required backend API, navigation entry, and responsive UI while following the existing MeetOnMemory design language.

Type of Change

  • New Feature
  • Bug Fix
  • Documentation Update
  • Refactor
  • Performance Improvement
  • Security Improvement
  • Other

Related Issue

Closes #86

Changes

Backend

  • Added GET /api/organization/members endpoint.
  • Added getOrganizationMembers controller in organizationController.js.
  • Returns organization members with populated user information including:
    • Name
    • Email
    • Role
    • Join date (createdAt)
    • Account verification status (isAccountVerified)

Team Members Page

Created a dedicated TeamMembers page featuring:

  • Organization member directory
  • Responsive member list
  • Real-time search
  • Role filtering
  • Sorting options
  • Member details modal
  • Loading, empty, and error states

Member List

Displays each organization member with:

  • Avatar
  • Name
  • Email
  • Role badge
  • Join date

Search

Implemented real-time search across:

  • Name
  • Email
  • Role

Filters

Added expandable filtering panel with:

  • All Members
  • Admin
  • Member

Sorting

Supports sorting by:

  • Name
  • Join date
  • Role

with both ascending and descending order.

Member Details

Added a detailed member modal displaying profile information when a member is selected.

Quick Actions

Added quick action for:

  • Copy email address to clipboard

Displays a toast notification after copying successfully.

Navigation

  • Added /team-members route in App.jsx.
  • Added a Team Members link to the navigation bar.

Design

  • Follows the existing MeetOnMemory SaaS design language.
  • Responsive across desktop, tablet, and mobile.
  • Consistent spacing, typography, and component styling.
  • Smooth hover and focus interactions.
  • Accessible with appropriate ARIA labels.

Implementation Summary

Backend Changes

  • Added getOrganizationMembers controller in organizationController.js.
  • Added GET /api/organization/members route in organizationRoutes.js.
  • API returns populated organization member information including:
    • Name
    • Email
    • Role
    • Created date
    • Account verification status

Frontend Changes

Created TeamMembers.jsx with:

  • Member list
  • Real-time search
  • Role filtering
  • Sorting
  • Member details modal
  • Copy email action
  • Loading state
  • Empty state
  • Error state with retry functionality

Navigation

  • Added /team-members route in App.jsx.
  • Added Team Members navigation item in Navbar.jsx.

Features Implemented

  • Organization member directory
  • Real-time search
  • Search by name
  • Search by email
  • Search by role
  • Role filtering
  • Sorting by name
  • Sorting by join date
  • Sorting by role
  • Ascending and descending sorting
  • Member details modal
  • Copy email to clipboard
  • Toast notifications
  • Loading state
  • Empty state
  • Error state
  • Retry action
  • Responsive layout
  • Accessible interface
  • MeetOnMemory design consistency

Testing

  • Tested locally
  • Existing functionality verified
  • No new warnings or errors

Verification

  • Prettier formatting passed.
  • ESLint completed successfully.
  • Vite production build completed successfully.
  • Backend API verified.
  • Team Members page verified across responsive layouts.
  • Changes committed and pushed to GitHub.
  • Existing authentication, organization management, AI features, and unrelated functionality remain unchanged.

Screenshots

N/A

Checklist

  • Code follows project conventions
  • Documentation updated where required
  • No unnecessary files included
  • Changes have been tested
  • Ready for review

Summary by CodeRabbit

  • New Features

    • Added a new Team Members page for signed-in users to view organization members.
    • Members can be searched, filtered by role, and sorted by name, role, or join date.
    • Added member details with quick email copy and a closer look at each member’s profile.
    • Added a new navigation item so the page is easier to access.
  • Bug Fixes

    • Improved handling of organization-related error messages and member access checks.

- Add API endpoint GET /api/organization/members to fetch organization members
- Create TeamMembers page with member list, search, and filters
- Implement member details modal with profile information
- Add role-based filtering (Admin/Member)
- Add search functionality for name, email, and role
- Add sorting by name, join date, and role
- Implement loading, empty, and error states
- Add quick actions (copy email)
- Add Team Members link to navigation bar
- Follow MeetOnMemory design language with responsive layout
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

@mrunmayeekokitkar is attempting to deploy a commit to the Shiv Raj Singh's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@mrunmayeekokitkar, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 53 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 53c466b5-9ac2-44bc-8f14-5399a4a25afc

📥 Commits

Reviewing files that changed from the base of the PR and between e9b4db1 and 72de9e9.

📒 Files selected for processing (3)
  • server/controllers/meetingController.js
  • server/routes/meetingRoutes.js
  • server/routes/organizationRoutes.js
📝 Walkthrough

Walkthrough

Adds a Team Members directory feature: a backend endpoint retrieving organization members with populated fields, a new frontend TeamMembers page supporting search, role filtering, sorting, and a details modal, plus routing and navigation wiring and minor formatting tweaks to existing organization controller responses.

Changes

Team Members Feature

Layer / File(s) Summary
Organization members API endpoint
server/controllers/organizationController.js, server/routes/organizationRoutes.js
Adds getOrganizationMembers (authenticates via req.user.id, validates organization association, returns populated members and organizationName, with 400/404/500 handling), registers GET /members, and applies minor formatting/punctuation changes to existing membership-check predicates and a 400 response.
TeamMembers page data and state logic
client/src/pages/TeamMembers.jsx
Defines role style/label mappings, component state, fetchMembers (axios GET with credentials), applyFiltersAndSort (search/role filter/sort by name, role, or joined date), and helper utilities (copy email, initials, date formatting) with effects to fetch and refilter.
TeamMembers list rendering, loading/error states
client/src/pages/TeamMembers.jsx
Renders loading spinner, error UI with retry, header with member count, search input, role filter dropdown, empty-state messaging, and interactive member cards with copy-email quick action.
Member details modal
client/src/pages/TeamMembers.jsx
Implements a modal showing avatar, name, email (with copy), role, joined date, and verification status, closable via overlay or button; exports the page component.
Routing and navigation wiring
client/src/App.jsx, client/src/components/Navbar.jsx
Adds a protected /team-members route, adds a "Team Members" nav link using the Users icon, and restructures the logo SVG markup (removing decorative circles).

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant TeamMembersPage
  participant OrganizationRoutes
  participant OrganizationController
  participant Database

  User->>TeamMembersPage: Navigate to /team-members
  TeamMembersPage->>OrganizationRoutes: GET /api/organization/members
  OrganizationRoutes->>OrganizationController: getOrganizationMembers(req, res)
  OrganizationController->>Database: Fetch user, verify organization
  OrganizationController->>Database: Fetch organization, populate members
  Database-->>OrganizationController: organization + members
  OrganizationController-->>TeamMembersPage: 200 { members, organizationName }
  TeamMembersPage->>TeamMembersPage: applyFiltersAndSort(search, role, sort)
  TeamMembersPage-->>User: Render filtered member cards
  User->>TeamMembersPage: Click member card
  TeamMembersPage-->>User: Show member details modal
Loading

Compact metadata:

  • Related Issues: #86 — Build Team Members & Organization Directory Page
  • Related PRs: None identified
  • Suggested labels: feature, frontend, backend
  • Suggested reviewers: imuniqueshiv

🐰 A rabbit hopped through org charts wide,
Found names and roles it could not hide,
It searched, it filtered, sorted true,
Copied emails, popped modals too,
Now teammates gather, side by side.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the main feature added: a Team Members/Organization Directory page.
Linked Issues check ✅ Passed The PR adds the team directory page, member fetch endpoint, search/filter/sort, details modal, copy-email action, and loading/error states.
Out of Scope Changes check ✅ Passed No substantial out-of-scope changes are evident; edits center on the new member directory and supporting route/controller work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Comment thread server/routes/organizationRoutes.js Fixed
Comment thread server/routes/organizationRoutes.js Fixed
…ion declarations

- Add apiLimiter to organizationRoutes.js to fix CodeQL security alerts
- Fix duplicate updateMeeting function declaration in meetingController.js
- Fix duplicate updateMeeting import in meetingRoutes.js
- Fix malformed getMeetingById function in meetingController.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
server/controllers/organizationController.js (1)

193-216: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Redundant DB round-trip: req.user already has organization.

userAuth middleware already loads the user via findById(decoded.id).select("-password") and assigns it to req.user. Re-querying userModel.findById(req.user.id) here just to read .organization adds an unnecessary DB call on every request to this endpoint.

⚡ Proposed fix
-    const user = await userModel.findById(req.user.id);
-    if (!user || !user.organization) {
+    if (!req.user.organization) {
       return res
         .status(400)
         .json({
           success: false,
           message: "User is not part of an organization.",
         });
     }
 
     const organization = await Organization.findById(
-      user.organization,
+      req.user.organization,
     ).populate({
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/controllers/organizationController.js` around lines 193 - 216,
`getOrganizationMembers` is doing an unnecessary
`userModel.findById(req.user.id)` lookup even though `userAuth` already
populated `req.user` with the authenticated user record. Update this handler to
read `req.user.organization` directly after the auth check, and keep the
existing guard for missing organization before calling
`Organization.findById(...).populate(...)`.
client/src/pages/TeamMembers.jsx (2)

70-109: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider useMemo instead of state+effect for filteredMembers.

applyFiltersAndSort recomputes and calls setFilteredMembers, triggering an extra render each time inputs change. A useMemo on the derived list would avoid the redundant state/effect indirection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@client/src/pages/TeamMembers.jsx` around lines 70 - 109, The filtered member
list in TeamMembers should be derived data instead of stored via state updates
in applyFiltersAndSort, since calling setFilteredMembers causes an extra render
whenever members, searchQuery, roleFilter, sortBy, or sortOrder changes.
Refactor the TeamMembers component to compute the final list with useMemo using
the same filtering and sorting logic, and remove the extra state/effect
indirection tied to filteredMembers and applyFiltersAndSort.

324-437: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Modal has no keyboard (Escape) dismissal or focus trap.

Closing only works via click on the overlay/X/Close button; keyboard-only users can't dismiss it with Escape, and focus isn't trapped inside the dialog.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@client/src/pages/TeamMembers.jsx` around lines 324 - 437, The member details
modal in TeamMembers.jsx only closes via mouse interactions and does not support
keyboard dismissal or focus containment. Update the selectedMember modal block
to add an Escape key handler that clears selectedMember, and add proper focus
trapping/initial focus management while the modal is open, ensuring focus
returns to the triggering element when it closes. Use the modal wrapper and
close handlers around selectedMember, setSelectedMember, and the existing
Close/X actions as the integration points.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/src/pages/TeamMembers.jsx`:
- Around line 41-42: The TeamMembers sorting state is hardcoded because `sortBy`
and `sortOrder` are created without setters, so `applyFiltersAndSort` can only
ever use the default name/ascending path. Update `TeamMembers.jsx` to use state
setters for these values, then add a sort control in the existing filter UI near
the role filter that lets users choose `name`, `role`, or `joined` and toggle
ascending/descending order, wiring those controls to `setSortBy` and
`setSortOrder` so the sort logic becomes reachable.
- Around line 111-114: The handleCopyEmail helper in TeamMembers.jsx shows a
success toast without checking whether navigator.clipboard.writeText actually
succeeds. Update handleCopyEmail to handle the returned promise from writeText,
and only call toast.success after it resolves; if it rejects, handle the failure
path instead of reporting success.
- Around line 49-54: The TeamMembers fetch is calling the wrong members endpoint
path and will 404 because the organization router is mounted under the plural
base route. Update the axios.get call in TeamMembers.jsx to use the correct
organizations members URL that matches the server.js mount path, and keep the
rest of the request options unchanged. Use the existing TeamMembers component
and its members-loading request as the place to fix the route.

---

Nitpick comments:
In `@client/src/pages/TeamMembers.jsx`:
- Around line 70-109: The filtered member list in TeamMembers should be derived
data instead of stored via state updates in applyFiltersAndSort, since calling
setFilteredMembers causes an extra render whenever members, searchQuery,
roleFilter, sortBy, or sortOrder changes. Refactor the TeamMembers component to
compute the final list with useMemo using the same filtering and sorting logic,
and remove the extra state/effect indirection tied to filteredMembers and
applyFiltersAndSort.
- Around line 324-437: The member details modal in TeamMembers.jsx only closes
via mouse interactions and does not support keyboard dismissal or focus
containment. Update the selectedMember modal block to add an Escape key handler
that clears selectedMember, and add proper focus trapping/initial focus
management while the modal is open, ensuring focus returns to the triggering
element when it closes. Use the modal wrapper and close handlers around
selectedMember, setSelectedMember, and the existing Close/X actions as the
integration points.

In `@server/controllers/organizationController.js`:
- Around line 193-216: `getOrganizationMembers` is doing an unnecessary
`userModel.findById(req.user.id)` lookup even though `userAuth` already
populated `req.user` with the authenticated user record. Update this handler to
read `req.user.organization` directly after the auth check, and keep the
existing guard for missing organization before calling
`Organization.findById(...).populate(...)`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c6d18423-598a-4990-a1bc-66af2342f4af

📥 Commits

Reviewing files that changed from the base of the PR and between d007009 and e9b4db1.

📒 Files selected for processing (5)
  • client/src/App.jsx
  • client/src/components/Navbar.jsx
  • client/src/pages/TeamMembers.jsx
  • server/controllers/organizationController.js
  • server/routes/organizationRoutes.js

Comment thread client/src/pages/TeamMembers.jsx
Comment thread client/src/pages/TeamMembers.jsx
Comment thread client/src/pages/TeamMembers.jsx
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
meetonmemory Ready Ready Preview, Comment Jul 7, 2026 9:43am

@imuniqueshiv imuniqueshiv added enhancement New feature or request ECSoC26 Eligible for Elite Coders Summer of Code 2026 automated scoring. good-ui +25 XP good-backend +50 XP advanced UI/UX frontend backend labels Jul 7, 2026
@imuniqueshiv imuniqueshiv merged commit 3af5b39 into imuniqueshiv:main Jul 7, 2026
8 checks passed
@imuniqueshiv

Copy link
Copy Markdown
Owner

@mrunmayeekokitkar Thank you once again for another excellent contribution to MeetOnMemory! 🚀

I really appreciate the consistent effort you've put into implementing the Team Members & Organization Directory feature. The implementation is well organized, responsive, and integrates nicely with the existing project architecture. Thank you as well for proactively addressing the review feedback and ensuring all CI checks passed before review.

I'm happy to have merged your PR! 🎉 If you found MeetOnMemory helpful, please consider ⭐ starring the repository. Looking forward to your future contributions—happy coding! 💙

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

Labels

advanced backend ECSoC26-L2 ECSoC26 Eligible for Elite Coders Summer of Code 2026 automated scoring. enhancement New feature or request frontend good-backend +50 XP good-ui +25 XP UI/UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

👥 Build Team Members & Organization Directory Page

3 participants