WDD 430: Web Full-Stack Development

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:

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.

  1. Open your sacrament-meetings project in VS Code and confirm you are on the peer-code-review branch:
    git branch
  2. Pull any remote changes so your local copy is up to date:
    git pull origin peer-code-review
  3. Merge peer-code-review into main and push:
    git checkout main
    git merge peer-code-review
    git push origin main

    Vercel will trigger a new production deployment automatically when main is 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.

  1. Create lib/actions.ts with the 'use server' directive. Add createMeeting, updateMeeting, and deleteMeeting Server Actions. Each action should call the corresponding function in lib/meetings-db.ts — replace the stubs from Week 03 with live SQL statements.
  2. Define a Zod schema (For example, MeetingFormSchema) in lib/actions.ts and call safeParse on the raw FormData values inside each create and update action before writing to the database.
  3. Wire the create form's action attribute to createMeeting and the edit form to updateMeeting.bind(null, id) using the meeting ID from the dynamic route segment (For example, app/meetings/[id]/edit/page.tsx).
  4. Add a delete button to each meeting row or card and connect it to a small form that submits to deleteMeeting with the meeting id.
  5. Call revalidatePath('/meetings') after each mutation, then redirect('/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.

  1. Wrap the database calls in each Server Action in a try...catch block. Log the caught error and re-throw a user-friendly Error so that unexpected failures surface cleanly.
  2. Create app/meetings/error.tsx as a Client Component ('use client'). It should accept error and reset props and render a helpful message with a "Try Again" button that calls reset() and a link back to /meetings.
  3. In the edit page (app/meetings/[id]/edit/page.tsx), call notFound() from next/navigation when getMeetingById returns null or undefined.
  4. Create app/meetings/[id]/edit/not-found.tsx that 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.

  1. Ensure every form input has a matching <label htmlFor> and a corresponding id. Add aria-describedby pointing to an error container below each field, and set aria-live="polite" on those containers so screen readers announce validation updates.
  2. Convert the create and edit form files to Client Components ('use client') and replace the plain action attribute with useActionState:
    const [state, formAction, isPending] = useActionState(createMeeting, initialState);
  3. Update createMeeting and updateMeeting in lib/actions.ts to accept a prevState parameter and return a State object (For example, { message, errors }) instead of throwing when validation fails. Use MeetingFormSchema.safeParse and return field-level error arrays so the form can display them inline.
  4. Render the state.errors for 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

  1. Run local checks before submission:
    npm run lint
    npm run build
  2. 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 alt text and headings follow a logical order.
  3. 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.
  4. 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

  1. GitHub repository URL for your sacrament-meetings repository.
  2. 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

  1. 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.