mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 09:19:51 +00:00
Merge remote-tracking branch 'origin/main' into chore/hostinger-accent-palette
# Conflicts: # src/app/icon.tsx # src/components/docs/shell.tsx # src/components/landing/footer.tsx # src/components/landing/nav.tsx
This commit is contained in:
commit
4bb157c705
4
.github/CODE_OF_CONDUCT.md
vendored
4
.github/CODE_OF_CONDUCT.md
vendored
@ -11,8 +11,8 @@ that standard.
|
||||
If you witness or experience behaviour that violates the Code, please
|
||||
report it privately to the project maintainer:
|
||||
|
||||
- Email: **a.donauskas@hostinger.com** with `[WaCRM conduct]` in the
|
||||
subject.
|
||||
- Email: **a.donauskas@hostinger.com** with `[CRM template conduct]` in
|
||||
the subject.
|
||||
|
||||
Reports are handled confidentially. Expect an acknowledgement within
|
||||
72 hours and a decision on next steps within a week.
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -1,5 +1,5 @@
|
||||
name: Bug report
|
||||
description: Something in WaCRM isn't working the way the docs say it should.
|
||||
description: Something in the template isn't working the way the docs say it should.
|
||||
title: "[bug] "
|
||||
labels: ["bug", "triage"]
|
||||
body:
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -6,6 +6,6 @@ contact_links:
|
||||
- name: Setup / "how do I..." questions
|
||||
url: https://github.com/ArnasDon/wacrm/blob/main/docs/README.md
|
||||
about: Check the docs first — setup, deploy, troubleshooting are all covered.
|
||||
- name: Using WaCRM as a template (forking)
|
||||
- name: Using this as a template (forking)
|
||||
url: https://github.com/ArnasDon/wacrm/blob/main/CONTRIBUTING.md
|
||||
about: WaCRM is a template. Most changes belong in your fork, not an upstream issue — here's how that works.
|
||||
about: This is a template. Most changes belong in your fork, not an upstream issue — here's how that works.
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
4
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -8,7 +8,7 @@ body:
|
||||
value: |
|
||||
Thanks for the idea — but read this first.
|
||||
|
||||
WaCRM is a **template**, not a collaborative product. The
|
||||
This is a **template**, not a collaborative product. The
|
||||
upstream scope is intentionally narrow, so most feature
|
||||
requests end up as *"build this in your fork"* rather than
|
||||
landing here. That's the point of a template.
|
||||
@ -29,7 +29,7 @@ body:
|
||||
id: problem
|
||||
attributes:
|
||||
label: What's the problem?
|
||||
description: What are you trying to do today that WaCRM makes harder than it should?
|
||||
description: What are you trying to do today that the template makes harder than it should?
|
||||
placeholder: |
|
||||
When a broadcast ends I have no way to see which recipients
|
||||
didn't reply so I can follow up manually.
|
||||
|
||||
6
.github/SECURITY.md
vendored
6
.github/SECURITY.md
vendored
@ -1,6 +1,6 @@
|
||||
# Security Policy
|
||||
|
||||
Thanks for taking the time to look into WaCRM's security.
|
||||
Thanks for taking the time to look into the security of this template.
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
@ -12,7 +12,7 @@ Instead, please report privately via one of:
|
||||
|
||||
- [GitHub Security Advisories](https://github.com/ArnasDon/wacrm/security/advisories/new)
|
||||
(preferred — keeps the disclosure, fix, and CVE all in one place).
|
||||
- Email: `a.donauskas@hostinger.com` with `[WaCRM security]` in the subject.
|
||||
- Email: `a.donauskas@hostinger.com` with `[CRM template security]` in the subject.
|
||||
|
||||
Include, if you can:
|
||||
|
||||
@ -59,4 +59,4 @@ action against anyone who:
|
||||
- Gives us reasonable time to respond before any public disclosure.
|
||||
- Doesn't exploit the issue beyond what's necessary to demonstrate it.
|
||||
|
||||
Thanks for helping keep WaCRM (and its forks) safe.
|
||||
Thanks for helping keep this template (and its forks) safe.
|
||||
|
||||
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Heads up: WaCRM is a template, not a collaborative product. Most
|
||||
Heads up: this is a template, not a collaborative product. Most
|
||||
changes belong in your fork. See CONTRIBUTING.md for which kinds of
|
||||
upstream PRs tend to land (security, correctness, docs) vs. which
|
||||
belong in a fork (new features, stack swaps, opinionated refactors).
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Using WaCRM
|
||||
# Using this template
|
||||
|
||||
WaCRM is a **template repository**, not a collaborative product. The
|
||||
This is a **template repository**, not a collaborative product. The
|
||||
expected flow is:
|
||||
|
||||
1. **Fork** it to your own GitHub account or organisation.
|
||||
@ -95,9 +95,9 @@ closed — open the issue first to align.
|
||||
|
||||
## If you maintain a public fork
|
||||
|
||||
- Rebrand. The WaCRM name, favicon, and `wacrm.tech` URL belong to the
|
||||
upstream project; please swap them for your own before putting your
|
||||
deployment in front of users.
|
||||
- Rebrand. The "CRM Template for WhatsApp" name, favicon, and
|
||||
`wacrm.tech` URL belong to the upstream project; please swap them
|
||||
for your own before putting your deployment in front of users.
|
||||
- Keep the MIT [`LICENSE`](./LICENSE) file — that's how the template's
|
||||
permissions travel with the code. Attribution in a `README` section
|
||||
is appreciated but not required.
|
||||
|
||||
10
README.md
10
README.md
@ -1,8 +1,8 @@
|
||||
# WaCRM
|
||||
# CRM Template for WhatsApp
|
||||
|
||||
> Self-hostable WhatsApp CRM template — shared inbox, contacts, sales
|
||||
> pipelines, broadcasts, and no-code automations. Fork it, brand it,
|
||||
> host it.
|
||||
> Self-hostable CRM template for WhatsApp — shared inbox, contacts,
|
||||
> sales pipelines, broadcasts, and no-code automations. Fork it, brand
|
||||
> it, host it.
|
||||
|
||||
[](./LICENSE)
|
||||
[](https://github.com/ArnasDon/wacrm/actions/workflows/ci.yml)
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
## Why fork this?
|
||||
|
||||
WaCRM is a **template**, not a product. Forking means you get:
|
||||
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.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# WaCRM documentation
|
||||
# Documentation
|
||||
|
||||
WaCRM is a self-hostable WhatsApp CRM built on Next.js and Supabase. These
|
||||
docs walk you from a freshly forked repo to a production deploy.
|
||||
A self-hostable CRM template for WhatsApp built on Next.js and Supabase.
|
||||
These docs walk you from a freshly forked repo to a production deploy.
|
||||
|
||||
## Reading order
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Automations cron
|
||||
|
||||
WaCRM's **Automations** module lets you build flows that react to WhatsApp
|
||||
The **Automations** module lets you build flows that react to WhatsApp
|
||||
events (new message, new contact, keyword match, schedule, etc.). Most
|
||||
steps run inline — the exception is the **Wait** step, which parks the
|
||||
execution in `automation_pending_executions` until its due time.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Deploy on Hostinger
|
||||
|
||||
Hostinger's **[Managed Node.js Hosting](https://www.hostinger.com/web-apps-hosting)**
|
||||
is the recommended way to run WaCRM in production: Hostinger patches the
|
||||
is the recommended way to run this template in production: Hostinger patches the
|
||||
OS and the Node runtime, handles SSL, and gives you a Git-based deploy
|
||||
flow from hPanel. You deploy from your fork without ever opening an SSH
|
||||
session if you don't want to.
|
||||
@ -93,7 +93,7 @@ baked into the client bundle.
|
||||
From the app page, click **Restart application** (or run the equivalent
|
||||
from the terminal). hPanel boots `npm start` behind its own reverse proxy
|
||||
on the domain you configured. Hit the URL in a browser — you should land
|
||||
on the WaCRM marketing page.
|
||||
on the marketing page.
|
||||
|
||||
SSL is provisioned automatically. If you used a subdomain, Hostinger's
|
||||
AutoSSL usually takes a minute or two; until then the site may serve the
|
||||
@ -139,7 +139,7 @@ idempotent.
|
||||
|
||||
## When to reach for a VPS instead
|
||||
|
||||
Managed Node.js covers most WaCRM deploys. Consider
|
||||
Managed Node.js covers most deploys of this template. Consider
|
||||
[Hostinger VPS](https://www.hostinger.com/vps-hosting) if you need:
|
||||
|
||||
- Long-running background workers beyond what the single Next.js process
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Getting started
|
||||
|
||||
Run WaCRM locally in about 15 minutes. This guide assumes Node.js 20+ and
|
||||
Run the template locally in about 15 minutes. This guide assumes Node.js 20+ and
|
||||
npm are already installed.
|
||||
|
||||
## 1. Fork and clone
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
# Supabase setup
|
||||
|
||||
WaCRM uses Supabase for Postgres, authentication, row-level security (RLS),
|
||||
and (optionally) storage. You need one Supabase project per WaCRM
|
||||
deployment.
|
||||
This template uses Supabase for Postgres, authentication, row-level security (RLS),
|
||||
and (optionally) storage. You need one Supabase project per deployment.
|
||||
|
||||
## 1. Create the project
|
||||
|
||||
@ -75,7 +74,7 @@ emails link back correctly.
|
||||
|
||||
## 6. (Optional) Storage
|
||||
|
||||
WaCRM downloads WhatsApp media through Meta's `/download` endpoint and
|
||||
The app downloads WhatsApp media through Meta's `/download` endpoint and
|
||||
currently relays it on demand rather than caching it in Supabase Storage.
|
||||
No bucket setup is required for a default install.
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ Set `NEXT_PUBLIC_SITE_URL` **and** add the same origin to Supabase →
|
||||
### Webhook verification fails in Meta
|
||||
|
||||
- The **verify token** in Meta must match exactly what you saved in
|
||||
**Settings → WhatsApp** inside WaCRM.
|
||||
**Settings → WhatsApp** inside the app.
|
||||
- The callback URL must be reachable without auth. Test it yourself:
|
||||
`curl 'https://crm.example.com/api/whatsapp/webhook?hub.mode=subscribe&hub.verify_token=<token>&hub.challenge=test'`
|
||||
should return `test`.
|
||||
@ -91,7 +91,7 @@ endpoint is fine and the problem is just the schedule.
|
||||
|
||||
### An automation fires twice for the same message
|
||||
|
||||
Most likely two WaCRM instances share one Supabase project and both
|
||||
Most likely two app instances share one Supabase project and both
|
||||
receive the same webhook. The webhook handler deduplicates by Meta's
|
||||
`wamid`, but only within a single deploy — split-brain setups can double
|
||||
up. Either consolidate to one deploy or route the webhook to exactly one.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# WhatsApp setup
|
||||
|
||||
WaCRM talks to the official **WhatsApp Business Cloud API** (Meta). Each
|
||||
This template talks to the official **WhatsApp Business Cloud API** (Meta). Each
|
||||
account stores its own `phone_number_id`, `waba_id`, and encrypted
|
||||
`access_token` — there is no shared app-level token. This page walks
|
||||
through getting those values and wiring the webhook.
|
||||
@ -45,9 +45,9 @@ generate a **System User** access token:
|
||||
- `whatsapp_business_messaging`
|
||||
4. Copy the token. **This is shown only once.**
|
||||
|
||||
## 4. Connect it inside WaCRM
|
||||
## 4. Connect it inside the app
|
||||
|
||||
1. Run WaCRM locally (or open your deployed instance).
|
||||
1. Run the app locally (or open your deployed instance).
|
||||
2. Sign in, then go to **Settings → WhatsApp**.
|
||||
3. Fill in:
|
||||
- **Phone number ID** — from step 3.
|
||||
@ -55,7 +55,7 @@ generate a **System User** access token:
|
||||
- **Access token** — the System User token from step 3.
|
||||
- **Verify token** — any random string you make up; you will paste the
|
||||
same value into Meta in the next step.
|
||||
4. Save. WaCRM encrypts the access token and verify token with your
|
||||
4. Save. The app encrypts the access token and verify token with your
|
||||
`ENCRYPTION_KEY` before writing them to Supabase.
|
||||
|
||||
## 5. Configure the webhook in Meta
|
||||
@ -68,7 +68,7 @@ Under **WhatsApp → Configuration → Webhook**:
|
||||
- Production: `https://<your-domain>/api/whatsapp/webhook`.
|
||||
- **Verify token**: the same string you entered in step 4.
|
||||
- Click **Verify and save**. Meta sends a GET with
|
||||
`hub.challenge` — WaCRM's webhook route decrypts stored verify tokens
|
||||
`hub.challenge` — the app's webhook route decrypts stored verify tokens
|
||||
and echoes the challenge back. If verification fails, double-check the
|
||||
verify token matches and the callback URL is publicly reachable.
|
||||
|
||||
@ -86,7 +86,7 @@ sync on the broadcast UI.
|
||||
## 6. Signature verification (required)
|
||||
|
||||
Set `META_APP_SECRET` to your app's **App Secret** (Meta for Developers →
|
||||
App Settings → Basic). WaCRM validates the `X-Hub-Signature-256` HMAC
|
||||
App Settings → Basic). The app validates the `X-Hub-Signature-256` HMAC
|
||||
on every inbound webhook and **rejects every request if the env var is
|
||||
not set** — anyone who knew the webhook URL could otherwise spoof
|
||||
messages and status updates. Configure it before pointing the webhook
|
||||
@ -96,9 +96,8 @@ at a deployed instance.
|
||||
|
||||
1. From Meta's **API Setup** page, send a test message to a number that is
|
||||
a registered tester.
|
||||
2. Watch the WaCRM Inbox — the message should appear within a second or
|
||||
two.
|
||||
3. Reply from WaCRM; the recipient gets a real WhatsApp message.
|
||||
2. Watch the Inbox — the message should appear within a second or two.
|
||||
3. Reply from the app; the recipient gets a real WhatsApp message.
|
||||
|
||||
If nothing shows up, see [troubleshooting.md](./troubleshooting.md).
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "wacrm",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"description": "Self-hostable WhatsApp CRM built on Next.js and Supabase — shared inbox, contacts, sales pipelines, broadcasts, and no-code automations.",
|
||||
"description": "Self-hostable CRM template for WhatsApp built on Next.js and Supabase — shared inbox, contacts, sales pipelines, broadcasts, and no-code automations.",
|
||||
"license": "MIT",
|
||||
"author": "Arnas Donauskas",
|
||||
"homepage": "https://wacrm.tech",
|
||||
|
||||
@ -52,7 +52,7 @@ export default function LoginPage() {
|
||||
</div>
|
||||
<CardTitle className="text-xl text-white">Welcome back</CardTitle>
|
||||
<CardDescription className="text-slate-400">
|
||||
Sign in to your WaCRM account
|
||||
Sign in to your account
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
||||
@ -102,7 +102,7 @@ export default function SignupPage() {
|
||||
</div>
|
||||
<CardTitle className="text-xl text-white">Create account</CardTitle>
|
||||
<CardDescription className="text-slate-400">
|
||||
Get started with WaCRM
|
||||
Get started with CRM Template for WhatsApp
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
||||
@ -11,11 +11,11 @@ import { decrypt } from '@/lib/whatsapp/encryption'
|
||||
* template locally, try to broadcast with it, and hit Meta's error
|
||||
* #132001 "Template name does not exist in the translation" — because
|
||||
* Meta had never seen the template, or had it approved under a
|
||||
* different language code than what WaCRM stored.
|
||||
* different language code than what we stored locally.
|
||||
*
|
||||
* This route pulls the source of truth (Meta's approved templates)
|
||||
* and upserts them into the local catalog by (user_id, name, language).
|
||||
* After a sync, every template row in WaCRM is guaranteed to match
|
||||
* After a sync, every local template row is guaranteed to match
|
||||
* something Meta will actually accept on send.
|
||||
*
|
||||
* Scope:
|
||||
|
||||
@ -3,9 +3,12 @@ import { DocsShell } from '@/components/docs/shell'
|
||||
import { listDocs } from '@/lib/docs/content'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: { template: '%s — WaCRM Docs', default: 'WaCRM Docs' },
|
||||
title: {
|
||||
template: '%s — CRM Template for WhatsApp Docs',
|
||||
default: 'CRM Template for WhatsApp Docs',
|
||||
},
|
||||
description:
|
||||
'Setup, configuration, and deployment docs for the WaCRM template.',
|
||||
'Setup, configuration, and deployment docs for the CRM Template for WhatsApp.',
|
||||
}
|
||||
|
||||
export default async function DocsLayout({
|
||||
|
||||
@ -16,7 +16,7 @@ export default async function DocsIndexPage() {
|
||||
Documentation
|
||||
</p>
|
||||
<h1 className="mt-2 text-3xl font-bold tracking-tight text-white sm:text-4xl">
|
||||
Self-host WaCRM end to end
|
||||
Self-host the CRM template for WhatsApp end to end
|
||||
</h1>
|
||||
<p className="mt-4 text-base leading-relaxed text-slate-400">
|
||||
Everything you need to take the template from a fresh fork to a
|
||||
|
||||
@ -5,7 +5,7 @@ import { SITE_URL } from '@/lib/seo/site-config'
|
||||
* robots.txt served at /robots.txt. We explicitly disallow every
|
||||
* gated area so crawlers don't spend their budget on pages they'll
|
||||
* bounce off. Auth pages are closed off too — no SEO value, and
|
||||
* we don't want "Sign in to WaCRM" competing with the landing page
|
||||
* we don't want a "Sign in" page competing with the landing page
|
||||
* in SERPs.
|
||||
*/
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
|
||||
@ -32,11 +32,17 @@ export function DocsShell({ pages, children }: DocsShellProps) {
|
||||
>
|
||||
{mobileOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
||||
</button>
|
||||
<Link href="/" className="flex items-center gap-2" aria-label="WaCRM home">
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center gap-2"
|
||||
aria-label="CRM Template for WhatsApp home"
|
||||
>
|
||||
<span className="flex h-8 w-8 items-center justify-center rounded-lg bg-violet-500">
|
||||
<MessageSquare className="h-4 w-4 text-white" />
|
||||
</span>
|
||||
<span className="text-lg font-semibold text-white">WaCRM</span>
|
||||
<span className="text-sm font-semibold text-white">
|
||||
CRM Template for WhatsApp
|
||||
</span>
|
||||
<span className="hidden rounded-md border border-slate-700 bg-slate-900 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-slate-400 sm:inline-block">
|
||||
Docs
|
||||
</span>
|
||||
|
||||
@ -70,7 +70,7 @@ export function FeaturesGrid() {
|
||||
<SectionHeader
|
||||
eyebrow="Everything you need"
|
||||
title="One toolkit for your WhatsApp business"
|
||||
description="Stop stitching together an inbox, a spreadsheet, and a broadcast tool. WaCRM brings them together — and talks to WhatsApp natively."
|
||||
description="Stop stitching together an inbox, a spreadsheet, and a broadcast tool. This CRM template for WhatsApp brings them together — and talks to WhatsApp natively."
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
|
||||
|
||||
@ -7,11 +7,17 @@ export function Footer() {
|
||||
<footer className="border-t border-slate-800 bg-slate-950">
|
||||
<div className="mx-auto grid w-full max-w-7xl grid-cols-2 gap-8 px-6 py-12 sm:grid-cols-5">
|
||||
<div className="col-span-2 sm:col-span-2">
|
||||
<Link href="/" className="flex items-center gap-2" aria-label="WaCRM home">
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center gap-2"
|
||||
aria-label="CRM Template for WhatsApp home"
|
||||
>
|
||||
<span className="flex h-8 w-8 items-center justify-center rounded-lg bg-violet-500">
|
||||
<MessageSquare className="h-4 w-4 text-white" />
|
||||
</span>
|
||||
<span className="text-lg font-semibold text-white">WaCRM</span>
|
||||
<span className="text-sm font-semibold text-white">
|
||||
CRM Template for WhatsApp
|
||||
</span>
|
||||
</Link>
|
||||
<p className="mt-3 max-w-sm text-sm text-slate-500">
|
||||
One toolkit for your WhatsApp business — shared inbox, pipelines,
|
||||
@ -58,7 +64,7 @@ export function Footer() {
|
||||
|
||||
<div className="border-t border-slate-900">
|
||||
<div className="mx-auto flex w-full max-w-7xl flex-col items-start justify-between gap-3 px-6 py-5 text-xs text-slate-500 sm:flex-row sm:items-center">
|
||||
<span>© {year} WaCRM. All rights reserved.</span>
|
||||
<span>© {year} CRM Template for WhatsApp. All rights reserved.</span>
|
||||
<span>Built on the official WhatsApp Business API.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -27,7 +27,9 @@ export function AnalyticsMock() {
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="ml-3 text-[10px] text-slate-500">Dashboard — WaCRM</span>
|
||||
<span className="ml-3 text-[10px] text-slate-500">
|
||||
Dashboard — CRM Template for WhatsApp
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3 p-4">
|
||||
|
||||
@ -47,7 +47,9 @@ export function AutomationMock() {
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="ml-3 text-[10px] text-slate-500">Automations — WaCRM</span>
|
||||
<span className="ml-3 text-[10px] text-slate-500">
|
||||
Automations — CRM Template for WhatsApp
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Dotted canvas — matches the real flow builder's background. */}
|
||||
|
||||
@ -14,7 +14,9 @@ export function InboxMock() {
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="ml-3 text-[10px] text-slate-500">Inbox — WaCRM</span>
|
||||
<span className="ml-3 text-[10px] text-slate-500">
|
||||
Inbox — CRM Template for WhatsApp
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-[180px_1fr] lg:grid-cols-[220px_1fr]">
|
||||
|
||||
@ -34,7 +34,9 @@ export function PipelineMock() {
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-slate-700" />
|
||||
<span className="ml-3 text-[10px] text-slate-500">Pipelines — WaCRM</span>
|
||||
<span className="ml-3 text-[10px] text-slate-500">
|
||||
Pipelines — CRM Template for WhatsApp
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-3 gap-3 p-4">
|
||||
|
||||
@ -60,11 +60,17 @@ export function LandingNav() {
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto flex h-16 w-full max-w-7xl items-center justify-between px-6">
|
||||
<Link href="/" className="flex items-center gap-2" aria-label="WaCRM home">
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center gap-2"
|
||||
aria-label="CRM Template for WhatsApp home"
|
||||
>
|
||||
<span className="flex h-8 w-8 items-center justify-center rounded-lg bg-violet-500">
|
||||
<MessageSquare className="h-4 w-4 text-white" />
|
||||
</span>
|
||||
<span className="text-lg font-semibold text-white">WaCRM</span>
|
||||
<span className="text-sm font-semibold text-white">
|
||||
CRM Template for WhatsApp
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<nav className="hidden items-center gap-8 md:flex">
|
||||
|
||||
@ -12,7 +12,7 @@ export function OpenSource() {
|
||||
<SectionHeader
|
||||
eyebrow="Open source"
|
||||
title="Fork it, brand it, host it"
|
||||
description="WaCRM is a template you can take and make your own. Grab the source on GitHub and self-host — we recommend Hostinger Managed Node.js Hosting for a zero-ops deploy."
|
||||
description="This CRM template for WhatsApp is a template you can take and make your own. Grab the source on GitHub and self-host — we recommend Hostinger Managed Node.js Hosting for a zero-ops deploy."
|
||||
/>
|
||||
|
||||
<div className="mx-auto grid max-w-5xl grid-cols-1 gap-5 md:grid-cols-2">
|
||||
@ -55,7 +55,7 @@ export function OpenSource() {
|
||||
</h3>
|
||||
<p className="mt-1.5 text-sm leading-relaxed text-slate-400">
|
||||
Best fit for this template — connect your forked repo to
|
||||
Managed Node.js Hosting and WaCRM is live in a few minutes. No
|
||||
Managed Node.js Hosting and your CRM is live in a few minutes. No
|
||||
servers to patch.
|
||||
</p>
|
||||
<span className="mt-5 inline-flex items-center gap-1.5 text-sm font-medium text-violet-400 transition-colors group-hover:text-violet-300">
|
||||
|
||||
@ -114,7 +114,9 @@ export function Sidebar({ open = false, onClose }: SidebarProps) {
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-violet-500">
|
||||
<MessageSquare className="h-4 w-4 text-white" />
|
||||
</div>
|
||||
<span className="text-lg font-semibold text-white">WaCRM</span>
|
||||
<span className="text-sm font-semibold text-white">
|
||||
CRM Template for WhatsApp
|
||||
</span>
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@ -214,7 +214,7 @@ export function ProfileForm() {
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Profile</CardTitle>
|
||||
<CardDescription className="text-slate-400">
|
||||
How you show up across WaCRM. Your avatar and name appear in the
|
||||
How you show up across the app. Your avatar and name appear in the
|
||||
header, sidebar, and anywhere your teammates see you.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
@ -56,9 +56,8 @@ export function SessionsCard() {
|
||||
Active sessions
|
||||
</CardTitle>
|
||||
<CardDescription className="text-slate-400">
|
||||
Sign out of every device where you're logged in to WaCRM —
|
||||
including this one. Useful if you lost a laptop or shared your
|
||||
password.
|
||||
Sign out of every device where you're logged in — including
|
||||
this one. Useful if you lost a laptop or shared your password.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
||||
@ -22,7 +22,7 @@ const ORDER: Record<string, { order: number; section: string; description: strin
|
||||
'getting-started': {
|
||||
order: 1,
|
||||
section: 'Setup',
|
||||
description: 'Fork, install, run WaCRM locally in about 15 minutes.',
|
||||
description: 'Fork, install, run the template locally in about 15 minutes.',
|
||||
},
|
||||
'supabase-setup': {
|
||||
order: 2,
|
||||
@ -37,12 +37,12 @@ const ORDER: Record<string, { order: number; section: string; description: strin
|
||||
'environment-variables': {
|
||||
order: 4,
|
||||
section: 'Setup',
|
||||
description: 'Full reference for every env var WaCRM reads.',
|
||||
description: 'Full reference for every env var the app reads.',
|
||||
},
|
||||
'deployment-hostinger': {
|
||||
order: 5,
|
||||
section: 'Deploy',
|
||||
description: 'Ship WaCRM on Hostinger Managed Node.js Hosting.',
|
||||
description: 'Ship the template on Hostinger Managed Node.js Hosting.',
|
||||
},
|
||||
'automations-and-cron': {
|
||||
order: 6,
|
||||
|
||||
@ -11,7 +11,7 @@ export interface FaqItem {
|
||||
export const FAQ_ITEMS: FaqItem[] = [
|
||||
{
|
||||
q: 'Do I need my own WhatsApp Business API access?',
|
||||
a: 'Yes. WaCRM plugs into your existing Meta WhatsApp Business setup — you bring the phone number and access token, we provide the CRM tooling around it. Any Meta-approved BSP (Business Solution Provider) works.',
|
||||
a: 'Yes. This CRM template for WhatsApp plugs into your existing Meta WhatsApp Business setup — you bring the phone number and access token, we provide the CRM tooling around it. Any Meta-approved BSP (Business Solution Provider) works.',
|
||||
},
|
||||
{
|
||||
q: 'Can my whole team share one WhatsApp number?',
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
export const SITE_URL =
|
||||
process.env.NEXT_PUBLIC_SITE_URL?.replace(/\/$/, '') || 'https://wacrm.tech'
|
||||
|
||||
export const SITE_NAME = 'WaCRM'
|
||||
export const SITE_NAME = 'CRM Template for WhatsApp'
|
||||
|
||||
export const SITE_TAGLINE = 'Run your WhatsApp business from one inbox'
|
||||
|
||||
/** Default description — reused by layout metadata and structured data. */
|
||||
export const SITE_DESCRIPTION =
|
||||
'WaCRM is a WhatsApp CRM for small teams: shared inbox, contact hub, sales pipelines, broadcasts, and no-code automations — built on the official WhatsApp Business API.'
|
||||
'A CRM template for WhatsApp built for small teams: shared inbox, contact hub, sales pipelines, broadcasts, and no-code automations — built on the official WhatsApp Business API.'
|
||||
|
||||
/**
|
||||
* Keyword targets. Search engines largely ignore the meta keywords
|
||||
@ -40,7 +40,7 @@ export const OG_IMAGE_ALT = `${SITE_NAME} — ${SITE_TAGLINE}`
|
||||
/** Organization info surfaced in JSON-LD. */
|
||||
export const ORG_INFO = {
|
||||
name: SITE_NAME,
|
||||
legalName: 'WaCRM',
|
||||
legalName: 'CRM Template for WhatsApp',
|
||||
url: SITE_URL,
|
||||
logo: `${SITE_URL}/icon`,
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user