Skip to content

Conversation

@ZL-Asica
Copy link
Member

✨ Features Updates && πŸ›  Code Refactor

πŸ“Œ Description

A broad upgrade that modernizes caching, moves the daily R2 garbage-collection workflow from \people to a separate api, replaces the home page slider with an accessible carousel, and significantly refactors the Projects and People experiences (search, layout, loading states, and semantics). Also includes small fixes for a Next.js warning and general code quality.

This PR:

  • Migrates server data caching to Next.js 16 use cache + cacheLife and adds an in-process concurrency coalescer for Airtable requests.
  • Replace the daily R2 cleanup job (GitHub Actions) with a secure token-gated API route.
  • Replaces the home page slider with a fully accessible Carousel.
  • Redesigns Projects: client search, collapsible SIG cards, balanced two-column layout, skeletons, dynamic imports, stronger SEO & JSON-LD.
  • Enhances People: in-page name search scoped to Active/Alumni tabs.
  • Unifies Markdown rendering with GFM + limited raw HTML support.
  • Cleans up layout containers, tweaks header/nav sizing, and improves a11y across the board.
  • Fixes the β€œcurrent time in client component” Next.js warning in the announcement popup.

These changes reduce Airtable/API load, improve time-to-interactive and perceived performance, and make navigation clearer and more accessible.

