Closes the trilogy. Three high-value gaps from PRs 2a/2b addressed:
1. Canvas users couldn't save. The Header (with Save / Activate /
Pause / Delete buttons) lived inside FlowBuilder so canvas-only
users had to toggle to List to persist any edit. Lifted into a
new components/flows/header.tsx that consumes useFlowEditor()
and is mounted ONCE in FlowEditorShell, above both views.
2. Validator issues weren't clickable from canvas. The
ValidationPanel was also FlowBuilder-internal. Lifted into
components/flows/validation-panel.tsx + mounted in the shell,
pinned sticky-bottom in either view. Clicks now go through the
editor context's new requestFlash(key) — both views subscribe:
- List view derives an "expanded with flash" set + an effect
scrolls the row into view. The flash class is rendered when
the card's key matches context.flashKey.
- Canvas view's pan-on-flash effect calls
reactFlow.setCenter() to bring the node into the viewport,
and the card renders an amber ring while flashed.
The flash auto-clears in the context after 1600ms; rapid
clicks on different issues cancel the previous timeout.
3. Canvas was unusable on phones — handles are ~10px and live
finger-drags between them aren't a practical workflow. Added
a useMatchMedia('(max-width: 767px)') guard in the shell that
forces list view and hides the toggle below the breakpoint.
The user's preferred view is preserved (just shadowed) so it
comes back when they widen.
Plus minor cleanup: the canvas's empty-state used to direct users
to switch to List view to add a node, but the floating "+" button
shipped in PR 2b made that stale — now shows the same Add-node
dropdown inline.
flow-builder.tsx shrinks by another ~370 lines (Header + StatusBadge
+ ValidationPanel + IssueLine + the local flashedKey + jumpToNode
all moved or replaced by context subscription).
No new tests — the change is structural + UI-only. Existing 319
still pass; typecheck, lint, build all clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .github | ||
| public | ||
| src | ||
| supabase/migrations | ||
| .editorconfig | ||
| .env.local.example | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| components.json | ||
| CONTRIBUTING.md | ||
| eslint.config.mjs | ||
| LICENSE | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.mjs | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
wacrm — CRM Template for WhatsApp
Self-hostable CRM template for WhatsApp® — shared inbox, contacts, sales pipelines, broadcasts, and no-code automations. Fork it, brand it, host it.
The marketing site and self-host docs live in a separate repo: ArnasDon/wacrm-site (wacrm.tech). This repo is the product — clone or fork it to run your own CRM.
What you get out of the box
- Shared inbox on the official WhatsApp Business API — multiple agents working one number, per-conversation assignment, status, and notes.
- Contacts + tags + custom fields, CSV import, deduplication.
- Sales pipelines (Kanban) with deals linked to conversations.
- Broadcasts with Meta-approved templates, delivery + read tracking, per-recipient variable substitution.
- No-code automations — triggers on inbound messages, new contacts, keywords, or schedule; conditional branches, waits, tags, webhooks. Visual builder.
- Real-time dashboard — response times, daily volume, pipeline value, cross-module activity feed.
- Account management — email, password, avatar, global sign-out.
Why fork this?
This is a template, not a product. Forking means you get:
- Full ownership — your code, your Supabase project, your domain, your data. No SaaS lock-in, no seat pricing, no trust dance.
- Full customisation — add the fields your team needs, remove the modules you don't, redesign anything. The stack is boring on purpose (Next.js + Supabase + Tailwind) so the learning curve is short.
- Zero ops to start — Hostinger Managed Node.js deploys a fork in a few clicks. No Docker, no Kubernetes, no infra team needed.
- Real security primitives — token encryption (AES-256-GCM), RLS on every table, HMAC-verified webhooks, CSP, rate limiting, CI typecheck/build on every PR.
Not a framework. Not an SDK. A concrete, working CRM you can stand up in an afternoon and make yours.
Quick start
# Fork on GitHub first: https://github.com/ArnasDon/wacrm → Fork
git clone https://github.com/<your-username>/wacrm.git
cd wacrm
npm install
cp .env.local.example .env.local # fill in Supabase + Meta creds
npm run dev
Open http://localhost:3000. You'll be redirected to /login (or
/dashboard if already signed in).
Documentation
Full self-host documentation — Supabase migrations, WhatsApp Business API config, and production deploy — lives at wacrm.tech/docs (source: ArnasDon/wacrm-site).
Key pages:
- Getting started
- Supabase setup
- WhatsApp setup
- Environment variables
- Deploy on Hostinger
- Architecture
- Troubleshooting
Stack
- App — Next.js 16 (App Router), React 19, TypeScript, Tailwind v4.
- Data — Supabase (Postgres + Auth + Storage + RLS).
- WhatsApp — Meta Cloud API (official WhatsApp Business API).
Contributing
This is a template, not a collaborative product — the expected flow is
fork → customise → deploy, not upstream contribution. Bug reports
and security issues are welcome; feature PRs often belong in your fork
rather than here. Details in
CONTRIBUTING.md and
.github/SECURITY.md.
License
MIT. Fork it, brand it, host it.