From 984d574f8bcf8cd5474b9484c095f585117f74f4 Mon Sep 17 00:00:00 2001 From: Danial Beg Date: Wed, 30 Sep 2026 23:09:31 -0700 Subject: [PATCH] Ask about a fee waiver a month out, not on submit day MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One task carried both jobs: "Pay the application fee (or apply for a waiver)", in the Submit phase. The paying belongs there. The asking does not — the request goes through the counselor, who is confirming eligibility for a whole cohort through October and November, and a student who reaches it on the day they submit has already missed it. They are two tasks now. "Ask your counselor about a fee waiver" sits in Before you apply, and its date box opens on a month before that school's deadline rather than on nothing, with the reason next to it. Nothing is written until the student saves it. The waiver is also one request, not one per school: a granted Common App waiver applies at every Common App school on the list, so it joins recommendations, the transcript and the CSS Profile as a shared task. Paying stays per school, which is what the old comment was right about and why the two had to come apart. Community colleges and trade schools do not get it. Reading the fee column of the Common App grid, 611 of its 1,128 schools charge nothing to apply at all, and two-year schools are overwhelmingly among them; a step about waiving a fee that does not exist is noise on the one list that should be shortest. A saved checklist is now topped up with any default task it lacks. Default tasks cannot be deleted — only custom ones can — so a list without one was saved before that task existed, and without this only students who add a school from today would ever see the waiver step. --- web/src/components/SchoolApplicationPage.tsx | 26 ++++++- web/src/data/applicationTasks.test.ts | 71 ++++++++++++++++++-- web/src/data/applicationTasks.ts | 58 ++++++++++++++-- 3 files changed, 142 insertions(+), 13 deletions(-) diff --git a/web/src/components/SchoolApplicationPage.tsx b/web/src/components/SchoolApplicationPage.tsx index f076a50..4d7cad5 100644 --- a/web/src/components/SchoolApplicationPage.tsx +++ b/web/src/components/SchoolApplicationPage.tsx @@ -18,9 +18,10 @@ import { useEffect, useRef, useState } from 'react' import { C, MODULE_COLORS } from '../lib/designTokens' import { Bar, CollegeLogo, SecLabel } from './moduleUI' import JourneyStepper from './JourneyStepper' -import { TASK_PHASES, tasksForEntry, isSharedTask } from '../data/applicationTasks' +import { TASK_PHASES, tasksForEntry, isSharedTask, suggestedWaiverDue, WAIVER_LEAD_DAYS } from '../data/applicationTasks' import { DEADLINE_TYPE_LABEL, DEADLINE_TYPE_MEANING, daysLabel, urgencyColor, type DeadlineEvent } from '../data/applicationDeadlines' import NetPriceFact from './NetPriceFact' +import { toIsoDay } from '../lib/personalDeadlines' import { APP_STATUS_META, CATEGORY_META, @@ -60,10 +61,13 @@ const plausibleDay = (v: string) => { return /^\d{4}-\d{2}-\d{2}$/.test(v) && year >= 2000 && year <= 2100 } -function TaskDueInput({ due, label, hint, onCommit }: { +function TaskDueInput({ due, label, hint, suggested, onCommit }: { due?: string label: string hint: string + /** A sensible date to open on, as `YYYY-MM-DD`. The student still has to + * save it — nothing is written until they do. */ + suggested?: string onCommit: (due: string | undefined) => void }) { // null = not editing: show the saved value. @@ -97,7 +101,7 @@ function TaskDueInput({ due, label, hint, onCommit }: { return (