1import{p as W,r as b,j as e,C as u,c as P,e as C,q as S,a as g,$ as Z,f as k,v as Y,J as o,aW as G,s as N,R as T,F as O,B as w,A as $,T as V,O as J,w as Q,S as F,b as M,U as X}from"./index-nbQLPUsP.js";import{T as ee,a as se,b as A,c as L}from"./tabs-DIsTv2CL.js";import{B}from"./BlockchainCredentialViewer-BS7WJMuW.js";import{S as ae}from"./SEOHead-PD39hXX2.js";import{U as te}from"./upload-DdhiZ2LJ.js";import{L as I}from"./loader-circle-BALS4HTy.js";import{P as re}from"./progress-CDasyQJe.js";import{A as z,a as R}from"./alert-BFgNIA8U.js";import{T as q}from"./trending-down-D0gJvMtK.js";import{C as H}from"./clock-kZzggmxd.js";import{Z as K}from"./zap-BNo1Lq--.js";import{a as ie}from"./html2pdf-DQcv4CxK.js";import{D as le}from"./download-Bq94dB4z.js";import{S as ne}from"./share-2-COiVAN0Q.js";import{G as U}from"./graduation-cap-D0XaxbnU.js";import"./external-link-CebresAU.js";/** 2 * @license lucide-react v0.462.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const ce=W("Building",[["rect",{width:"16",height:"20",x:"4",y:"2",rx:"2",ry:"2",key:"76otgf"}],["path",{d:"M9 22v-4h6v4",key:"r93iot"}],["path",{d:"M8 6h.01",key:"1dz90k"}],["path",{d:"M16 6h.01",key:"1x0f13"}],["path",{d:"M12 6h.01",key:"1vi96p"}],["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M8 14h.01",key:"6423bh"}]]);function de({userId:i,onComplete:c}){const[m,y]=b.useState(!1),[f,l]=b.useState(!1),[x,j]=b.useState(null),a=t=>{var n;const r=(n=t.target.files)==null?void 0:n[0];if(r){if(r.type!=="application/pdf"){o.error("Please upload a PDF file");return}if(r.size>20*1024*1024){o.error("File size must be less than 20MB");return}j(r)}},h=async()=>{var t,r;if(x){y(!0);try{const n=G(i),v=`${n}/${Date.now()}_${x.name}`,{error:d}=await N.storage.from("resumes").upload(v,x,{cacheControl:"3600",upsert:!1});if(d)throw console.error("Storage upload error:",d),new Error(`Storage error: ${d.message}`);o.success("Resume uploaded! Parsing with AI..."),y(!1),l(!0);const{data:s,error:p}=await N.functions.invoke("parse-resume",{body:{resumeUrl:v,userId:n}});if(console.log("Parse resume response:",{data:s,error:p}),p){console.error("Parse resume function error:",p),l(!1),(t=p.message)!=null&&t.includes("credits")?o.error("AI Credits Exhausted",{description:"Please add credits to your workspace in Settings > Usage"}):(r=p.message)!=null&&r.includes("violates row-level security")?o.error("Permission error",{description:"Database access denied. Please contact support."}):o.error("Failed to parse resume",{description:p.message||"Unknown error occurred"});return}if(l(!1),s!=null&&s.success){const{totalSkills:D,totalEducation:_,totalEmployment:E}=s.summary;D+_+E>0?(o.success("Resume processed successfully! ð",{description:`Created ${D} skills, ${_} education, ${E} employment credentials`}),c()):o.warning("Resume processed but no data extracted",{description:"Please check if your resume has a standard format with clear sections"})}else s!=null&&s.error?o.error("Failed to parse resume",{description:s.error}):o.error("Unexpected response from parser")}catch(n){console.error("Error uploading resume:",n),o.error("Upload failed",{description:n.message||"An unexpected error occurred"}),y(!1),l(!1)}}};return e.jsxs(u,{className:"border-2 border-dashed",children:[e.jsxs(P,{children:[e.jsxs(C,{className:"flex items-center gap-2",children:[e.jsx(te,{className:"w-5 h-5"}),"Upload Resume"]}),e.jsx(S,{children:"Upload your PDF resume to automatically create blockchain credentials"})]}),e.jsxs(g,{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-col items-center justify-center border-2 border-dashed border-primary/20 rounded-lg p-8 hover:border-primary/40 transition-colors",children:[e.jsx(Z,{className:"w-12 h-12 text-primary mb-4"}),e.jsxs("label",{htmlFor:"resume-upload",className:"cursor-pointer",children:[e.jsx("input",{id:"resume-upload",type:"file",accept:".pdf",onChange:a,className:"hidden",disabled:m||f}),e.jsx(k,{variant:"outline",asChild:!0,disabled:m||f,children:e.jsx("span",{children:"Choose PDF Resume"})})]}),x&&e.jsxs("p",{className:"text-sm text-muted-foreground mt-2",children:["Selected: ",x.name]})]}),x&&e.jsx(k,{onClick:h,disabled:m||f,className:"w-full",children:m?e.jsxs(e.Fragment,{children:[e.jsx(I,{className:"mr-2 h-4 w-4 animate-spin"}),"Uploading..."]}):f?e.jsxs(e.Fragment,{children:[e.jsx(I,{className:"mr-2 h-4 w-4 animate-spin"}),"AI Parsing Resume..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Y,{className:"mr-2 h-4 w-4"}),"Parse & Create Credentials"]})}),e.jsxs("div",{className:"text-xs text-muted-foreground space-y-1",children:[e.jsx("p",{children:"⢠PDF files only (max 20MB)"}),e.jsx("p",{children:"⢠AI will extract skills, education, and employment"}),e.jsx("p",{children:"⢠Blockchain credentials created automatically"})]})]})]})}function oe({userId:i}){const[c,m]=b.useState([]),[y,f]=b.useState(!0);b.useEffect(()=>{l()},[i]);const l=async()=>{try{const t=G(i),{data:r,error:n}=await N.from("user_skills").select("skill_id, skills(name)").eq("user_id",t);if(n)throw n;const v=await Promise.all(r.map(async d=>{try{const{data:s}=await N.functions.invoke("ml-decay-prediction",{body:{userId:t,skillId:d.skill_id}});return s==null?void 0:s.prediction}catch(s){return console.error("Error getting prediction:",s),null}}));m(v.filter(d=>d!==null))}catch(t){console.error("Error loading decay data:",t),o.error("Failed to load skill decay analysis")}finally{f(!1)}},x=t=>{switch(t){case"excellent":return"text-green-600 bg-green-50 border-green-200";case"good":return"text-blue-600 bg-blue-50 border-blue-200";case"declining":return"text-amber-600 bg-amber-50 border-amber-200";case"critical":return"text-red-600 bg-red-50 border-red-200";default:return"text-gray-600 bg-gray-50 border-gray-200"}},j=t=>{switch(t){case"excellent":return e.jsx(V,{className:"h-4 w-4"});case"good":return e.jsx($,{className:"h-4 w-4"});case"declining":return e.jsx(q,{className:"h-4 w-4"});case"critical":return e.jsx(O,{className:"h-4 w-4"});default:return e.jsx(H,{className:"h-4 w-4"})}};if(y)return e.jsx(u,{children:e.jsx(g,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center py-8",children:[e.jsx(T,{className:"h-6 w-6 animate-spin text-primary"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Analyzing skill proficiency..."})]})})});const a=c.filter(t=>t.decay_status==="critical"),h=c.filter(t=>t.decay_status==="declining");return e.jsx("div",{className:"space-y-6",children:e.jsxs(u,{children:[e.jsxs(P,{children:[e.jsxs(C,{className:"flex items-center gap-2",children:[e.jsx(q,{className:"h-5 w-5"}),"ML-Powered Skill Decay Analysis"]}),e.jsx(S,{children:"Real-time proficiency tracking with machine learning predictions"})]}),e.jsxs(g,{children:[a.length>0&&e.jsxs(z,{className:"mb-4 border-red-200 bg-red-50",children:[e.jsx(O,{className:"h-4 w-4 text-red-600"}),e.jsxs(R,{className:"text-red-800",children:[e.jsxs("strong",{children:[a.length," skill(s) require immediate attention."]})," ","Refresher training strongly recommended to prevent significant proficiency loss."]})]}),h.length>0&&a.length===0&&e.jsxs(z,{className:"mb-4 border-amber-200 bg-amber-50",children:[e.jsx(H,{className:"h-4 w-4 text-amber-600"}),e.jsxs(R,{className:"text-amber-800",children:[e.jsxs("strong",{children:[h.length," skill(s) showing decline."]})," ","Consider scheduling practice sessions within the next week."]})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:c.map(t=>e.jsxs(u,{className:`border ${x(t.decay_status)}`,children:[e.jsx(P,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(C,{className:"text-sm font-medium",children:t.skill_name}),e.jsxs(w,{variant:"outline",className:x(t.decay_status),children:[j(t.decay_status),e.jsx("span",{className:"ml-1 capitalize",children:t.decay_status})]})]})}),e.jsxs(g,{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between text-sm mb-1",children:[e.jsx("span",{className:"text-muted-foreground",children:"Current Proficiency"}),e.jsxs("span",{className:"font-semibold",children:[Math.round(t.predicted_proficiency*100),"%"]})]}),e.jsx(re,{value:t.predicted_proficiency*100,className:"h-2"})]}),e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:"Days Inactive:"}),e.jsx("span",{className:"font-medium",children:t.days_inactive})]}),t.education_bonus>0&&e.jsxs("div",{className:"flex items-center gap-1 text-xs text-green-600",children:[e.jsx($,{className:"h-3 w-3"}),e.jsxs("span",{children:["+",Math.round(t.education_bonus*100),"% degree bonus"]})]}),t.employment_bonus>0&&e.jsxs("div",{className:"flex items-center gap-1 text-xs text-blue-600",children:[e.jsx(V,{className:"h-3 w-3"}),e.jsxs("span",{children:["+",Math.round(t.employment_bonus*100),"% work experience"]})]}),e.jsxs("div",{className:"pt-2 border-t",children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-2",children:t.recommendation}),t.next_refresh_in_days>0&&e.jsxs(k,{size:"sm",variant:"outline",className:"w-full",children:[e.jsx(T,{className:"h-3 w-3 mr-1"}),"Refresh in ",t.next_refresh_in_days," days"]}),t.next_refresh_in_days<=0&&e.jsxs(k,{size:"sm",variant:"default",className:"w-full",children:[e.jsx(T,{className:"h-3 w-3 mr-1"}),"Refresh Now"]})]}),e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground pt-2 border-t",children:[e.jsx("span",{children:"ML Confidence:"}),e.jsxs(w,{variant:"secondary",className:"text-xs",children:[Math.round(t.confidence_level*100),"%"]})]})]})]},t.skill_id))})]})]})})}function me({userId:i}){const[c,m]=b.useState([]),[y,f]=b.useState(!1),[l,x]=b.useState(!1),[j,a]=b.useState(null),h=async()=>{var r,n,v;f(!0);try{const[d,s,p]=await Promise.all([N.from("skill_credentials").select("credential_id, holder_user_id, created_at").eq("holder_user_id",i).is("blockchain_record_id",null).limit(20),N.from("educational_degree_credentials").select("credential_id, holder_user_id, created_at").eq("holder_user_id",i).is("blockchain_record_id",null).limit(20),N.from("employment_history_credentials").select("credential_id, holder_user_id, created_at").eq("holder_user_id",i).is("blockchain_record_id",null).limit(20)]),D=[...((r=d.data)==null?void 0:r.map(_=>({..._,credential_type:"SKILL"})))||[],...((n=s.data)==null?void 0:n.map(_=>({..._,credential_type:"EDUCATION"})))||[],...((v=p.data)==null?void 0:v.map(_=>({..._,credential_type:"EMPLOYMENT"})))||[]];m(D)}catch(d){console.error("Error loading pending credentials:",d),o.error("Failed to load pending credentials")}finally{f(!1)}},t=async()=>
6{if(c.length===0){o.error("No pending credentials to process");return}x(!0),a(null);try{o.info(`Processing ${c.length} credentials in batch...`);const r=c.map(d=>({credentialId:d.credential_id,credentialType:d.credential_type,userId:d.holder_user_id})),{data:n,error:v}=await N.functions.invoke("batch-write-to-blockchain",{body:{credentials:r}});if(v)throw v;if(n.success){a(n.gasSavings),o.success(`â ${r.length} credentials written to blockchain!`,{description:`Gas savings: ${n.gasSavings} | Block #${n.blockNumber}`});const d=r.map(async s=>{try{await N.functions.invoke("ipfs-metadata-storage",{body:{credentialId:s.credentialId,tableName:s.credentialType==="SKILL"?"skill_credentials":s.credentialType==="EDUCATION"?"educational_degree_credentials":"employment_history_credentials",metadata:{credentialType:s.credentialType,userId:s.userId,blockchainTx:n.batchTransactionHash,merkleRoot:n.merkleRoot}}})}catch(p){console.error("IPFS upload error:",p)}});await Promise.all(d),await h()}else throw new Error(n.error||"Batch write failed")}catch(r){console.error("Batch processing error:",r),o.error("Failed to process batch")}finally{x(!1)}};return e.jsxs(u,{children:[e.jsx(P,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(C,{className:"flex items-center gap-2",children:[e.jsx(K,{className:"h-5 w-5 text-yellow-500"}),"Batch Blockchain Writer"]}),e.jsx(S,{children:"Process multiple credentials in a single transaction (90%+ gas savings)"})]}),e.jsx(k,{onClick:h,variant:"outline",size:"sm",disabled:y,children:y?e.jsx(I,{className:"h-4 w-4 animate-spin"}):"Refresh"})]})}),e.jsxs(g,{className:"space-y-4",children:[j&&e.jsxs(z,{className:"border-green-200 bg-green-50",children:[e.jsx(q,{className:"h-4 w-4 text-green-600"}),e.jsxs(R,{className:"text-green-800",children:[e.jsxs("strong",{children:["Gas Cost Reduced by ",j,"!"]})," Batch processing saved significant transaction fees."]})]}),c.length>0?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Pending Credentials"}),e.jsxs(w,{variant:"secondary",children:[c.length," credentials"]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 text-center",children:[e.jsxs("div",{className:"bg-blue-50 rounded-lg p-3",children:[e.jsx("div",{className:"text-2xl font-bold text-blue-600",children:c.filter(r=>r.credential_type==="SKILL").length}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Skills"})]}),e.jsxs("div",{className:"bg-green-50 rounded-lg p-3",children:[e.jsx("div",{className:"text-2xl font-bold text-green-600",children:c.filter(r=>r.credential_type==="EDUCATION").length}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Education"})]}),e.jsxs("div",{className:"bg-purple-50 rounded-lg p-3",children:[e.jsx("div",{className:"text-2xl font-bold text-purple-600",children:c.filter(r=>r.credential_type==="EMPLOYMENT").length}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Employment"})]})]})]}),e.jsxs("div",{className:"bg-muted/50 rounded-lg p-4 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{children:"Individual Transactions:"}),e.jsxs("span",{className:"font-mono",children:["~",c.length*21e3," gas"]})]}),e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{children:"Batch Transaction:"}),e.jsx("span",{className:"font-mono text-green-600",children:"~21000 gas"})]}),e.jsxs("div",{className:"flex items-center justify-between text-sm font-semibold",children:[e.jsx("span",{children:"Estimated Savings:"}),e.jsxs("span",{className:"text-green-600",children:["~",((1-21e3/(c.length*21e3))*100).toFixed(0),"%"]})]})]}),e.jsx(k,{onClick:t,disabled:l,className:"w-full",size:"lg",children:l?e.jsxs(e.Fragment,{children:[e.jsx(I,{className:"h-4 w-4 mr-2 animate-spin"}),"Processing Batch..."]}):e.jsxs(e.Fragment,{children:[e.jsx(K,{className:"h-4 w-4 mr-2"}),"Process ",c.length," Credentials"]})}),e.jsx("p",{className:"text-xs text-muted-foreground text-center",children:"All credentials will be verified via Merkle tree proof on Polygon blockchain"})]}):e.jsxs("div",{className:"text-center py-8",children:[e.jsx(Y,{className:"h-12 w-12 text-green-500 mx-auto mb-4"}),e.jsx("p",{className:"text-muted-foreground",children:"All credentials are on-chain!"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"No pending credentials to process"})]})]})]})}const xe=async(i,c,m,y,f)=>{const l=` 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>${i} - Digital Passport</title> 12 <style> 13 * { margin: 0; padding: 0; box-sizing: border-box; } 14 body { 15 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; 16 color: #1a1a1a; 17 line-height: 1.6; 18 padding: 40px; 19 background: #ffffff; 20 } 21 .header { 22 border-bottom: 3px solid #0066cc; 23 padding-bottom: 20px; 24 margin-bottom: 30px; 25 } 26 .header h1 { 27 font-size: 32px; 28 color: #0066cc; 29 margin-bottom: 8px; 30 } 31 .header .subtitle { 32 font-size: 14px; 33 color: #666; 34 } 35 .did-box { 36 background: #f5f5f5; 37 padding: 15px; 38 border-radius: 8px; 39 margin: 20px 0; 40 border-left: 4px solid #0066cc; 41 } 42 .did-box strong { 43 display: block; 44 margin-bottom: 5px; 45 color: #0066cc; 46 } 47 .did-box code { 48 font-family: 'Courier New', monospace; 49 font-size: 11px; 50 color: #333; 51 word-break: break-all; 52 } 53 .section { 54 margin: 30px 0; 55 page-break-inside: avoid; 56 } 57 .section-title { 58 font-size: 20px; 59 color: #0066cc; 60 margin-bottom: 15px; 61 padding-bottom: 8px; 62 border-bottom: 2px solid #e0e0e0; 63 } 64 .credential-card { 65 background: #fafafa; 66 border: 1px solid #e0e0e0; 67 border-radius: 8px; 68 padding: 20px; 69 margin-bottom: 15px; 70 page-break-inside: avoid; 71 } 72 .credential-card h3 { 73 font-size: 16px; 74 color: #1a1a1a; 75 margin-bottom: 8px; 76 } 77 .credential-card .meta { 78 font-size: 13px; 79 color: #666; 80 margin-bottom: 12px; 81 } 82 .blockchain-info { 83 background: #e8f4ff; 84 border: 1px solid #b3d9ff; 85 border-radius: 6px; 86 padding: 12px; 87 margin-top: 10px; 88 } 89 .blockchain-info .label { 90 font-size: 11px; 91 color: #0066cc; 92 font-weight: 600; 93 text-transform: uppercase; 94 letter-spacing: 0.5px; 95 } 96 .blockchain-info .value { 97 font-family: 'Courier New', monospace; 98 font-size: 10px; 99 color: #333; 100 word-break: break-all; 101 margin-top: 4px; 102 } 103 .stats-grid { 104 display: grid; 105 grid-template-columns: repeat(4, 1fr); 106 gap: 15px; 107 margin: 20px 0; 108 } 109 .stat-box { 110 text-align: center; 111 padding: 15px; 112 background: #f5f5f5; 113 border-radius: 6px; 114 } 115 .stat-box .number { 116 font-size: 28px; 117 font-weight: bold; 118 color: #0066cc; 119 } 120 .stat-box .label { 121 font-size: 12px; 122 color: #666; 123 margin-top: 5px; 124 } 125 .footer { 126 margin-top: 40px; 127 padding-top: 20px; 128 border-top: 2px solid #e0e0e0; 129 font-size: 11px; 130 color: #666; 131 text-align: center; 132 } 133 .verification-badge { 134 display: inline-block; 135 background: #10b981; 136 color: white; 137 padding: 4px 12px; 138 border-radius: 12px; 139 font-size: 11px; 140 font-weight: 600; 141 margin-left: 10px; 142 } 143 </style> 144 </head> 145 <body> 146 <div class="header"> 147 <h1>ð Digital Passport</h1> 148 <p class="subtitle">Blockchain-Verified Professional Credentials</p> 149 <h2 style="margin-top: 15px; color: #333;">${i}</h2> 150 </div> 151 152 <div class="did-box"> 153 <strong>ð Decentralized Identity (DID)</strong> 154 <code>${c}</code> 155 </div> 156 157 <div class="stats-grid"> 158 <div class="stat-box"> 159 <div class="number">${m.length+y.length+f.length}</div> 160 <div class="label">Total Credentials</div> 161 </div> 162 <div class="stat-box"> 163 <div class="number">${m.length}</div> 164 <div class="label">Skills</div> 165 </div> 166 <div class="stat-box"> 167 <div class="number">${y.length}</div> 168 <div class="label">Education</div> 169 </div> 170 <div class="stat-box"> 171 <div class="number">${f.length}</div> 172 <div class="label">Employment</div> 173 </div> 174 </div> 175 176 ${y.length>0?` 177 <div class="section"> 178 <h2 class="section-title">ð Education</h2> 179 ${y.map(a=>` 180 <div class="credential-card"> 181 <h3>${a.degree_level} in ${a.degree_field}
182 <span class="verification-badge">â VERIFIED</span> 183 </h3> 184 <div class="meta"> 185 ${a.institution_name} ⢠Graduated: ${new Date(a.graduation_date).toLocaleDateString()} 186 ${a.gpa?` ⢠GPA: ${a.gpa}`:""} 187 </div> 188 <div class="blockchain-info"> 189 <div class="label">Blockchain Credential ID</div> 190 <div class="value">${a.credential_id}</div> 191 ${a.blockchain_record_id?` 192 <div class="label" style="margin-top: 8px;">Transaction Hash</div> 193 <div class="value">${a.blockchain_record_id}</div> 194 `:""} 195 </div> 196 </div> 197 `).join("")} 198 </div> 199 `:""} 200 201 ${f.length>0?` 202 <div class="section"> 203 <h2 class="section-title">ð¼ Employment History</h2> 204 ${f.map(a=>` 205 <div class="credential-card"> 206 <h3>${a.job_title} 207 <span class="verification-badge">â VERIFIED</span> 208 </h3> 209 <div class="meta"> 210 ${a.employer_name} ⢠211 ${new Date(a.employment_start_date).toLocaleDateString()} - 212 ${a.employment_end_date?new Date(a.employment_end_date).toLocaleDateString():"Present"} 213 ${a.employment_duration_months?` ⢠${a.employment_duration_months} months`:""} 214 </div> 215 <div class="blockchain-info"> 216 <div class="label">Blockchain Credential ID</div> 217 <div class="value">${a.credential_id}</div> 218 ${a.blockchain_record_id?` 219 <div class="label" style="margin-top: 8px;">Transaction Hash</div> 220 <div class="value">${a.blockchain_record_id}</div> 221 `:""} 222 </div> 223 </div> 224 `).join("")} 225 </div> 226 `:""} 227 228 ${m.length>0?` 229 <div class="section"> 230 <h2 class="section-title">ð Certified Skills</h2> 231 ${m.map(a=>{var h;return` 232 <div class="credential-card"> 233 <h3>${((h=a.skills)==null?void 0:h.name)||a.skill_id} 234 <span class="verification-badge">â VERIFIED</span> 235 </h3> 236 <div class="meta"> 237 Proficiency: ${Math.round(a.proficiency_level*100)}% ⢠238 ${a.proficiency_description} 239 </div> 240 <div class="blockchain-info"> 241 <div class="label">Blockchain Credential ID</div> 242 <div class="value">${a.credential_id}</div> 243 ${a.blockchain_record_id?` 244 <div class="label" style="margin-top: 8px;">Transaction Hash</div> 245 <div class="value">${a.blockchain_record_id}</div> 246 `:""} 247 </div> 248 </div> 249 `}).join("")} 250 </div> 251 `:""} 252 253 <div class="footer"> 254 <p><strong>Blockchain Security Notice</strong></p> 255 <p>All credentials are cryptographically signed and recorded on the Polygon blockchain.</p> 256 <p>Transaction hashes can be independently verified at mumbai.polygonscan.com</p> 257 <p style="margin-top: 10px;">Generated on ${new Date().toLocaleString()} ⢠GenAIx Digital Passport</p> 258 </div> 259 </body> 260 </html> 261 `,x=document.createElement("div");x.innerHTML=l;const j={margin:.5,filename:`${i.replace(/\s+/g,"_")}_Digital_Passport.pdf`,image:{type:"jpeg",quality:.98},html2canvas:{scale:2,useCORS:!0},jsPDF:{unit:"in",format:"letter",orientation:"portrait"}};try{return await ie().set(j).from(x).save(),!0}catch(a){throw console.error("PDF generation error:",a),a}};function $e(){const{user:i,loading:c}=J(),m=Q(),[y,f]=b.useState(!0),[l,x]=b.useState(null),[j,a]=b.useState([]),[h,t]=b.useState([]),[r,n]=b.useState([]);b.useEffect(()=>{!c&&!i?m("/auth"):i&&v()},[i,c,m]);const v=async()=>{if(i)try{const s=G(i.uid),{data:p}=await N.from("profiles").select("*").eq("user_id",s).single();x(p);const{data:D}=await N.from("skill_credentials").select("*, skills(name)").eq("holder_user_id",s).eq("credential_status","ACTIVE");a(D||[]);const{data:_}=await N.from("educational_degree_credentials").select("*").eq("holder_user_id",s).eq("credential_status","ACTIVE");t(_||[]);const{data:E}=await N.from("employment_history_credentials").select("*").eq("holder_user_id",s).eq("credential_status","ACTIVE");n(E||[])}catch(s){console.error("Error loading passport data:",s),o.error("Failed to load passport data")}finally{f(!1)}};if(c||y)return e.jsx("div",{className:"flex items-center justify-center min-h-screen",children:e.jsxs("div",{className:"text-center",children:[e.jsx(F,{className:"h-12 w-12 text-primary animate-pulse mx-auto mb-4"}),e.jsx("p",{className:"text-muted-foreground",children:"Loading your digital passport..."})]})});const d=j.length+h.length+r.length;return e.jsxs(e.Fragment,{children:[e.jsx(ae,{title:"My Digital Passport | GenAIx",description:"View your complete blockchain-verified digital passport with all credentials, education, and employment history."}),e.jsxs("div",{className:"container mx-auto px-4 py-8 max-w-7xl",children:[e.jsxs("div",{className:"mb-8",children:[e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-4 mb-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-4xl font-bold mb-2",children:"My Digital Passport"}),e.jsx("p",{className:"text-muted-foreground",children:"Blockchain-verified credentials ⢠Portable ⢠Privacy-first"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(k,{variant:"outline",onClick:async()=>{try{const s=(l==null?void 0:l.full_name)||i.email||"User",p=(l==null?void 0:l.did)||"N/A";
261await xe(s,p,j,h,r),o.success("PDF exported successfully!")}catch{o.error("Failed to export PDF")}},children:[e.jsx(le,{className:"h-4 w-4 mr-2"}),"Export PDF"]}),e.jsxs(k,{onClick:()=>m("/credentials"),children:[e.jsx(ne,{className:"h-4 w-4 mr-2"}),"Share Credentials"]})]})]}),e.jsx(u,{className:"mb-6 border-primary/20 bg-gradient-to-r from-primary/5 via-background to-accent/5",children:e.jsx(g,{className:"pt-6",children:e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"p-3 rounded-xl bg-primary/10",children:e.jsx(F,{className:"h-6 w-6 text-primary"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"font-semibold mb-2",children:"Why GenAIx Digital Passport is Unique"}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4 text-sm",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(w,{variant:"outline",className:"shrink-0 bg-green-500/10 text-green-600 border-green-500/30",children:"Patent Pending"}),e.jsx("span",{className:"text-muted-foreground",children:"Temporal skill decay tracking predicts when skills need refreshing"})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(w,{variant:"outline",className:"shrink-0 bg-blue-500/10 text-blue-600 border-blue-500/30",children:"Polygon Mainnet"}),e.jsx("span",{className:"text-muted-foreground",children:"Credentials verified on real blockchain, not testnet"})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(w,{variant:"outline",className:"shrink-0 bg-purple-500/10 text-purple-600 border-purple-500/30",children:"Resume Upload"}),e.jsx("span",{className:"text-muted-foreground",children:"AI parses your resume to auto-generate credentials"})]})]})]})]})})}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[e.jsx(u,{children:e.jsx(g,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Total Credentials"}),e.jsx("p",{className:"text-3xl font-bold",children:d})]}),e.jsx(F,{className:"h-8 w-8 text-primary"})]})})}),e.jsx(u,{children:e.jsx(g,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Skills"}),e.jsx("p",{className:"text-3xl font-bold",children:j.length})]}),e.jsx($,{className:"h-8 w-8 text-blue-500"})]})})}),e.jsx(u,{children:e.jsx(g,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Education"}),e.jsx("p",{className:"text-3xl font-bold",children:h.length})]}),e.jsx(U,{className:"h-8 w-8 text-green-500"})]})})}),e.jsx(u,{children:e.jsx(g,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Employment"}),e.jsx("p",{className:"text-3xl font-bold",children:r.length})]}),e.jsx(M,{className:"h-8 w-8 text-purple-500"})]})})})]})]}),d>0&&i&&e.jsx("div",{className:"mb-8",children:e.jsx(me,{userId:i.uid})}),d>0&&j.length>0&&i&&e.jsx("div",{className:"mb-8",children:e.jsx(oe,{userId:i.uid})}),d===0&&i&&e.jsx("div",{className:"mb-8",children:e.jsx(de,{userId:i.uid,onComplete:v})}),l&&e.jsxs(u,{className:"mb-8",children:[e.jsx(P,{children:e.jsxs(C,{className:"flex items-center gap-2",children:[e.jsx(X,{className:"h-5 w-5"}),"Profile Information"]})}),e.jsx(g,{children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Full Name"}),e.jsx("p",{className:"font-medium",children:l.full_name||"Not set"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Email"}),e.jsx("p",{className:"font-medium",children:l.email})]}),l.company_name&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Company"}),e.jsx("p",{className:"font-medium",children:l.company_name})]}),l.location&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Location"}),e.jsx("p",{className:"font-medium",children:l.location})]})]})})]}),e.jsxs(ee,{defaultValue:"skills",className:"space-y-6",children:[e.jsxs(se,{className:"grid w-full grid-cols-3",children:[e.jsxs(A,{value:"skills",children:[e.jsx($,{className:"h-4 w-4 mr-2"}),"Skills (",j.length,")"]}),e.jsxs(A,{value:"education",children:[e.jsx(U,{className:"h-4 w-4 mr-2"}),"Education (",h.length,")"]}),e.jsxs(A,{value:"employment",children:[e.jsx(M,{className:"h-4 w-4 mr-2"}),"Employment (",r.length,")"]})]}),e.jsx(L,{value:"skills",className:"space-y-4",children:j.length===0?e.jsx(u,{className:"border-dashed",children:e.jsxs(g,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx($,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("p",{className:"text-muted-foreground mb-4",children:"No skill credentials yet"}),e.jsx(k,{onClick:()=>m("/courses"),children:"Browse Courses"})]})}):j.map(s=>{var p;return e.jsxs(u,{children:[e.jsxs(P,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(C,{children:((p=s.skills)==null?void 0:p.name)||s.skill_id}),e.jsxs(w,{children:[Math.round(s.proficiency_level*100),"% Proficient"]})]}),e.jsx(S,{children:s.proficiency_description})]}),e.jsx(g,{children:e.jsx(B,{credential:s,credentialType:"SKILL"})})]},s.credential_id)})}),e.jsx(L,{value:"education",className:"space-y-4",children:h.length===0?e.jsx(u,{className:"border-dashed",children:e.jsxs(g,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx(U,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("p",{className:"text-muted-foreground",children:"No education credentials yet"})]})}):h.map(s=>e.jsxs(u,{children:[e.jsxs(P,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(C,{children:[s.degree_level," in ",s.degree_field]}),e.jsx(w,{variant:"outline",children:s.institution_name})]}),e.jsxs(S,{children:["Graduated: ",new Date(s.graduation_date).toLocaleDateString(),s.gpa&&` ⢠GPA: ${s.gpa}`]})]}
261),e.jsx(g,{children:e.jsx(B,{credential:s,credentialType:"EDUCATION"})})]},s.credential_id))}),e.jsx(L,{value:"employment",className:"space-y-4",children:r.length===0?e.jsx(u,{className:"border-dashed",children:e.jsxs(g,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx(M,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("p",{className:"text-muted-foreground",children:"No employment credentials yet"})]})}):r.map(s=>e.jsxs(u,{children:[e.jsxs(P,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(C,{children:s.job_title}),e.jsxs(w,{variant:"outline",children:[e.jsx(ce,{className:"h-3 w-3 mr-1"}),s.employer_name]})]}),e.jsxs(S,{children:[new Date(s.employment_start_date).toLocaleDateString()," - "," ",s.employment_end_date?new Date(s.employment_end_date).toLocaleDateString():"Present",s.employment_duration_months&&` ⢠${s.employment_duration_months} months`]})]}),e.jsx(g,{children:e.jsx(B,{credential:s,credentialType:"EMPLOYMENT"})})]},s.credential_id))})]})]})]})}export{$e as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.