Skip to content

Conversation

@kevinrutledge
Copy link
Collaborator

Summary

Structural refactoring to align with Next.js App Router conventions and prepare for Contact Groups. Reorganizes routes, splits components, standardizes naming.

Why I Refactored

Non profit requirements include Contact Groups with member-only authentication via token handoff from pasofoodcooperative.com. The flat route structure made authentication boundaries unclear. Route groups fix this.

The 800+ line data grid handled too much. Splitting it enables reuse for the Contact Groups member selector (376+ members need virtualized lists and search).

Changes

Route Groups

Created route groups by authentication type.

(public)/ contains the landing page. No auth required.

(protected)/ contains the referral database. Requires staff password via query parameter.

This prepares for (member)/ where Contact Groups pages will live. Members arrive from the co-op portal with a 60-minute token.

Route groups are organizational. URLs stay the same.

Component Splitting

Split referral-data-grid.tsx into focused modules.

referral-data-grid.tsx handles the core table. Column definitions, TanStack Table instance, row rendering.

data-table-toolbar.tsx handles desktop controls. Search, filters, column visibility, density, PDF export.

data-table-pagination.tsx handles page navigation. Size selector, prev/next, row count.

data-table-filter-panel.tsx handles desktop filter UI. Operator dropdowns, value inputs.

data-table-mobile-drawer.tsx handles mobile filters. Collapsible drawer for small screens.

data-table-types.ts holds shared types and constants. Prevents duplication across components.

table-filters.ts contains the custom TanStack filter function.

The toolbar and pagination components can now be reused for Contact Groups without duplication.

Service Renaming

Renamed for consistency.

email-service.ts becomes email.ts. referral-store.ts becomes referral.ts.

Moved table-filters.ts from src/lib/ to src/components/referral/. It contains referral-specific logic that belongs with its component.

Added import "server-only" to services. This fails the build if someone imports server code into a client component. OWASP recommends this pattern for credential protection.

Schema Additions

api.ts defines ApiReferral with z.coerce.date() for JSON date handling.

error.ts centralizes error codes as a TypeScript enum.

auth.ts is a placeholder for token validation. Will support the ownerid|timestamp|hmac_signature format emails specified.

Type Safety

Fixed type mismatch. Components declared ColumnDef<Referral> but received ApiReferral[] from the hook. These types handle dates differently. Components now correctly use ApiReferral.

Updated filter function signature to match TanStack Table v8 spec.

Accessibility

Added aria-hidden="true" to decorative SVGs. Screen readers skip these.

Added type="button" to non-submit buttons. Prevents unintended form submissions.

Other

Removed unused src/app/api/referral/[id]/route.ts.
Removed empty src/lib/.gitkeep.
Added /team/rutledge page.
Updated middleware for route group paths.
Added test/mocks/request.ts helper.

Files Changed

39 files changed

New:
  src/actions/referral.ts
  src/app/(protected)/layout.tsx
  src/app/(public)/layout.tsx
  src/app/team/rutledge/page.tsx
  src/components/referral/data-table-*.tsx (5 files)
  src/components/referral/data-table-types.ts
  src/lib/auth.ts
  src/schema/api.ts
  src/schema/error.ts
  test/mocks/request.ts
  test/team/rutledge.test.tsx

Renamed:
  page.tsx to (public)/page.tsx
  referral-database/page.tsx to (protected)/referral-database/page.tsx
  email-service.ts to email.ts
  referral-store.ts to referral.ts
  lib/table-filters.ts to components/referral/table-filters.ts

Deleted:
  src/app/api/referral/[id]/route.ts
  src/lib/.gitkeep

Test Plan

  • TypeScript compiles
  • ESLint passes
  • 33 tests pass
  • Build succeeds
  • Referral database loads and functions
  • Filters, search, sorting work
  • PDF export works
  • Mobile drawer works
  • Landing page form submits

Breaking Changes

None.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a comprehensive structural refactoring to prepare for the Contact Groups feature. It introduces Next.js route groups for authentication boundaries, splits an 800+ line data grid component into focused reusable modules, renames services for consistency, and improves type safety with proper API response handling.

Key Changes

  • Created (public) and (protected) route groups with dedicated layouts to establish clear authentication boundaries
  • Split referral-data-grid.tsx into six focused components (toolbar, pagination, filter panel, mobile drawer, types, and filters) for better maintainability and reusability
  • Reorganized schemas into api.ts, error.ts with proper type coercion for JSON date handling; renamed services for consistency

Reviewed changes

Copilot reviewed 35 out of 39 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/services/referral.ts Renamed from referral-store.ts with database operations
src/services/email.ts Renamed from email-service.ts with email sending logic
src/schema/api.ts New schema file for API-specific types including ApiReferral
src/schema/error.ts Centralized error codes as TypeScript enum
src/components/referral/data-table-*.tsx Split components for toolbar, pagination, filter panel, and mobile drawer
src/components/referral/data-table-types.ts Shared types and constants for table components
src/components/referral/table-filters.ts Custom TanStack filter function with proper type signature
src/middleware.ts Updated with cookie-based authentication for database access
src/lib/auth.ts New authentication helper with verifyDatabaseAccess function
src/actions/referral.ts New server actions for form submission and toggle operations
src/app/(public)/layout.tsx Layout for public routes with Header component
src/app/(protected)/layout.tsx Layout for protected routes with Header component
src/app/team/rutledge/page.tsx New team member page
test/mocks/request.ts Mock helper for NextRequest in tests
test/team/rutledge.test.tsx Tests for team member page

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kevinrutledge kevinrutledge merged commit 23477af into develop Dec 14, 2025
3 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.

3 participants