diff --git a/HeadySystems_v13/apps/heady_admin_ui/analytics.html b/HeadySystems_v13/apps/heady_admin_ui/analytics.html new file mode 100644 index 00000000..fddaa2cf --- /dev/null +++ b/HeadySystems_v13/apps/heady_admin_ui/analytics.html @@ -0,0 +1,570 @@ + + + + + + + Analytics - Heady Admin Dashboard + + + + + + + + + +
+ + + + +
+ + +
+
+ Time Range: +
+ + + + + +
+
+ +
+
+ Auto-refresh: +
+
+
+
+ +
+ + +
+
+ + +
+

+ 📈 + Real-Time Metrics +

+
+
+
+
+
+
+
+ + +
+

+ + System Performance +

+
+ +
+
+

Traffic Overview

+
+
+
+ + +
+
+

Resource Usage

+
+
+
+
+
+ + +
+

+ 📊 + Distribution & Comparison +

+
+ +
+
+

Traffic by Vertical

+
+
+
+ + +
+
+

Vertical Comparison

+
+
+
+
+
+ + +
+

+ 🔥 + Activity Patterns +

+
+
+

Activity Heatmap (Hour × Day)

+
+
+
+
+ + +
+

+ 📱 + Quick Stats +

+
+
+
+
+
+
+ + +
+

+ 🎯 + System Health +

+
+
+

CPU Utilization

+
+
+
+

Memory Usage

+
+
+
+

Network Load

+
+
+
+
+ + +
+

+ 🔍 + System Status +

+
+
+
+
+
+
+
+
+ + +
+

+ 🔔 + Recent Alerts +

+
+
+
+
+ + +
+

+ 📋 + Recent Activity +

