| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Rig Performance Dashboard</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <script> |
| tailwind.config = { |
| theme: { |
| extend: { |
| colors: { |
| primary: '#4F46E5', |
| secondary: '#10B981', |
| danger: '#EF4444', |
| warning: '#F59E0B', |
| info: '#3B82F6' |
| } |
| } |
| } |
| } |
| |
| |
| const sampleData = { |
| 'Rig 101': { |
| unsafeActions: 8, |
| unsafeConditions: 12, |
| stopWorkAuthority: 5, |
| dataSelfService: 72, |
| reliabilityScore: 85, |
| complianceScore: 88, |
| verification: 28, |
| cctvFindings: 8, |
| nptRig: 3.2 |
| }, |
| 'Rig 102': { |
| unsafeActions: 12, |
| unsafeConditions: 18, |
| stopWorkAuthority: 8, |
| dataSelfService: 65, |
| reliabilityScore: 78, |
| complianceScore: 82, |
| verification: 22, |
| cctvFindings: 15, |
| nptRig: 4.8 |
| }, |
| 'Rig 103': { |
| unsafeActions: 5, |
| unsafeConditions: 9, |
| stopWorkAuthority: 3, |
| dataSelfService: 82, |
| reliabilityScore: 92, |
| complianceScore: 91, |
| verification: 35, |
| cctvFindings: 5, |
| nptRig: 2.7 |
| }, |
| 'Rig 104': { |
| unsafeActions: 15, |
| unsafeConditions: 22, |
| stopWorkAuthority: 10, |
| dataSelfService: 58, |
| reliabilityScore: 72, |
| complianceScore: 75, |
| verification: 18, |
| cctvFindings: 22, |
| nptRig: 5.5 |
| }, |
| 'Rig 105': { |
| unsafeActions: 18, |
| unsafeConditions: 25, |
| stopWorkAuthority: 12, |
| dataSelfService: 48, |
| reliabilityScore: 68, |
| complianceScore: 72, |
| verification: 15, |
| cctvFindings: 28, |
| nptRig: 6.8 |
| }, |
| 'Rig 106': { |
| unsafeActions: 7, |
| unsafeConditions: 10, |
| stopWorkAuthority: 4, |
| dataSelfService: 75, |
| reliabilityScore: 88, |
| complianceScore: 86, |
| verification: 32, |
| cctvFindings: 7, |
| nptRig: 3.0 |
| }, |
| 'Rig 107': { |
| unsafeActions: 10, |
| unsafeConditions: 15, |
| stopWorkAuthority: 6, |
| dataSelfService: 68, |
| reliabilityScore: 82, |
| complianceScore: 84, |
| verification: 25, |
| cctvFindings: 12, |
| nptRig: 4.2 |
| }, |
| 'Rig 108': { |
| unsafeActions: 20, |
| unsafeConditions: 28, |
| stopWorkAuthority: 15, |
| dataSelfService: 42, |
| reliabilityScore: 65, |
| complianceScore: 68, |
| verification: 12, |
| cctvFindings: 32, |
| nptRig: 7.5 |
| }, |
| 'Rig 109': { |
| unsafeActions: 6, |
| unsafeConditions: 8, |
| stopWorkAuthority: 3, |
| dataSelfService: 80, |
| reliabilityScore: 90, |
| complianceScore: 89, |
| verification: 38, |
| cctvFindings: 4, |
| nptRig: 2.5 |
| }, |
| 'Rig 110': { |
| unsafeActions: 14, |
| unsafeConditions: 20, |
| stopWorkAuthority: 9, |
| dataSelfService: 62, |
| reliabilityScore: 75, |
| complianceScore: 78, |
| verification: 20, |
| cctvFindings: 18, |
| nptRig: 5.2 |
| } |
| }; |
| |
| let currentRig = 'Rig 101'; |
| |
| function updateDashboard(rig) { |
| currentRig = rig; |
| const data = sampleData[rig]; |
| |
| |
| const overallScore = Math.round( |
| (getScore(data.unsafeActions + data.unsafeConditions, 20, false) * 0.15 + |
| getScore(data.stopWorkAuthority, 5, false) * 0.1 + |
| getScore(data.dataSelfService, 60, true) * 0.1 + |
| getScore((data.reliabilityScore + data.complianceScore)/2, 80, true) * 0.25 + |
| getScore(data.verification, 25, true) * 0.1 + |
| getScore(100 - data.cctvFindings, 85, true) * 0.15 + |
| getScore(100 - (data.nptRig/10*100), 70, true) * 0.25) |
| ); |
| |
| document.getElementById('overall-score').textContent = `${overallScore}%`; |
| document.getElementById('overall-gauge-value').textContent = `${overallScore}%`; |
| document.querySelector('#overall-card .progress-bar').style.width = `${overallScore}%`; |
| |
| |
| updateIndicator(1, 'Unsafe Actions', 'Unsafe Action Findings', data.unsafeActions, 10, false, 'cases'); |
| updateIndicator(2, 'Unsafe Conditions', 'Unsafe Condition Findings', data.unsafeConditions, 15, false, 'cases'); |
| updateIndicator(3, 'Stop Work Authority', 'SWA Findings', data.stopWorkAuthority, 5, false, 'cases'); |
| updateIndicator(4, 'Data Self-Service', 'Employee Self-Service Rate', data.dataSelfService, 60, true, '%'); |
| updateIndicator(5, 'Reliability Score', 'Equipment Reliability', data.reliabilityScore, 80, true, '%'); |
| updateIndicator(6, 'Compliance Score', 'Regulatory Compliance', data.complianceScore, 80, true, '%'); |
| updateIndicator(7, 'Verification', 'V&V Activities Completed', data.verification, 25, true, '%'); |
| updateIndicator(8, 'CCTV Findings', 'i-CCTV Findings', data.cctvFindings, 10, false, 'cases'); |
| updateIndicator(9, 'NPT Rig', 'Non-Productive Time', data.nptRig, 3.5, false, 'hours'); |
| |
| |
| document.querySelectorAll('.rig-option').forEach(option => { |
| option.classList.remove('bg-primary', 'text-white'); |
| if (option.textContent === rig) { |
| option.classList.add('bg-primary', 'text-white'); |
| } |
| }); |
| |
| |
| updateStatusCounts(); |
| } |
| |
| function updateIndicator(id, name, description, current, target, higherIsBetter, unit) { |
| const card = document.getElementById(`indicator-${id}`); |
| const score = getScore(current, target, higherIsBetter); |
| |
| |
| const statusBadge = card.querySelector('.status-badge'); |
| statusBadge.className = 'px-2 py-1 text-xs font-semibold rounded-full status-badge ' + |
| getStatusClass(score); |
| statusBadge.textContent = getStatusText(score); |
| |
| |
| card.querySelector('.indicator-value').textContent = `${current} ${unit}`; |
| card.querySelector('.indicator-target').textContent = `${higherIsBetter ? '≥' : '≤'} ${target} ${unit}`; |
| |
| |
| const progressBar = card.querySelector('.progress-bar'); |
| progressBar.style.width = `${higherIsBetter ? |
| Math.min(100, (current / target) * 100) : |
| Math.max(0, 100 - (current / target) * 100)}%`; |
| progressBar.className = `progress-bar h-2 rounded-full ${getStatusColor(score)}`; |
| } |
| |
| function getScore(current, target, higherIsBetter) { |
| return higherIsBetter ? |
| Math.min(100, (current / target) * 100) : |
| Math.max(0, 100 - (current / target) * 100); |
| } |
| |
| function getStatusClass(score) { |
| if (score >= 80) return 'bg-green-100 text-green-800'; |
| if (score >= 50) return 'bg-yellow-100 text-yellow-800'; |
| return 'bg-red-100 text-red-800'; |
| } |
| |
| function getStatusColor(score) { |
| if (score >= 80) return 'bg-green-500'; |
| if (score >= 50) return 'bg-yellow-500'; |
| return 'bg-red-500'; |
| } |
| |
| function getStatusText(score) { |
| if (score >= 80) return 'Good'; |
| if (score >= 50) return 'Moderate'; |
| return 'Critical'; |
| } |
| |
| function updateStatusCounts() { |
| const cards = document.querySelectorAll('.indicator-card:not(#overall-card)'); |
| let good = 0, moderate = 0, critical = 0; |
| |
| cards.forEach(card => { |
| const status = card.querySelector('.status-badge').textContent; |
| if (status === 'Good') good++; |
| else if (status === 'Moderate') moderate++; |
| else critical++; |
| }); |
| |
| document.getElementById('good-count').textContent = `${good}/${cards.length}`; |
| document.getElementById('moderate-count').textContent = `${moderate}/${cards.length}`; |
| document.getElementById('critical-count').textContent = `${critical}/${cards.length}`; |
| } |
| |
| function openIndicatorModal(id) { |
| const indicatorNames = [ |
| '', |
| 'Unsafe Actions', |
| 'Unsafe Conditions', |
| 'Stop Work Authority', |
| 'Data Self-Service', |
| 'Reliability Score', |
| 'Compliance Score', |
| 'Verification', |
| 'CCTV Findings', |
| 'NPT Rig' |
| ]; |
| |
| document.getElementById('modal-title').textContent = `Update ${indicatorNames[id]} Data`; |
| document.getElementById('indicator-id').value = id; |
| |
| |
| const currentData = sampleData[currentRig]; |
| const values = [ |
| null, |
| currentData.unsafeActions, |
| currentData.unsafeConditions, |
| currentData.stopWorkAuthority, |
| currentData.dataSelfService, |
| currentData.reliabilityScore, |
| currentData.complianceScore, |
| currentData.verification, |
| currentData.cctvFindings, |
| currentData.nptRig |
| ]; |
| |
| document.getElementById('indicator-value').value = values[id]; |
| |
| |
| document.getElementById('indicator-modal').classList.remove('hidden'); |
| } |
| |
| function closeIndicatorModal() { |
| document.getElementById('indicator-modal').classList.add('hidden'); |
| } |
| |
| function saveIndicatorData() { |
| const id = parseInt(document.getElementById('indicator-id').value); |
| const newValue = parseFloat(document.getElementById('indicator-value').value); |
| |
| if (isNaN(newValue)) { |
| alert('Please enter a valid number'); |
| return; |
| } |
| |
| |
| const fields = [ |
| '', |
| 'unsafeActions', |
| 'unsafeConditions', |
| 'stopWorkAuthority', |
| 'dataSelfService', |
| 'reliabilityScore', |
| 'complianceScore', |
| 'verification', |
| 'cctvFindings', |
| 'nptRig' |
| ]; |
| |
| sampleData[currentRig][fields[id]] = newValue; |
| |
| |
| updateDashboard(currentRig); |
| closeIndicatorModal(); |
| } |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| updateDashboard('Rig 101'); |
| }); |
| </script> |
| <style> |
| .indicator-card { |
| transition: all 0.3s ease; |
| } |
| .indicator-card:hover { |
| transform: translateY(-5px); |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| } |
| .progress-bar { |
| height: 8px; |
| border-radius: 4px; |
| transition: width 0.5s ease; |
| } |
| .gauge { |
| width: 120px; |
| height: 120px; |
| position: relative; |
| border-radius: 50%; |
| background: conic-gradient( |
| #EF4444 0% 25%, |
| #F59E0B 25% 50%, |
| #10B981 50% 100% |
| ); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| margin: 0 auto; |
| } |
| .gauge::before { |
| content: ''; |
| position: absolute; |
| width: 80%; |
| height: 80%; |
| background: white; |
| border-radius: 50%; |
| } |
| .gauge-value { |
| position: relative; |
| font-weight: bold; |
| font-size: 1.5rem; |
| } |
| .modal-overlay { |
| background-color: rgba(0, 0, 0, 0.5); |
| } |
| .rig-option { |
| transition: all 0.2s ease; |
| cursor: pointer; |
| } |
| .rig-option:hover:not(.bg-primary) { |
| background-color: #E0E7FF; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50"> |
| <div class="min-h-screen"> |
| |
| <header class="bg-white shadow-sm"> |
| <div class="max-w-7xl mx-auto px-4 py-4 sm:px-6 lg:px-8 flex justify-between items-center"> |
| <div class="flex items-center"> |
| <i class="fas fa-oil-rig text-blue-500 text-2xl mr-3"></i> |
| <h1 class="text-xl font-bold text-gray-800">Rig Performance Dashboard</h1> |
| </div> |
| <div class="flex items-center space-x-4"> |
| <div class="relative"> |
| <i class="fas fa-bell text-gray-500 text-xl"></i> |
| <span class="absolute top-0 right-0 h-2 w-2 rounded-full bg-red-500"></span> |
| </div> |
| <div class="flex items-center"> |
| <img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""> |
| <span class="ml-2 text-sm font-medium text-gray-700">Rig Supervisor</span> |
| </div> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <main class="max-w-7xl mx-auto px-4 py-6 sm:px-6 lg:px-8"> |
| |
| <div class="mb-8"> |
| <div class="flex justify-between items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Rig Operational Performance</h2> |
| <div class="flex space-x-3"> |
| <div class="relative"> |
| <select class="appearance-none bg-white border border-gray-300 rounded-md pl-3 pr-8 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary"> |
| <option>Last 7 Days</option> |
| <option>Last 30 Days</option> |
| <option>Last 90 Days</option> |
| <option selected>This Year</option> |
| </select> |
| <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"> |
| <i class="fas fa-chevron-down text-xs"></i> |
| </div> |
| </div> |
| <button class="bg-primary hover:bg-primary-dark text-white px-4 py-2 rounded-md text-sm font-medium flex items-center"> |
| <i class="fas fa-download mr-2"></i> Export |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div class="mb-6 bg-white rounded-lg shadow p-4"> |
| <h3 class="text-lg font-medium text-gray-800 mb-3">Select Rig</h3> |
| <div class="grid grid-cols-2 md:grid-cols-5 gap-2"> |
| <div class="rig-option bg-primary text-white text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 101')"> |
| Rig 101 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 102')"> |
| Rig 102 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 103')"> |
| Rig 103 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 104')"> |
| Rig 104 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 105')"> |
| Rig 105 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 106')"> |
| Rig 106 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 107')"> |
| Rig 107 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 108')"> |
| Rig 108 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 109')"> |
| Rig 109 |
| </div> |
| <div class="rig-option bg-gray-100 text-gray-800 text-center py-2 px-4 rounded-md" |
| onclick="updateDashboard('Rig 110')"> |
| Rig 110 |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6"> |
| <div id="overall-card" class="bg-white rounded-lg shadow p-4 indicator-card"> |
| <div class="flex justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Overall Score</p> |
| <h3 id="overall-score" class="text-2xl font-bold text-gray-800">78%</h3> |
| </div> |
| <div class="gauge"> |
| <span id="overall-gauge-value" class="gauge-value">78%</span> |
| </div> |
| </div> |
| <div class="mt-2"> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-primary h-2 rounded-full" style="width: 78%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-white rounded-lg shadow p-4 indicator-card"> |
| <div class="flex justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Good Indicators</p> |
| <h3 id="good-count" class="text-2xl font-bold text-gray-800">5/9</h3> |
| </div> |
| <div class="p-3 rounded-full bg-green-100 text-green-600"> |
| <i class="fas fa-check-circle text-xl"></i> |
| </div> |
| </div> |
| <p class="text-xs text-gray-500 mt-2">Meeting or exceeding targets</p> |
| </div> |
| <div class="bg-white rounded-lg shadow p-4 indicator-card"> |
| <div class="flex justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Needs Attention</p> |
| <h3 id="moderate-count" class="text-2xl font-bold text-gray-800">2/9</h3> |
| </div> |
| <div class="p-3 rounded-full bg-yellow-100 text-yellow-600"> |
| <i class="fas fa-exclamation-triangle text-xl"></i> |
| </div> |
| </div> |
| <p class="text-xs text-gray-500 mt-2">Approaching critical levels</p> |
| </div> |
| <div class="bg-white rounded-lg shadow p-4 indicator-card"> |
| <div class="flex justify-between"> |
| <div> |
| <p class="text-sm font-medium text-gray-500">Critical Issues</p> |
| <h3 id="critical-count" class="text-2xl font-bold text-gray-800">2/9</h3> |
| </div> |
| <div class="p-3 rounded-full bg-red-100 text-red-600"> |
| <i class="fas fa-times-circle text-xl"></i> |
| </div> |
| </div> |
| <p class="text-xs text-gray-500 mt-2">Immediate action required</p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> |
| |
| <div id="indicator-1" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">Unsafe Actions</h3> |
| <p class="text-sm text-gray-500">Unsafe Action Findings</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">8 cases</span> |
| <span class="indicator-target">≤ 10 cases</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full" style="width: 80%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(1)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-2" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">Unsafe Conditions</h3> |
| <p class="text-sm text-gray-500">Unsafe Condition Findings</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Moderate</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">12 cases</span> |
| <span class="indicator-target">≤ 15 cases</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-yellow-500 h-2 rounded-full" style="width: 60%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(2)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-3" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">Stop Work Authority</h3> |
| <p class="text-sm text-gray-500">SWA Findings</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">5 cases</span> |
| <span class="indicator-target">≤ 5 cases</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full" style="width: 100%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(3)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-4" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">Data Self-Service</h3> |
| <p class="text-sm text-gray-500">Employee Self-Service Rate</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">72%</span> |
| <span class="indicator-target">≥ 60%</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full" style="width: 120%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(4)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-5" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">Reliability Score</h3> |
| <p class="text-sm text-gray-500">Equipment Reliability</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">85%</span> |
| <span class="indicator-target">≥ 80%</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full, style="width: 106%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(5)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-6" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">Compliance Score</h3> |
| <p class="text-sm text-gray-500">Regulatory Compliance</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">88%</span> |
| <span class="indicator-target">≥ 80%</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full" style="width: 110%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(6)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-7" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">Verification</h3> |
| <p class="text-sm text-gray-500">V&V Activities Completed</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">28%</span> |
| <span class="indicator-target">≥ 25%</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full" style="width: 112%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(7)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-8" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">CCTV Findings</h3> |
| <p class="text-sm text-gray-500">i-CCTV Findings</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">8 cases</span> |
| <span class="indicator-target">≤ 10 cases</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full" style="width: 80%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(8)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="indicator-9" class="bg-white rounded-lg shadow overflow-hidden indicator-card"> |
| <div class="p-5"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h3 class="text-lg font-semibold text-gray-800">NPT Rig</h3> |
| <p class="text-sm text-gray-500">Non-Productive Time</p> |
| </div> |
| <span class="status-badge px-2 py-1 text-xs font-semibold rounded-full">Good</span> |
| </div> |
| <div class="mt-4"> |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> |
| <span class="indicator-value">3.2 hours</span> |
| <span class="indicator-target">≤ 3.5 hours</span> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2"> |
| <div class="progress-bar bg-green-500 h-2 rounded-full" style="width: 91%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-5 py-3 border-t border-gray-200"> |
| <button onclick="openIndicatorModal(9)" class="text-primary hover:text-primary-dark text-sm font-medium flex items-center"> |
| <i class="fas fa-edit mr-1"></i> Update Status |
| </button> |
| </div> |
| </div> |
| </div> |
| </main> |
| </div> |
|
|
| |
| <div id="indicator-modal" class="hidden fixed inset-0 z-50 overflow-y-auto"> |
| <div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> |
| <div class="fixed inset-0 transition-opacity modal-overlay" aria-hidden="true"> |
| <div class="absolute inset-0 bg-gray-500 opacity-75"></div> |
| </div> |
| <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span> |
| <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"> |
| <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4"> |
| <h3 id="modal-title" class="text-lg leading-6 font-medium text-gray-900 mb-4">Update Indicator Data</h3> |
| <input type="hidden" id="indicator-id"> |
| <div class="mb-4"> |
| <label for="indicator-value" class="block text-sm font-medium text-gray-700">Current Value</label> |
| <input type="number" id="indicator-value" class="mt-1 focus:ring-primary focus:border-primary block w-full shadow-sm sm:text-sm border-gray-300 rounded-md"> |
| </div> |
| </div> |
| <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"> |
| <button type="button" onclick="saveIndicatorData()" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-primary text-base font-medium text-white hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary sm:ml-3 sm:w-auto sm:text-sm"> |
| Save |
| </button> |
| <button type="button" onclick="closeIndicatorModal()" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"> |
| Cancel |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=alterzick/rig-performance-dashboard" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |