📂 CV-urile mele:

📄 CV Builder — diaspora.ro

3 template-uri · 3 sloturi · scor ATS · scrisoare intenție · bare competențe · mod anonim · preview live

🤖 Melissa
📊 Completitudine0%
0
Scor ATS
Calculez...

📝 Date personale

Fără foto

Portret pașaport, max 500 KB.

🎯 Profil profesional

💼 Experiență profesională

🎓 Educație și formare

🗣️ Limbi străine

🛠️ Competențe cu bare vizuale

Adaugă fiecare competență cu nivel grafic:

🚗 Permis de conducere

📚 Informații suplimentare

⚙️ Setări CV & Ordine secțiuni

Culoare personalizată

Mută secțiunile sus/jos cu butoanele → ele apar în această ordine în previzualizare:

👁️ Preview CV
🤫 MOD ANONIM ACTIV

✉️ Trimite CV pe email

CV-ul va fi generat ca PDF și trimis ca atașament la adresa introdusă mai jos.

🔗 Link de partajare CV

Link-ul conține toate datele CV-ului (fără poză). La accesare, CV-ul se încarcă automat.

`; try{ const blob=htmlDocx.asBlob(fullHtml,{orientation:'portrait',margins:{top:720,right:720,bottom:720,left:720}}); const a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download=fname+'.docx'; a.click(); URL.revokeObjectURL(a.href); }catch(e){ alert('Eroare export Word: '+e.message); console.error('[DOCX]',e); } } /* ===== EMAIL MODAL ===== */ function openEmailModal(){ const f=state.f||{}; const name=((f.fname||'')+' '+(f.lname||'')).trim()||''; const role=f.role||''; const subj='CV'+(name?' — '+name:'')+(role?' — '+role:''); document.getElementById('em-subject').value=subj; const msg='Bună ziua,\n\nVă trimit atașat CV-ul meu'+(role?' pentru poziția de '+role:'')+'.\nSunt disponibil/ă pentru un interviu la o dată convenabilă.\n\nCu stimă,\n'+(name||''); document.getElementById('em-body').value=msg; document.getElementById('em-to').value=''; document.getElementById('em-status').textContent=''; document.getElementById('em-status').className='email-status'; document.getElementById('em-send-btn').disabled=false; document.getElementById('em-send-btn').textContent='✉️ Trimite CV'; document.getElementById('email-overlay').classList.add('open'); document.body.style.overflow='hidden'; setTimeout(()=>document.getElementById('em-to').focus(),100); } function closeEmailModal(){ document.getElementById('email-overlay').classList.remove('open'); document.body.style.overflow=''; } async function sendCvEmail(){ const to=(document.getElementById('em-to').value||'').trim(); const subject=(document.getElementById('em-subject').value||'').trim(); const message=(document.getElementById('em-body').value||'').trim(); const statusEl=document.getElementById('em-status'); const btnEl=document.getElementById('em-send-btn'); if(!to || !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(to)){ statusEl.textContent='⚠️ Introdu o adresă email validă.'; statusEl.className='email-status err'; document.getElementById('em-to').focus(); return; } btnEl.disabled=true; btnEl.textContent='⏳ Generez PDF...'; statusEl.textContent=''; statusEl.className='email-status'; try { // Generează PDF ca base64 folosind același flux ca exportPDF() const cvEl=document.getElementById('cv'); if(!cvEl) throw new Error('Previzualizarea CV nu a fost găsită.'); const canvas=await html2canvas(cvEl,{scale:2,useCORS:true,logging:false,backgroundColor:'#ffffff'}); const imgW=210; const pageH=297; const imgH=canvas.height*imgW/canvas.width; const pdf=new jspdf.jsPDF({orientation:'portrait',unit:'mm',format:'a4'}); let yOff=0; let page=0; while(yOff0) pdf.addPage(); const srcY=yOff/imgH*canvas.height; const srcH=Math.min(pageH/imgH*canvas.height, canvas.height-srcY); const tmp=document.createElement('canvas'); tmp.width=canvas.width; tmp.height=srcH; tmp.getContext('2d').drawImage(canvas,0,srcY,canvas.width,srcH,0,0,canvas.width,srcH); pdf.addImage(tmp.toDataURL('image/jpeg',0.92),'JPEG',0,0,imgW,srcH*imgW/canvas.width); yOff+=pageH; page++; } const pdfBase64=pdf.output('datauristring').split(',')[1]; const f=state.f||{}; const name=((f.fname||'')+' '+(f.lname||'')).trim()||'CV'; const filename='CV_'+name.replace(/\s+/g,'_')+'.pdf'; btnEl.textContent='📤 Trimit email...'; const resp=await fetch('/api/cv/email',{ method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({ to, subject, message, pdfBase64, filename, senderName: name }) }); const data=await resp.json().catch(()=>({})); if(data.ok){ statusEl.textContent='✅ Email trimis cu succes la '+to+'!'; statusEl.className='email-status ok'; btnEl.textContent='✅ Trimis!'; setTimeout(closeEmailModal, 2500); } else { statusEl.textContent='❌ '+(data.err||'Eroare necunoscută la trimitere.'); statusEl.className='email-status err'; btnEl.disabled=false; btnEl.textContent='✉️ Încearcă din nou'; } } catch(e){ statusEl.textContent='❌ Eroare: '+(e.message||e); statusEl.className='email-status err'; btnEl.disabled=false; btnEl.textContent='✉️ Încearcă din nou'; } } /* ===== ATS RECALC CU JOB DESCRIPTION ===== */ function recalcATS(){ const jd=(document.getElementById('ats-jd-input')||{}).value||''; updateCompleteness(jd); } /* ===== INIT ===== */ function init(){ loadFromHash(); loadState(); bindFields(); ['exp','edu','lang'].forEach(renderEntries); renderSkillItems(); renderSectionOrder(); updatePhotoThumb(); updateSlotUI(); /* Cover letter date default */ const clDate=document.getElementById('cl-date'); if(clDate&&!clDate.value) clDate.value=new Date().toISOString().slice(0,10); /* Seed example on first open */ if(!state.exp.length&&!state.edu.length&&!state.f.fname){ state.f.fname='Ana'; state.f.lname='Ionescu'; state.f.role='Asistent medical specialist'; state.f.email='ana.ionescu@email.com'; state.f.phone='+40 712 345 678'; state.f.city='Berlin'; state.f.country='Germania'; state.f.mother='Română'; state.f.nat='Română'; state.f.bio='Asistent medical cu 3 ani experiență în Germania. Adaptabilă, empatică, cu bune abilități de comunicare în echipă multiculturală.'; state.f.digital='SAP Medical, MS Office, Word'; state.f.jobs='Nursing clinic, ADministrare tratamente'; addEntry('exp',{from:'2022',to:'prezent',role:'Asistent medical',company:'Charité Berlin',city:'Berlin',country:'Germania',desc:'Îngrijire 12 pacienți/zi, administrare tratamente IV, colaborare echipă multidisciplinară de 8 persoane.'}); addEntry('edu',{from:'2018',to:'2022',diploma:'Licență Asistență Medicală',school:'UMF Carol Davila',city:'București',country:'România',subjects:'Anatomie, Farmacologie, Nursing clinic'}); addEntry('lang',{name:'Germană',lst:'B2',rd:'B2',iact:'B1',pro:'B1',wrt:'B2'}); state.skillItems=[{name:'SAP Medical',level:4},{name:'MS Office',level:5},{name:'Nursing clinic',level:5},{name:'Administrare tratamente',level:4}]; saveState(); bindFields(); renderEntries('exp'); renderEntries('edu'); renderEntries('lang'); renderSkillItems(); renderSectionOrder(); } renderCV(); updateCompleteness(); } document.addEventListener('DOMContentLoaded', init);