← Back to Projects
CRM / Outreach

CanvassKit

A field contact tracker built after watching a nonprofit coordinator manually relay her entire team's daily outreach through three separate steps. Runs inside Google Workspace.

Role
Designer & Builder
Stack
Google Apps Script, Tailwind CSS, Vanilla JS
Deployed to
Going Home 2, community safety initiative
Status
Production-ready, active use
canvasskit · demo mode · data stored locally
Open full screen ↗

Three steps to store one day's data

While contracting with the nonprofit as media lead, I sat down with one of the senior staff members and asked her to walk me through her day. I recorded her describing her process. Her outreach workers would text her their contact logs at the end of each shift. She would compile those texts into a note on her phone. Then she would transfer that note into a file on her computer to store it. Three separate steps, every single day, to capture data that should have taken one.

The room for error at each handoff was significant. Texts got missed. Phone notes had no structure. File transfers introduced inconsistencies. And when it came time to report back to her supervisors, she was reconstructing the week from a pile of freeform notes rather than pulling from a clean record.

No budget, no IT, no onboarding

The organization runs on Google Workspace. There was no budget for a SaaS CRM, no IT support for a custom deployment, and no tolerance for a tool that required more than five minutes to learn. Any solution had to live inside tools the team already had open.

The constraint shaped every decision: Google Apps Script as the backend, Google Sheets as the database, and a web app UI that required zero installation. The field staff needed to open a link and start logging.

Two contact types. One dashboard. Full export.

After recording that conversation, I pulled the transcript and used it to map the exact shape of the problem: two types of field interactions (detailed engagements and quick touches), a supervisor view with running totals, and a date-range export for reporting. The product was designed from her words, not from assumptions.

CanvassKit separates contacts into two categories that match real field behavior. A Hard Contact is a detailed engagement: name, staff member, location, and notes. A Quick Contact is a single-click log for time-constrained interactions where detail isn't possible.

The dashboard shows live stats: total contacts, hard contacts, and active team members. The contacts table displays the last ten interactions with delete and detail view. Export pulls any date range to CSV or JSON in one click.

The goal was zero training time. If someone needs a walkthrough, it isn't done yet.

GAS backend, flat Sheet, dual deployment mode

The backend is Google Apps Script serving a web app. A single Sheet tab stores all contacts as flat rows: id, type, name, staff, location, notes, date, user, and role. doPost handles create and delete. doGet handles the UI and list endpoint. Authentication is a shared secret key passed with each request.

The demo embedded above runs entirely in localStorage with no server. It's a feature, not a workaround. Field staff can use the demo mode when offline, and contacts can be exported and manually merged later.

  • Timestamp-based IDs avoid collision without a server-generated UUID
  • User name and role persist in localStorage across sessions
  • Export filters by date range before downloading, so grant reporting pulls exactly the right period
  • AOS animations on the stat cards add momentum without adding weight

Deployed. In active use.

CanvassKit is production-ready and in active use by the Going Home 2 outreach team. The core loop, log a contact, view the table, export for reporting, is complete and stable.

Planned additions: search and filter in the contacts table, a soft contact detail form, and batch delete for supervisors managing data hygiene.

← All Projects SoloBill →