Repository navigation
Application Tracking: split status from tasks, and let students date their own work - #47
Merged
Merged
Conversation
The add-a-date form offered Application Tracking or Financial Aid, so a driving test, a shift, or a form due at school had to be filed under one of them or not recorded at all. There is a third option now. 'Custom' is a DeadlineModule but not a module: there is nothing to open. It is a bucket for dates that belong to the student rather than to the app, and making it a module value is what lets it be filtered in settings, counted in the week strip and exported like everything else, with no special case anywhere. Only self-set dates can carry it — derivation produces the other two — so nextDueForModule keeps returning nothing for it, which is right: there is no Custom card to hang a "next due" chip on. Three places assumed there were exactly two modules and are now driven by one list. The worst was the deadline row's short label, a two-value ternary where anything that was not Application Tracking rendered as "Financial Aid" — a Custom date would have claimed to be financial aid. Settings had its own hardcoded copy of the module names, and the add form had hand-written options. Stored rows with an unrecognised module still fall back rather than being dropped. The row is the student's own work, and a module name we no longer recognise is no reason to lose it. The option reads "Custom — anything else", because "Custom" alone in a list of two app areas reads as a setting rather than as a place to put a driving test.
A student coming back to this module wants to see where each application stands, not re-read the strategy checklist. It opened on Overview. The nav keeps its existing order — overview, discover, list, status — which is a teaching order, and also the order the guided tour walks through. The landing tab and the reading order are answering different questions, so they do not have to match. Status's empty state had to change with it. It said "Add colleges to your list first" and offered no way to get there, which was tolerable as the fourth tab and is not as the first thing a new student sees. It now has a button through to the College List, where the search box is.
Application Status carried five things: a progress hero, three stat tiles, a stage funnel, per-college status rows, and — behind a click — each college's task checklist in a popup. It answered two different questions badly at once. It is two pages now. **Application Status** keeps the overview: the ring, the next deadline, the balance chips, the tiles, the funnel, and a row per college showing status at a glance. Where do I stand. **Tasks** is new and holds what was trapped in the modal: every college as a section, its checklist grouped by phase, ordered by deadline. What do I do next. Clicking a college on the status page lands on its section rather than opening a dialog. The modal was the real problem. The most actionable thing in the module showed one college at a time and closed the moment you looked away, so a student could not see everything they owed without opening and shutting a dialog per school. SchoolTasksModal is deleted; its body is now SchoolTaskList, used by the page. Colleges we hold no deadline for sort last rather than being dropped — most colleges outside the curated set have no date on file, and hiding them would hide most of the list. The confetti on finishing a school's checklist moved with the checklist. It was the one moment in this module worth marking and losing it with the modal would have been a loss.
Ten colleges at ten tasks each is a hundred checkboxes in one scroll, and the ticked ones are the ones least worth the space. A college with every task done now collapses to its header — name, "All N done", category, status — and reopens on a click. Nothing else collapses. A student opens this page to work, and putting their unfinished work behind a click would be the wrong trade; only the work that is over gets folded away. A college the student clicked through to from the status page is never collapsed either, since they asked for it by name and arriving at a closed box would be a dead end. Also guards the scroll-into-view call. Scrolling to the focused college is a courtesy, and an environment without scrollIntoView — jsdom, as it turns out — must not throw out of an effect and take the page with it. Seven tests: the deadline ordering, that unfinished colleges stay open and offer no toggle, that finished ones collapse and reopen, that a focused one is exempt, the cross-college progress count, and the empty state's way out.
A college's application deadline is derived and fixed. The dates that actually need remembering are the ones leading up to it — have the essay drafted by the 12th, ask Ms. Reyes by the 15th — and there was nowhere to put them. A student could add a task but not say when it was due. AppTask carries an optional `due` now, set from a date control on each task row. Empty until they use it, so an untouched checklist stays a checklist rather than becoming a wall of date pickers. Dated tasks derive into DeadlineEvents, so they appear on the calendar, the week strip and the deadline panel beside everything else. The title carries the college — "Draft the supplemental essay — Harvard" — because on a calendar the task name alone says nothing about which school it belongs to. They are marked source 'self': the student chose the date. Ticking one from the calendar writes the task's own done flag, not the stored id list, so the calendar and the college's checklist cannot disagree about whether the same thing is finished. Withdrawn applications contribute nothing; their tasks are not work any more. The tests caught a real bug before it shipped. Event ids were `task-<collegeId>-<taskId>` and parsed with a greedy pattern, so `task-harvard-c-1` split into `harvard-c` and `1`. Both halves can contain hyphens — `cal-poly`, and every task a student adds themselves is `c-1`, `c-2` — which meant ticking a self-added task would have written to the wrong place, or nowhere. The delimiter is `::` and the round trip is tested across all four shapes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Deploying timeline-prototype with
|
| Latest commit: |
4b8a0ff
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://7dc74a2e.timeline-prototype.pages.dev |
| Branch Preview URL: | https://feat-ui-changes.timeline-prototype.pages.dev |
ZubairQazi
added a commit
that referenced
this pull request
Sep 24, 2026
…m dates main (#47) split Application Status into an overview plus a Tasks tab, while this branch replaced the tasks popup with a page per school and folded the College List into Discover. Kept this branch's structure; brought in the rest. - Task due dates: the date control from SchoolTaskList now sits on each task row of the school page, so dated tasks still reach the calendar, week strip and deadline panel. - Shared tasks (recommendations, transcript, CSS Profile) keep one date for every school that needs them: set from any school, shown on the calendar once ("— all your schools"), and ticked from the calendar for every school. - The module opens on Application Status; its empty state links to Discover (the College List tab it pointed at is gone). - Custom dates, the deadline panel/row and settings changes come in as-is. - The Tasks tab (ApplicationTasksTab, SchoolTaskList) is dropped: the school pages cover it. Its task-event tests move to applicationTaskEvents.test.ts.
ZubairQazi
added a commit
that referenced
this pull request
Sep 24, 2026
Fixes from reviewing the merge and the Category sort added on top of it. Application Status - "Sort by" gains Category: schools grouped under reach / match / safety / unranked headings, by deadline within each. - A category this build doesn't know shows as Unranked instead of crashing every view (normalized once where the list loads; storage untouched). Task due dates - The date box keeps focus while typing, saves after a pause or on leaving, never saves a half-typed value, and only clears when really emptied. - Shared tasks keep one date and tick across every school (withdrawn ones included, so a school brought back is in step); a new school inherits both, preferring an active school's date. - Dates saved per school before this stay on the calendar, one per date, instead of all but one being dropped. From main (#47), made to work here - The tour resets to Application Status, the tab the module opens on. - The calendar's remove button only shows on the student's own dates, not task dates (tagged with isTask); Dashboard "next due" skips ticked-off items and task dates. - Custom dates stay visible for settings saved before Custom existed: saves now record which modules existed, and older lists are read by what they could only have been chosen from. - Settings saves run in order on the last confirmed write, so a quick second change can't drop the first and a failed one can't slip through. - Calendar writes compute once outside state updaters and wait for their list to load, so they can't save a stale copy. - One ISO-day parser instead of two.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five UI changes, each a separate commit, read in order.
Custom tasks in the sidebar
The add-a-date form offered Application Tracking or Financial Aid, so a driving test, a shift, or a form due at school had to be filed under one of them or not recorded at all. There is a Custom option now.
Customis aDeadlineModulebut not a module — there is nothing to open. Making it a module value rather than a special case is what lets it filter in settings, count in the week strip and export like everything else with no branching anywhere. Only self-set dates carry it, sonextDueForModulestill returns nothing for it, which is right.Three places assumed there were exactly two modules. The worst was the deadline row's short label — a two-value ternary where anything that was not Application Tracking rendered as "Financial Aid", so a Custom date would have claimed to be financial aid on every row. Settings kept its own hardcoded copy of the names, and the add form had hand-written options. All three read one list now.
The module opens on Application Status
A student coming back wants to see where each application stands, not re-read the strategy checklist.
The nav keeps its order — overview, discover, list, status — which is a teaching order and also the order the guided tour walks. The landing tab and the reading order answer different questions.
Status's empty state had to change with it: it said "Add colleges to your list first" and offered no way to get there, which was tolerable as the fourth tab and is not as the first thing a new student sees. It has a button through to the College List now.
Status split into two pages
Application Status carried five things and answered two questions badly at once.
The modal was the real problem. The most actionable content in the module showed one college at a time and closed the moment you looked away, so a student could not see everything they owed without opening and shutting a dialog per school.
SchoolTasksModalis deleted; its body is nowSchoolTaskList, used by the page. The confetti on finishing a school moved with it.Colleges with no deadline on file sort last rather than being dropped — most colleges outside the curated set have no date, and hiding them would hide most of the list.
Finished colleges fold away
Ten colleges at ten tasks each is a hundred checkboxes in one scroll, and the ticked ones are least worth the space. A college with every task done collapses to its header and reopens on a click.
Nothing else collapses. A student opens this page to work; putting unfinished work behind a click would be the wrong trade. A college reached by clicking through from the status page is never collapsed either — they asked for it by name, and arriving at a closed box is a dead end.
Also guards the
scrollIntoViewcall. Scrolling to the focused college is a courtesy, and an environment without it — jsdom, as it turns out — must not throw out of an effect and take the page down.Tasks can carry their own dates
A college's application deadline is derived and fixed. The dates that actually need remembering are the ones leading up to it — essay drafted by the 12th, recommendations asked by the 15th — and there was nowhere to put them.
AppTaskcarries an optionaldue, set from a control on each row that stays empty until used, so an untouched checklist does not become a wall of date pickers.Dated tasks derive into
DeadlineEvents and appear on the calendar, the week strip and the deadline panel. The title carries the college — "Draft the supplemental essay — Harvard" — because on a calendar the task name alone does not say which school. Ticking one from the calendar writes the task's own done flag, not the stored id list, so the two views cannot disagree about whether the same thing is finished.A bug the tests caught
Event ids were
task-<collegeId>-<taskId>, parsed greedily, sotask-harvard-c-1split intoharvard-cand1. Both halves can contain hyphens —cal-poly, and every task a student adds themselves isc-1,c-2. Ticking a self-added task would have written to the wrong college or nowhere. The delimiter is::and the round trip is tested across all four shapes.Testing
408 tests, 29 files (+23). New coverage: the Custom module end to end including storage round-trip, the Tasks page's ordering, collapse, focus exemption and empty state, and task-deadline derivation plus the tick write-through.
tsc -b,eslint .,vitest run,npm run buildclean locally.What is not verified
Everything here was checked by rendering components and by tests. Nobody has clicked through this module in a live session — this work has had no authenticated environment available. The Tasks page, the collapse, the date control and the status→tasks jump all render correctly and are tested, but none has been used. The preview deploy is worth two minutes before merging.
One judgement call worth a second opinion: the undated date control is deliberately faint — a small dashed picker. It keeps the list clean at the cost of discoverability, and a student may not notice dates are available at all.