Skip to main content

Admin CRM overview

emaw-crm-app is the staff web app, branded EMAW Admin. It replaces Planning Center for contacts and events and Mailchimp for email, and adds the map, store operations and resource publishing. It is a client only; the API is the Django backend, documented for this app in docs/CRM_FRONTEND_GUIDE.md.

Package nameemaw-admin
StackReact 19, Vite 8, TypeScript 6, React Router 8 (data router, lazy route modules), TanStack Query 5, Tailwind 4 with in-repo UI primitives, Leaflet + react-leaflet + Geoman + leaflet.heat, Recharts, Tiptap (rich text), CodeMirror (HTML), Vitest + Testing Library
HostingCloudflare Workers (static assets + /rest/* proxy), not Pages
URLsdev https://admin-dev.everymanawarrior.cc, prod https://admin.everymanawarrior.cc, both behind Cloudflare Access
Sign-inCloudflare Access (Google Workspace) and a backend account in the Django group CRM Staff or with granted capabilities
Own docsREADME.md, src/api/README.md
TestsVitest, 64 test files

Routes​

Route table in src/routes/router.tsx and src/routes/paths.ts; each feature declares its routes in src/features/<area>/routes.tsx, gated by a capability through src/features/auth/routeGate.tsx. Everything except /login and /google/callback renders inside Root (RequireAuth + AppShell).

PathCapabilityPage
/loginpublicStaff sign-in (password or Google)
/google/callbackpublicLanding for the Google OAuth popup (connect Google for Meet)
/anyDashboard; scoped users get links into their filtered list and map
/contacts, /contacts/new, /contacts/:idcontacts.view / contacts.editList with filters, bulk assign, CSV export; create; detail with Profile, Groups & Tags, Notes, Activity, Registrations, Orders, Campaign history, Location tabs
/groupsgroups.manageGroups, Tags, Roles, Note categories
/regionsgeography.manageRegion and Area tree, polygon editor, assignment
/mapmapPoints, heat map, sales layer, geography overlay, drawing tools, filters
/shapescampaignsSaved map shapes used as audiences
/templates, /templates/new, /templates/:idtemplatesEmail templates: block designer, rich text or HTML, AI draft, image library, preview, test send
/campaigns, /campaigns/:id, /campaigns/:id/reportcampaignsList; four-step wizard (Email & event, Audience, Prepare & test, Send/schedule); delivery report
/events, /events/new, /events/:ideventsEvents; detail tabs Details, Tickets, Registrations, Attendees (check-in), Meet attendance
/store, /store/orders, /store/orders/:id, /store/orders/other/:id, /store/inventorystoreDashboard with charts; web orders (resubmit/refresh to Deposco, CSV); Deposco-only orders; inventory with per-SKU history
/resources, /resources/new, /resources/:idresourcesWebsite resources: media upload to R2, cover image, publish/unpublish
*404

The sidebar (src/components/layout/AppShell.tsx) hides entries the user lacks the capability for. There is no donations UI yet.

Layout​

src/
api/ typed fetch wrapper (client.ts), errors, query helpers, CSV download, directUpload (presigned PUT)
components/
layout/ AppShell, environment banner
ui/ buttons, inputs, dialogs, toasts, tables, badges
features/ one folder per area: auth, home, contacts, groups, geography, shapes, notes,
activity, map, audience, templates, campaigns, events, store, resources
each with api.ts, types, screens, routes.tsx, *.test.tsx
routes/ route table, router, placeholder and 404 pages
lib/ small utilities
config.ts the ONLY place env vars are read
test/ Vitest setup and fixtures
worker/index.ts the /rest proxy Worker
scripts/deploy.mjs
wrangler.jsonc
public/_headers