Add notes toggle for projects and parts

This commit is contained in:
chris 2025-12-09 11:49:30 -05:00
parent 710b32191a
commit d3391dce3b
2 changed files with 57 additions and 4 deletions

View File

@ -161,8 +161,10 @@ if (projects.length > 0) {
projects.forEach((p, index) => { projects.forEach((p, index) => {
if (!p.parts) { p.parts = []; changed = true; } if (!p.parts) { p.parts = []; changed = true; }
if (!p.color) { p.color = colors[index % colors.length]; changed = true; } if (!p.color) { p.color = colors[index % colors.length]; changed = true; }
if (p.note === undefined) { p.note = ''; changed = true; }
p.parts.forEach(pt => { p.parts.forEach(pt => {
if (pt.max === undefined) { pt.max = null; changed = true; } if (pt.max === undefined) { pt.max = null; changed = true; }
if (pt.note === undefined) { pt.note = ''; changed = true; }
}); });
}); });
if (changed) { localStorage.setItem('crochetCounters', JSON.stringify(projects)); } if (changed) { localStorage.setItem('crochetCounters', JSON.stringify(projects)); }
@ -319,9 +321,9 @@ function closeModal() {
part.name = val; part.name = val;
} }
else if (modalState.type === 'renameProject') { else if (modalState.type === 'renameProject') {
const project = projects.find(p => p.id === modalState.pId); const project = projects.find(p => p.id === modalState.pId);
project.name = val; project.name = val;
} }
else if (modalState.type === 'manualCount') { else if (modalState.type === 'manualCount') {
const num = parseInt(val); const num = parseInt(val);
if (!isNaN(num) && num >= 0) { if (!isNaN(num) && num >= 0) {
@ -345,7 +347,26 @@ function closeModal() {
save(); save();
closeModal(); closeModal();
} }
modalInput.addEventListener("keyup", (e) => { if (e.key === "Enter") saveModal(); }); modalInput.addEventListener("keyup", (e) => { if (e.key === "Enter") saveModal(); });
function toggleNote(id) {
const el = document.getElementById(id);
if (!el) return;
el.classList.toggle('show');
}
function updateProjectNote(e, pId) {
const project = projects.find(p => p.id === pId);
project.note = e.target.value;
save();
}
function updatePartNote(e, pId, partId) {
const project = projects.find(p => p.id === pId);
const part = project.parts.find(pt => pt.id === partId);
part.note = e.target.value;
save();
}
// --- Render Logic --- // --- Render Logic ---
function render() { function render() {
@ -371,6 +392,7 @@ function render() {
const lockBtnClass = part.locked ? 'btn-lock locked-active' : 'btn-lock'; const lockBtnClass = part.locked ? 'btn-lock locked-active' : 'btn-lock';
const controlsDimmed = (part.locked || part.finished) ? 'dimmed' : ''; const controlsDimmed = (part.locked || part.finished) ? 'dimmed' : '';
const hideControls = part.finished ? 'hidden-controls' : ''; const hideControls = part.finished ? 'hidden-controls' : '';
const partNoteId = `part-note-${project.id}-${part.id}`;
partsHtml += ` partsHtml += `
<div class="part-card ${isLocked} ${isFinished} ${isMinimized}"> <div class="part-card ${isLocked} ${isFinished} ${isMinimized}">
@ -399,12 +421,17 @@ function render() {
<button class="action-btn ${lockBtnClass}" onclick="togglePartLock(${project.id}, ${part.id})">${lockIcon}</button> <button class="action-btn ${lockBtnClass}" onclick="togglePartLock(${project.id}, ${part.id})">${lockIcon}</button>
<button class="action-btn btn-plus ${controlsDimmed}" onclick="updateCount(${project.id}, ${part.id}, 1)">+</button> <button class="action-btn btn-plus ${controlsDimmed}" onclick="updateCount(${project.id}, ${part.id}, 1)">+</button>
</div> </div>
<div class="note-area" id="${partNoteId}">
<textarea placeholder="Notes for this part..." oninput="updatePartNote(event, ${project.id}, ${part.id})">${part.note || ''}</textarea>
</div>
<button class="note-toggle" onclick="toggleNote('${partNoteId}')">Notes</button>
</div>`; </div>`;
}); });
const projectContainer = document.createElement('div'); const projectContainer = document.createElement('div');
projectContainer.className = `project-container ${projectCollapsedClass}`; projectContainer.className = `project-container ${projectCollapsedClass}`;
projectContainer.style = `--project-color: ${project.color}`; projectContainer.style = `--project-color: ${project.color}`;
const projectNoteId = `project-note-${project.id}`;
projectContainer.innerHTML = ` projectContainer.innerHTML = `
<div class="project-header"> <div class="project-header">
<div class="project-title-group"> <div class="project-title-group">
@ -417,6 +444,10 @@ function render() {
<button class="btn-delete-project" onclick="deleteProject(${project.id})">×</button> <button class="btn-delete-project" onclick="deleteProject(${project.id})">×</button>
</div> </div>
</div> </div>
<div class="note-area" id="${projectNoteId}">
<textarea placeholder="Notes for this project..." oninput="updateProjectNote(event, ${project.id})">${project.note || ''}</textarea>
</div>
<button class="note-toggle" onclick="toggleNote('${projectNoteId}')">Notes</button>
<div class="part-list">${partsHtml}</div> <div class="part-list">${partsHtml}</div>
`; `;
grid.appendChild(projectContainer); grid.appendChild(projectContainer);

View File

@ -274,6 +274,28 @@ h1 {
} }
.count-subtext strong { color: var(--project-color); } .count-subtext strong { color: var(--project-color); }
.note-toggle {
background: none; border: 1px dashed var(--border); color: var(--text-muted);
padding: 4px 10px; border-radius: 10px; cursor: pointer; font-size: 0.9rem;
}
.note-toggle:hover { color: var(--project-color); border-color: var(--project-color); }
.note-area {
display: none;
margin-top: 10px;
}
.note-area.show { display: block; }
.note-area textarea {
width: 100%;
min-height: 90px;
border-radius: 10px;
border: 1px solid var(--border);
background: var(--input-bg);
color: var(--text);
padding: 10px;
font-size: 0.95rem;
resize: vertical;
}
.controls { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; padding: 0 5px; } .controls { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; padding: 0 5px; }
button.action-btn { button.action-btn {