Skip to content

Auto-collapse past schedule days#343

Open
Copilot wants to merge 6 commits intomainfrom
copilot/collapse-yesterdays-schedule
Open

Auto-collapse past schedule days#343
Copilot wants to merge 6 commits intomainfrom
copilot/collapse-yesterdays-schedule

Conversation

Copy link
Contributor

Copilot AI commented Feb 16, 2026

Multi-day conference schedules automatically collapse days that have passed, reducing visual clutter and focusing users on current and upcoming content.

Changes

  • Date comparison utility: Added isScheduleInPast() to time-utils.ts comparing schedule dates against current time using existing stripTime() helper

  • Collapsible UI: Modified DaySchedule component with:

    • State management for collapse/expand (defaults to collapsed for past days)
    • Chevron icon indicators (ChevronRightIcon collapsed, ChevronDownIcon expanded)
    • Clickable header to toggle state
    • "(click to expand)" hint text for collapsed days
  • Test coverage: Added 10 unit tests validating date comparison logic for past/present/future dates and time-of-day independence

Visual behavior

Collapsed (default for past days):

collapsed

Expanded (on click):

expanded

Example usage

// New utility function
import { isScheduleInPast } from '@/lib/program/time-utils'

const isPast = isScheduleInPast('2024-09-15') // true if date has passed
const [isOpen, setIsOpen] = useState(!isPast) // Auto-collapse past days

