Skip to content

[CORE-328] Member Management Page Layout and SEO - #60

Merged
elvisdragonmao merged 13 commits into
mainfrom
feat/CORE-328-member-management-page-layout-and-seo
Jul 17, 2026
Merged

elvisdragonmao merged 13 commits into
mainfrom
feat/CORE-328-member-management-page-layout-and-seo

Conversation

@1457dys

@1457dys 1457dys commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Type of changes

  • Feature/Fix/Docs/Refactor/CI/Test/Chore

Purpose

  • Add XXX
  • Resolve issue #XXX

Additional Information

Summary by CodeRabbit

  • New Features

    • Added a new member data dashboard page with view switching, column visibility controls, and searchable table-style response display.
    • Added view management actions, including creating, renaming, duplicating, locking, unlocking, deleting, and reordering views.
    • Added a column strip panel for showing, hiding, and collapsing grouped questions.
  • Bug Fixes

    • Improved responsive behavior for admin navigation on smaller screens.
    • Refined table and scroll behavior for better readability and smoother horizontal/vertical scrolling.
  • Style

    • Updated table, layout, and dropdown visuals for a cleaner, more consistent dashboard experience.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 32 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 Plus

Run ID: f5d6f789-3103-40f1-bbf0-81d31c0873ad

📥 Commits

Reviewing files that changed from the base of the PR and between c7465bb and 16bf2d0.

📒 Files selected for processing (16)
  • e2e/member-data.spec.ts
  • src/features/dashboard/components/ColumnRow/ColumnRow.module.css
  • src/features/dashboard/components/ColumnRow/ColumnRow.tsx
  • src/features/dashboard/components/MemberDataPage.module.css
  • src/features/dashboard/components/MemberDataPage.tsx
  • src/features/dashboard/components/ViewTabDropdown/ViewTabDropdown.module.css
  • src/features/dashboard/components/ViewTabDropdown/ViewTabDropdown.tsx
  • src/features/form/hooks/useFormResponses.ts
  • src/features/form/hooks/useViews.ts
  • src/features/form/services/api.ts
  • src/layouts/AdminLayout.tsx
  • src/layouts/AdminNav.module.css
  • src/layouts/AdminNav.tsx
  • src/routes/AppRouter.tsx
  • src/shared/components/Table/Table.module.css
  • src/shared/components/Table/Table.tsx
📝 Walkthrough

Walkthrough

This PR adds a member data admin page with view selection, column visibility controls, and a sortable view dropdown. It also adds view API/query hooks, extends the shared table component, and wires the page into admin routing, navigation, layout, and SEO metadata.

Changes

Member data dashboard

