Lesar Consults Website - Technical Documentation Guide

A technical guide for developers who may maintain the codebase of the website, CTOs and IT teams working for Lesar Consults.

https://www.lesarconsults.org/arrow-up-right

1. High-Level System Overview

The website code is hosted on GitHub in the repository below. Kindly email [email protected] for access to this repository.

1.1 What the Website Does

Lesar Consults is a professional consultancy firm website serving two primary purposes:

  • Public-facing platform: Showcases services, team, projects, and resources for potential clients and partners

  • Admin dashboard: Enables content management, lead tracking, and resource publishing

1.2 Core Features

Feature
Description

Service Showcase

Seven specialized consultancy services with detailed pages

Team Profiles

Individual team member profiles with education, expertise, and project history

Project Portfolio

Featured and archived projects with metrics and achievements

Resource Library

Gated and ungated downloadable resources (reports, tools, case studies)

Contact Wizard

Multi-step form with file uploads and email notifications

Admin Dashboard

Lead management, resource editing, analytics overview

1.3 User Flows

Public Users:

Admin Users:

1.4 Architecture Diagram


2. Technology Stack

2.1 Frontend Framework

Technology
Version
Purpose

React

18.3.1

UI component library

TypeScript

5.x

Type-safe JavaScript

Vite

5.x

Build tool and dev server

Why React + Vite: Fast development iteration with HMR, excellent TypeScript support, and optimised production builds.

2.2 Styling System

Technology
Purpose

Tailwind CSS

Utility-first styling

tailwindcss-animate

Animation utilities

shadcn/ui

Pre-built component library

CSS Variables

Design token system

