Hotel payables ยท Guide payments ยท Expenses ยท Cash position
Hotels Outstanding
โ
โ hotels unpaid
Guides Outstanding
โ
โ guides unpaid
Expenses This Month
โ
โ transactions
Total Paid (Hotels)
โ
all time
Total Outstanding
โ
hotels + guides
๐งพ Add Expense
๐ฆ Guide Payment Record
Payments Made
๐ต Add Sales Entry
Deposits / Payments Received
๐
GOWILD
Safari & Tour Platform
Operator PIN
I'm a client โ Plan my safari โ
0
Trips
0
Active
0
Vouchers Sent
0
Hotels Confirmed
0
Awaiting Reply
๐
No trips yet โ click New Trip to get started.
On SafariAvailableConflict โ Unassigned
โ ๏ธ Trips Without Guide Assigned
โ New Trip Reservation
๐ Trip Details
๐จ Hotel Bookings
No hotels added yet
๐ฏ Activities & Logistics
๐งช AI Safari Consultant Lab
Admin only โ testing environment. Will not affect clients.
👋 AI Safari Consultant โ Lab Mode.
Try: "2 nights Amboseli Sopa, 1 night Nakuru, 2 nights Masai Mara, Land Cruiser, 4 adults, evening game drives"
Quick Mara 3NClassic Kenya 7NTanzania CircuitAmboseli + Mara
When AI fills the calculator, switch to the Calculator tab to see the result. The AI uses your lodge library to match rates.
๐ฆ Guide Assignment
Guide Legs
Pick Guide to Add
0
Total Guides
0
Languages
0
Avg. Years Exp.
0
Active
๐
No guides yet โ click Add New Guide to get started.
Plan Your Dream Safari
Build your personalised safari quote in minutes โ choose your destinations, lodge, vehicle and activities.
1 Destination
2 Dates & Guests
3 Lodge
4 Vehicle
5 Activities
6 Your Quote
Where would you like to go?
Select one or more destinations for your safari.
Who's travelling?
Tell us how many guests and your preferred start date. You'll choose lodges and set the nights at each property in the next step.
Optional โ you can leave this blank for now
How many guests?
Choose the number of travellers in each age group.
2
0
0
Choose your accommodation
For each destination, pick a lodge and set how many nights you'd like to stay. Your total trip duration is calculated automatically.
Total Duration
0 nights ยท 1 day
Estimated Total
โ
Select your safari vehicle
Your private vehicle will be dedicated exclusively to your group.
What experiences would you like?
Select optional activities to add to your safari.
๐
Thank you! Your enquiry has been sent.
Our team will review your safari plan and get back to you within 24 hours with a personalised itinerary and confirmation.
Your Safari Quote
Here's a summary of your personalised safari package.
Your Details
We'll respond within 24 hours with your full personalised itinerary
Estimated Total
โ
โ๏ธ Crop Your Photo
Drag to reposition ยท Corners to resize ยท Frame = 3:2 (1200ร800px) โ the exact size used in PDFs
1200 ร 800 px
๐ Orange frame = exact area that will be saved (3:2 ratio, landscape)
Drag the frame to choose the best part of the photo ยท The frame always keeps 3:2 ratio
>
๐ฆ
Install GOWILD
Add to home screen ยท Works offline
๐ Vehicle Library
Add and price your vehicle types. The daily rate will be auto-filled when selected.
๐ฟ Park Library
Define parks with seasonal rates. Leave date range blank for a fixed rate year-round.
๐๏ธ Lodge Library
Define lodges / camps with seasonal rates. Leave date range blank for a fixed rate.
๐ฏ Activity Library
Define your standard activities and costs. When adding activities to a park, select from this library to auto-fill the name and price.
๐ข Company Management
Companies
Company Details
โ New Guide
๐งโ๐ฆฑ
โ โ โ โ โ
โ New Lead
$
๐ณ Payment Tracking
$
Date
Method
Gross Amount
Net
No payments recorded yet
Total Received (Net)โ
Total Packageโ
Progress
0%
Balance Remainingโ
๐จ Hotel Booking Status
No hotels added yet โ click ๏ผ Add Hotel
๐๏ธ Connect to Supabase Database
Step 1 โ Create your free Supabase project
Go to supabase.com โ click Start your project โ sign in with GitHub
Click New Project, name it safari-calculator, set a password, choose region nearest to you (e.g. Frankfurt)
Wait ~2 minutes for it to set up
Step 2 โ Create your database tables
In your Supabase dashboard, go to SQL Editor โ click New Query, paste the SQL below and click Run:
CREATE TABLE quotes (
id bigserial PRIMARY KEY,
created_at timestamptz DEFAULT now(),
client text,
destination text,
guests int,
days int,
currency text,
total_label text,
total_raw numeric,
guest_mode text,
breakdown jsonb
);
CREATE TABLE vehicle_library (
id bigserial PRIMARY KEY,
name text NOT NULL,
rate numeric NOT NULL DEFAULT 0,
image_url text DEFAULT ''
);
CREATE TABLE park_library (
id bigserial PRIMARY KEY,
name text NOT NULL,
location text,
seasons jsonb NOT NULL DEFAULT '[]',
website text DEFAULT '',
image_url text DEFAULT '',
description text DEFAULT ''
);
CREATE TABLE accom_library (
id bigserial PRIMARY KEY,
name text NOT NULL,
location text,
seasons jsonb NOT NULL DEFAULT '[]',
website text DEFAULT '',
image_url text DEFAULT '',
description text DEFAULT ''
);
CREATE TABLE activity_library (
id bigserial PRIMARY KEY,
name text NOT NULL,
category text NOT NULL DEFAULT 'Other',
cost numeric NOT NULL DEFAULT 0
);
-- Allow public read/write (fine for private use)
ALTER TABLE quotes ENABLE ROW LEVEL SECURITY;
ALTER TABLE vehicle_library ENABLE ROW LEVEL SECURITY;
ALTER TABLE park_library ENABLE ROW LEVEL SECURITY;
ALTER TABLE accom_library ENABLE ROW LEVEL SECURITY;
ALTER TABLE activity_library ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all" ON quotes FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY "Allow all" ON vehicle_library FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY "Allow all" ON park_library FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY "Allow all" ON accom_library FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY "Allow all" ON activity_library FOR ALL USING (true) WITH CHECK (true);
CREATE TABLE crm_leads (
id bigserial PRIMARY KEY,
created_at timestamptz DEFAULT now(),
name text NOT NULL,
phone text DEFAULT '',
email text DEFAULT '',
destination text DEFAULT '',
travel_date date,
group_size int,
budget numeric,
source text DEFAULT '',
stage text NOT NULL DEFAULT 'New Lead',
followup_date date,
followup_note text DEFAULT '',
notes jsonb DEFAULT '[]',
linked_quote jsonb,
currency text DEFAULT 'USD'
);
ALTER TABLE crm_leads ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all" ON crm_leads FOR ALL USING (true) WITH CHECK (true);
-- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-- MULTI-TENANT SCHEMA (run once in Supabase SQL editor)
-- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-- 1. Companies table
CREATE TABLE IF NOT EXISTS companies (
id bigserial PRIMARY KEY,
created_at timestamptz DEFAULT now(),
name text NOT NULL,
pin text NOT NULL UNIQUE,
email text DEFAULT '',
phone text DEFAULT '',
website text DEFAULT '',
address text DEFAULT '',
logo text DEFAULT '',
primary_color text DEFAULT '#c8933a',
plan text DEFAULT 'starter',
active boolean DEFAULT true
);
-- Insert your own company first (admin plan shows Admin panel)
INSERT INTO companies (name, pin, plan, active)
VALUES ('My Safari Company', '1234', 'admin', true)
ON CONFLICT (pin) DO NOTHING;
-- 2. Add company_id to all tables
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
ALTER TABLE guides ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
ALTER TABLE quotes ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
ALTER TABLE vehicle_library ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
ALTER TABLE park_library ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
ALTER TABLE accom_library ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
ALTER TABLE activity_library ADD COLUMN IF NOT EXISTS company_id bigint REFERENCES companies(id);
-- 3. RLS policies (one per table โ filters by company_id)
ALTER TABLE crm_leads ENABLE ROW LEVEL SECURITY;
ALTER TABLE guides ENABLE ROW LEVEL SECURITY;
ALTER TABLE reservations ENABLE ROW LEVEL SECURITY;
ALTER TABLE quotes ENABLE ROW LEVEL SECURITY;
ALTER TABLE vehicle_library ENABLE ROW LEVEL SECURITY;
ALTER TABLE park_library ENABLE ROW LEVEL SECURITY;
ALTER TABLE accom_library ENABLE ROW LEVEL SECURITY;
ALTER TABLE activity_library ENABLE ROW LEVEL SECURITY;
-- Allow all for now (app-level filtering handles isolation)
-- Tighten with JWT claims for production
CREATE POLICY IF NOT EXISTS "company_access" ON crm_leads FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY IF NOT EXISTS "company_access" ON guides FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY IF NOT EXISTS "company_access" ON reservations FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY IF NOT EXISTS "company_access" ON quotes FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY IF NOT EXISTS "company_access" ON vehicle_library FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY IF NOT EXISTS "company_access" ON park_library FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY IF NOT EXISTS "company_access" ON accom_library FOR ALL USING (true) WITH CHECK (true);
CREATE POLICY IF NOT EXISTS "company_access" ON activity_library FOR ALL USING (true) WITH CHECK (true);
-- Add deposit & hotel tracking columns (run if table already exists)
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS total_cost numeric;
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS deposit_amt numeric;
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS deposit_date date;
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS payment_note text DEFAULT '';
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS payment_method text DEFAULT 'Bank Transfer';
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS surcharge_pct numeric DEFAULT 0;
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS paid_by text DEFAULT '';
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS pay_ref text DEFAULT '';
ALTER TABLE crm_leads ADD COLUMN IF NOT EXISTS hotels jsonb DEFAULT '[]';
CREATE TABLE IF NOT EXISTS guides (
id bigserial PRIMARY KEY,
created_at timestamptz DEFAULT now(),
name text NOT NULL,
status text DEFAULT 'Active',
years int DEFAULT 0,
languages text[] DEFAULT '{}',
specialities text[] DEFAULT '{}',
region text DEFAULT '',
parks text DEFAULT '',
phone text DEFAULT '',
email text DEFAULT '',
bio text DEFAULT '',
rating int DEFAULT 5,
photo text DEFAULT ''
);
ALTER TABLE guides ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all" ON guides FOR ALL USING (true) WITH CHECK (true);
CREATE TABLE IF NOT EXISTS reservations (
id bigserial PRIMARY KEY,
created_at timestamptz DEFAULT now(),
group_name text NOT NULL,
trip_ref text DEFAULT '',
arrival_date date,
departure_date date,
vehicle text DEFAULT '',
agent text DEFAULT '',
flight_in text DEFAULT '',
flight_out text DEFAULT '',
status text DEFAULT 'Planning',
hotel_bookings jsonb DEFAULT '[]',
transport text DEFAULT '',
transfers text DEFAULT '',
balloon text DEFAULT '',
meals text DEFAULT '',
remarks text DEFAULT ''
);
ALTER TABLE reservations ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all" ON reservations FOR ALL USING (true) WITH CHECK (true);
-- Guide dispatch columns
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS assigned_guide text;
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS assigned_guide_id text;
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS guide_legs jsonb DEFAULT '[]';
-- Storage bucket for lodge & park photos
INSERT INTO storage.buckets (id, name, public)
VALUES ('safari-photos', 'safari-photos', true)
ON CONFLICT DO NOTHING;
CREATE POLICY "Allow all safari-photos"
ON storage.objects FOR ALL
USING (bucket_id = 'safari-photos')
WITH CHECK (bucket_id = 'safari-photos');
Step 3 โ Get your API keys
In Supabase dashboard โ Project Settings โ API โ copy your Project URL and anon public key below:
โ ๏ธ The anon key is safe to use here โ it only has the permissions you set in the SQL above. Never paste your service_role key.