W04 Assignment: Sacrament Meeting Planner
Overview
Build on your Sacrament Meeting Planner by implementing Server Actions for data mutations, adding graceful error handling for failed operations and missing records, and improving your forms with accessible server-side validation. By the end, bishopric leaders will be able to create, edit, and delete meeting records through forms that give clear, accessible feedback — and the app will handle bad input and unexpected failures without crashing.
Requirements
This week's assignment adds three capabilities to the Sacrament Meeting Planner you built in Week 03:
- Meeting create, update, and delete operations are handled by Server Actions in
lib/actions.ts. The mutation stubs inlib/meetings-db.tsare replaced with live SQL. - Unexpected errors in meetings routes are caught by
error.tsx. Requests for a meeting ID that does not exist triggernotFound()and render anot-found.tsxpage. - The create and edit forms validate input on the server using Zod and
useActionState, returning field-level error messages to the form witharia-describedbyandaria-liveso they are accessible to screen readers.
Instructions
Leveraging AI
You may use AI to ask conceptual questions, diagnose errors, and generate small snippets. You are responsible for understanding, testing, and explaining all code in your submission.
Review the course AI Policy.
Bring your previous work into main
Peer code reviews are now focused on the team project PRs. Of course, you can continue to work with your
teammates on this project and request reviews. However, at this point you are going to merge your work on the
peer-code-review branch into main so all previous work lands in the production branch
before you add new features. All Week 04 commits go directly on main.
- Open your sacrament-meetings project in VS Code and confirm you are on the
peer-code-reviewbranch:git branch - Pull any remote changes so your local copy is up to date:
git pull origin peer-code-review - Merge
peer-code-reviewintomainand push:git checkout main git merge peer-code-review git push origin mainVercel will trigger a new production deployment automatically when
mainis updated. You can confirm it in your Vercel dashboard under Deployments.
Why not create a new branch for Week 04? This week intentionally practices a common real-world
pattern: after a peer-reviewed Pull Request is merged, small incremental features go directly onto main. On a
professional team, however, you would often create a new feature branch (For example,
w04-mutations) and open a fresh Pull Request — especially if the work is substantial, you want another round
of review, or your team requires all changes to go through a PR. Both approaches are valid; the right choice
depends on team conventions and the scope of the work.
Implement Server Actions for data mutations
Review the Mutating Data learning activity, then apply the same patterns to the Sacrament Meeting Planner.
- Create
lib/actions.tswith the'use server'directive. AddcreateMeeting,updateMeeting, anddeleteMeetingServer Actions. Each action should call the corresponding function inlib/meetings-db.ts— replace the stubs from Week 03 with live SQL statements. - Define a Zod schema (For example,
MeetingFormSchema) inlib/actions.tsand callsafeParseon the rawFormDatavalues inside each create and update action before writing to the database. - Wire the create form's
actionattribute tocreateMeetingand the edit form toupdateMeeting.bind(null, id)using the meeting ID from the dynamic route segment (For example,app/meetings/[id]/edit/page.tsx). - Add a delete button to each meeting row or card and connect it to a small form that submits to
deleteMeetingwith the meetingid. - Call
revalidatePath('/meetings')after each mutation, thenredirect('/meetings')where appropriate, and verify the list refreshes immediately after each operation.
Add error handling
Review the Handling Errors learning activity, then add graceful error handling to the meetings routes.
- Wrap the database calls in each Server Action in a
try...catchblock. Log the caught error and re-throw a user-friendlyErrorso that unexpected failures surface cleanly. - Create
app/meetings/error.tsxas a Client Component ('use client'). It should accepterrorandresetprops and render a helpful message with a "Try Again" button that callsreset()and a link back to/meetings. - In the edit page (
app/meetings/[id]/edit/page.tsx), callnotFound()fromnext/navigationwhengetMeetingByIdreturnsnullorundefined. - Create
app/meetings/[id]/edit/not-found.tsxthat renders a friendly "Meeting not found" message and a link back to/meetings. Test it by navigating to a non-existent meeting ID.
Improve form accessibility and server-side validation
Review the Improving Accessibility learning activity, then apply the same patterns to the meeting create and edit forms.
- Ensure every form input has a matching
<label htmlFor>and a correspondingid. Addaria-describedbypointing to an error container below each field, and setaria-live="polite"on those containers so screen readers announce validation updates. - Convert the create and edit form files to Client Components (
'use client') and replace the plainactionattribute withuseActionState:const [state, formAction, isPending] = useActionState(createMeeting, initialState); - Update
createMeetingandupdateMeetinginlib/actions.tsto accept aprevStateparameter and return aStateobject (For example,{ message, errors }) instead of throwing when validation fails. UseMeetingFormSchema.safeParseand return field-level error arrays so the form can display them inline. - Render the
state.errorsfor each field beneath its input and confirm the error messages appear and disappear correctly as you submit valid and invalid data.
Required quality and accessibility checks
- Run local checks before submission:
npm run lint npm run build - Run accessibility checks on the main user-facing routes:
- Verify keyboard navigation works for links, buttons, and form controls.
- Ensure form inputs have clear labels and interactive elements have accessible names.
- Confirm images use meaningful
alttext and headings follow a logical order.
- Run Lighthouse in Chrome DevTools on key pages and review all the categories for mobile and desktop environments. Address any issues such as color contrast, missing labels, or incorrect semantic structure before submission.
- Use AI to review your code for implementation issues before submission. Ask it to focus on bugs,
accessibility, incorrect routing or API behavior, type-safety problems, and missing assignment requirements
rather than style preferences.
Example prompt
Review for bugs, accessibility problems, incorrect Next.js App Router usage, API route issues, type-safety problems, and places where I may have missed the assignment requirements. Prioritize findings by severity. For each finding, include: (1) what is wrong, (2) why it matters, (3) the file or route involved, and (4) a specific fix. Do not praise the code or suggest optional refactors unless they are directly related to correctness, accessibility, or assignment compliance.
Submission Instructions
Submit the following in the text entry area in Canvas:
Project Links
- GitHub repository URL for your sacrament-meetings repository.
- Vercel production URL for your deployed app. Since this week's work lands directly on
main, Vercel deploys it to production automatically. Find the URL in your Vercel project dashboard under Deployments — look for the entry tagged Production.
Reflection
- A brief reflection on the challenges you faced, any improvements you made or considered for the app, and a summary of how you used AI during the development process.