-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e6cb8e0
commit 94899a3
Showing
2 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
let events = []; | ||
let timer = null; | ||
let currentTimerIndex = 0; | ||
|
||
|
||
document.addEventListener('DOMContentLoaded', (event) => { | ||
function updateEventsList() { | ||
const eventsTableBody = document.getElementById('eventsUl'); | ||
eventsTableBody.innerHTML = ''; | ||
|
||
events.forEach(event => { | ||
const row = document.createElement('tr'); | ||
|
||
const nameCell = document.createElement('td'); | ||
nameCell.textContent = event.name; | ||
row.appendChild(nameCell); | ||
|
||
const durationCell = document.createElement('td'); | ||
durationCell.textContent = `${event.duration} seconds`; | ||
row.appendChild(durationCell); | ||
|
||
eventsTableBody.appendChild(row); | ||
}); | ||
} | ||
|
||
function updateStartButton() { | ||
document.getElementById('startTimer').disabled = events.length === 0; | ||
} | ||
|
||
function updateTimerDisplay(seconds, eventName = '') { | ||
const formatted = new Date(seconds * 1000).toISOString().substr(11, 8); | ||
document.getElementById('timer').textContent = formatted; | ||
document.getElementById('currentEventName').textContent = eventName || 'Waiting for next event...'; | ||
} | ||
|
||
function startEventTimer() { | ||
if (currentTimerIndex >= events.length) { | ||
currentTimerIndex = 0; | ||
return; | ||
} | ||
|
||
const event = events[currentTimerIndex]; | ||
if (!event.start) event.start = Date.now(); | ||
|
||
const eventName = events[currentTimerIndex].name; | ||
updateTimerDisplay(event.duration, eventName); | ||
|
||
timer = setInterval(() => { | ||
if (event.duration <= 0) { | ||
clearInterval(timer); | ||
event.end = Date.now(); | ||
appendToTable(event); | ||
currentTimerIndex++; | ||
|
||
if (currentTimerIndex < events.length) { | ||
startEventTimer(); | ||
} else { | ||
currentTimerIndex = 0; | ||
} | ||
} else { | ||
event.duration--; | ||
const eventName = events[currentTimerIndex].name; | ||
updateTimerDisplay(event.duration, eventName); | ||
} | ||
}, 1000); | ||
} | ||
|
||
function appendToTable(event) { | ||
const tableBody = document.getElementById('eventTable').getElementsByTagName('tbody')[0]; | ||
const row = tableBody.insertRow(); | ||
const nameCell = row.insertCell(0); | ||
const startCell = row.insertCell(1); | ||
const endCell = row.insertCell(2); | ||
nameCell.textContent = event.name; | ||
startCell.textContent = new Date(event.start).toLocaleString(); | ||
endCell.textContent = new Date(event.end).toLocaleString(); | ||
} | ||
|
||
document.getElementById('addEvent').addEventListener('click', () => { | ||
console.log("hello, from event adder"); | ||
const name = document.getElementById('eventName').value.trim(); | ||
const duration = parseInt(document.getElementById('eventDuration').value.trim(), 10); | ||
if (name && duration > 0) { | ||
events.push({ name, duration, start: null, end: null }); | ||
document.getElementById('eventName').value = ''; | ||
document.getElementById('eventDuration').value = ''; | ||
updateStartButton(); | ||
} | ||
|
||
updateEventsList(); | ||
|
||
const exportableEvents = events.map(({name, duration}) => ({name, duration})); | ||
document.getElementById('importJsonText').value = JSON.stringify(exportableEvents, null, 2); | ||
|
||
console.log('events', events); | ||
}); | ||
|
||
document.getElementById('exportCsv').addEventListener('click', () => { | ||
console.log("events", events); | ||
|
||
const headers = "Name,Start,End\n"; | ||
|
||
const csvRows = events.map(e => { | ||
const start = e.start ? e.start : ''; | ||
const end = e.end ? e.end : ''; | ||
return `${e.name},${start},${end}`; | ||
}); | ||
|
||
const csvContent = headers + csvRows.join("\n"); | ||
|
||
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); | ||
const url = URL.createObjectURL(blob); | ||
|
||
const link = document.createElement('a'); | ||
link.href = url; | ||
link.download = 'events.csv'; | ||
document.body.appendChild(link); | ||
link.click(); | ||
document.body.removeChild(link); | ||
}); | ||
|
||
document.getElementById('importJson').addEventListener('click', () => { | ||
const input = document.getElementById('importJsonText').value; | ||
try { | ||
const importedEvents = JSON.parse(input); | ||
if (Array.isArray(importedEvents)) { | ||
events = importedEvents; | ||
updateEventsList(); | ||
updateStartButton(); | ||
} else { | ||
alert('Invalid JSON: Expected an array of events.'); | ||
} | ||
} catch (e) { | ||
alert('Invalid JSON format.'); | ||
} | ||
}); | ||
|
||
document.getElementById('startTimer').addEventListener('click', () => { | ||
if (events.length > 0) { | ||
startEventTimer(); | ||
} | ||
}); | ||
|
||
updateStartButton(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Event Timer</title> | ||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet"> | ||
</head> | ||
<body class="p-8 bg-gray-100"> | ||
<div class="text-center"> | ||
<h1 class="text-4xl font-bold mb-4">Wireless and Mobile Health Event Timer</h1> | ||
<div id="currentEventName" class="text-3xl font-bold mb-2">--</div> | ||
<div id="timer" class="text-6xl font-mono mb-4">00:00:00</div> | ||
<button id="startTimer" class="bg-green-500 text-white px-8 py-4 mb-8" disabled>Start</button> | ||
</div> | ||
|
||
<div class="flex justify-center space-x-10"> | ||
<div class="bg-white p-6 rounded-lg shadow-lg"> | ||
<input type="text" id="eventName" placeholder="Event Name" class="border p-2 w-full mb-2"> | ||
<input type="number" id="eventDuration" placeholder="Duration (seconds)" class="border p-2 w-full mb-4"> | ||
<button id="addEvent" class="bg-blue-500 text-white px-4 py-2 w-full">Add Event</button> | ||
|
||
<div id="eventsList" class="mt-4"> | ||
<h2 class="text-lg mb-2">Events List</h2> | ||
<div class="max-h-64 overflow-y-auto"> | ||
<table class="w-full text-left"> | ||
<thead class="bg-gray-200"> | ||
<tr> | ||
<th class="px-4 py-2">Name</th> | ||
<th class="px-4 py-2">Duration</th> | ||
</tr> | ||
</thead> | ||
<tbody id="eventsUl"> | ||
<!-- Events will be dynamically added here --> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
<h3 class="text-lg mt-4">Event JSON</h3> | ||
<textarea id="importJsonText" placeholder="JSON will be updated here..." class="border p-2 w-full mt-4 h-32"></textarea> | ||
<button id="importJson" class="bg-blue-500 text-white px-4 py-2 mt-2 w-full">Import Events</button> | ||
</div> | ||
|
||
<div class="bg-white p-6 rounded-lg shadow-lg"> | ||
<div class="mb-4"> | ||
<table class="w-full text-left" id="eventTable"> | ||
<thead class="bg-gray-200"> | ||
<tr> | ||
<th class="px-4 py-2">Name</th> | ||
<th class="px-4 py-2">Start</th> | ||
<th class="px-4 py-2">End</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<!-- Timer events will be listed here --> | ||
</tbody> | ||
</table> | ||
</div> | ||
<button id="exportCsv" class="bg-gray-500 text-white px-4 py-2 mt-4 w-full">Export as CSV</button> | ||
</div> | ||
</div> | ||
|
||
<script src="app.js"></script> | ||
</body> | ||
</html> |