basic initial code
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,3 @@
|
||||
node_modules
|
||||
package.json
|
||||
package-lock.json
|
||||
dist
|
||||
/.cache
|
||||
31
.vscode/tasks.json
vendored
Normal file
31
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build TypeScript and Bundle Static Site",
|
||||
"type": "shell",
|
||||
"command": "cd ${workspaceFolder}; source nodetopath.sh; npm run build",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Clean site",
|
||||
"type": "shell",
|
||||
"command": "cd ${workspaceFolder}; rm -rf dist",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
3
init.sh
3
init.sh
@@ -3,5 +3,8 @@
|
||||
#source node binaries
|
||||
. nodetopath.sh
|
||||
npm install -g typescript
|
||||
npm install -g ts-node
|
||||
npm install --save-dev @types/node
|
||||
npm install --save-dev typescript parcel-bundler
|
||||
npm install chart.js@4.4.1
|
||||
npm install chartjs-plugin-annotation@3.1.0
|
||||
10834
package-lock.json
generated
Normal file
10834
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
package.json
Normal file
14
package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"chart.js": "^4.4.1",
|
||||
"chartjs-plugin-annotation": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.30",
|
||||
"parcel-bundler": "^1.12.5",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "parcel build src/roast.html --public-url=./ --out-dir dist"
|
||||
}
|
||||
}
|
||||
19
postcss.config.js
Normal file
19
postcss.config.js
Normal file
@@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
// Other PostCSS plugins can be listed here if you use them.
|
||||
],
|
||||
minify: true, // Ensure this is set to true so Parcel uses the provided options
|
||||
terserOptions: {
|
||||
mangle: {
|
||||
// Specify functions that should not be mangled by their names
|
||||
reserved: [
|
||||
"setPlan",
|
||||
"logEvent",
|
||||
"exportCSV",
|
||||
"resetSystem",
|
||||
"navigateTemp",
|
||||
"logTemp"
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
124
src/roast.css
Normal file
124
src/roast.css
Normal file
@@ -0,0 +1,124 @@
|
||||
body {
|
||||
background-color: #e6ccff;
|
||||
font-family: Arial, sans-serif;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#timer {
|
||||
font-size: 48px;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 2px solid #666;
|
||||
margin: 0;
|
||||
}
|
||||
#create-plan {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
#create-plan input {
|
||||
width: 80%;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
}
|
||||
#create-plan button {
|
||||
margin-top: 10px;
|
||||
padding: 10px 20px;
|
||||
font-size: 18px;
|
||||
}
|
||||
#controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.button-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
.button-group button:not(.nav-btn) {
|
||||
font-size: 20px;
|
||||
border: 2px solid #666;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.button-group .nav-btn {
|
||||
padding: 15px 25px;
|
||||
font-size: 20px;
|
||||
border: 2px solid #666;
|
||||
background-color: #E8E;
|
||||
color: #333;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.button-group button:active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
#event-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
margin: 20px;
|
||||
}
|
||||
#event-buttons button {
|
||||
padding: 15px 25px;
|
||||
font-size: 20px;
|
||||
border: 2px solid #666;
|
||||
background-color: #afa;
|
||||
color: #333;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#event-buttons button:active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
#log-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#log-table table {
|
||||
table-layout: fixed;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
}
|
||||
#log-table th, #log-table td {
|
||||
border: 1px solid #666;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
#log-table th {
|
||||
background-color: #f0e6ff;
|
||||
}
|
||||
#export-csv {
|
||||
margin: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
#export-csv button {
|
||||
padding: 10px 20px;
|
||||
font-size: 18px;
|
||||
border: 2px solid #666;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#export-csv button:active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
#temp-buttons {
|
||||
margin: 8px;
|
||||
}
|
||||
#temp-buttons button {
|
||||
text-align: center;
|
||||
width: 3.5em;
|
||||
}
|
||||
44
src/roast.html
Normal file
44
src/roast.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Stovetop Coffee Roast Logger</title>
|
||||
<link rel="stylesheet" href="./roast.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="timer">0:00</div>
|
||||
<div id="create-plan">
|
||||
<input type="text" id="plan-input" placeholder="Enter temperatures (comma separated)">
|
||||
<button onclick="setPlan()">Set Plan</button>
|
||||
</div>
|
||||
<div id="controls" class="hidden">
|
||||
<div id="temp-buttons" class="button-group"></div>
|
||||
<div id="event-buttons" class="button-group">
|
||||
<button onclick="logEvent('Charge')">Charge</button>
|
||||
<button onclick="logEvent('Yellow')">Yellow</button>
|
||||
<button onclick="logEvent('First Crack')">First Crack</button>
|
||||
<button onclick="logEvent('Second Crack')">Second Crack</button>
|
||||
<button onclick="logEvent('Drop')">Drop</button>
|
||||
</div>
|
||||
<div id="export-csv">
|
||||
<button onclick="exportCSV()">Export CSV</button>
|
||||
<button onclick="resetSystem()">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="log-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>Event</th>
|
||||
<th>Temperature</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="log-body">
|
||||
<!-- Log entries will be inserted here -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script src="./roast.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
23
src/roast.ts
23
src/roast.ts
@@ -5,6 +5,7 @@ let targets: number[] = [];
|
||||
let currentTargetIndex = 0;
|
||||
let interval: NodeJS.Timeout | null = null;
|
||||
|
||||
|
||||
function startTimer(): void {
|
||||
if (isRunning) {
|
||||
alert("Timer is already running. Click again to reset.");
|
||||
@@ -36,20 +37,20 @@ function logEvent(eventName: string): void {
|
||||
isRunning = false;
|
||||
}
|
||||
startTimer();
|
||||
log.push({ time: formatTime(timer), event: eventName, temp: null });
|
||||
log.push({ time: formatTime(timer), event: eventName });
|
||||
updateLog();
|
||||
return;
|
||||
}
|
||||
if (eventName === "Drop") {
|
||||
stopTimer();
|
||||
log.push({ time: formatTime(timer), event: eventName, temp: null });
|
||||
log.push({ time: formatTime(timer), event: eventName });
|
||||
updateLog();
|
||||
document.getElementById("create-plan")!.classList.add("hidden");
|
||||
document.getElementById("create-plan")!.classList.remove("hidden");
|
||||
const tempButtons = document.getElementById("temp-buttons")!;
|
||||
tempButtons.innerHTML = "";
|
||||
return;
|
||||
}
|
||||
log.push({ time: formatTime(timer), event: eventName, temp: null });
|
||||
log.push({ time: formatTime(timer), event: eventName });
|
||||
updateLog();
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ function resetSystem(): void {
|
||||
stopTimer();
|
||||
log = [];
|
||||
updateLog();
|
||||
document.getElementById("create-plan")!.classList.add("hidden");
|
||||
document.getElementById("create-plan")!.classList.remove("hidden");
|
||||
const tempButtons = document.getElementById("temp-buttons")!;
|
||||
tempButtons.innerHTML = "";
|
||||
}
|
||||
@@ -136,4 +137,16 @@ function exportCSV(): void {
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
// Expose functions to the global scope
|
||||
if (typeof window !== 'undefined') {
|
||||
window.startTimer = startTimer;
|
||||
window.stopTimer = stopTimer;
|
||||
window.logEvent = logEvent;
|
||||
window.resetSystem = resetSystem;
|
||||
window.setPlan = setPlan;
|
||||
window.navigateTemp = navigateTemp;
|
||||
window.logTemp = logTemp;
|
||||
window.exportCSV = exportCSV;
|
||||
}
|
||||
Reference in New Issue
Block a user