Skip to content

Commit d6821db

Browse files
committed
Rondes loggen + varianten + gewicht-piklijst + nieuwe voedingsitems
1 parent 6a26b65 commit d6821db

1 file changed

Lines changed: 115 additions & 31 deletions

File tree

index.html

Lines changed: 115 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
button.ghost{background:none; border:1px solid var(--line); color:var(--text); border-radius:12px; padding:10px 14px}
4242
/* detail sheet */
4343
#sheetWrap{position:fixed; inset:0; background:rgba(0,0,0,.55); display:none; z-index:20}
44-
#sheet{position:absolute; left:0; right:0; bottom:0; max-height:86%; overflow-y:auto;
44+
#sheet{position:absolute; left:0; right:0; bottom:0; max-height:86%; overflow-y:auto; padding-top:20px;
4545
background:var(--card); border-radius:20px 20px 0 0; padding:20px 16px 30px}
4646
#sheet h2{margin:0 0 4px; font-size:1.1rem}
4747
.badge{display:inline-block; font-size:.72rem; background:var(--card2); color:var(--muted);
@@ -57,6 +57,9 @@
5757
.chips{display:flex; flex-wrap:wrap; gap:6px}
5858
.chip{background:var(--card2); border:1px solid var(--line); color:var(--text); border-radius:10px; padding:8px 10px; font-size:.82rem}
5959
.chip b{color:var(--accent); font-weight:700}
60+
.chip.on{border-color:var(--accent); color:var(--accent); font-weight:600}
61+
.xclose{position:absolute; top:12px; right:12px; background:var(--card2); border:0; color:var(--muted);
62+
font-size:1.05rem; padding:6px 11px; border-radius:10px}
6063
.entry{display:flex; align-items:center; gap:8px; background:var(--card2); border-radius:10px; padding:8px 10px; margin-top:6px; font-size:.88rem}
6164
.entry span:first-child{flex:1}
6265
.entry button{background:none; border:0; color:var(--muted); font-size:1rem; padding:2px 6px}
@@ -237,8 +240,19 @@ <h1 id="titel">Training</h1>
237240
}
238241

