|
|
<!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> |