The implementation integrates with existing DevTimeProvider for testing conference-day scenarios.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fonts.googleapis.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/website/website/node_modules/.bin/../next/dist/bin/next build (dns block)
  • storybook.js.org
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/website/website/node_modules/.bin/../storybook/dist/bin/dispatcher.js dev -p 6006 --port 6006 --ci hub.com/.extrahesed (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Collapse yesterdays schedule</issue_title>
<issue_description>When we are at day two of the conference. Collapse and minimise the first days content</issue_description>

<agent_instructions>Collapse (or auto scroll) the schedule for days that are in the past</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Greptile Summary

This PR adds auto-collapsing of past schedule days in multi-day conference views. It introduces an isScheduleInPast() utility that compares dates using the existing stripTime() helper, and modifies the DaySchedule component to default past days to collapsed state with a clickable header to expand.

  • Test file uses Jest instead of Vitest: The test file imports from @jest/globals (not a project dependency) and uses @jest-environment instead of @vitest-environment. This will cause test failures. The project migrated to Vitest in a recent PR (Upgrade to Vitest and enhance testing framework #336).
  • Collapse button applies to all days: The clickable <button> wrapping the date heading applies to all days, but chevron icons and expand hints only appear for past days. Users can accidentally collapse current/future days with no visual way to expand them back.
  • Utility function is clean: The isScheduleInPast() implementation follows existing patterns well and integrates with the DevTimeProvider for testing scenarios.

Confidence Score: 2/5

  • This PR has a test infrastructure issue that will cause CI failures and a UX bug that needs addressing before merge.
  • Score of 2 reflects two concrete issues: (1) the test file will fail because it imports from @jest/globals which is not a project dependency — the project uses Vitest, and (2) the collapse button inadvertently allows users to hide current/future day schedules with no visual affordance to recover. The core utility function and Storybook story are well-implemented.
  • __tests__/lib/program/time-utils.test.ts needs Jest-to-Vitest migration; src/components/program/ProgramScheduleView.tsx needs the collapse button scoped to past days only.

Important Files Changed

Filename Overview
tests/lib/program/time-utils.test.ts New test file with good coverage of isScheduleInPast and isScheduleToday, but uses @jest-environment and imports from @jest/globals instead of Vitest — these will cause test failures since @jest/globals is not a project dependency.
src/components/program/ProgramScheduleView.tsx Adds collapsible past-day feature to DaySchedule with state, chevron icons, and conditional rendering. The button click handler applies to all days but visual affordance (chevrons, hint text) only appears for past days, allowing users to accidentally collapse current/future days.
src/lib/program/time-utils.ts Clean addition of isScheduleInPast() using existing stripTime() helper, consistent with the existing isScheduleToday() pattern.
src/components/program/ProgramScheduleView.stories.tsx Adds pastDayData fixture and a PastDayCollapsed story demonstrating the new collapsible feature. Uses past (2024) and far-future (2099) dates to ensure the behavior is visible.

Flowchart

flowchart TD
    A[DaySchedule renders] --> B{isScheduleInPast?}
    B -->|Yes| C[isOpen = false<br/>Show chevron + hint]
    B -->|No| D[isOpen = true<br/>No collapse affordance]
    C --> E{User clicks header?}
    D --> F{User clicks header?}
    E -->|Toggle| G[Show/hide schedule content]
    F -->|Toggle| H[Show/hide schedule content<br/>⚠️ No visual cue to re-expand]
    G --> I[Chevron updates:<br/>▶ collapsed / ▼ expanded]
    H --> J[No chevron shown]
Loading

Last reviewed commit: 5d46e4a

Context used:

  • Context from dashboard - AGENTS.md (source)

@vercel
Copy link

vercel bot commented Feb 16, 2026

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

Project Deployment Actions Updated (UTC)
cloudnativedays Ready Ready Preview, Comment Feb 16, 2026 0:40am

Request Review

…nent to collapse past days

Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
Copilot AI changed the title [WIP] Collapse yesterday's schedule content Auto-collapse past schedule days Feb 16, 2026
Copilot AI requested a review from Starefossen February 16, 2026 11:53
@Starefossen Starefossen marked this pull request as ready for review February 16, 2026 11:54
@Starefossen Starefossen requested a review from a team as a code owner February 16, 2026 11:54
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +2 to +11
* @jest-environment jsdom
*/
import {
describe,
it,
expect,
jest,
beforeEach,
afterEach,
} from '@jest/globals'
Copy link

Choose a reason for hiding this comment

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

Tests use Jest instead of Vitest

This project uses Vitest (not Jest) — see package.json and vitest.config.ts. The @jest-environment directive on line 2 won't be recognized by Vitest and should be @vitest-environment. Additionally, @jest/globals is not listed as a project dependency, so this import will fail at build/test time.

Since Vitest is configured with globals: true, the describe, it, and expect functions are available globally and don't need to be imported at all. The jest and beforeEach/afterEach imports are unused in this file anyway.

Every other test file in the project uses @vitest-environment:

Suggested change
* @jest-environment jsdom
*/
import {
describe,
it,
expect,
jest,
beforeEach,
afterEach,
} from '@jest/globals'
/**
* @vitest-environment jsdom
*/
import {
isScheduleInPast,
isScheduleToday,
} from '@/lib/program/time-utils'

Context Used: Context from dashboard - AGENTS.md (source)

Comment on lines +407 to +427
<button
onClick={() => setIsOpen(!isOpen)}
className={clsx(
'group inline-flex items-center gap-2 transition-colors',
isPast && 'hover:text-brand-cloud-blue dark:hover:text-blue-400',
)}
aria-expanded={isOpen}
>
<h2 className="font-space-grotesk text-2xl font-semibold text-brand-slate-gray dark:text-white">
{formatConferenceDateLong(schedule.date)}
</h2>
{isPast && (
<span className="text-brand-slate-gray dark:text-gray-400">
{isOpen ? (
<ChevronDownIcon className="h-6 w-6 transition-transform group-hover:scale-110" />
) : (
<ChevronRightIcon className="h-6 w-6 transition-transform group-hover:scale-110" />
)}
</span>
)}
</button>
Copy link

Choose a reason for hiding this comment

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

Non-past days collapsible without visual cue

The <button> wraps the heading for all days, but the chevron icon and "(click to expand)" hint are only rendered when isPast is true. This means a user can accidentally collapse a current or future day's schedule by clicking the heading, and there is no visual indication that the content is collapsible or how to expand it again.

Consider either:

  1. Only rendering the <button> wrapper for past days (and keeping a plain <h2> for non-past days), or
  2. Showing the chevron icon for all days when collapsed

Option 1 would be the most straightforward fix:

Suggested change
<button
onClick={() => setIsOpen(!isOpen)}
className={clsx(
'group inline-flex items-center gap-2 transition-colors',
isPast && 'hover:text-brand-cloud-blue dark:hover:text-blue-400',
)}
aria-expanded={isOpen}
>
<h2 className="font-space-grotesk text-2xl font-semibold text-brand-slate-gray dark:text-white">
{formatConferenceDateLong(schedule.date)}
</h2>
{isPast && (
<span className="text-brand-slate-gray dark:text-gray-400">
{isOpen ? (
<ChevronDownIcon className="h-6 w-6 transition-transform group-hover:scale-110" />
) : (
<ChevronRightIcon className="h-6 w-6 transition-transform group-hover:scale-110" />
)}
</span>
)}
</button>
{isPast ? (
<button
onClick={() => setIsOpen(!isOpen)}
className={clsx(
'group inline-flex items-center gap-2 transition-colors',
'hover:text-brand-cloud-blue dark:hover:text-blue-400',
)}
aria-expanded={isOpen}
>
<h2 className="font-space-grotesk text-2xl font-semibold text-brand-slate-gray dark:text-white">
{formatConferenceDateLong(schedule.date)}
</h2>
<span className="text-brand-slate-gray dark:text-gray-400">
{isOpen ? (
<ChevronDownIcon className="h-6 w-6 transition-transform group-hover:scale-110" />
) : (
<ChevronRightIcon className="h-6 w-6 transition-transform group-hover:scale-110" />
)}
</span>
</button>
) : (
<h2 className="font-space-grotesk text-2xl font-semibold text-brand-slate-gray dark:text-white">
{formatConferenceDateLong(schedule.date)}
</h2>
)}

@Starefossen
Copy link
Member

@copilot make sure to run pnpm check and pnpm test. Review all the review comments in the pull request.

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.

Collapse yesterdays schedule

2 participants