33import type { ReactNode , RefObject } from "react" ;
44import React , { forwardRef } from "react" ;
55import Image from "next/image" ;
6- import html2canvas from "html2canvas" ;
7- import jsPDF from "jspdf" ;
6+ // Removed imports for PDF functionality
87
9- export const handleDownload = async (
10- certRef : RefObject < HTMLDivElement | null > ,
11- name : string ,
12- ) => {
13- if ( ! certRef . current ) return ;
14-
15- // Wait a bit to ensure images are loaded
16- await new Promise ( resolve => setTimeout ( resolve , 500 ) ) ;
17-
18- const canvas = await html2canvas ( certRef . current , {
19- useCORS : true ,
20- scale : 2 ,
21- backgroundColor : null ,
22- logging : true , // Enable logging to debug
23- allowTaint : true , // Allow tainted images
24- foreignObjectRendering : true , // Better SVG/CSS rendering
25- } ) ;
26-
27- const imgData = canvas . toDataURL ( "image/png" ) ;
28-
29- const pdf = new jsPDF ( {
30- orientation : "landscape" ,
31- unit : "px" ,
32- format : [ canvas . width , canvas . height ] ,
33- } ) ;
34-
35- pdf . addImage ( imgData , "PNG" , 0 , 0 , canvas . width , canvas . height ) ;
36- pdf . save ( `${ name } -certificate.pdf` ) ;
37- } ;
8+ // Removed PDF download functionality - keeping only PNG export
389
3910export interface CertificateProps {
4011 title : string ;
@@ -47,73 +18,112 @@ const Certificate = forwardRef<HTMLDivElement, CertificateProps>(
4718 ( props , ref ) => {
4819 const { title, name, mainSentence, description1 } = props ;
4920
50- const background = "/assets/images/bg-certificate.png" ;
51- const logo = " /assets/images/codebility.png" ;
52- const signature = " /assets/images/signature1.png" ;
21+ // Use relative paths - Next.js serves from public folder
22+ const logo = ' /assets/images/codebility.png' ;
23+ const signature = ' /assets/images/signature1.png' ;
5324
5425 return (
5526 < div
5627 ref = { ref }
57- className = "relative h-[700px] w-[1000px] overflow-hidden font-sans text-white "
28+ className = "relative h-[700px] w-[1000px] overflow-hidden"
5829 style = { {
59- backgroundImage : `url(${ background } )` ,
60- backgroundSize : "cover" ,
61- backgroundPosition : "center" ,
62- backgroundColor : "transparent" ,
30+ backgroundColor : "#0a0a1a" ,
31+ backgroundImage : `
32+ radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.1) 0%, transparent 50%),
33+ radial-gradient(circle at 80% 50%, rgba(255, 119, 198, 0.1) 0%, transparent 50%),
34+ radial-gradient(circle at 50% 100%, rgba(120, 198, 255, 0.1) 0%, transparent 50%),
35+ linear-gradient(180deg, rgba(255,255,255,0.02) 0%, transparent 100%)
36+ ` ,
37+ fontFamily : "'Arial', sans-serif" ,
38+ position : "relative" ,
6339 } }
6440 >
65- < div className = "flex h-full w-full flex-col justify-between px-40 py-10 text-center" >
66- < div >
67- < div className = "mx-auto w-60 h-[80px] relative" >
68- < img className = "mx-auto w-60" src = { logo } alt = "logo" />
41+ { /* Background pattern - simple dots for better PDF rendering */ }
42+ < svg className = "absolute inset-0 w-full h-full" style = { { opacity : 0.05 } } >
43+ < defs >
44+ < pattern id = "dots" x = "0" y = "0" width = "40" height = "40" patternUnits = "userSpaceOnUse" >
45+ < circle cx = "2" cy = "2" r = "1" fill = "white" />
46+ < circle cx = "22" cy = "22" r = "1" fill = "white" />
47+ < circle cx = "2" cy = "22" r = "1" fill = "white" />
48+ < circle cx = "22" cy = "2" r = "1" fill = "white" />
49+ </ pattern >
50+ </ defs >
51+ < rect width = "100%" height = "100%" fill = "url(#dots)" />
52+ </ svg >
53+
54+ { /* Decorative border with glow effect */ }
55+ < div
56+ className = "absolute rounded-lg"
57+ style = { {
58+ top : "40px" ,
59+ left : "40px" ,
60+ right : "40px" ,
61+ bottom : "40px" ,
62+ border : "2px solid rgba(255,255,255,0.3)" ,
63+ boxShadow : "inset 0 0 20px rgba(255,255,255,0.1), 0 0 20px rgba(120, 119, 198, 0.3)"
64+ } }
65+ />
66+ < div
67+ className = "absolute rounded-lg"
68+ style = { {
69+ top : "50px" ,
70+ left : "50px" ,
71+ right : "50px" ,
72+ bottom : "50px" ,
73+ border : "1px solid rgba(255,255,255,0.2)" ,
74+ } }
75+ />
76+
77+ { /* Corner decorations */ }
78+ < div className = "absolute w-16 h-16 border-t-2 border-l-2 border-white/30 rounded-tl-lg" style = { { top : "60px" , left : "60px" } } />
79+ < div className = "absolute w-16 h-16 border-t-2 border-r-2 border-white/30 rounded-tr-lg" style = { { top : "60px" , right : "60px" } } />
80+ < div className = "absolute w-16 h-16 border-b-2 border-l-2 border-white/30 rounded-bl-lg" style = { { bottom : "60px" , left : "60px" } } />
81+ < div className = "absolute w-16 h-16 border-b-2 border-r-2 border-white/30 rounded-br-lg" style = { { bottom : "60px" , right : "60px" } } />
82+
83+ < div className = "relative h-full w-full px-40 pt-20 pb-24 text-center" style = { { color : "white" , zIndex : 1 } } >
84+ { /* Top section with logo and title */ }
85+ < div className = "mb-6" >
86+ < div className = "mx-auto w-48 h-[60px] relative mb-3" >
87+ < img
88+ className = "mx-auto w-48 h-auto"
89+ src = { logo }
90+ alt = "logo"
91+ onError = { ( e ) => console . error ( 'Failed to load logo:' , e ) }
92+ style = { { maxHeight : "60px" , objectFit : "contain" } }
93+ />
6994 </ div >
70- < h1 className = "mt-3 leading-tight" >
71- < span className = "my-5 text-5xl font-bold" > CERTIFICATE</ span >
95+ < h1 className = "leading-tight" style = { { color : "white" } } >
96+ < span className = "text-5xl font-bold" style = { { color : "white" } } > CERTIFICATE</ span >
7297 </ h1 >
73- < h1 >
74- < span className = "text-3xl" > OF { title } </ span >
98+ < h1 className = "mt-2" style = { { color : "white" } } >
99+ < span className = "text-3xl" style = { { color : "white" , letterSpacing : "0.05em" } } > OF { title } </ span >
75100 </ h1 >
76- < p className = "mt-1 text-base" > This certifies that</ p >
77- < h2 className = "mt-1 text-3xl font-semibold" >
101+ </ div >
102+
103+ { /* Middle section with content - better spacing */ }
104+ < div className = "mb-8 px-12" >
105+ < p className = "text-base mb-2" style = { { color : "white" , letterSpacing : "0.02em" } } > This certifies that</ p >
106+ < h2 className = "text-3xl font-semibold mb-3" style = { { color : "white" , letterSpacing : "0.08em" , wordSpacing : "0.2em" } } >
78107 { name . toUpperCase ( ) }
79108 </ h2 >
80- < hr className = "mx-20 my-3 border-t border-white" />
81- { mainSentence }
82- < br />
83- { description1 }
84- < br />
85- < br />
86- < br />
87- < p > Authorized by:</ p >
109+ < hr className = "mx-20 my-4 border-t border-white" style = { { borderColor : "white" } } />
110+ < div className = "mb-4 leading-relaxed" style = { { color : "white" , letterSpacing : "0.02em" , lineHeight : "1.6" } } > { mainSentence } </ div >
111+ < div className = "leading-relaxed" style = { { color : "white" , letterSpacing : "0.02em" , lineHeight : "1.6" } } > { description1 } </ div >
88112 </ div >
89-
90- { /* Projects */ }
91- { /* <div className="mt-3">
92- <h3 className="mb-2 text-base font-semibold">
93- Key Projects Completed:
94- </h3>
95- <ul className="mx-auto grid grid-cols-2 gap-x-8 gap-y-3 px-20 text-left text-sm">
96- {key_projects.map((proj, idx) => (
97- <li
98- key={idx}
99- className="flex items-start gap-2 leading-relaxed"
100- >
101- <span className="mt-[2px] text-base text-white">•</span>
102- <span className="underline">{proj}</span>
103- </li>
104- ))}
105- </ul>
106- </div> */ }
107-
108- { /* Signature */ }
109- < div className = "mt-10" >
110- < div className = "relative mx-auto w-fit" >
111- < img
112- src = { signature }
113- alt = "signature"
114- className = "pointer-events-none mx-auto w-60 opacity-90"
115- />
116- </ div >
113+
114+ { /* Bottom section with signature - moved up significantly */ }
115+ < div className = "mt-8" >
116+ < p className = "mb-2" style = { { color : "white" , letterSpacing : "0.05em" } } > Authorized by:</ p >
117+ < img
118+ src = { signature }
119+ alt = "signature"
120+ className = "pointer-events-none mx-auto opacity-90"
121+ onError = { ( e ) => console . error ( 'Failed to load signature:' , e ) }
122+ style = { { maxHeight : "50px" , width : "200px" , objectFit : "contain" } }
123+ />
124+ < p className = "mt-1 text-sm" style = { { color : "rgba(255,255,255,0.8)" , letterSpacing : "0.03em" } } >
125+ CEO & Founder , Codebility
126+ </ p >
117127 </ div >
118128 </ div >
119129 </ div >
0 commit comments