Layer / File(s) Summary
Views data plumbing
src/features/form/services/api.ts, src/features/form/hooks/useViews.ts, src/features/form/hooks/useFormResponses.ts, src/shared/queryKeys/org.ts
Adds views API endpoints, query keys, and hooks for loading views and detailed response records.
View dropdown
src/features/dashboard/components/ViewTabDropdown/*
Adds the sortable dropdown UI for selecting, creating, renaming, locking, duplicating, deleting, and reordering views.
Column visibility panel
src/features/dashboard/components/ColumnRow/*
Adds the column chip strip, section popover, and per-question visibility controls.
Table ellipsis support
src/shared/components/Table/*, src/shared/components/ScrollArea/ScrollContainer.module.css
Extends the shared table with per-column ellipsis/maxWidth handling, className support, themeable cell styling, and smaller scrollbar sizing.
Member data page
src/features/dashboard/components/MemberDataPage*
Adds the member data page, derives table rows and columns, manages hidden questions, and renders the dashboard layout.
Admin entry wiring
src/features/dashboard/components/index.ts, src/layouts/AdminLayout*, src/layouts/AdminNav*, src/routes/AppRouter.tsx, src/seo/seo.config.ts
Adds the admin route, nav link, fixed-height layout option, mobile nav behavior, SEO entry, and dashboard export.

Sequence Diagram(s)

sequenceDiagram
  participant AppRouter
  participant MemberDataPage
  participant useViews
  participant apiListViews
  participant useFormResponsesWithDetails
  participant apiGetFormResponse
  participant ViewTabDropdown
  participant ColumnRow

  AppRouter->>MemberDataPage: render /orgs/:orgSlug/members
  MemberDataPage->>useViews: load form views
  useViews->>apiListViews: listViews(formId)
  MemberDataPage->>useFormResponsesWithDetails: load detailed responses
  useFormResponsesWithDetails->>apiGetFormResponse: getFormResponse(responseId)
  MemberDataPage->>ViewTabDropdown: pass active view and view actions
  MemberDataPage->>ColumnRow: pass visibility state and toggles
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • EthelHsiao — dashboard page, table, and routing changes.
  • elvisdragonmao — form API/hooks and admin shell wiring.

Poem

I hopped through tabs with a fluffy grin,
And found new chips to tuck within.
The columns folded, neat and bright,
While views danced softly left to right.
Hoppy dashboards, shining now. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is clearly related to the new member management page work and its layout/SEO focus.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/CORE-328-member-management-page-layout-and-seo

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.

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

🧹 Nitpick comments (1)
src/features/dashboard/components/MemberDataPage.module.css (1)

38-54: 📐 Maintainability & Code Quality | 🔵 Trivial

Dead CSS rules detected: .dropdownButton and .placeholderText

The CSS classes .dropdownButton and .placeholderText defined in MemberDataPage.module.css are not referenced anywhere in the codebase (including MemberDataPage.tsx or any other file). They appear to be unused styles.

Consider removing these definitions to reduce bundle size and improve code maintainability.

Dead CSS definitions
.dropdownButton {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.75rem 1rem;
	border: 0;
	border-radius: 0.75rem;
	background: `#4a4861`;
	color: `#f4f2ff`;
	font-size: 1.125rem;
	line-height: 1;
	cursor: pointer;
}

.dropdownButton:hover {
	background: `#565371`;
}

And lines 121-125 for .placeholderText.

🤖 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 `@src/features/dashboard/components/MemberDataPage.module.css` around lines 38
- 54, Remove the unused CSS module rules in MemberDataPage.module.css: both
.dropdownButton (and its :hover state) and .placeholderText are not referenced
anywhere, so delete their definitions to keep the stylesheet lean. Check the
styles used by MemberDataPage.tsx and preserve only classes that are actually
imported and applied.
🤖 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 `@src/features/dashboard/components/ColumnRow/ColumnRow.module.css`:
- Line 8: The stylesheet in ColumnRow.module.css has lint issues from the
comment spacing and camelCase keyframe names. Fix the Line 8 comment formatting
so it matches the expected spacing, then rename the keyframes defined for the
chip scrolling/animation behavior to kebab-case and update every reference to
those animations in the related ColumnRow styles. Make sure the affected rules
in the chip container and animation blocks all use the same new keyframe names
so Stylelint passes.

In `@src/features/dashboard/components/ColumnRow/ColumnRow.tsx`:
- Around line 1-102: Reformat the ColumnRow component to satisfy prettier
--check; adjust the JSX and imports in ColumnRow so the file matches the
repository’s Prettier style, especially the long component signature, nested
popover/section rendering, and conditional className expressions. Use ColumnRow,
PopoverPrimitive.Content, and the mapped section/question chip blocks as the
main spots to reflow without changing behavior.

In `@src/features/dashboard/components/MemberDataPage.module.css`:
- Line 18: Stylelint is flagging inconsistent blank-line spacing between
declarations in MemberDataPage.module.css. Update the affected rule blocks so
the declarations around border-radius and scroll-snap-type follow
declaration-empty-line-before consistently by removing the extra blank line
before border-radius and adding the required blank line before scroll-snap-type,
keeping the surrounding selector blocks intact.

In `@src/features/dashboard/components/MemberDataPage.tsx`:
- Line 245: The Table JSX in MemberDataPage has stray formatting that breaks
prettier, specifically the self-closing tag near showRowNumber in the Table
component. Reformat the MemberDataPage render output so the Table element
matches the project's prettier style and removes the extra whitespace, keeping
the change localized to the JSX around the Table, tableData, and tableColumns
usage.
- Line 21: The page is pinned to a single form because MemberDataPage uses the
hardcoded MOCK_FORM_ID for every data hook and mutation. Replace that constant
with the actual form identifier from the route or org context in MemberDataPage,
and thread it through the existing useViews, useFormById, useSections,
useWorkflow, and useFormResponsesWithDetails calls so the loaded data follows
the active org/form. Remove the mock constant once the real source is wired in,
and keep orgSlug only for org-specific UI/accessibility if needed.

In
`@src/features/dashboard/components/ViewTabDropdown/ViewTabDropdown.module.css`:
- Line 35: The keyframe name dropdownIn in the ViewTabDropdown.module.css styles
violates the configured keyframes-name-pattern rule. Rename the `@keyframes`
identifier to kebab-case and update every usage that references dropdownIn in
the same stylesheet so the animation name stays consistent and passes Stylelint.
- Around line 126-129: The .itemTitle styles in ViewTabDropdown.module.css only
set flex sizing, so long view names can still prevent the row from shrinking and
push the action buttons out of view. Update the .itemTitle rule to allow
shrinking and truncation by adding min-width: 0 along with
text-overflow/overflow/white-space ellipsis styling, keeping the change scoped
to the ViewTabDropdown item layout.

In `@src/features/dashboard/components/ViewTabDropdown/ViewTabDropdown.tsx`:
- Around line 1-357: This file is failing prettier --check due to
formatting-only issues in ViewTabDropdown; run the formatter on ViewTabDropdown
and keep the existing logic intact. Focus on the JSX and hook blocks around
ViewTabDropdown, SortableViewItem, and the effect/handler definitions so
spacing, wrapping, and indentation match the project’s Prettier rules.
- Around line 215-244: The view row in ViewTabDropdown is clickable only via a
div onClick, so keyboard users cannot select a view. Update the row element
around the tab item to be keyboard-accessible by adding the appropriate
semantics and focus handling (for example, a button-like or option-like role
with tabIndex) and wire Enter/Space to the existing handleSelectView behavior.
Keep the rename input and drag handle interactions working by preserving the
current editingViewId and dragListeners logic.

In `@src/features/form/hooks/useFormResponses.ts`:
- Around line 13-21: The detailed responses query in useFormResponsesWithDetails
currently fans out one getFormResponse call per item and uses Promise.all, so a
single failure rejects the whole query. Update the queryFn to keep using
listFormResponses plus getFormResponse, but switch the per-response aggregation
to a failure-tolerant approach such as Promise.allSettled so one bad detail
fetch does not empty the entire result. Filter to fulfilled results and return
only the successful ResponsesGetFormResponse items while preserving the existing
queryKey and enabled behavior.

In `@src/features/form/hooks/useViews.ts`:
- Around line 29-34: The `useUpdateView` mutation currently invalidates
`formKeys.views(formId)` on every successful `api.updateView` call, which causes
repeated refetches during the `MemberDataPage` reorder flow. Update
`useUpdateView` so bulk reorder calls can skip per-mutation invalidation, or
defer invalidation until the reorder batch completes; keep the behavior
localized around `useUpdateView`, `useMutation`, and the `qc.invalidateQueries`
callback.
- Around line 1-59: Prettier is failing on useViews, so reformat the module to
match the project style. Update the exports in useViews and the mutation objects
in useCreateView, useDuplicateView, useUpdateView, useLockView, useUnlockView,
and useDeleteView so the file passes formatting checks without changing
behavior.

In `@src/layouts/AdminNav.module.css`:
- Around line 123-138: The .burgerBtn hidden state still leaves the button
focusable on desktop, so update the default styling in AdminNav.module.css to
remove it from the tab order by using a non-focusable hidden state such as
display: none or visibility: hidden, then restore its visible/interactive styles
inside the mobile breakpoint where .burgerBtn is meant to appear; make the same
adjustment for the corresponding secondary hidden rules referenced by the review
so the desktop state cannot receive keyboard focus.

In `@src/shared/components/Table/Table.module.css`:
- Around line 134-135: Remove the deprecated word-break: break-word declaration
from Table.module.css and keep overflow-wrap: break-word as the
standard-compliant wrapping rule. Update the table cell/text wrapping styles in
the same CSS module so the intended behavior remains unchanged while eliminating
the Stylelint error.

In `@src/shared/components/Table/Table.tsx`:
- Line 157: The Table cell rendering in Table uses a raw ReactNode fallback for
non-custom columns, which can still crash on plain objects or arrays. Update the
fallback in the Table component’s cell render logic so that when column.render
is absent it follows the documented behavior from the Table interface comment:
prefer a stringified value via toString() for non-null values, and keep the
existing dash fallback only for empty/undefined cases. Make the change in the
Table render path that builds content for each row/column so auto-generated
columns from Record<string, unknown> rows stay safe.

---

Nitpick comments:
In `@src/features/dashboard/components/MemberDataPage.module.css`:
- Around line 38-54: Remove the unused CSS module rules in
MemberDataPage.module.css: both .dropdownButton (and its :hover state) and
.placeholderText are not referenced anywhere, so delete their definitions to
keep the stylesheet lean. Check the styles used by MemberDataPage.tsx and
preserve only classes that are actually imported and applied.
🪄 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 Plus

Run ID: 331a30d3-4f8f-468f-97a1-f59c2391fdc1

📥 Commits

Reviewing files that changed from the base of the PR and between ba85b61 and c7465bb.

📒 Files selected for processing (20)
  • src/features/dashboard/components/ColumnRow/ColumnRow.module.css
  • src/features/dashboard/components/ColumnRow/ColumnRow.tsx
  • src/features/dashboard/components/MemberDataPage.module.css
  • src/features/dashboard/components/MemberDataPage.tsx
  • src/features/dashboard/components/ViewTabDropdown/ViewTabDropdown.module.css
  • src/features/dashboard/components/ViewTabDropdown/ViewTabDropdown.tsx
  • src/features/dashboard/components/index.ts
  • src/features/form/hooks/useFormResponses.ts
  • src/features/form/hooks/useViews.ts
  • src/features/form/services/api.ts
  • src/layouts/AdminLayout.module.css
  • src/layouts/AdminLayout.tsx
  • src/layouts/AdminNav.module.css
  • src/layouts/AdminNav.tsx
  • src/routes/AppRouter.tsx
  • src/seo/seo.config.ts
  • src/shared/components/ScrollArea/ScrollContainer.module.css
  • src/shared/components/Table/Table.module.css
  • src/shared/components/Table/Table.tsx
  • src/shared/queryKeys/org.ts

Comment thread src/features/dashboard/components/ColumnRow/ColumnRow.module.css Outdated
Comment thread src/features/dashboard/components/ColumnRow/ColumnRow.tsx Outdated
Comment thread src/features/dashboard/components/MemberDataPage.module.css
Comment thread src/features/dashboard/components/MemberDataPage.tsx Outdated
Comment thread src/features/dashboard/components/MemberDataPage.tsx Outdated
Comment thread src/features/form/hooks/useViews.ts Outdated
Comment thread src/features/form/hooks/useViews.ts
Comment thread src/layouts/AdminNav.module.css
Comment thread src/shared/components/Table/Table.module.css Outdated
Comment thread src/shared/components/Table/Table.tsx Outdated
@github-actions

Copy link
Copy Markdown

✅ Snapshot Deployment Ready

Item Value
Status Status
Preview https://pr-60.core-system.sdc.nycu.club
Commit 4fea7ec05504835ccf1b9abae7342082f32c683d
Triggered by @elvisdragonmao

Open Preview

@elvisdragonmao
elvisdragonmao merged commit 4ad36c0 into main Jul 17, 2026
7 checks passed
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.

2 participants