Found in Stripe Dashboard โ Developers โ API Keys. Never share this key.
Deal Adjustments
Target Dates
Internal Notes
Changes update totals immediately. Save to persist.
Fertigation Skid
Precision Irrigation
Control Panels & Modules
Sensors & Monitoring
Panels (Hardware)
Shipping
Commissioning
Data Platform ($/point/month)
Products are stored in Supabase. Changes here update pricing for all users instantly.
Category
Product Name
SKU
Price ($)
Active
Microsoft SSO Configuration
Configure Microsoft OAuth so your team can sign in with their work accounts.
Uses Supabase Auth โ no extra backend needed.
Azure Portal โ App Registrations โ your app โ Application (client) ID.
Open Azure Portal โ
Azure Portal โ Microsoft Entra ID โ Overview โ Tenant ID (the UUID shown there)
Azure App Registration setup:
1. Azure Portal โ Microsoft Entra ID โ App registrations โ your app โ Authentication
2. Add Redirect URI โ Single-page application (SPA) โ
3. Also add Supabase callback URL in Azure (from Supabase Auth โ Providers โ Azure)
4. Azure โ Overview โ copy Application (client) ID and Directory (tenant) ID
5. Paste both above, set Tenant URL in Supabase to https://login.microsoftonline.com/YOUR-TENANT-ID/
Supabase Connection
SQL Setup
Run in Supabase SQL Editor:
create extension if not exists "pgcrypto";
create table if not exists proposals (
id uuid default gen_random_uuid() primary key,
created_at timestamptz default now(),
updated_at timestamptz default now(),
project_name text, company_name text, account_executive text,
status text default 'draft' check (status in ('draft','sent','accepted','declined','expired')),
grand_total numeric(12,2), monthly_fee numeric(10,2),
payload jsonb not null default '{}'::jsonb
);
create index if not exists proposals_status_idx on proposals(status);
create index if not exists proposals_ae_idx on proposals(account_executive);
create index if not exists proposals_created_idx on proposals(created_at desc);
create table if not exists price_config (
id uuid default gen_random_uuid() primary key,
updated_at timestamptz default now(), updated_by text,
prices jsonb not null default '{}'::jsonb
);
create unique index if not exists price_config_one on price_config((true));
insert into price_config(updated_by,prices) values('system','{}') on conflict do nothing;
create or replace function set_updated_at() returns trigger as $$
begin new.updated_at=now(); return new; end; $$ language plpgsql;
drop trigger if exists t_prop_upd on proposals;
create trigger t_prop_upd before update on proposals for each row execute function set_updated_at();
drop trigger if exists t_price_upd on price_config;
create trigger t_price_upd before update on price_config for each row execute function set_updated_at();
alter table proposals enable row level security;
alter table price_config enable row level security;
drop policy if exists "open" on proposals;
drop policy if exists "open" on price_config;
create policy "open" on proposals for all using(true) with check(true);
create policy "open" on price_config for all using(true) with check(true);
-- Product Catalog table
create table if not exists product_catalog (
id uuid default gen_random_uuid() primary key,
created_at timestamptz default now(),
category text not null,
name text not null,
sku text,
price numeric(10,4) default 0,
active boolean default true
);
create index if not exists catalog_category_idx on product_catalog(category);
alter table product_catalog enable row level security;
drop policy if exists "open" on product_catalog;
create policy "open" on product_catalog for all using(true) with check(true);
-- Proposal templates table
create table if not exists proposal_templates (
id uuid default gen_random_uuid() primary key,
created_at timestamptz default now(),
updated_at timestamptz default now(),
template jsonb not null default '{}'::jsonb
);
alter table proposal_templates enable row level security;
drop policy if exists "open" on proposal_templates;
create policy "open" on proposal_templates for all using(true) with check(true);
-- Supabase Storage bucket for proposal images
-- Run this in the Supabase Dashboard > Storage > New bucket:
-- Name: proposal-images | Public: true
create or replace view proposals_summary as
select id, created_at, updated_at, project_name, company_name, account_executive,
status, grand_total, monthly_fee,
coalesce(jsonb_array_length(payload->'rooms'),0) as room_count,
coalesce(jsonb_array_length(payload->'skids'),0) as skid_count
from proposals order by created_at desc;
Saved Proposals
Click โป Refresh List above.
Grow Rooms
Add and configure each grow room or zone
Editing Room
I/O Points
Monitoring
Panel
Equipment
DO
Light Dim
AO
Relay
Contactor
RIB
DI
AI
PAR
SI
TO
BACnet Pts
Type
TOTALS
0
0
0
0
0
0
0
0
0
0
0
0
Tank Monitoring
Fertigation Skids
Configure each nutrient delivery skid independently
Editing Skid
Monitoring Equipment
Extras / Miscellaneous
Additional line items
Extra Items
Description
SKU
Qty
Unit Price
Total
Bill of Materials
Complete hardware & pricing breakdown
Project Handoff
Information for the delivery team
Documents & Drawings
Handoff Notes
Pipeline Dashboard
Live from Supabase
Total Proposals
โ
Pipeline Value
โ
Accepted Value
โ
Avg Deal Size
โ
Est. MRR
โ
Total Rooms
โ
Revenue by Status
Pipeline by AE
Monthly Closed Value
Status Breakdown
All Proposals
HubSpot CRM
Search deals and import contact & company info directly into this project
Supabase Edge Function Proxy (required โ HubSpot blocks direct browser requests)
Deploy this Edge Function once to your Supabase project, then paste the URL below.
It proxies requests to HubSpot so the browser CORS restriction is bypassed.
Customize your proposal template โ add sections, images, and content before saving as PDF
Proposal Sections
Drag to reorder. Toggle visibility. Each section appears in the final PDF.
Image Library
Upload images to Supabase Storage for use in proposals. Images are stored per-account.
Preview & Export
To export as PDF: click Preview, then use your browser's Print โ Save as PDF function.
Cin7 Core Invoicing
Create sales orders and invoices directly in Cin7 Core from this proposal
Cin7 Core Connection
Get these from Cin7 Core โ Settings โ API โ inventory.dearsystems.com/ExternalAPI. Create a new Application and copy the Account ID and Application Key.
Product SKU Mapping
Map Growlink product SKUs to your Cin7 product codes. These are used when creating line items on the invoice.
Category
Growlink Product
Growlink SKU
Cin7 Product Code
Tax Rule
Account Code
Invoice Settings
Invoice Preview
Review what will be sent to Cin7 before creating the invoice.
Click "Preview Invoice" to see the line items that will be sent to Cin7.
Invoices for this Project
No invoices created yet for this project.
Hardware$0
Ship & Comm$0
Grand Total$0
Growlink Pro/mo$0/mo
0 Rooms0 Skids
Add Grow Room
Add Fertigation Skid
Configure Grow Room
Customer Proposal
Welcome back
Sign in with your Growlink Microsoft account to access the IO Sheet tool.