All Leads

Enquiries from WhatsApp, Instagram and website
Live

Enquiries

All channels · click a row to open details
Contact Source Destination Status Package interest Assigned Notes Received

Pipeline

Leads by conversion stage

Hotel & Stay Prices

Base nightly rate · all locations
PropertyTierBase /nightPeak /nightOff /night

Tour Packages

Per-person from prices shown on homepage
PackageRouteDurationBase /personPeak /person

Date-based Price Rules

Overrides applied automatically by date · first matching rule wins
FromToRule name SnowlineFloret HotelAlpine

Change Log

All price updates and lead status changes

System Architecture

How leads flow from each channel to the dashboard — read-only source of truth design
Source 1
WhatsApp Business
Customer sends a message → Zapier catches webhook → appends row to Master Sheet
via Zapier
Source 2
Instagram DMs
DM or comment → Make/Zapier → normalised row → Master Sheet
via Make
Source 3
Website form
Contact form submits → Google Apps Script → appends row to Master Sheet
Apps Script
Source of Truth (owner only)
Master Google Sheet
All leads land here. Protected: automation can only append rows — it cannot edit or delete existing data. Staff have view-only access to this sheet.
Append-only API Owner-protected
↓        ↓
Owner access
This dashboard
Reads Master Sheet via API. Owner can update lead status, add notes, change prices. All writes go back to Master Sheet only — never overwrites raw data.
Password protected
Staff access
Staff Google Sheet
A second sheet that syncs from Master. Staff can only edit: Status, Notes, Assigned-to columns. They cannot delete rows or see raw source data. Changes sync back to Master every 5 min.
No delete permission

Google Apps Script (website form → Master Sheet)

Paste this script in Google Sheets → Extensions → Apps Script. Deploy as Web App (anyone can access). Use the deployment URL as your form's POST endpoint.
function doPost(e) { var data = JSON.parse(e.postData.contents); var sheet = SpreadsheetApp.openById('YOUR_SHEET_ID') .getSheetByName('Leads'); sheet.appendRow([ new Date(), // timestamp data.name, data.phone, data.email, data.destination, data.package, data.message, 'website', // source 'new', // status — automation sets only '', // notes — staff fills this '', // assigned_to ]); return ContentService .createTextOutput(JSON.stringify({status:'ok'})) .setMimeType(ContentService.MimeType.JSON); }

Zapier recipe — WhatsApp Business → Master Sheet

1. Trigger: WhatsApp Business → New Message
2. Action: Google Sheets → Create Spreadsheet Row
3. Map: Sender Name → name · Sender Phone → phone · Message Body → message · set source = "whatsapp" · set status = "new"
4. Turn on the Zap. New WhatsApp enquiries land in Master Sheet automatically.

Protecting the Master Sheet (critical)

In Google Sheets: Data → Protect sheet and ranges
→ Protect columns A–I (all raw capture columns) — only you can edit
→ Allow staff to edit only columns J (Notes), K (Assigned), L (Status)
→ Share the sheet with staff as Editor but with column-level protection above
→ Automation service account gets only appendRow scope — not read/write full sheet

Settings

Change password

Google Sheets integration

Price API Secret

This must match the PRICES_SECRET environment variable set in your Vercel project settings for floret-journeys. The dashboard sends this as a Bearer token when publishing prices.

Staff members

Data

⚠ Unsaved price changes
Phone
Email
Source
Received
Destination
Package
Travel dates
Group size
Budget