progresspulse-pwa
Version:
A modern PWA for tracking progress and achieving goals with iPhone-style design
2 lines (1 loc) • 5.53 kB
JavaScript
var D=Object.defineProperty;var v=(g,a,r)=>a in g?D(g,a,{enumerable:!0,configurable:!0,writable:!0,value:r}):g[a]=r;var x=(g,a,r)=>v(g,typeof a!="symbol"?a+"":a,r);import{d as F,E as C}from"./index-DqU0AOOp.js";import"./ui-DTulVQEa.js";import"./vendor-BtIrUdbE.js";import"./router-CAWuvUE2.js";import"./charts-BwVdQLxe.js";const u=class u{static getInstance(){return u.instance||(u.instance=new u),u.instance}drawTable(a,r,l,e){const t=a.internal.pageSize.width,i=(t-40)/r.length;let s=e;return a.setFillColor(240,240,240),a.rect(20,s,t-40,8,"F"),a.setDrawColor(0,0,0),a.setLineWidth(.1),a.rect(20,s,t-40,8,"S"),a.setTextColor(0,0,0),a.setFontSize(9),a.setFont("helvetica","bold"),r.forEach((n,c)=>{a.text(n,22+c*i,s+5),c<r.length-1&&a.line(20+(c+1)*i,s,20+(c+1)*i,s+8)}),s+=8,a.setFont("helvetica","normal"),a.setFontSize(8),l.forEach((n,c)=>{c%2===1&&(a.setFillColor(250,250,250),a.rect(20,s,t-40,6,"F")),a.setDrawColor(200,200,200),a.rect(20,s,t-40,6,"S"),n.forEach((d,S)=>{a.text(d,22+S*i,s+4),S<n.length-1&&a.line(20+(S+1)*i,s,20+(S+1)*i,s+6)}),s+=6}),s+10}async generateProgressReport(a,r){try{const l=await F.users.get(a);if(!l)throw new Error("User not found");let e=await F.getGoalsByUser(a);r&&r.length>0&&(e=e.filter(o=>r.includes(o.id)));const t=new C,i=t.internal.pageSize.width,s=t.internal.pageSize.height;let n=20;t.setTextColor(0,0,0),t.setFontSize(16),t.setFont("helvetica","bold"),t.text("PROGRESSPULSE",20,n),t.text("PROGRESS STATEMENT",i-20,n,{align:"right"}),n+=10,t.setDrawColor(0,0,0),t.setLineWidth(.5),t.line(20,n,i-20,n),n+=15,t.setFontSize(10),t.setFont("helvetica","normal"),t.text(`Account Holder: ${l.name}`,20,n),t.text(`Statement Date: ${new Date().toLocaleDateString()}`,i-20,n,{align:"right"}),n+=8,t.text(`Email: ${l.email}`,20,n),t.text(`Total Goals: ${e.length}`,i-20,n,{align:"right"}),n+=20;const c=["Status","Count","Percentage"],d=e.length,S=[["Completed",e.filter(o=>o.status==="completed").length.toString(),`${(e.filter(o=>o.status==="completed").length/d*100).toFixed(1)}%`],["Active",e.filter(o=>o.status==="active").length.toString(),`${(e.filter(o=>o.status==="active").length/d*100).toFixed(1)}%`],["Paused",e.filter(o=>o.status==="paused").length.toString(),`${(e.filter(o=>o.status==="paused").length/d*100).toFixed(1)}%`]];t.setFontSize(12),t.setFont("helvetica","bold"),t.text("ACCOUNT SUMMARY",20,n),n+=10,n=this.drawTable(t,c,S,n),t.setFontSize(12),t.setFont("helvetica","bold"),t.text("GOAL TRANSACTIONS",20,n),n+=10;const f=["Date","Goal","Category","Progress","Status","Target"],P=e.map(o=>[new Date(o.createdAt).toLocaleDateString(),o.title.length>20?o.title.substring(0,20)+"...":o.title,o.category,`${o.targetValue?(o.currentValue/o.targetValue*100).toFixed(1):"0"}%`,o.status.toUpperCase(),`${o.targetValue}${o.unit||""}`]);n=this.drawTable(t,f,P,n);for(const o of e){const m=await F.getProgressByGoal(o.id);if(m.length===0)continue;n>s-60&&(t.addPage(),n=20),t.setFontSize(11),t.setFont("helvetica","bold"),t.text(`PROGRESS ENTRIES - ${o.title.toUpperCase()}`,20,n),n+=10;const $=["Date","Value","Running Total","Note"],z=m.map(h=>[new Date(h.date).toLocaleDateString(),`+${h.value}${o.unit||""}`,`${h.value}${o.unit||""}`,h.note?h.note.length>30?h.note.substring(0,30)+"...":h.note:"-"]);n=this.drawTable(t,$,z,n)}const w=t.internal.pages.length-1;for(let o=1;o<=w;o++)t.setPage(o),t.setDrawColor(0,0,0),t.setLineWidth(.5),t.line(20,s-20,i-20,s-20),t.setTextColor(0,0,0),t.setFontSize(8),t.setFont("helvetica","normal"),t.text(`Page ${o} of ${w}`,i-20,s-10,{align:"right"}),t.text("ProgressPulse - Progress Tracking Platform",20,s-10);const T=`progress-statement-${new Date().toISOString().split("T")[0]}.pdf`;t.save(T)}catch(l){throw console.error("Failed to generate PDF report:",l),l}}async generateGoalCertificate(a){try{const r=await F.goals.get(a);if(!r||r.status!=="completed")throw new Error("Goal not found or not completed");const l=await F.users.get(r.userId);if(!l)throw new Error("User not found");const e=new C("landscape"),t=e.internal.pageSize.width,i=e.internal.pageSize.height;e.setDrawColor(0,0,0),e.setLineWidth(2),e.rect(20,20,t-40,i-40),e.setLineWidth(.5),e.rect(25,25,t-50,i-50),e.setTextColor(0,0,0),e.setFontSize(24),e.setFont("helvetica","bold"),e.text("CERTIFICATE OF COMPLETION",t/2,60,{align:"center"}),e.setFontSize(18),e.setFont("helvetica","normal"),e.text("This certifies that",t/2,90,{align:"center"}),e.setFontSize(20),e.setFont("helvetica","bold"),e.text(l.name.toUpperCase(),t/2,110,{align:"center"}),e.setFontSize(18),e.setFont("helvetica","normal"),e.text("has successfully completed",t/2,130,{align:"center"}),e.setFontSize(16),e.setFont("helvetica","bold"),e.text(r.title.toUpperCase(),t/2,150,{align:"center"}),e.setFontSize(12),e.setFont("helvetica","normal");const s=r.updatedAt?new Date(r.updatedAt).toLocaleDateString():new Date().toLocaleDateString();e.text(`Completion Date: ${s}`,t/2,170,{align:"center"}),e.text(`Target: ${r.targetValue}${r.unit||""} | Category: ${r.category}`,t/2,185,{align:"center"});const n=`PP-${r.id.slice(0,8).toUpperCase()}`;e.setFontSize(10),e.text(`Certificate ID: ${n}`,t/2,i-40,{align:"center"}),e.text("ProgressPulse Platform",t/2,i-30,{align:"center"});const c=`certificate-${r.title.replace(/[^a-zA-Z0-9]/g,"-").toLowerCase()}.pdf`;e.save(c)}catch(r){throw console.error("Failed to generate certificate:",r),r}}};x(u,"instance");let p=u;const E=p.getInstance(),y=(g,a)=>E.generateProgressReport(g,a);export{p as PDFExportService,y as generateProgressReport,E as pdfExportService};