"Perfection is an asymptote — we are forever chasing it, forever closing the gap."
Local Borga is a full-stack e-commerce platform connecting customers (local and diaspora) to high-quality Ghanaian foodstuffs, farm equipment, and a bespoke custom milling & production service. Built for intercontinental reach — direct from Accra, Ghana to the world.
Live at: https://local-borga.vercel.app
| Feature | Description |
|---|---|
| 🛒 Fresh Shop | Browse and order from a curated catalog of premium Ghanaian staples |
| 🚜 Farm Tools Store | Dedicated storefront for Ghanaian farming equipment — cutlasses, sprayers, tillers, and more |
| ⚙️ Custom Milling | Commission bespoke milling orders (gari, flours) by weight and texture |
| 📦 Order Tracking | Real-time production status updates via Supabase Realtime |
| 🖨️ Print Labels | Admin-generated printable shipping labels with QR codes |
| 📊 Admin Dashboard | Revenue analytics, live production feed, order status management |
| 🔐 Authentication | Email/password + Google OAuth via Supabase Auth |
| 👤 Customer Accounts | Order history, realtime status updates, profile management |
| 💳 Real Payments | Paystack integration — server-side initialize + verify, no card data touches the server |
| 📱 SMS & WhatsApp | Twilio-powered order confirmations and status updates to customers |
| 📦 Stock Tracking | Live stock levels on every product card — atomic deduction on checkout |
| 🔍 Product Pages | Individual detail pages with parallax hero, quantity selector, related products |
| 🌍 Intercontinental | Designed for both local Ghana orders and diaspora shipping |
Frontend Next.js 16 (App Router) + TypeScript
Styling Tailwind CSS
Animations Framer Motion
UI Components Lucide React, Recharts, Sonner (toasts)
Database Supabase (PostgreSQL)
Realtime Supabase Realtime (postgres_changes)
Auth Supabase Auth (Email + Google OAuth)
Payments Paystack (server-side initialize + verify)
Notifications Twilio (SMS + WhatsApp Business API)
Deployment Vercel
local-borga/
└── web-client/ # Next.js app — deployed to Vercel
├── app/
│ ├── page.tsx # Storefront (hero, catalog, tracking, milling)
│ ├── layout.tsx # Root layout + CartProvider + Toaster
│ ├── globals.css
│ ├── auth/
│ │ ├── page.tsx # Sign in / Sign up (email + Google OAuth)
│ │ └── callback/
│ │ └── route.ts # Supabase OAuth callback handler
│ ├── account/
│ │ └── page.tsx # Customer account — order history + realtime
│ ├── farm-tools/
│ │ └── page.tsx # Farm equipment storefront
│ ├── products/
│ │ └── [id]/
│ │ └── page.tsx # Individual product detail page
│ ├── admin/
│ │ ├── page.tsx # Admin dashboard (orders, analytics)
│ │ ├── login/
│ │ │ └── page.tsx # Admin authentication
│ │ └── components/
│ │ ├── Navbar.tsx
│ │ └── PrintableLabel.tsx
│ └── api/
│ ├── products/
│ │ ├── route.ts # GET all (?section=), POST new
│ │ └── [id]/route.ts # GET, PATCH, DELETE one
│ ├── orders/
│ │ ├── route.ts # GET all, POST new + stock deduction + notify
│ │ └── [id]/route.ts # GET one (tracking), PATCH status + notify
│ ├── payment/
│ │ ├── initialize/route.ts # POST — Paystack transaction init (server-side)
│ │ └── verify/route.ts # POST — Paystack payment verification
│ ├── account/
│ │ └── orders/route.ts # GET orders by userId or email
│ └── admin/
│ └── login/
│ └── route.ts # POST — JWT authentication
├── src/
│ ├── context/
│ │ └── CartContext.tsx # Global cart — SHELF, CUSTOM_MILLING, FARM_TOOL
│ └── lib/
│ ├── notify.ts # Twilio SMS + WhatsApp utility
│ └── supabase/
│ ├── server.ts # Service role client (API routes only)
│ └── browser.ts # Anon client (Realtime subscriptions)
└── public/
└── images/ # Product + farm tool images
└── farm-tools/ # Farm equipment images
- Node.js 18+
- A Supabase project
- A Vercel account
- A Paystack account
- A Twilio account (for SMS + WhatsApp)
git clone https://github.com/your-username/local-borga.git
cd local-borga/web-clientnpm installCreate web-client/.env.local:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_...
SUPABASE_SERVICE_ROLE_KEY=sb_secret_...
# Admin
ADMIN_PASSWORD=your-admin-password
JWT_SECRET=your-long-random-secret
# App
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Paystack
PAYSTACK_SECRET_KEY=sk_live_...
NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY=pk_live_...
# Twilio (SMS + WhatsApp)
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your-auth-token
TWILIO_PHONE_NUMBER=+12345678900
TWILIO_WHATSAPP_NUMBER=+14155238886
ADMIN_PHONE_NUMBER=+233XXXXXXXXXIn the Supabase SQL Editor, run in order:
supabase/setup.sql— createsproductsandorderstables, RLS policies, Realtime publicationsupabase/stock-migration.sql— addsstock_quantitycolumn +deduct_stock()functionsupabase/farm-tools-seed.sql— addssectioncolumn and seeds 12 farm tool products
npm run dev| Column | Type | Notes |
|---|---|---|
id |
serial | Primary key |
name |
text | Product name |
price |
numeric | In USD |
category |
text | e.g. GARI, FLOUR, HAND TOOLS |
description |
text | |
image |
text | Path to /public/images/ |
is_premium |
boolean | Shows "Limited Edition" / "Premium" badge |
section |
text | staples or farm_tools |
stock_quantity |
integer | Decremented atomically on order |
created_at |
timestamptz |
| Column | Type | Notes |
|---|---|---|
id |
bigserial | Primary key / tracking ID |
item_name |
text | |
order_type |
text | shelf, custom_milling, farm_tool |
milling_style |
text | Fine / Medium / Coarse |
weight_kg |
numeric | |
total_price |
numeric | |
status |
text | pending → milling → completed → shipped |
cart_items |
jsonb | Array of {name, quantity, price} |
customer_name |
text | |
customer_email |
text | |
customer_phone |
text | E.164 format — used for SMS + WhatsApp |
shipping_address |
jsonb | {address, city, country} |
user_id |
uuid | Links to Supabase Auth user |
paystack_reference |
text | For payment reconciliation |
created_at |
timestamptz |
Deployed on Vercel from the repo root with vercel.json:
{
"framework": "nextjs",
"installCommand": "cd web-client && npm install",
"buildCommand": "cd web-client && npm run build",
"outputDirectory": "web-client/.next"
}All environment variables must be added to Vercel's project settings.
Admin updates order status
→ PATCH /api/orders/[id]
→ Supabase saves row
→ Supabase broadcasts UPDATE event
→ supabaseBrowser.channel() receives payload
→ Customer sees toast + account page row updates live
→ Twilio fires SMS + WhatsApp to customer's phone
Customer clicks Pay
→ POST /api/payment/initialize (secret key stays server-side)
→ Paystack popup opens in secure iframe
→ Customer pays
→ POST /api/payment/verify (amount + reference verified server-side)
→ POST /api/orders (order created only after verified)
→ Stock deducted atomically via deduct_stock()
→ SMS + WhatsApp confirmation sent to customer
→ SMS alert sent to admin
| Event | Customer | Admin |
|---|---|---|
| Order placed | ✅ SMS + WhatsApp | ✅ SMS |
| Status updated | ✅ SMS + WhatsApp | — |
Notifications are non-blocking — if Twilio is unconfigured or fails, orders complete normally.
- Phase I: Storefront, catalog, custom milling, order tracking
- Phase II: Auth, accounts, Paystack payments, stock tracking, product pages, SMS/WhatsApp
- Bonus: Farm Tools storefront
- Phase III: Shipping rate calculator (local + international)
- Phase III: Product filtering and search on detail pages
- Phase III: WhatsApp Business dedicated sender (production)
- Phase III: Paystack webhooks for async payment reconciliation
Cosmos Kyeremeh — Local Borga Executive Accra, Ghana
Built with obsessive attention to detail. © 2025 Local Borga.