239242
/* ---------- helpers ---------- */
243+
function rondeEntries(id){
244+
const ann=annulled();
245+
return state.log.entries.filter(x=>x.type==='ronde'&&x.oefening===id&&!ann.has(x.ts));
246+
}
247+
function laatsteKg(id){
248+
const ann=annulled();
249+
const es=state.log.entries.filter(x=>!ann.has(x.ts)&&x.oefening===id&&(x.type==='gewicht'||x.type==='ronde')&&x.gewicht!=null);
250+
return es.length? es[es.length-1].gewicht : null;
251+
}
240252
function laatsteGewicht(oefId){
241-
const e = [...state.log.entries].reverse().find(x=>x.type==='gewicht'&&x.oefening===oefId);
253+
const ann=annulled();
254+
const es=state.log.entries.filter(x=>!ann.has(x.ts)&&x.oefening===oefId&&(x.type==='gewicht'||x.type==='ronde')&&x.gewicht!=null);
255+
const e=es[es.length-1];
242256
if(e) return e.gewicht+' kg ('+e.datum.slice(5)+')';
243257
const dag = state.schema.dagen.find(d=>(d.oefeningen||[]).some(o=>o.id===oefId&&o.vorigGewicht));
244258
if(dag){ const o=dag.oefeningen.find(o=>o.id===oefId); if(o.vorigGewicht) return o.vorigGewicht+' kg (vorige week)' }
@@ -283,6 +297,7 @@ <h1 id="titel">Training</h1>
283297
<p class="focus">${d.focus}</p>
284298
<div class="meta">${d.duur}${d.reeks? ' · '+d.reeks:''}</div>
285299
<div class="desc">${d.beschrijving}</div>`;
300+
if(d.rust) h+=`<div class="hist">⏱ ${d.rust}</div>`;
286301
if((d.oefeningen||[]).length){
287302
h+='<ul class="exlist">';
288303
d.oefeningen.forEach(o=>{
@@ -344,24 +359,37 @@ <h1 id="titel">Training</h1>
344359
<div class="hist">Eiwit /100 g staat op de verpakking; met gewicht erbij rekent de app zelf. Alles leeg? Dan telt het als "te schatten" tot Claude het 's nachts invult, en komt het item in je tik-lijst.</div></div>`;
345360
main.innerHTML=h;
346361
}
362+
function topGewichten(id, it){
363+
const telling={};
364+
((it.gewichten)||[]).forEach((g,i)=>{ telling[g]=(telling[g]||0)+(0.5-i*0.1); }); // historiek (nachtelijke taak), licht gewogen
365+
const ann=annulled();
366+
state.log.entries.filter(x=>x.type==='eiwit'&&x.item===id&&x.gram&&!ann.has(x.ts))
367+
.forEach(x=>{ telling[x.gram]=(telling[x.gram]||0)+1; });
368+
return Object.entries(telling).sort((a,b)=>b[1]-a[1]).slice(0,5).map(x=>parseFloat(x[0]));
369+
}
347370
function openEiwitSheet(id){
348371
const it=vindItem(id); if(!it) return;
349-
sheet.innerHTML=`<h2>${it.naam}</h2>
372+
const top=topGewichten(id, it);
373+
const standaard = top.length? top[0] : it.portieGram; // meest ingegeven gewicht als default
374+
let chips='';
375+
if(top.length) chips='<div class="chips" style="margin:8px 0 0">'+top.map(g=>
376+
`<button type="button" class="chip" onclick="zetGram(${g})">${g} g</button>`).join('')+'</div>';
377+
sheet.innerHTML=`<button class="xclose" type="button" onclick="closeSheet()">✕</button>
378+
<h2>${it.naam}</h2>
350379
<span class="badge">${it.eiwitPer100g} g eiwit / 100 g</span>
351380
<div class="sec">Gewicht (g)</div>
352-
<div class="logrow"><input id="gIn" type="number" inputmode="numeric" value="${it.portieGram}">
353-
<button class="ghost" onclick="resetPortie(${it.portieGram})">standaard</button></div>
381+
<div class="logrow"><input id="gIn" type="number" inputmode="numeric" value="${standaard}">
382+
<button class="ghost" type="button" onclick="zetGram(${it.portieGram})">portie</button></div>
383+
${chips}
354384
<div class="hist" id="gPrev"></div>
355-
<br><button class="primary" onclick="bevestigEiwit('${id}')">Toevoegen</button>
356-
<button class="ghost" style="width:100%;margin-top:8px" onclick="closeSheet()">Annuleren</button>`;
385+
<br><button class="primary" type="button" onclick="bevestigEiwit('${id}')">Toevoegen</button>
386+
<button class="ghost" type="button" style="width:100%;margin-top:8px" onclick="closeSheet()">Annuleren</button>`;
357387
sheetWrap.style.display='block';
358388
const upd=()=>{ const g=parseFloat(document.getElementById('gIn').value)||0;
359389
document.getElementById('gPrev').textContent='= '+Math.round(g*it.eiwitPer100g/100)+' g eiwit'; };
360390
document.getElementById('gIn').addEventListener('input',upd); upd();
361391
}
362-
function resetPortie(g){
363-
const el=document.getElementById('gIn'); el.value=g; el.dispatchEvent(new Event('input'));
364-
}
392+
function zetGram(g){ const el=document.getElementById('gIn'); el.value=g; el.dispatchEvent(new Event('input')); }
365393
function bevestigEiwit(id){
366394
const it=vindItem(id);
367395
const g=parseFloat(document.getElementById('gIn').value);
@@ -445,7 +473,7 @@ <h1 id="titel">Training</h1>
445473
h+='<div class="card"><p class="focus">Krachtprogressie</p>';
446474
const kr={};
447475
Object.entries(tr.kracht||{}).forEach(([id,v])=>{ kr[id]={naam:v.naam,punten:v.punten.slice()}; });
448-
state.log.entries.filter(x=>x.type==='gewicht'&&!ann.has(x.ts)).forEach(x=>{
476+
state.log.entries.filter(x=>(x.type==='gewicht'||(x.type==='ronde'&&x.gewicht!=null))&&!ann.has(x.ts)).forEach(x=>{
449477
const naam=(state.oef[x.oefening]||{}).naam||x.oefening;
450478
kr[x.oefening]=kr[x.oefening]||{naam,punten:[]};
451479
if(!kr[x.oefening].punten.some(p=>p.d===x.datum&&p.kg===x.gewicht)) kr[x.oefening].punten.push({d:x.datum,kg:x.gewicht});
@@ -481,35 +509,91 @@ <h1 id="titel">Training</h1>
481509
render();
482510
}
483511

484-
/* ---------- detail sheet ---------- */
485-
let curEx=null, curDatum=null;
512+
/* ---------- detail sheet (oefening + rondes) ---------- */
513+
let curEx=null, curDatum=null, curVariant=null;
514+
function fmtRonde(r, ex){
515+
let s='R'+(r.ronde||'?')+': ';
516+
if(r.reps!=null) s+=r.reps+((ex.meting==='sec')?' sec':'×');
517+
if(r.variant) s+=' '+r.variant;
518+
if(r.gewicht!=null) s+=' @'+r.gewicht+' kg';
519+
return s;
520+
}
521+
function gekozenVariant(id){
522+
if(curVariant) return curVariant;
523+
const rs=rondeEntries(id).filter(r=>r.variant);
524+
return rs.length? rs[rs.length-1].variant : null;
525+
}
526+
function kiesVariant(el,v){
527+
curVariant=v;
528+
el.parentNode.querySelectorAll('.chip').forEach(c=>c.classList.remove('on'));
529+
el.classList.add('on');
530+
}
486531
function openSheet(id, datum){
487-
curEx=id; curDatum=datum;
488-
const ex = state.oef[id]; if(!ex) return;
489-
const lg = laatsteGewicht(id);
490-
let h = `<h2>${ex.naam}</h2>
532+
curEx=id; curDatum=datum; curVariant=null;
533+
renderOefSheet();
534+
sheetWrap.style.display='block';
535+
}
536+
function renderOefSheet(){
537+
const id=curEx, datum=curDatum;
538+
const ex=state.oef[id]; if(!ex) return;
539+
const meting=ex.meting||'reps';
540+
const rondes=rondeEntries(id);
541+
const vandaag=rondes.filter(r=>r.datum===datum);
542+
const vDatums=[...new Set(rondes.filter(r=>r.datum<datum).map(r=>r.datum))].sort();
543+
const vDag=vDatums[vDatums.length-1];
544+
let h=`<button class="xclose" type="button" onclick="closeSheet()">✕</button>
545+
<h2>${ex.naam}</h2>
491546
<span class="badge">${ex.patroon}</span><span class="badge">${ex.materiaal}</span>
492547
${ex.svg? '<div class="illu">'+ex.svg+'</div>':''}
493548
<div class="sec">Uitvoering</div><div class="uitleg">${ex.uitleg}</div>
494549
<div class="sec">Progressie</div><div class="uitleg">${ex.progressie}</div>`;
495-
if(ex.logGewicht){
496-
h+=`<div class="sec">Gewicht loggen</div>
497-
${lg? '<div class="hist">Laatst: '+lg+'</div>':''}
550+
if(meting!=='geen'){
551+
if(vDag){
552+
const vorige=rondes.filter(r=>r.datum===vDag);
553+
h+=`<div class="sec">Vorige keer (${vDag.slice(8)}/${vDag.slice(5,7)})</div><div class="hist">${vorige.map(r=>fmtRonde(r,ex)).join(' · ')}</div>`;
554+
} else {
555+
const lg=laatsteGewicht(id);
556+
if(lg) h+=`<div class="sec">Vorige keer</div><div class="hist">${lg}</div>`;
557+
}
558+
if(vandaag.length){
559+
h+='<div class="sec">Vandaag</div>';
560+
vandaag.forEach(r=>{ h+=`<div class="entry"><span>${fmtRonde(r,ex)}</span><button type="button" onclick="annuleerRonde('${r.ts}')">✕</button></div>`; });
561+
}
562+
const nr=vandaag.length+1;
563+
h+=`<div class="sec">Ronde ${nr} loggen</div>
498564
<div class="logrow">
499-
<input id="wIn" type="number" inputmode="decimal" step="0.5" placeholder="kg">
500-
<button class="ghost" onclick="logGewicht()">Opslaan</button>
501-
</div>`;
565+
<input id="rIn" type="number" inputmode="numeric" placeholder="${meting==='sec'?'seconden':'aantal herhalingen'}">`;
566+
if(ex.logGewicht){
567+
const kg=laatsteKg(id);
568+
h+=`<input id="rKg" type="number" inputmode="decimal" step="0.5" placeholder="kg"${kg? ' value="'+kg+'"':''}>`;
569+
}
570+
h+='</div>';
571+
if(ex.varianten && ex.varianten.length){
572+
const gv=gekozenVariant(id);
573+
h+='<div class="chips" style="margin-top:8px">'+ex.varianten.map(v=>
574+
`<button type="button" class="chip${v===gv?' on':''}" onclick="kiesVariant(this,'${v}')">${v}</button>`).join('')+'</div>';
575+
}
576+
h+=`<button class="primary" type="button" onclick="logRonde()">Ronde ${nr} opslaan</button>
577+
<div class="hist">⏱ Rust 60–90 sec voor je aan de volgende ronde begint.</div>`;
502578
}
503-
h+='<br><button class="primary" onclick="closeSheet()">Sluiten</button>';
504-
sheet.innerHTML=h; sheetWrap.style.display='block';
579+
h+='<button class="ghost" type="button" style="width:100%;margin-top:10px" onclick="closeSheet()">Sluiten</button>';
580+
sheet.innerHTML=h;
505581
}
506-
function closeSheet(){ sheetWrap.style.display='none' }
507-
function logGewicht(){
508-
const v = parseFloat(document.getElementById('wIn').value);
509-
if(!v){ toast('Geef een gewicht in'); return }
510-
addEntry({type:'gewicht', datum:curDatum, oefening:curEx, gewicht:v});
511-
closeSheet(); render();
582+
function logRonde(){
583+
const ex=state.oef[curEx]; const meting=ex.meting||'reps';
584+
const n=parseFloat(document.getElementById('rIn').value);
585+
if(isNaN(n)||n<=0){ toast(meting==='sec'?'Geef het aantal seconden in':'Geef het aantal herhalingen in'); return }
586+
const entry={type:'ronde', datum:curDatum, oefening:curEx,
587+
ronde:rondeEntries(curEx).filter(r=>r.datum===curDatum).length+1, reps:n};
588+
const kgEl=document.getElementById('rKg');
589+
if(kgEl){ const kg=parseFloat(kgEl.value); if(!isNaN(kg)&&kg>0) entry.gewicht=kg; }
590+
const v=gekozenVariant(curEx);
591+
if(ex.varianten && v) entry.variant=v;
592+
addEntry(entry);
593+
renderOefSheet(); render();
512594
}
595+
function annuleerRonde(ts){ addEntry({type:'annuleer', datum:curDatum, ref:ts}); renderOefSheet(); render(); }
596+
function closeSheet(){ sheetWrap.style.display='none' }
513597

514598
/* ---------- toast ---------- */
515599
let toastT;

0 commit comments

Comments
 (0)