import React,{useState,useRef}from "react"; import{Download,Share2,Mail,Phone,Linkedin,Github,Calendar,Users,Code,ExternalLink,CheckCircle}from "lucide-react"; // @ts-ignore import html2pdf from "html2pdf.js"; import pro5 from "./img/pro5.png"; function App(){const cvRef = useRef<HTMLDivElement>(null);const [showToast,setShowToast] = useState(false);const downloadCV = async () =>{if (!cvRef.current) return;document.documentElement.classList.add("exporting");try{// chờ font sẵn sàng để tránh nhảy chữ // @ts-ignore if (document.fonts?.ready) await document.fonts.ready;const opt ={margin: [12,12,12,12],// mm: khớp @page filename: "Pham_Tuan_Kiet_Frontend_Intern_CV.pdf",image:{type:"jpeg",quality: .98},html2canvas:{scale:2,useCORS: true,letterRendering: true,backgroundColor: "#ffffff",ignoreElements: (el: Element) => (el as HTMLElement).classList?.contains("no-print") || (el as HTMLElement).getAttribute("data-html2canvas-ignore") !== null},jsPDF:{unit:"mm",format: "a4",orientation: "portrait"},pagebreak:{mode:["css","legacy"],avoid: [".print-avoid-break","h2",".card","p","li"]}}as const;await (html2pdf() as any).from(cvRef.current).set(opt).save()}finally{document.documentElement.classList.remove("exporting")}}const sharCV = async () =>{try{await navigator.clipboard.writeText("https://cv.kietnetwork.com/");setShowToast(true);setTimeout(() => setShowToast(false),3000)}catch (err){console.error(err)}}const personalInfo ={name: "Phạm Tuấn Kiệt",title: "INTERN FRONTEND DEVELOPER",birthYear: "2003",location: "Vĩnh Long",email: "tnkiet.it@gmail.com",phone: "+84 778 198 530",linkedin: "https://www.linkedin.com/in/tnkietit/",github: "https://github.com/tnkietit",about: "Sinh viên CNTT năm 3 đam mê Frontend. Có kinh nghiệm web responsive, làm việc nhóm, chủ động học công nghệ mới.",education:{university:{name:"ĐH Công nghệ Sài Gòn",major: "Công nghệ Thông tin",period: "2022 - 2026"},scholarship:{name:"Học bổng Lương Văn Can",period: "2022 - Now"}},activities: ["Founder hocbongchosinhvien.com","TikTok @hocbongchosinhvien (20K)"]}const skills ={languages:["JavaScript","TypeScript","HTML5","CSS3"],frontend: ["React.js","Tailwind CSS","Responsive Design","Bootstrap"],tools: ["Git/GitHub","VS Code","Figma","Vite"],}const projects = [{name: "Học Bổng Cho Sinh Viên Website",desc: "Hệ thống tổng hợp học bổng, lọc thông minh, đồng bộ dữ liệu, thông báo.",team: 1,feats: ["Scholarship Directory","Smart Filtering","Live Data Sync","Notification System"],techs: ["React","Next.js","TailwindCSS","Google Sheets API","TypeScript","Vite"],demo: "https://apply.hocbongchosinhvien.com/",github: "#"},{name: "Task Management App",desc: "Ứng dụng quản lý công việc cá nhân UI thân thiện.",team: 1,feats: ["Smart Filtering","Data Persistence","Responsive Design","Statistics Dashboard","Task Management"],techs: ["React","TypeScript","Tailwind CSS","Local Storage"],demo: "https://task-manager.kietnetwork.com/",github: "#"}];return (<div className="min-h-screen"> {} <div className="no-print fixed top-4 right-4 z-50" data-html2canvas-ignore> {showToast && (<div className="bg-green-500 text-white px-4 py-2 rounded-lg shadow flex items-center gap-2"> <CheckCircle size={18} /> <span>Đã copy link CV vào clipboard!</span> </div>)} </div> <div className="no-print flex justify-end gap-3 p-4" data-html2canvas-ignore> <button onClick={downloadCV} className="bg-blue-600 text-white px-4 py-2 rounded flex items-center gap-2"> <Download size={18} /> Tải PDF </button> <button onClick={() => window.print()} className="bg-gray-800 text-white px-4 py-2 rounded"> In (PDF sắc nét) </button> <button onClick={sharCV} className="bg-green-600 text-white px-4 py-2 rounded flex items-center gap-2"> <Share2 size={18} /> Chia sẻ </button> </div> {} <div className="a4-wrap"> <div id="cv-root" ref={cvRef} className="a4-sheet"> {} <div className="a4-grid"> {} <aside className="print-avoid-break" style={{background:"#0f172a",color:"#fff",padding:"6mm"}}> <div className="text-center" style={{marginBottom:"6mm"}}> <div className="mx-auto overflow-hidden" style={{width: "32mm",height: "32mm",borderRadius:"9999px"}}> {} <img src={pro5} alt="Profile" width={121} height={121} style={{width:"100%",height:"100%",objectFit:"cover"}} /> </div> <h1 style={{fontWeight:700,fontSize:"12pt",marginTop:"3mm"}}>{personalInfo.name}</h1> <p style={{color:"#93c5fd",fontSize:"9pt"}}>{personalInfo.birthYear} • {personalInfo.location}</p> </div> <div style={{marginBottom:"6mm"}}> <h3 style={{fontWeight:600,fontSize:"10pt",color:"#93c5fd",marginBottom:"3mm"}}>Liên hệ</h3> <div style={{fontSize:"9pt",display:"grid",rowGap:"2mm"}}> <div className="flex items-center gap-2"><Phone size={14} />{personalInfo.phone}</div> <div className="flex items-center gap-2"><Mail size={14} /><span className="break-all">{personalInfo.email}</span></div> <div className="flex items-center gap-2"><Linkedin size={14} /><span>linkedin.com/in/tnkietit</span></div> <div className="flex items-center gap-2"><Github size={14} /><span>github.com/tnkietit</span></div> </div> </div> <div style={{marginBottom:"6mm"}}> <h3 style={{fontWeight:600,fontSize:"10pt",color:"#93c5fd",marginBottom:"3mm"}}>About Me</h3> <p style={{fontSize:"9pt",lineHeight:1.5,color:"#e5e7eb"}}> {personalInfo.about} </p> </div> <div style={{marginBottom:"6mm"}}> <h3 style={{fontWeight:600,fontSize:"10pt",color:"#93c5fd",marginBottom:"3mm"}}>Học vấn</h3> <div style={{fontSize:"9pt"}}> <div style={{fontWeight:600}}>{personalInfo.education.university.name}</div> <div style={{color:"#93c5fd"}}>{personalInfo.education.university.major}</div> <div className="flex items-center gap-1" style={{fontSize:"8.5pt",color:"#cbd5e1",marginTop:"1mm"}}> <Calendar size={12}/> <span>{personalInfo.education.university.period}</span> </div> <div style={{fontSize:"8.5pt",color:"#4ade80",marginTop:"1mm"}}> {personalInfo.education.scholarship.name} • {personalInfo.education.scholarship.period} </div> </div> </div> <div> <h3 style={{fontWeight:600,fontSize:"10pt",color:"#93c5fd",marginBottom:"3mm"}}>Hoạt động</h3> <ul style={{fontSize:"9pt",paddingLeft:"14px",margin:0}}> {personalInfo.activities.map((a,i)=>(<li key={i} style={{marginBottom:"2mm"}}>{a}</li>))} </ul> </div> </aside> {} <main> {} <section className="cv-section print-avoid-break" style={{marginBottom:"6mm"}}> <h1 style={{fontSize:"16pt",fontWeight:800,color:"#111827",margin:0}}>{personalInfo.title}</h1> <div style={{height:"2px",width:"22mm",background:"#2563eb",marginTop:"3mm"}} /> </section> {} <section className="cv-section print-avoid-break" style={{marginBottom:"6mm"}}> <h2 style={{fontSize:"12pt",fontWeight:700,color:"#111827",margin:"0 0 4mm 0",display:"flex",alignItems:"center",gap:"6px"}}> <Code size={18} /> Technical Skills </h2> <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"4mm"}}> {[{title:"Languages",items:skills.languages,badge:"#dbeafe",text:"#1e40af"},{title:"Frontend",items:skills.frontend,badge:"#dcfce7",text:"#166534"},{title:"Tools",items:skills.tools,badge:"#ede9fe",text:"#5b21b6"},{title:"Others",items:[],badge:"#fee2e2",text:"#7f1d1d"}].map((box,i)=>(<div key={i} className="card" style={{background:"#f9fafb",padding:"4mm"}}> <h3 style={{fontWeight:600,color:"#1f2937",margin:"0 0 3mm 0",fontSize:"10pt"}}>{box.title}</h3> <div style={{display:"flex",flexWrap:"wrap",gap:"3mm"}}> {box.items.map((x,idx)=>(<span key={idx} style={{background: box.badge,color: box.text,padding:"2px 6px",borderRadius:"9999px",fontSize:"8.5pt",fontWeight:600}}>{x}</span>))} </div> </div>))} </div> </section> {} <section className="cv-section print-avoid-break" style={{marginBottom:"6mm"}}> <h2 style={{fontSize:"12pt",fontWeight:700,color:"#111827",margin:"0 0 4mm 0"}}>Work Experience</h2> <div className="card" style={{background:"#f9fafb",padding:"6mm",textAlign:"center"}}> <div style={{fontSize:"28px",color:"#d1d5db",marginBottom:"3mm"}}>💼</div> <h3 style={{fontSize:"10.5pt",fontWeight:600,color:"#374151",margin:"0 0 2mm"}}>Sẵn sàng cho cơ hội đầu tiên</h3> <p style={{fontSize:"9pt",color:"#6b7280",margin:0}}> Tìm vị trí thực tập Frontend để áp dụng kiến thức và phát triển kỹ năng thực tế. </p> </div> </section> {} <section className="cv-section"> <h2 style={{fontSize:"12pt",fontWeight:700,color:"#111827",margin:"0 0 4mm 0"}}>Projects</h2> <div style={{display:"grid",gap:"4mm"}}> {projects.map((p,idx)=>(<div key={idx} className="card print-avoid-break" style={{background:"#fff",border:"1px solid #e5e7eb",padding:"4.5mm"}}> <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:"2mm"}}> <h3 style={{fontSize:"11pt",fontWeight:700,color:"#111827",margin:0}}>{p.name}</h3> <div style={{display:"flex",alignItems:"center",gap:"4px",fontSize:"8.5pt",color:"#4b5563"}}> <Users size={14} /> <span>{p.team} người</span> </div> </div> <p style={{fontSize:"9pt",color:"#374151",margin:"0 0 2mm 0"}}>{p.desc}</p> <div style={{marginBottom:"2mm"}}> <h4 style={{fontWeight:600,color:"#1f2937",margin:"0 0 1mm 0",fontSize:"9.5pt"}}>Key Features</h4> <ul style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"2mm",fontSize:"8.5pt",color:"#374151",paddingLeft:"12px",margin:0}}> {p.feats.map((f,i)=>(<li key={i}>{f}</li>))} </ul> </div> <div style={{marginBottom:"2mm"}}> <h4 style={{fontWeight:600,color:"#1f2937",margin:"0 0 1mm 0",fontSize:"9.5pt"}}>Technologies</h4> <div style={{display:"flex",flexWrap:"wrap",gap:"3mm"}}> {p.techs.map((t,i)=>(<span key={i} style={{background:"#f3f4f6",color:"#374151",padding:"2px 6px",borderRadius:"6px",fontSize:"8.5pt"}}> {t} </span>))} </div> </div> <div style={{display:"flex",gap:"6mm",fontSize:"9pt"}}> <a href={p.github} style={{display:"flex",alignItems:"center",gap:"4px",color:"#2563eb"}}> <Github size={16}/> GitHub </a> <a href={p.demo} style={{display:"flex",alignItems:"center",gap:"4px",color:"#16a34a"}}> <ExternalLink size={16}/> Live Demo </a> </div> </div>))} </div> </section> </main> </div> </div> </div> </div>)}export default App;{}
