');w.document.close();setTimeout(()=>w.print(),500)} function cust(){ $('app').innerHTML='

Customers

'+ (S.customers.length?S.customers.map(function(c){return'
'+esc(c.first_name+' '+c.last_name)+'
'+esc(c.phone||'')+' ยท '+esc(c.email||'')+' ยท '+c.vehicle_count+' vehicle(s)
'}).join(''):'
No customers
')+ '
'; } window.addCust=function(){modal('Add Customer','
',async()=>{try{await api('/customers',{method:'POST',body:JSON.stringify({shop_id:S.shopId,first_name:$('cf-fn').value,last_name:$('cf-ln').value,phone:$('cf-ph').value,email:$('cf-em').value})});toast('Added');render()}catch(e){toast(e.message,'err')}})} window.showCustVehicles=async function(cid){const v=S.vehicles.filter(v=>v.customer_id===cid);modal('Vehicles',v.length?v.map(x=>'
'+esc([x.year,x.make,x.model,x.color].filter(Boolean).join(' '))+' ยท VIN: '+esc(x.vin||'N/A')+'
').join(''):'
No vehicles
')} function veh(){modal('Add Vehicle','
',async()=>{try{await api('/vehicles',{method:'POST',body:JSON.stringify({shop_id:S.shopId,customer_id:$('vf-cust').value,make:$('vf-make').value,model:$('vf-model').value,year:parseInt($('vf-year').value)||null,color:$('vf-color').value,vin:$('vf-vin').value})});toast('Added');render()}catch(e){toast(e.message,'err')}})} function tmpl(){/* simplified for build */ $('app').innerHTML='

Templates

'+S.templates.map(t=>'
'+esc(t.name)+'
'+esc(t.description||'')+' ยท '+t.labor_hours+'hrs
').join('')+'
'} window.addTmpl=function(){modal('New Template','
',async()=>{try{await api('/templates',{method:'POST',body:JSON.stringify({shop_id:S.shopId,name:$('tf-name').value,description:$('tf-desc').value,labor_hours:parseFloat($('tf-hrs').value)})});toast('Added');render()}catch(e){toast(e.message,'err')}})} window.delTmpl=async function(id){try{await api('/templates/'+id,{method:'DELETE'});toast('Deleted');render()}catch(e){toast(e.message,'err')}} function sett(){ const s=S.settings; $('app').innerHTML='

Settings

'+ '
'+ '
'+ '
'+ '
'+ '
'; } window.saveSett=async function(){try{await api('/settings',{method:'PUT',body:JSON.stringify({shop_id:S.shopId,business_name:$('ss-name').value,business_phone:$('ss-phone').value,business_email:$('ss-email').value,business_address:$('ss-addr').value,labor_rate_hourly:parseFloat($('ss-rate').value),tax_rate:parseFloat($('ss-tax').value),parts_markup_pct:parseFloat($('ss-markup').value),booking_url:$('ss-booking').value})});toast('Saved');render()}catch(e){toast(e.message,'err')}} window.exportCSV=function(){window.open('/api/mobilemech/jobs/export?shop_id='+S.shopId,'_blank')} render(); })();