Skip to main content

Leadership Dashboard

Executive-level dashboard for leadership and management to monitor multiple sites/industries with KPI tracking, status categorization, time-based analysis, and quick site navigation. Designed for high-level oversight across all managed facilities.


Overview

The Leadership Dashboard provides a bird's-eye view of all sites/industries under management. Executives can quickly assess performance across multiple facilities, identify high-priority issues, pin important sites for quick access, and drill down into specific site details. The dashboard automatically categorizes sites by status (Safe, High, Pinned) with configurable time periods (Day, Month, Year).

Location: libs/leadership/

Route: /leadership

Permission Required: LEADERSHIP (Executive/Management only)


Key Features

1. Multi-Site Overview Table

Accordion-Based Organization:

  • Sites grouped by status category (PINNED, HIGH, SAFE)
  • Color-coded indicators for quick visual assessment
  • Collapsible sections with count badges
  • Sticky header and first column for easy navigation

Status Categories:

PINNED Sites

  • Color: No color indicator
  • Purpose: User-pinned sites for quick access
  • Badge: Shows count of pinned sites
  • Behavior: Sites manually pinned by executive

SAFE Sites

  • Color: Green (#05dca4)
  • Purpose: Sites operating within normal parameters
  • Badge: Green background with site count
  • Behavior: Automatically categorized by backend based on thresholds

HIGH Priority Sites

  • Color: Red (#F84848)
  • Purpose: Sites requiring attention (threshold violations, alerts)
  • Badge: Red background with site count
  • Behavior: Automatically categorized by backend based on alerts/thresholds

2. Time Period Selection

Three Time Views:

Day View (Hourly)

  • Type: HOUR
  • Display Name: "Day"
  • Date Picker: Single date picker
  • Table Header Prefix: "Total"
  • Use Case: Today's hourly data for all sites

Month View (Daily Average)

  • Type: DATE
  • Display Name: "Month"
  • Date Picker: Month picker
  • Table Header Prefix: "Daily Avg."
  • Use Case: Monthly overview with daily averages

Year View (Monthly Average)

  • Type: MONTH
  • Display Name: "Year"
  • Date Picker: Year picker
  • Table Header Prefix: "Daily Avg."
  • Use Case: Annual overview with monthly averages

Toggle Buttons:

LeadershipHelper.i.leadershipDateType = {
HOUR: {
id: 'HOUR',
displayName: 'Day',
datePickerType: null,
tableHeaderPrefix: 'Total'
},
DATE: {
id: 'DATE',
displayName: 'Month',
datePickerType: 'month',
tableHeaderPrefix: 'Daily Avg.'
},
MONTH: {
id: 'MONTH',
displayName: 'Year',
datePickerType: 'year',
tableHeaderPrefix: 'Daily Avg.'
}
};

3. Site Management Actions

Pin/Unpin Sites:

  • Click pin icon to mark important sites
  • Pinned sites appear in "PINNED" accordion
  • Retains original status color indicator in pinned view
  • Tooltip shows "Already Pinned" for pinned sites in other sections

Redirect to Site:

  • External link icon opens site in new tab
  • Automatic login to selected industry/site
  • Opens in new tab with noopener,noreferrer for security
  • Popup permission warning if browser blocks new tab

4. Dynamic KPI Table

Responsive Table Structure:

  • Sticky First Column: Site/Industry name always visible
  • Sticky Action Column: Pin and redirect buttons always visible (desktop)
  • Horizontal Scroll: For wide data tables
  • Dynamic Headers: Backend-controlled column headers
  • HTML Content Support: Cells can render formatted HTML

Table Features:

  • Border-separated cells for clarity
  • Responsive column widths based on content
  • Minimum width calculation for site names (8px per character)
  • Color-coded status indicators
  • Last updated timestamp with refresh button

Architecture

Data Flow

User Opens Leadership Dashboard

LeadershipDataProvider Initializes

LeadershipController.getLeadershipListData({ date1, type })

API Client → GET /executiveData

Backend returns:
- headers: { col1: "Site Name", col2: "Consumption", ... }
- rows: [{ columns: {...}, meta: {...} }]
- maxLengthName: 25

Update LeadershipDataContext

Process rows into status categories (PINNED, SAFE, HIGH)

Render Accordions with Tables

User Actions (Pin/Redirect)

API Client → PUT /executivePinIndustry or GET /executiveIndustryLogin

Update UI

Key Components

1. LeadershipDataProvider

  • Purpose: Global state management for leadership dashboard
  • Location: libs/leadership/src/store/LeadershipStore.js
  • State Variables:
    • leadershipData - All site data with headers and rows
    • isLoading - Initial data loading state
    • params - Query parameters (date1, type)
    • fullScreenLoader - Full-screen loader for actions
    • lastUpdatedTime - Time of last data refresh

Context Value:

{
leadershipData: {
headers: {
col1: "Site Name",
col2: "Total Consumption",
col3: "Water Balance",
col4: "Alerts"
},
rows: [
{
columns: {
col1: "Site A",
col2: "1,234 kL",
col3: "85%",
col4: "2"
},
meta: {
industryId: "IND_123",
status: "SAFE",
isPinned: false
}
}
],
modifiedRows: {
PINNED: [...],
SAFE: [...],
HIGH: [...]
},
maxLengthName: 25
},
isLoading: false,
params: { date1: '25/02/2026', type: 'HOUR' },
fullScreenLoader: false,
lastUpdatedTime: '10:30 AM',
setParams: (params) => {},
getLoginData: (params) => {},
pinIndustry: (params) => {},
getExecutiveListData: () => {}
}

2. LeadershipDashboardPage

  • Purpose: Main leadership dashboard container
  • Location: libs/leadership/src/LeadershipDashboardPage.jsx
  • Features:
    • Fixed header with industry name and site count
    • Context provider wrapper
    • Bug report integration
    • SSO notification reminder
    • Executive navbar

3. LeaderShipFixedBar

  • Purpose: Fixed header showing industry name and site count
  • Display:
    {Industry Name} - Total Sites {count}
  • Dynamic Count: Updates based on filtered data

4. LeadershipHeader

  • Purpose: Date selector and refresh controls
  • Location: libs/leadership/src/components/LeadershipHeader.jsx
  • Features:
    • Time period toggle buttons (Day/Month/Year)
    • Date picker (changes based on selected period)
    • Last updated timestamp
    • Refresh button
    • Analytics tracking

5. LeadershipListView

  • Purpose: Main content area with status accordions
  • Location: libs/leadership/src/components/LeadershipListView.jsx
  • Features:
    • Loading state with custom loader
    • Data not found fallback
    • Status-based accordion rendering
    • Backdrop loader for actions
    • Popup permission handling

6. LeadershipAccordian

  • Purpose: Individual status section (PINNED, SAFE, HIGH)
  • Features:
    • Collapsible section with expand/collapse
    • Color-coded status badge
    • Site count indicator
    • Responsive table with sticky columns
    • Pin and redirect actions

7. ExecutiveNavbar

  • Purpose: Special navbar for leadership view
  • Location: libs/components/src/appNavBar/ExecutiveNavbar.jsx
  • Features: Executive-specific navigation options

API Integration

Get Leadership List Data

GET /executiveData
Params: {
date1: '25/02/2026',
type: 'HOUR' // or 'DATE', 'MONTH'
}

Response: {
headers: {
col1: "Site Name",
col2: "Total Consumption (kL)",
col3: "Water Balance (%)",
col4: "Alerts",
col5: "Quality Score"
},
rows: [
{
columns: {
col1: "Manufacturing Plant A",
col2: "1,234.5",
col3: "<span style='color: green'>85%</span>",
col4: "2",
col5: "Good"
},
meta: {
industryId: "IND_123",
status: "SAFE",
isPinned: false
}
},
{
columns: {
col1: "Office Campus B",
col2: "567.8",
col3: "<span style='color: red'>45%</span>",
col4: "7",
col5: "Critical"
},
meta: {
industryId: "IND_456",
status: "HIGH",
isPinned: true
}
}
],
maxLengthName: 25
}

Response Processing: Backend returns raw rows, frontend groups by status:

modifiedRows = {
PINNED: rows.filter(r => r.meta.isPinned),
SAFE: rows.filter(r => r.meta.status === 'SAFE' && !r.meta.isPinned),
HIGH: rows.filter(r => r.meta.status === 'HIGH' && !r.meta.isPinned)
};

Pin/Unpin Industry

PUT /executivePinIndustry
Request Body: {
industryId: 'IND_123',
isPinned: true // or false
}

Response: {
status: 200,
message: 'Industry pinned successfully'
}

Frontend Logic:

const pinIndustry = (industryId, isPinned) => {
const pinParams = {
industryId: industryId,
isPinned: !isPinned // Toggle pin state
};

leaderStore.pinIndustry(pinParams);
// Automatically refreshes data after update
};

Industry Login (Redirect)

GET /executiveIndustryLogin
Params: {
industryId: 'IND_123'
}

Response: {
status: 200,
token: 'jwt_token_for_industry_123',
redirectUrl: 'https://app.aquagen.com'
}

Frontend Logic:

const redirectToIndustry = async (industryId) => {
// Get login credentials for industry
await leaderStore.getLoginData({ industryId });

// Track analytics
AnalyticsService.sendEvent(AnalyticEvents.LEADERSHIP_REDIRECT, {
industryId
});

// Open in new tab
const baseUrl = `${window.location.protocol}//${window.location.host}`;
const newTab = window.open(baseUrl, '_blank', 'noopener,noreferrer');

// Check if popup was blocked
if (!newTab || newTab.closed || typeof newTab.closed === 'undefined') {
setShowPermissionPopup(true);
}
};

Usage Examples

1. Initialize Leadership Dashboard

import LeadershipDashboardPage from '@aquagen-mf-webapp/leadership';

function LeadershipRoute() {
return <LeadershipDashboardPage />;
}

2. Access Leadership Context

import { useContext } from 'react';
import { LeadershipDataContext } from '@aquagen-mf-webapp/leadership/store/LeadershipStore';

function CustomLeadershipWidget() {
const leaderStore = useContext(LeadershipDataContext);

const totalSites = leaderStore.leadershipData?.rows?.length || 0;
const safeSites = leaderStore.leadershipData?.modifiedRows?.SAFE?.length || 0;
const highPrioritySites = leaderStore.leadershipData?.modifiedRows?.HIGH?.length || 0;

return (
<div>
<h3>Total Sites: {totalSites}</h3>
<p>Safe: {safeSites}</p>
<p>High Priority: {highPrioritySites}</p>
</div>
);
}

3. Change Time Period

const handlePeriodChange = (newType) => {
let newDate = moment();

// Adjust date based on type
if (newType === LeadershipHelper.i.leadershipDateType.DATE.id) {
newDate = newDate.startOf('month');
}
if (newType === LeadershipHelper.i.leadershipDateType.MONTH.id) {
newDate = newDate.startOf('year');
}

leaderStore.setParams({
type: newType,
date1: DateFormatter.formatter(newDate)
});
};

// Usage
<ToggleButton
value={LeadershipHelper.i.leadershipDateType.HOUR.id}
onClick={() => handlePeriodChange(LeadershipHelper.i.leadershipDateType.HOUR.id)}
>
Day
</ToggleButton>

4. Pin/Unpin Site

const handlePinToggle = (industryId, currentPinState) => {
leaderStore.pinIndustry({
industryId: industryId,
isPinned: !currentPinState
});

// Data automatically refreshes after pin update
};

// Render pin button
<IconButton onClick={() => handlePinToggle(site.meta.industryId, site.meta.isPinned)}>
{site.meta.isPinned ? (
<Icon icon={'bi:pin-fill'} style={{ color: 'black' }} />
) : (
<Icon icon={'bi:pin'} />
)}
</IconButton>

5. Redirect to Site

const handleSiteRedirect = async (industryId) => {
try {
// Get login data
await leaderStore.getLoginData({ industryId });

// Track event
AnalyticsService.sendEvent(AnalyticEvents.LEADERSHIP_REDIRECT, {
industryId
});

// Open site in new tab
const baseUrl = `${window.location.protocol}//${window.location.host}`;
window.open(baseUrl, '_blank', 'noopener,noreferrer');
} catch (error) {
console.error('Redirect failed', error);
}
};

6. Refresh Data

const handleRefresh = () => {
// Track analytics
AnalyticsService.sendEvent(AnalyticEvents.LEADERSHIP_REFRESH_CLICK);

// Show full-screen loader
leaderStore.setFullScreenLoader(true);

// Refresh with current date
leaderStore.setParams({
...leaderStore.params,
date1: moment().format('DD/MM/YYYY')
});
};

// Render refresh button
<ButtonBase onClick={handleRefresh}>
<RefreshRoundedIcon />
</ButtonBase>

Status Configuration

LeadershipHelper.i.leadershipListSatusEnum = {
PINNED: 'PINNED',
HIGH: 'HIGH',
SAFE: 'SAFE'
};

LeadershipHelper.i.leadershipListSatusColor = {
PINNED: null, // No color indicator
SAFE: '#05dca4', // Green
HIGH: '#F84848' // Red
};

// Get status array in order
LeadershipHelper.i.leadershipStatusArray
// Returns: ['PINNED', 'HIGH', 'SAFE']

Responsive Design

Desktop (md+)

  • Full-width table with horizontal scroll
  • Sticky first column (site name)
  • Sticky last column (actions)
  • All accordion sections visible

Mobile (xs-sm)

  • Full-width horizontal scroll
  • Sticky first column only
  • Action column scrolls with table
  • Minimum column widths: 200px
  • Touch-friendly accordions

Responsive Column Width:

minWidth: {
xs: '200px',
sm: !headingIndex && leaderStore.leadershipData?.maxLengthName
? `${leaderStore.leadershipData?.maxLengthName * 8}px`
: 'fit-content'
}

Best Practices

1. Handle Loading States

const { isLoading, fullScreenLoader } = useContext(LeadershipDataContext);

if (isLoading) {
return <CustomLoader />;
}

// Show backdrop loader for actions
<BackdropLoader isLoading={fullScreenLoader} />

2. Handle Empty Data

if (!leaderStore.leadershipData && !leaderStore.isLoading) {
return (
<GenericInfo
lottieData={assets.lotties.dataNotFound}
subTitle="Data Not Found"
/>
);
}

3. Prevent Popup Blockers

const newTab = window.open(baseUrl, '_blank', 'noopener,noreferrer');

// Check if popup was blocked
if (!newTab || newTab.closed || typeof newTab.closed === 'undefined') {
setShowPermissionPopup(true);
}

// Show popup permission helper
<PopupPermission
open={showPermissionPopup}
handleClose={() => setShowPermissionPopup(false)}
/>

4. Track Analytics Events

// Date type change
AnalyticsService.sendEvent(
AnalyticEvents.LEADERSHIP_DATE_TYPE_CHANGE,
{ type: 'HOUR', date1: '25/02/2026' }
);

// Date change
AnalyticsService.sendEvent(
AnalyticEvents.LEADERSHIP_DATE_CHANGE,
{ type: 'DATE', date1: '01/02/2026' }
);

// Site redirect
AnalyticsService.sendEvent(
AnalyticEvents.LEADERSHIP_REDIRECT,
{ industryId: 'IND_123' }
);

// Refresh click
AnalyticsService.sendEvent(AnalyticEvents.LEADERSHIP_REFRESH_CLICK);

5. HTML Content Security

Table cells support HTML rendering:

<div dangerouslySetInnerHTML={{
__html: row.columns[headerId] ? row.columns[headerId] : '-'
}} />

Ensure backend sanitizes HTML to prevent XSS attacks.


Troubleshooting

Sites Not Categorized Correctly

Cause: Backend not returning proper status in meta Solution: Verify API response includes meta.status

rows: [
{
columns: {...},
meta: {
status: 'SAFE', // Must be 'SAFE', 'HIGH', or 'PINNED'
isPinned: false
}
}
]

Pin Not Working

Cause: API error or missing industryId Solution: Check console and verify PUT request

const pinIndustry = async (params) => {
const response = await LeadershipController.pinIndustry(params);
if (response.status !== 200) {
console.log('Unable to Pin Industry');
}
getExecutiveListData(); // Refresh data
};

Redirect Opens Multiple Tabs

Cause: Double-click or rapid clicks Solution: Disable button during loading

const [redirecting, setRedirecting] = useState(false);

const redirectToIndustry = async (industryId) => {
if (redirecting) return;
setRedirecting(true);

await leaderStore.getLoginData({ industryId });
window.open(baseUrl, '_blank', 'noopener,noreferrer');

setRedirecting(false);
};

Date Picker Not Changing

Cause: Date not formatted correctly based on type Solution: Use handleDateChangeBasedonType helper

const handleDateChangeBasedonType = (dateType, newValue) => {
let newDate = newValue || moment();

if (dateType === LeadershipHelper.i.leadershipDateType.DATE.id) {
newDate = newDate.startOf('month'); // Month view starts at month beginning
}
if (dateType === LeadershipHelper.i.leadershipDateType.MONTH.id) {
newDate = newDate.startOf('year'); // Year view starts at year beginning
}

return DateFormatter.formatter(newDate);
};

Integration with Other Features

Executive Navbar

  • Custom navbar for leadership view
  • Replaces standard app navigation
  • Provides executive-specific menu options
  • Auto-integrated via LeadershipDataProvider

SSO Notification Reminder

  • Reminds executives to enable SSO if not configured
  • Shows only for super users/admins
  • Dismissible notification

Bug Report

  • Bug reporting widget available in leadership view
  • Allows executives to report issues directly
  • Includes screenshot and context capture

Analytics Tracking

Events Tracked:

// Page view
AnalyticEvents.PAGE_VIEW

// Date type change (Day/Month/Year)
AnalyticEvents.LEADERSHIP_DATE_TYPE_CHANGE

// Date change
AnalyticEvents.LEADERSHIP_DATE_CHANGE

// Refresh button click
AnalyticEvents.LEADERSHIP_REFRESH_CLICK

// Site redirect
AnalyticEvents.LEADERSHIP_REDIRECT


Last Updated: February 2026 Module Location: libs/leadership/