Design System Colors (from index.css):

  • --navy: 227 57% 19% (#162356) - Primary brand color

  • --cream: 37 65% 91% (#FAEED4) - Secondary background

  • --dark-red: 0 50% 33% (#8B1E1E) - Accent color

2.3 Routing

Package
Purpose

react-router-dom

Client-side routing

Routes are defined in App.tsx with protected routes using ProtectedRoute component.

2.4 Backend Services (Supabase)

Service
Usage

PostgreSQL Database

Leads, resources, profiles tables

Supabase Auth

Admin authentication

Storage

File uploads (leads-uploads, resources buckets)

Edge Functions

Signed URLs, email forwarding

2.5 Email System

  • Edge function send-lead-email forwards lead data to an external webhook (n8n on Railway)

  • Non-blocking: Email failures don't prevent form submission

2.6 Deployment

Platform
Purpose

Vercel

Frontend hosting with analytics

Supabase Cloud

Backend hosting

Configuration files: vercel.json, public/_redirects


3. Frontend Architecture

3.1 Folder Structure

3.2 Component Categories

Page Components (src/pages/):

  • Full-page layouts with SEO metadata

  • Compose multiple UI components

  • Handle data fetching

Layout Components:

  • Navbar.tsx: Responsive navigation with dropdown menus

  • Footer.tsx: Site footer with newsletter signup

  • AdminLayout.tsx: Admin sidebar and header

Feature Components:

  • ContactWizard.tsx: Multi-step form orchestrator

  • ResourceEditor/index.tsx: Rich text editor for resources

UI Primitives (src/components/ui/):

  • Button, Card, Dialog, Input, etc.

  • Built on Radix UI primitives

  • Styled with Tailwind CSS

3.3 Styling Conventions


4. Page-by-Page Breakdown

4.1 Home Page (/)

File: src/pages/Index.tsx

Components:

  • Hero: Full-width hero with CTA buttons

  • PartnersMarquee: Animated logo carousel

  • ServicesStrip: Service overview cards

  • Counters: Animated impact statistics

  • FeaturedCase: Highlighted project

  • ResourcesGrid: Latest resources preview

  • WhyChoose: Value propositions

Data Source: Static imports, Supabase for resources

4.2 About Page (/about)

File: src/pages/About.tsx

Components:

  • AboutHero: Hero with headline from JSON

  • ValuesGrid: Company values cards

  • ApproachTimeline: Methodology steps

  • Image3DCarousel: Work showcase

  • QASection: Quality assurance points

  • PartnersMarquee: Client logos

Data Source: src/data/about.json

4.3 Services Page (/services)

File: src/pages/Services.tsx

Features:

  • Service grid with alternating layouts

  • Icon mapping for each service type

  • Links to individual service detail pages

Data Source: src/data/services.json

4.4 Team Page (/team)

File: src/pages/Team.tsx

Components:

  • TeamGrid: Grid of team member cards

  • Timeline: Company milestones

  • Links to individual member profiles

Data Source: src/data/team.json, src/data/milestones.json

4.5 Projects Page (/projects)

File: src/pages/Projects.tsx

Features:

  • Featured projects with full details

  • Additional projects in card grid

  • Metrics and achievements display

  • Download button for certain projects

Data Source: src/data/projects.json

4.6 Resources Page (/resources)

File: src/pages/Resources.tsx

Features:

  • Search and filter functionality

  • Category scroller

  • Type and year filters

  • Resource cards with thumbnails

Data Source: Supabase resources table

4.7 Contact Page (/contact)

File: src/pages/Contact.tsx

Contains ContactWizard component (detailed in Section 5).

4.8 Admin Dashboard (/admin/dashboard)

File: src/pages/admin/AdminDashboard.tsx

Features:

  • Statistics cards (resources, leads, downloads)

  • Recent activity feed

  • Quick action links

Data Source: Supabase queries on mount

4.9 Admin Leads (/admin/leads)

File: src/pages/admin/AdminLeads.tsx

Features:

  • Lead table with search/filter

  • Export to PDF, CSV, Excel

  • Lead detail modal with file attachments

  • Delete with cascade (files + records)


5. Contact Wizard (Detailed)

5.1 Wizard Structure

Main Component: src/components/contact/ContactWizard.tsx

Step Components (src/components/contact/steps/):

Step
Component
Purpose

1

StepOne.tsx

Full name collection

2

StepTwo.tsx

Organization and role

3

StepThree.tsx

Email and phone with country code

4

StepFour.tsx

Service selection and project description

5

StepFive.tsx

Budget, timeframe, file uploads

6

StepSix.tsx

Privacy consent

5.2 State and Validation

Form State Shape (TypeScript interface):

Validation Rules (isStepValid() function):

Step
Validation

1

fullName.length > 0

2

organization.length > 0

3

Valid email regex + phone length > 0

4

At least one service + description filled

5

Timeframe selected

6

Consent checkbox checked

Submission Guards:

  • isSubmitting state prevents double-submission

  • isSubmitted flag disables button after success

5.3 Submission Flow (End-to-End)

1

Submit Request: create lead record

  1. User clicks "Submit Request".

  2. Generate client-side UUID for lead_id.

  3. INSERT into leads table (lead record stored).

2

Upload files (for each file)

  1. Request signed upload URL from Edge Function (create-signed-url).

  2. PUT file directly to the signed upload URL.

  3. Request signed download URL from Edge Function (get-signed-download-url).

  4. INSERT a record into leads_uploads with file_path (and store signed URL as file_url if needed).

3

Post-submit notifications and UX

  1. Invoke send-lead-email Edge Function (non-blocking).

  2. Show success toast to user.

  3. Navigate to SuccessOptions component.

Error Handling:

  • File upload failures are logged but don't block submission.

  • Email failures are caught and logged silently.

  • Database errors show a user-friendly toast.


6. Supabase Database Schema

6.1 Tables

leads - Contact form submissions

Column
Type
Purpose

id

UUID (PK)

Unique identifier

name

TEXT

Contact name

email

TEXT

Email address

organization

TEXT

Company/institution

role

TEXT

Job title

phone

TEXT

Phone number

country_code

TEXT

Phone country code

interested_in

TEXT

Selected services

other_service

TEXT

Custom service input

message

TEXT

Project description

budget

TEXT

Budget range

timeframe

TEXT

Project timeline

resource_id

UUID (FK)

If download-gated lead

consent

BOOLEAN

Privacy consent

created_at

TIMESTAMPTZ

Submission timestamp

leads_uploads - File attachments

Column
Type
Purpose

id

UUID (PK)

Unique identifier

lead_id

UUID (FK)

Parent lead reference

file_url

TEXT

Signed download URL

file_path

TEXT

Storage path for deletion

created_at

TIMESTAMPTZ

Upload timestamp

resources - Content items

Column
Type
Purpose

id

TEXT (PK)

Slug-based identifier

slug

TEXT

URL-friendly identifier

title

TEXT

Resource title

summary

TEXT

Short description

content_html

TEXT

Rich text content

categories

TEXT[]

Category array

tags

TEXT[]

Tag array

type

TEXT

article/case_study/report/tool/download

thumbnail_url

TEXT

Cover image URL

file_url

TEXT

Downloadable file URL

author

TEXT

Content author

published_at

TIMESTAMPTZ

Publication date

year

INTEGER

Publication year

featured

BOOLEAN

Featured flag

seo

JSONB

SEO metadata

profiles - Admin users

Column
Type
Purpose

id

UUID (PK, FK to auth.users)

User ID

is_admin

BOOLEAN

Admin privilege flag

6.2 Relationships


7. Supabase Storage and Signed URLs

7.1 Why Signed URLs

  • Security: Prevent direct bucket access

  • Expiration: URLs expire after 1 hour

  • Audit Trail: Track who requested access

  • RLS Bypass: Service role generates URLs server-side

7.2 Upload Flow

1

Request signed upload URL

Client: POST /functions/v1/create-signed-url Body: { bucket: "leads-uploads", filename: "doc.pdf" }

2

Edge Function generates upload URL

Edge Function: createSignedUploadUrl(object_path, 3600) (service role). Response: { upload_url: "...", object_path: "leads/12345_doc.pdf" }

3

Client uploads file

Client: PUT file directly to upload_url. Storage: File saved to bucket at returned object_path.

7.3 Download Flow

1

Request signed download URL

Client: POST /functions/v1/get-signed-download-url Body: { bucket: "leads-uploads", object_path: "leads/12345_doc.pdf" }

2

Edge Function returns signed URL

Edge Function: createSignedUrl(object_path, 3600) Response: { signed_download_url: "..." }

3

Client uses signed URL

Client: Open signed_download_url in new tab (or link for admin).

7.4 File Path Generation


8. Supabase Edge Functions

8.1 create-signed-url

Purpose: Generate pre-signed upload URL Location: supabase/functions/create-signed-url/index.ts

Input:

Output:

Called: During ContactWizard file upload step

8.2 get-signed-download-url

Purpose: Generate pre-signed download URL Location: supabase/functions/get-signed-download-url/index.ts

Input:

Output:

Called: During file upload (for record) and admin file viewing

8.3 send-lead-email

Purpose: Forward lead data to email notification service Location: supabase/functions/send-lead-email/index.tsx

Flow:

1
  1. Receive lead payload from client.

2
  1. Forward to RAILWAY_WEBHOOK_URL (n8n) for processing.

3
  1. n8n sends email via configured provider.

Called: After successful lead insert (non-blocking)


9. Email System

9.1 Architecture

9.2 Template Mapping

The lead data object passed to the webhook contains:

  • name, email, organization, role

  • phone, country_code

  • interested_in, other_service

  • message, budget, timeframe

  • consent, id

n8n transforms this into email templates.

9.3 Error Handling

9.4 Non-Blocking Design

Email failures are logged and follow best-effort, they don't prevent:

  • Lead database record creation

  • File uploads

  • User success feedback


10. Admin Dashboard

10.1 Route Protection

File: src/components/admin/ProtectedRoute.tsx

Logic (stepper):

1
  1. Check AuthContext loading state.

2
  1. If loading > 200ms, show skeleton/loading UI.

3
  1. If not loading and no user, redirect to /admin/login.

4
  1. If requireAdmin prop is true and !isAdmin, show "Access Denied".

5
  1. Otherwise, render children.

10.2 Authentication Flow

File: src/contexts/AuthContext.tsx

Flow (stepper):

1
  1. On mount: supabase.auth.getSession() to initialize session.

2
  1. Listen to onAuthStateChange() for auth updates.

3
  1. On user change: call checkAdminStatus(userId) which queries profiles table for is_admin flag.

4
  1. Expose context values: user, session, isAdmin, signIn, signOut.

10.3 Lead Data Access

AdminLeads.tsx:

File Attachment Access:

10.4 Export Features

Format
Library

PDF

jsPDF

CSV

XLSX

Excel

XLSX


11. JSON-Driven Content

11.1 Team Page

File: src/data/team.json

Structure:

Rendering:

11.2 Services Page

File: src/data/services.json

Structure:

11.3 Projects Page

File: src/data/projects.json

Rendering:

11.4 About Page

File: src/data/about.json

Contains: hero content, whoWeAre paragraphs, values, approach steps, qualityAssurance, carousel slides.

11.5 Benefits of JSON-Driven Content

  • No database dependency for static content

  • Version controlled content changes

  • Fast build-time imports

  • Easy content updates without code changes

  • Type-safe with TypeScript interfaces


12. Routing and Access Control

12.1 Route Definitions

File: src/App.tsx

12.2 Authentication Checks

  • ProtectedRoute wraps admin pages

  • requireAdmin prop enforces is_admin flag check

  • Unauthenticated users redirect to /admin/login

  • Non-admin authenticated users see "Access Denied"

12.3 Redirect Behavior

Condition
Behavior

Unauthenticated + admin route

Redirect to /admin/login

Authenticated + /admin/login

Redirect to /admin/dashboard

Not admin + requireAdmin route

Show "Access Denied"


13. Environment Configuration

13.1 Frontend Variables (Vite)

Variable
Purpose

VITE_SUPABASE_URL

Supabase project URL

VITE_SUPABASE_ANON_KEY

Public anonymous key

VITE_SUPABASE_FUNCTIONS_URL

Edge functions base URL

Usage: import.meta.env.VITE_SUPABASE_URL

13.2 Backend Secrets (Edge Functions)

Variable
Purpose

SUPABASE_URL

Auto-injected Supabase URL

SUPABASE_SERVICE_ROLE_KEY

Auto-injected service role key

RAILWAY_WEBHOOK_URL

n8n email webhook endpoint

Usage: Deno.env.get("RAILWAY_WEBHOOK_URL")

13.3 Client Configuration

File: src/integrations/supabase/client.ts


14. Error Handling and UX Safeguards

14.1 Client-Side Validation

  • Per-step validation in ContactWizard

  • Email regex validation

  • Required field checks

  • Inline error messages

14.2 Backend Error Handling

14.3 Graceful Failure Strategies

  • File upload failures don't block form submission

  • Email failures are logged but silent to user

  • Network errors show retry-friendly messages

  • 404 pages for missing resources/team members

14.4 User Feedback Mechanisms

Scenario
Feedback

Form success

Toast + success modal

Form error

Toast with error message

Loading states

Spinner animations

Empty states

"No results found" messages


15. Maintenance and Extensibility

15.1 Adding New Pages

  1. Create page component in src/pages/

  2. Add route in App.tsx

  3. Add to navigation in Navbar.tsx and Footer.tsx

  4. Include SEO metadata with react-helmet-async

15.2 Adding New Services

  1. Add entry to src/data/services.json

  2. ServiceDetail page auto-renders based on slug

  3. Update Navbar dropdown if needed

15.3 Extending Contact Wizard

  1. Create new step component in src/components/contact/steps/

  2. Add to step renderer in ContactWizard

  3. Update totalSteps constant

  4. Add validation logic to isStepValid()

  5. Update FormData interface

15.4 Updating JSON Content

  1. Edit relevant JSON file in src/data/

  2. TypeScript will catch schema mismatches

  3. Changes take effect on next build/deploy

15.5 Adding Database Tables

  1. Create migration in supabase/migrations/

  2. Update TypeScript types in src/integrations/supabase/types.ts

  3. Add RLS policies for security

  4. Test locally before deploying

15.6 Code Quality Guidelines

  • Run npm run lint before committing

  • Run npm run typecheck for type safety

  • Follow existing component patterns

  • Use shadcn/ui components when possible

  • Keep components under 300 lines


Appendix A: Key File Reference

Purpose
File

Route definitions and provider setup

src/App.tsx

Authentication state management

src/contexts/AuthContext.tsx

Supabase client configuration

src/integrations/supabase/client.ts

Database TypeScript types

src/integrations/supabase/types.ts

Multi-step form logic

src/components/contact/ContactWizard.tsx

Route protection HOC

src/components/admin/ProtectedRoute.tsx

Design system and global styles

src/index.css

Tailwind configuration

tailwind.config.ts

Last updated