Module 10 · Web Development with JavaScript
"Final project: Tallybook's pay-an-invoice page"
Plan your final project, an accessible, responsive payment page that calculates exactly, validates clearly, talks to the API safely and is backed by tests.
About 20 minutes
The problem
Tallybook wants the new pay-an-invoice page live before the next month-end. Your final project is the page itself, and the evidence that it works for every customer: on a small phone, with a keyboard, with a screen reader, on a bad connection, and when someone types something unexpected.
The concept
What the page includes
| Part | Built in |
|---|---|
| Exact money: totals and formatting in kobo | lessons 2 and 3 |
| Semantic, accessible HTML | lesson 4 |
| Mobile-first, responsive CSS | lesson 5 |
| Live balance as the customer types | lesson 6 |
| Clear, accessible validation | lesson 7 |
| Every API outcome handled, with loading states | lesson 8 |
| Automated tests for the logic | lesson 9 |
Evidence
A checklist with a result for each item: keyboard only, screen reader (NVDA on Windows, VoiceOver on a phone), 320px wide, 200% zoom, Lighthouse accessibility score, slow network (DevTools' "Slow 3G"), and the test results.
Example
The checklist as data, so it can be scored and reported the same way each time you re-check the page:
JavaScript
const checks = [
{ area: "Keyboard", check: "Every control reachable and usable with Tab, Enter and Space", passed: true },
{ area: "Screen reader", check: "Labels, errors and the live balance are announced", passed: true },
{ area: "Small screen", check: "Usable at 320px wide without horizontal scrolling", passed: true },
{ area: "Zoom", check: "Usable at 200% zoom", passed: true },
{ area: "Money", check: "Totals match the API for the test invoices", passed: true },
{ area: "Validation", check: "Every error has a visible, linked message", passed: true },
{ area: "Network", check: "Slow and failed requests show clear messages and no double payments", passed: false },
{ area: "Tests", check: "All logic tests pass", passed: true },
];
const failed = checks.filter((c) => !c.passed);
console.log(`${checks.length - failed.length} of ${checks.length} checks passed`);
for (const c of failed) console.log(`To fix: ${c.area}: ${c.check}`);7 of 8 checks passed
To fix: Network: Slow and failed requests show clear messages and no double paymentsA page isn't finished when it looks right on your laptop; it's finished when this list is all passes on real devices.
Walkthrough
- Build the page from lessons 4 to 8 in one file, with the tests from lesson 9.
- Run every check on a real phone as well as your computer, and record the results honestly.
- Fix what fails, re-check, and keep the before-and-after.
- Open the project brief on the course page and plan the write-up.
Practice
Practice
How many checks fail in the example checklist?
Task
6 minWrite the release note for the new page (60 to 140 words): what's better for customers, how it was checked for accessibility (at least two methods), how network problems are handled, and anything still to do.
Your work is checked for
- Benefits for customers (live balance, phone, clear errors)
- At least two accessibility checks
- Network handling
- Still to do
- Between 60 and 140 words
Check your understanding
Answer every question to check.