πŸ” Feature Changes

  • New component or page

    • src/components/home/Carousel.tsx (accessible carousel with keyboard/swipe, play/pause)
    • src/app/api/r2-gc/route.ts (token-gated R2 GC)
    • src/components/shared/SearchBar.tsx, src/hooks/useSearch.ts (reusable search)
    • src/components/shared/MarkdownContents.tsx (remark-gfm + rehype-raw)
    • src/components/projects/ProjectsClient/* (client search, collapsible SIG cards, layout balance)
    • src/components/projects/TeamMembers/* (role grouping, alumni badge, sorting)
  • API update

    • New POST /api/r2-gc with x-cron-token (or ?token=) and JSON body controlling prefix, age, cadence, and delete caps.
  • UI/UX improvement

    • Projects: search & filters, two independent columns, polished skeletons, better card affordances, breadcrumb/back link, richer media blocks.
    • People: scoped name search (Active/Alumni), result counts, empty-state messaging.
    • Header: type & spacing adjustments; layout uses a consistent max-width and padding.
    • Not-found: add β€œBack to Previous Page” button; gentler hover scale.
  • Other:

    • GitHub Actions r2-gc.yml (scheduled daily 08:00 UTC) to ping the R2 cleanup endpoint.

πŸ”„ Refactor Changes

  • Code optimization

    • Airtable: server-only module + use cache/cacheLife('halfDays') and in-process inflight coalescing to prevent thundering herds.
    • Dynamic imports for heavier components on Project pages.
  • Improve maintainability

    • Extracted shared search & markdown components; clearer file boundaries for Projects UI (ProjectsClient).
    • ESLint scoped rule overrides for specific files (dangerouslySetInnerHTML for JSON-LD, import sort).
  • Remove unnecessary code

    • Removed legacy Container wrapper, old Slides component, scattered revalidate exports, and REVALIDATE_TIME env usage.
  • Other:

    • Standardized next.config.ts with cacheComponents and named cacheLife buckets (halfDays, days).

πŸ›  Bug Fixes

  • Fixed issue: Next.js warerroring β€œused new Date() in a Client Component without a Suspense boundary”

    • PopupAnnouncement: compute today after hydration and store in state; remove useMemo(new Date()) in render path; ensure SSR/CSR parity.
  • Improved error handling

    • POST /api/r2-gc returns 401 for invalid/missing token; robust JSON parsing with safe defaults.
    • getProjects: null/empty-array guards; safe banner/OG image handling.
  • Performance fix

    • Dynamic imports, Image fill with responsive sizes, skeleton loading, column balancing to reduce layout shifts.
  • Add people parameter to getProjects() for reducing api call.

  • Other:

    • External links in HomeIntro/MediaBanner use <a> with rel="noopener noreferrer".
    • CSS: hide WebKit’s default search cancel button globally for consistent styling.

βœ… Checklist

  1. Feature Updates:
  • Code follows project coding style.
  • Tested in a Next.js environment.
  • Relevant documentation is updated (README caching section).
  1. Bug Fixes:
  • Bug has been reproduced and verified.
  • Fix does not introduce new issues.
  • Added necessary tests.
  1. Code Refactor:
  • No breaking changes introduced (see β€œNotes” for one env var removal).
  • Performance improvement validated.
  • Documentation updated if necessary.

πŸ“œ Dependency Changes

No Next.js/React/Tailwind version bumps in this PR. Added utilities for markdown and UI composition.

Dependency Name Old Version New Version Reason
clsx β€” ^2.1.1 Simpler conditional class composition
remark-gfm β€” ^4.0.1 GitHub-Flavored Markdown support
rehype-raw β€” ^7.0.0 (Limited) raw HTML pass-through in markdown

πŸ’¬ Additional Notes

  • Caching migration (important):

    • Replaced unstable_cache/revalidate with Next 16 use cache + cacheLife('halfDays') and per-table inflight coalescing (src/lib/airtable/airtable.ts).
    • Removed REVALIDATE_TIME usage and the env var; delete it from deployments.
    • Customized cacheLife presets in next.config.ts for clear β€œhalf-days” and β€œdays” buckets.
  • R2 GC automation:

    • New workflow: .github/workflows/r2-gc.yml runs 08:00 UTC daily and via manual dispatch.

    • Requires R2_CRON_SECRET GitHub secret. The action POSTs JSON to /api/r2-gc with configurable:

      {
        "prefix":"images/",
        "maxAgeDays":60,
        "minIntervalHours":24,
        "maxDeletePerRun":250
      }
    • The page-load-time GC in people/page.tsx was removed; cleanup is now centralized and throttled server-side.

  • Projects UI/UX:

    • New client layer (ProjectsClient) provides debounced search, collapsible SIGs, and balanced two-column stacking using estimated collapsed heights to avoid jarring shifts.
    • Loading skeletons approximate final layout (yellow accents, cards, placeholders).
    • Detail page (/projects/[id]): JSON-LD (CreativeWork), robust OG/Twitter metadata, dynamic imports for video/publications.
  • People experience:

    • Search within current tab (Active/Alumni), result counts, and a clear empty-state.
    • BioClamp and markdown blocks now pipe through MarkdownContents.
  • A11y & polish:

    • Carousel: keyboard arrows + space to pause/play; hover/focus pauses; respects reduced-motion; screen-reader hints; better controls focus rings.
    • Search inputs have proper labels/roles; WebKit cancel icon hidden for consistent styling.
    • Links and buttons refined with visible focus indications.
  • Minor UI changes:

    • Removed Container in favor of consistent max-w-7xl and px-4 on layout/main.
    • Header typography scaled slightly for legibility on desktop.

Files of Interest (high-level)

  • Automation: .github/workflows/r2-gc.yml, src/app/api/r2-gc/route.ts
  • Caching: src/lib/airtable/airtable.ts, next.config.ts, README.md, src/lib/consts.ts (removed revalidateTime)
  • Projects: src/app/projects/page.tsx, src/app/projects/[id]/page.tsx, src/app/projects/loading.tsx, src/components/projects/ProjectsClient/*, src/components/projects/TeamMembers/*, src/components/projects/ProjectVideo.tsx, src/components/projects/ProjectPublications.tsx
  • People: src/components/people/PeopleDirectory.tsx, src/components/people/BioClamp.tsx
  • Home: src/components/home/Carousel.tsx (+ removed Slides.tsx)
  • Shared: src/components/shared/MarkdownContents.tsx, src/components/shared/SearchBar.tsx, src/components/shared/Header/*, src/app/layout.tsx, src/app/globals.css
  • Fix: src/components/shared/PopupAnnouncement.tsx (Next.js runtime error resolved)

- Replace `unstable_cache` with new `use cache` API which introduced in Next.js 16.
- Switch revalidation to `cacheLife` for following the latest conventions.
- Remove `REVALIDATE_TIME` constant from `.env` as it's no longer needed.
- Remove all `revalidate`, `dynamicParams`, `runtime` options since not supported with cacheComponents.
- Move r2-gc from `/people` to a seperate API route `/api/r2-gc` and work with GitHub Actions for CRON scheduling.
- Improved build time API calls by setting up in-process coalescing of concurrent reads for the same table (reduced to only 18 calls at build time).
- Default revalidation changed to 12 hours for all cache calls.
@ZL-Asica ZL-Asica requested a review from Copilot October 26, 2025 20:04
@ZL-Asica ZL-Asica self-assigned this Oct 26, 2025
@ZL-Asica ZL-Asica added the enhancement general tag for new features to add label Oct 26, 2025
@github-actions
Copy link

🎨 Lint Check

βœ… Lint: No linting issues found!

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 modernizes the DTR website's caching strategy by migrating to Next.js 16's use cache API, enhances UX/accessibility across Projects and People pages with client-side search and improved layouts, and centralizes R2 garbage collection through a secure API endpoint. The changes reduce API load, improve perceived performance, and strengthen semantic HTML and accessibility.

  • Replaces legacy unstable_cache with Next.js 16 use cache + cacheLife presets and adds in-process request coalescing for Airtable calls
  • Redesigns Projects page with collapsible SIG cards, client-side search/filters, balanced two-column layout, and dynamic imports for heavy components
  • Adds in-page name search to People directory scoped to Active/Alumni tabs with result counts and empty states
  • Replaces home carousel with accessible version supporting keyboard navigation, play/pause controls, and reduced-motion preferences
  • Migrates daily R2 cleanup from page-load to token-gated API route triggered by GitHub Actions

Reviewed Changes

Copilot reviewed 43 out of 44 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/lib/consts.ts Removes REVALIDATE_TIME env constant, replaced by Next.js 16 caching
src/lib/airtable/airtable.ts Migrates to use cache + cacheLife('halfDays') with in-process inflight coalescing
src/lib/airtable/project.ts Adds people parameter to getProjects() to reduce API calls, adds null guards for banner image
src/lib/airtable/sig.ts Passes people to getProjects(), filters null projects
src/hooks/useSearch.ts New hook for debounced search state management
src/hooks/useCarousel.ts New hook for carousel state including keyboard, touch, autoplay, and reduced-motion
src/components/shared/SearchBar.tsx Reusable search input component with clear button
src/components/shared/MarkdownContents.tsx Unified markdown renderer with GFM and limited raw HTML support
src/components/shared/PopupAnnouncement.tsx Fixes Next.js warning by computing date after hydration instead of in render
src/components/shared/Header/index.tsx Replaces Container with inline padding/max-width
src/components/shared/Header/DesktopNav.tsx Increases font size for desktop navigation
src/components/projects/ProjectsClient/* New client-side search, collapsible SIG cards, balanced two-column layout
src/components/projects/TeamMembers/* Refactored into role-grouped layout with alumni badges and sorting
src/components/projects/ProjectVideo.tsx Dynamic import, improved semantic HTML with section/heading structure
src/components/projects/ProjectPublications.tsx Enhanced card-based layout with icons and external link indicators
src/components/people/PeopleDirectory.tsx Adds scoped name search with result counts and empty states
src/components/people/BioClamp.tsx Uses shared MarkdownContents component
src/components/home/Carousel.tsx New accessible carousel with keyboard/touch support and play/pause controls
src/app/projects/page.tsx Simplified to delegate to ProjectsClient, improved metadata and SEO
src/app/projects/loading.tsx Skeleton loading matching new two-column layout with yellow accents
src/app/projects/[id]/page.tsx Adds JSON-LD structured data, back link, dynamic imports, improved metadata
src/app/people/page.tsx Removes page-load R2 GC call
src/app/layout.tsx Removes Container wrapper, uses inline max-width and padding
src/app/globals.css Hides WebKit search cancel button globally for consistent styling
src/app/api/r2-gc/route.ts New token-gated API endpoint for R2 garbage collection
next.config.ts Adds cacheComponents and custom cacheLife presets (halfDays, days)
.github/workflows/r2-gc.yml Daily scheduled workflow to trigger R2 cleanup API
package.json Adds clsx, remark-gfm, rehype-raw dependencies
README.md Updates caching documentation to reference Next.js 16 use cache

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ZL-Asica and others added 2 commits October 26, 2025 15:09
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions
Copy link

🎨 Lint Check

βœ… Lint: No linting issues found!

@ZL-Asica ZL-Asica marked this pull request as ready for review October 26, 2025 20:12
@ZL-Asica ZL-Asica merged commit 124fd5e into main Oct 26, 2025
2 checks passed
@ZL-Asica ZL-Asica deleted the feature/projects-update branch December 11, 2025 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement general tag for new features to add size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants