Leistungsumfang & Meilensteine
Made by gik studio
'); w.document.close();w.focus();setTimeout(()=>w.print(),500); } function exportHTML(){ savePropAC(); const html=''+(lang==='de'?'Angebot':'Proposal')+' '+($('p-nr').value||'')+' '+buildProposalHTML(true)+' '; const a=document.createElement('a'); a.href='data:text/html;charset=utf-8,'+encodeURIComponent(html); a.download='angebot-'+($('p-nr').value||'export')+'.html'; a.click(); } function renderAll(){renderMilestones();renderTimeline();renderExclusions();renderLineItems();} // ── Autocomplete ────────────────────────────────────────────────────────── function acLoad(k){try{return JSON.parse(localStorage.getItem(k)||'[]');}catch(e){return[];}} function acSave(k,v){ if(!v||v.trim().length<2)return; const t=v.trim(),list=acLoad(k),ix=list.indexOf(t); if(ix>-1)list.splice(ix,1); list.unshift(t); if(list.length>30)list.length=30; try{localStorage.setItem(k,JSON.stringify(list));}catch(e){} } function initAC(id,k){ const inp=document.getElementById(id); if(!inp)return; const wrap=document.createElement('div'); wrap.className='ac-wrap'; inp.parentNode.insertBefore(wrap,inp); wrap.appendChild(inp); const dd=document.createElement('div'); dd.className='ac-dropdown'; wrap.appendChild(dd); let ai=-1,cur=[]; function showAC(q){ cur=acLoad(k).filter(v=>v.toLowerCase().includes(q.toLowerCase())).slice(0,8); if(!cur.length||q.length<2){dd.style.display='none';return;} dd.innerHTML=cur.map(v=>`
${v.replace(/&/g,'&').replace(/`).join(''); dd.style.display='block';ai=-1; Array.from(dd.children).forEach((el,i)=>{ el.addEventListener('mousedown',ev=>{ev.preventDefault();inp.value=cur[i];dd.style.display='none';inp.dispatchEvent(new Event('input',{bubbles:true}));inp.dispatchEvent(new Event('change',{bubbles:true}));}); }); } inp.addEventListener('input',function(){showAC(this.value.trim());}); inp.addEventListener('focus',function(){if(this.value.trim().length>=2)showAC(this.value.trim());}); inp.addEventListener('blur',()=>setTimeout(()=>{dd.style.display='none';},150)); inp.addEventListener('keydown',function(e){ const its=Array.from(dd.children); if(dd.style.display==='none'||!its.length)return; if(e.key==='ArrowDown'){e.preventDefault();ai=Math.min(ai+1,its.length-1);} else if(e.key==='ArrowUp'){e.preventDefault();ai=Math.max(ai-1,-1);} else if(e.key==='Enter'&&ai>=0){e.preventDefault();inp.value=cur[ai];dd.style.display='none';inp.dispatchEvent(new Event('input',{bubbles:true}));inp.dispatchEvent(new Event('change',{bubbles:true}));return;} else if(e.key==='Escape'){dd.style.display='none';return;} its.forEach((el,i)=>el.className='ac-item'+(i===ai?' ac-active':'')); }); } function savePropAC(){ [['f-name','prop-ac-name'],['f-job','prop-ac-job'],['f-addr','prop-ac-addr'], ['f-email','prop-ac-email'],['f-phone','prop-ac-phone'],['f-web','prop-ac-web'], ['c-name','prop-ac-cname'],['c-ref','prop-ac-cref'],['c-addr','prop-ac-caddr'], ['p-nr','prop-ac-pnr'],['p-proj','prop-ac-proj'] ].forEach(([id,k])=>{const el=$(id);if(el&&el.value.trim())acSave(k,el.value.trim());}); } // ── INIT ────────────────────────────────────────────────────────────────── $('p-date').value=new Date().toISOString().split('T')[0]; // Default milestones milestones=[ {id:1,title:'Konzeption & Design',desc:'Analyse der Anforderungen, Erstellung von Wireframes und Designkonzepten.',price:0,dur:'1 Woche'}, {id:2,title:'Entwicklung',desc:'Umsetzung des genehmigten Designs, Programmierung aller Funktionen.',price:0,dur:'2 Wochen'}, {id:3,title:'Testing & Übergabe',desc:'QualitΓ€tssicherung, Bugfixes, Dokumentation und Übergabe an den Auftraggeber.',price:0,dur:'3 Tage'}, ]; timeline=[ {id:1,phase:'Konzeption & Design',start:'',end:'',note:''}, {id:2,phase:'Entwicklung',start:'',end:'',note:''}, {id:3,phase:'Testing & Abnahme',start:'',end:'',note:''}, ]; exclusions=[ {id:1,text:lang==='de'?'Texterstellung / Copywriting':'Copywriting / content creation'}, {id:2,text:lang==='de'?'Fotografie und Bildbearbeitung':'Photography and image editing'}, {id:3,text:lang==='de'?'Hosting und Domain':'Hosting and domain'}, ]; lineItems=[ {id:1,desc:'',qty:1,price:0}, ]; renderAll(); [['f-name','prop-ac-name'],['f-job','prop-ac-job'],['f-addr','prop-ac-addr'], ['f-email','prop-ac-email'],['f-phone','prop-ac-phone'],['f-web','prop-ac-web'], ['c-name','prop-ac-cname'],['c-ref','prop-ac-cref'],['c-addr','prop-ac-caddr'], ['p-nr','prop-ac-pnr'],['p-proj','prop-ac-proj'] ].forEach(([id,k])=>initAC(id,k)); window.toggleSidebar = function() { const layout = document.querySelector('.layout'); layout.classList.toggle('collapsed'); localStorage.setItem('rechnio_sidebar_collapsed', layout.classList.contains('collapsed')); }; if(localStorage.getItem('rechnio_sidebar_collapsed')==='true'){ document.querySelector('.layout').classList.add('collapsed'); } // Global Sync: Theme & Language (function() { const savedLang = localStorage.getItem('rechnio_lang'); if (savedLang && savedLang !== lang) setLang(savedLang); const savedTheme = localStorage.getItem('rechnio_theme'); if (savedTheme === 'dark') { document.body.classList.add('dark'); document.getElementById('theme-btn').textContent = 'β˜€οΈ'; dark = true; } })();

Toolkit-Einstellungen

Globales Profil synchronisieren Teile Name, Adresse und IBAN zwischen deinen Tools.
Verbundene Tools