+
+
+ +
+ + + +
+ + + + + + + + + diff --git a/HeadySystems_v13/apps/heady_admin_ui/css/analytics.css b/HeadySystems_v13/apps/heady_admin_ui/css/analytics.css new file mode 100644 index 00000000..f38e43b7 --- /dev/null +++ b/HeadySystems_v13/apps/heady_admin_ui/css/analytics.css @@ -0,0 +1,778 @@ +/* ======================================== + Heady Admin UI - Analytics Styles + ======================================== */ + +/* ======================================== + Chart Container Styles + ======================================== */ + +.chart-container { + background: var(--bg-card); + backdrop-filter: blur(20px); + border-radius: var(--radius-xl); + padding: var(--spacing-xl); + box-shadow: var(--shadow-lg); + border: 1px solid var(--border-color); + position: relative; + overflow: hidden; +} + +.chart-container::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, rgba(99, 102, 241, 0.05), transparent); + pointer-events: none; +} + +.chart-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--spacing-lg); +} + +.chart-title { + font-size: 1.25rem; + font-weight: 600; + color: var(--text-primary); +} + +.chart-wrapper { + position: relative; + min-height: 300px; +} + +/* ======================================== + Metric Card Styles + ======================================== */ + +.metric-card { + background: var(--bg-card); + backdrop-filter: blur(20px); + border-radius: var(--radius-lg); + padding: var(--spacing-lg); + box-shadow: var(--shadow-md); + border: 1px solid var(--border-color); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.metric-card:hover { + transform: translateY(-4px); + box-shadow: var(--shadow-xl); + border-color: var(--color-primary); +} + +.metric-card.success { + border-left: 4px solid var(--color-success); +} + +.metric-card.warning { + border-left: 4px solid var(--color-warning); +} + +.metric-card.danger { + border-left: 4px solid var(--color-error); +} + +.metric-card.info { + border-left: 4px solid var(--color-info); +} + +.metric-card-content { + position: relative; + z-index: 1; +} + +.metric-header { + display: flex; + align-items: center; + gap: var(--spacing-sm); + margin-bottom: var(--spacing-md); +} + +.metric-icon { + font-size: 1.5rem; +} + +.metric-title { + font-size: 0.875rem; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; + font-weight: 600; +} + +.metric-body { + display: flex; + flex-direction: column; + gap: var(--spacing-md); +} + +.metric-value-container { + display: flex; + align-items: baseline; + gap: var(--spacing-sm); +} + +.metric-value { + font-size: 2.5rem; + font-weight: 700; + color: var(--text-primary); + line-height: 1; +} + +.metric-value.value-update { + animation: valueFlash 0.3s ease; +} + +@keyframes valueFlash { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +.metric-trend { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-size: 0.875rem; + font-weight: 600; + padding: 0.25rem 0.5rem; + border-radius: var(--radius-sm); +} + +.metric-trend.trend-up { + color: var(--color-success); + background: rgba(16, 185, 129, 0.1); +} + +.metric-trend.trend-down { + color: var(--color-error); + background: rgba(239, 68, 68, 0.1); +} + +.metric-trend.trend-neutral { + color: var(--text-secondary); + background: rgba(107, 114, 128, 0.1); +} + +.trend-icon { + font-size: 1rem; +} + +.metric-sparkline { + height: 60px; + width: 100%; +} + +/* ======================================== + Mini Chart Styles + ======================================== */ + +.mini-chart { + background: rgba(255, 255, 255, 0.03); + border-radius: var(--radius-md); + padding: var(--spacing-md); +} + +.mini-chart-content { + display: flex; + flex-direction: column; + gap: var(--spacing-sm); +} + +.mini-chart-header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.mini-chart-label { + font-size: 0.75rem; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.mini-chart-value { + font-size: 1rem; + font-weight: 700; + color: var(--text-primary); +} + +.mini-chart-sparkline { + height: 40px; + width: 100%; +} + +/* ======================================== + Status Indicator Styles + ======================================== */ + +.status-indicator { + display: inline-flex; + align-items: center; + gap: var(--spacing-sm); +} + +.status-indicator-content { + display: flex; + align-items: center; + gap: var(--spacing-sm); +} + +.status-dot { + width: 12px; + height: 12px; + border-radius: 50%; + position: relative; +} + +.status-dot.status-operational { + background: var(--color-success); +} + +.status-dot.status-warning { + background: var(--color-warning); +} + +.status-dot.status-error { + background: var(--color-error); +} + +.status-dot.status-unknown { + background: #6b7280; +} + +.status-text { + display: flex; + flex-direction: column; +} + +.status-label { + font-size: 0.875rem; + font-weight: 600; + color: var(--text-primary); +} + +.status-message { + font-size: 0.75rem; + color: var(--text-secondary); +} + +/* ======================================== + Progress Ring Styles + ======================================== */ + +.progress-ring-container { + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; +} + +.progress-ring-svg { + transform: rotate(-90deg); +} + +.progress-ring-bg { + fill: none; + stroke: rgba(255, 255, 255, 0.1); +} + +.progress-ring-fill { + fill: none; + stroke-linecap: round; + transition: stroke-dashoffset 1s ease; +} + +.progress-ring-text { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; +} + +.progress-ring-value { + font-size: 1.5rem; + font-weight: 700; + color: var(--text-primary); +} + +.progress-ring-label { + font-size: 0.75rem; + color: var(--text-secondary); + margin-top: 0.25rem; +} + +/* ======================================== + Data Table Styles + ======================================== */ + +.data-table-container { + background: var(--bg-card); + backdrop-filter: blur(20px); + border-radius: var(--radius-lg); + overflow: hidden; + border: 1px solid var(--border-color); +} + +.data-table { + width: 100%; + border-collapse: collapse; +} + +.data-table thead { + background: rgba(255, 255, 255, 0.05); +} + +.data-table th { + padding: var(--spacing-md); + text-align: left; + font-size: 0.875rem; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid var(--border-color); +} + +.data-table th.sortable { + cursor: pointer; + user-select: none; + transition: color 0.2s ease; +} + +.data-table th.sortable:hover { + color: var(--color-primary); +} + +.data-table td { + padding: var(--spacing-md); + font-size: 0.875rem; + color: var(--text-primary); + border-bottom: 1px solid rgba(255, 255, 255, 0.03); +} + +.data-table tbody tr.even { + background: rgba(255, 255, 255, 0.02); +} + +.data-table tbody tr:hover { + background: rgba(99, 102, 241, 0.1); +} + +.data-table-pagination { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--spacing-md); + background: rgba(255, 255, 255, 0.03); +} + +.pagination-btn { + background: var(--bg-card); + border: 1px solid var(--border-color); + color: var(--text-primary); + padding: var(--spacing-sm) var(--spacing-md); + border-radius: var(--radius-md); + cursor: pointer; + font-size: 0.875rem; + font-weight: 500; + transition: all 0.2s ease; +} + +.pagination-btn:hover:not(:disabled) { + background: var(--bg-card-hover); + border-color: var(--color-primary); +} + +.pagination-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.pagination-info { + font-size: 0.875rem; + color: var(--text-secondary); +} + +/* ======================================== + Alert Feed Styles + ======================================== */ + +.alert-feed-container { + display: flex; + flex-direction: column; + gap: var(--spacing-sm); +} + +.alert-item { + display: flex; + align-items: flex-start; + gap: var(--spacing-sm); + padding: var(--spacing-md); + border-radius: var(--radius-md); + border-left: 3px solid; + background: rgba(255, 255, 255, 0.03); + transition: all 0.2s ease; +} + +.alert-item:hover { + background: rgba(255, 255, 255, 0.05); + transform: translateX(4px); +} + +.alert-item.alert-success { + border-left-color: var(--color-success); +} + +.alert-item.alert-info { + border-left-color: var(--color-info); +} + +.alert-item.alert-warning { + border-left-color: var(--color-warning); +} + +.alert-item.alert-error { + border-left-color: var(--color-error); +} + +.alert-icon { + font-size: 1.25rem; + flex-shrink: 0; +} + +.alert-content { + flex: 1; + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.alert-message { + font-size: 0.875rem; + color: var(--text-primary); +} + +.alert-time { + font-size: 0.75rem; + color: var(--text-secondary); +} + +/* ======================================== + Time Range Picker Styles + ======================================== */ + +.time-range-picker { + display: flex; + gap: var(--spacing-xs); + background: rgba(255, 255, 255, 0.05); + border-radius: var(--radius-md); + padding: var(--spacing-xs); +} + +.time-range-btn { + background: transparent; + border: none; + color: var(--text-secondary); + padding: var(--spacing-sm) var(--spacing-md); + border-radius: var(--radius-sm); + cursor: pointer; + font-size: 0.875rem; + font-weight: 500; + transition: all 0.2s ease; +} + +.time-range-btn:hover { + color: var(--text-primary); + background: rgba(255, 255, 255, 0.05); +} + +.time-range-btn.active { + background: var(--gradient-purple); + color: white; +} + +/* ======================================== + Analytics Grid Layouts + ======================================== */ + +.analytics-grid { + display: grid; + gap: var(--spacing-lg); +} + +.analytics-grid.metrics { + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); +} + +.analytics-grid.charts { + grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); +} + +.analytics-grid.widgets { + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); +} + +/* ======================================== + Control Panel Styles + ======================================== */ + +.analytics-controls { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: var(--spacing-md); + margin-bottom: var(--spacing-xl); +} + +.control-group { + display: flex; + align-items: center; + gap: var(--spacing-md); +} + +.control-label { + font-size: 0.875rem; + color: var(--text-secondary); + font-weight: 500; +} + +.auto-refresh-toggle { + display: flex; + align-items: center; + gap: var(--spacing-sm); + background: rgba(255, 255, 255, 0.05); + border-radius: var(--radius-md); + padding: var(--spacing-sm) var(--spacing-md); +} + +.toggle-switch { + position: relative; + width: 44px; + height: 24px; + background: rgba(255, 255, 255, 0.1); + border-radius: var(--radius-full); + cursor: pointer; + transition: background 0.3s ease; +} + +.toggle-switch.active { + background: var(--color-success); +} + +.toggle-switch::after { + content: ''; + position: absolute; + top: 2px; + left: 2px; + width: 20px; + height: 20px; + background: white; + border-radius: 50%; + transition: transform 0.3s ease; +} + +.toggle-switch.active::after { + transform: translateX(20px); +} + +/* ======================================== + Export Button Styles + ======================================== */ + +.export-buttons { + display: flex; + gap: var(--spacing-sm); +} + +.export-btn { + background: var(--bg-card); + border: 1px solid var(--border-color); + color: var(--text-primary); + padding: var(--spacing-sm) var(--spacing-md); + border-radius: var(--radius-md); + cursor: pointer; + font-size: 0.875rem; + font-weight: 500; + display: flex; + align-items: center; + gap: var(--spacing-xs); + transition: all 0.2s ease; +} + +.export-btn:hover { + background: var(--bg-card-hover); + border-color: var(--color-primary); + transform: translateY(-2px); +} + +.export-btn .icon { + font-size: 1rem; +} + +/* ======================================== + Responsive Design + ======================================== */ + +@media (max-width: 768px) { + .analytics-grid.metrics, + .analytics-grid.charts, + .analytics-grid.widgets { + grid-template-columns: 1fr; + } + + .analytics-controls { + flex-direction: column; + align-items: flex-start; + } + + .time-range-picker { + width: 100%; + overflow-x: auto; + } + + .metric-value { + font-size: 2rem; + } + + .chart-wrapper { + min-height: 250px; + } +} + +@media (max-width: 480px) { + .metric-card { + padding: var(--spacing-md); + } + + .metric-value { + font-size: 1.75rem; + } + + .chart-container { + padding: var(--spacing-md); + } +} + +/* ======================================== + Print Styles + ======================================== */ + +@media print { + body { + background: white; + color: black; + } + + .header, + .footer, + .analytics-controls, + .export-buttons, + .nav { + display: none; + } + + .glass-card, + .metric-card, + .chart-container { + background: white; + border: 1px solid #ddd; + box-shadow: none; + page-break-inside: avoid; + } + + .analytics-grid { + display: block; + } + + .analytics-grid > * { + margin-bottom: 1rem; + page-break-inside: avoid; + } + + .metric-value, + .chart-title, + .status-label { + color: black; + } + + .metric-trend, + .status-dot { + border: 1px solid #ddd; + } +} + +/* ======================================== + Dark/Light Theme Support + ======================================== */ + +body.light-theme .chart-container, +body.light-theme .metric-card, +body.light-theme .data-table-container { + background: rgba(255, 255, 255, 0.95); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +body.light-theme .progress-ring-bg { + stroke: rgba(0, 0, 0, 0.1); +} + +body.light-theme .data-table thead { + background: rgba(0, 0, 0, 0.03); +} + +body.light-theme .data-table tbody tr.even { + background: rgba(0, 0, 0, 0.02); +} + +body.light-theme .data-table tbody tr:hover { + background: rgba(99, 102, 241, 0.1); +} + +/* ======================================== + Accessibility + ======================================== */ + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} + +/* Focus styles for keyboard navigation */ +.time-range-btn:focus, +.export-btn:focus, +.pagination-btn:focus, +.toggle-switch:focus { + outline: 2px solid var(--color-primary); + outline-offset: 2px; +} + +/* High contrast mode support */ +@media (prefers-contrast: high) { + .metric-card, + .chart-container, + .data-table-container { + border: 2px solid var(--text-primary); + } + + .metric-trend, + .status-dot { + border: 1px solid currentColor; + } +} diff --git a/HeadySystems_v13/apps/heady_admin_ui/index.html b/HeadySystems_v13/apps/heady_admin_ui/index.html index 0087274d..40f86d04 100644 --- a/HeadySystems_v13/apps/heady_admin_ui/index.html +++ b/HeadySystems_v13/apps/heady_admin_ui/index.html @@ -28,6 +28,10 @@

📊 Dashboard + + 📊 + Analytics + + + Page ${this.currentPage} of ${totalPages} + + + + + `; + + this.container.innerHTML = html; + this.attachEventListeners(); + } + + attachEventListeners() { + // Sort listeners + this.container.querySelectorAll('th.sortable').forEach(th => { + th.addEventListener('click', () => { + const column = th.dataset.column; + this.sort(column); + }); + }); + + // Pagination listeners + this.container.querySelectorAll('.pagination-btn').forEach(btn => { + btn.addEventListener('click', () => { + const action = btn.dataset.action; + if (action === 'prev' && this.currentPage > 1) { + this.currentPage--; + this.render(); + } else if (action === 'next' && this.currentPage < Math.ceil(this.data.length / this.pageSize)) { + this.currentPage++; + this.render(); + } + }); + }); + } + + sort(column) { + if (this.sortColumn === column) { + this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc'; + } else { + this.sortColumn = column; + this.sortDirection = 'asc'; + } + + this.data.sort((a, b) => { + const aVal = a[column]; + const bVal = b[column]; + + if (aVal < bVal) return this.sortDirection === 'asc' ? -1 : 1; + if (aVal > bVal) return this.sortDirection === 'asc' ? 1 : -1; + return 0; + }); + + this.render(); + } + + getPaginatedData() { + const start = (this.currentPage - 1) * this.pageSize; + const end = start + this.pageSize; + return this.data.slice(start, end); + } + + setData(data) { + this.data = data; + this.currentPage = 1; + this.render(); + } +} + +/** + * AlertFeed - Real-time alert stream + */ +class AlertFeed { + constructor(options) { + this.container = typeof options.container === 'string' + ? document.querySelector(options.container) + : options.container; + + if (!this.container) { + console.error('AlertFeed container not found'); + return; + } + + this.alerts = options.alerts || []; + this.maxAlerts = options.maxAlerts || 10; + + this.render(); + } + + render() { + let html = '
'; + + this.alerts.slice(0, this.maxAlerts).forEach(alert => { + const typeClass = `alert-${alert.type}`; + const icon = this.getAlertIcon(alert.type); + const timeAgo = this.getTimeAgo(alert.timestamp); + + html += ` +
+ ${icon} +
+
${alert.message}
+
${timeAgo}
+
+
+ `; + }); + + html += '
'; + this.container.innerHTML = html; + } + + getAlertIcon(type) { + const icons = { + success: '✓', + info: 'ℹ', + warning: '⚠', + error: '✗' + }; + return icons[type] || icons.info; + } + + getTimeAgo(timestamp) { + const now = Date.now(); + const diff = now - timestamp; + + const seconds = Math.floor(diff / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + if (days > 0) return `${days}d ago`; + if (hours > 0) return `${hours}h ago`; + if (minutes > 0) return `${minutes}m ago`; + return `${seconds}s ago`; + } + + addAlert(alert) { + this.alerts.unshift(alert); + if (this.alerts.length > this.maxAlerts * 2) { + this.alerts = this.alerts.slice(0, this.maxAlerts * 2); + } + this.render(); + } + + clearAlerts() { + this.alerts = []; + this.render(); + } +} + +// Export classes +if (typeof module !== 'undefined' && module.exports) { + module.exports = { MetricCard, MiniChart, StatusIndicator, ProgressRing, DataTable, AlertFeed }; +} diff --git a/HeadySystems_v13/apps/heady_field/dashboard.html b/HeadySystems_v13/apps/heady_field/dashboard.html index de37b364..b9bc2b74 100644 --- a/HeadySystems_v13/apps/heady_field/dashboard.html +++ b/HeadySystems_v13/apps/heady_field/dashboard.html @@ -266,6 +266,67 @@

South Field B

+ + +
+

+ 📊 + Field Analytics +

+
+
+
📈
+
+

Sensor Reading Trends

+

↑ 2.3%

+
+
+
+
+
+
+
+
+
+ +
+
⚠️
+
+

Anomaly Detection

+

2

+

+ Minor alerts detected +

+
+
+ +
+
🌡️
+
+

Temp Range (24h)

+

68-78°F

+
+
+
+
+
+ +
+
💧
+
+

Humidity Avg

+

65%

+
+
+
+
+
+
+
+
+
+
+
diff --git a/HeadySystems_v13/apps/heady_kinetic/dashboard.html b/HeadySystems_v13/apps/heady_kinetic/dashboard.html index 3f8e7e42..26090c85 100644 --- a/HeadySystems_v13/apps/heady_kinetic/dashboard.html +++ b/HeadySystems_v13/apps/heady_kinetic/dashboard.html @@ -312,6 +312,71 @@

+ + +
+

+ 📊 + Thermal Analytics +

+
+
+
🌡️
+
+

Temperature Trends

+

72°F

+
+
+
+
+
+
+
+
+
+ +
+
+
+

Energy Consumption

+

3.2 kW

+
+
+
+
+
+
+
+
+
+ +
+
📱
+
+

Active Devices

+

89

+
+
+
+
+
+ +
+
+
+

System Efficiency

+

87%

+
+
+
+
+
+
+
+
+
+
+
diff --git a/HeadySystems_v13/apps/heady_legacy/dashboard.html b/HeadySystems_v13/apps/heady_legacy/dashboard.html index f07435f5..2887bb92 100644 --- a/HeadySystems_v13/apps/heady_legacy/dashboard.html +++ b/HeadySystems_v13/apps/heady_legacy/dashboard.html @@ -297,6 +297,67 @@

✅ Liveness Detection

+ + +
+

+ 📊 + Security Analytics +

+
+
+
🔐
+
+

Authentication Patterns

+

450/hr

+
+
+
+
+
+
+
+
+
+ +
+
⚠️
+
+

Security Events

+

5

+

+ Low priority alerts +

+
+
+ +
+
👥
+
+

Active Users (24h)

+

120

+
+
+
+
+
+ +
+
+
+

Success Rate

+

95.6%

+
+
+
+
+
+
+
+
+
+
+
diff --git a/HeadySystems_v13/apps/heady_make/dashboard.html b/HeadySystems_v13/apps/heady_make/dashboard.html index b76838fe..9476e11f 100644 --- a/HeadySystems_v13/apps/heady_make/dashboard.html +++ b/HeadySystems_v13/apps/heady_make/dashboard.html @@ -210,6 +210,71 @@

+ + +
+

+ 📊 + Manufacturing Analytics +

+
+
+
+
+

Print Success Rate

+

95.3%

+
+
+
+
+
+
+
+
+
+ +
+
📦
+
+

Material Usage (kg)

+

2.5

+
+
+
+
+
+
+
+
+
+ +
+
⏱️
+
+

Avg Queue Time

+

15 min

+
+
+
+
+
+
+
+
+
+ +
+
🖨️
+
+

Printer Efficiency

+

87%

+
+
+
+
+
+
+