169169 < script src ="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js "> </ script >
170170 <!-- EmailJS for contact form functionality -->
171171 < script type ="text/javascript " src ="https://cdn.jsdelivr.net/npm/@emailjs/browser@4/dist/email.min.js "> </ script >
172+ < script type ="text/javascript ">
173+ // Initialize EmailJS with your public key
174+ ( function ( ) {
175+ emailjs . init ( '1a0XajOl0aHeAdOjA' ) ;
176+ } ) ( ) ;
177+ </ script >
172178</ head >
173179
174180< body class ="leading-relaxed ">
@@ -675,7 +681,7 @@ <h3 class="font-semibold mb-6">Send a Message</h3>
675681 < textarea name ="message "> </ textarea >
676682 </ form >
677683
678- < div class ="space-y-6 " id =" contactForm ">
684+ < form id =" contactForm " class ="space-y-6 ">
679685 <!-- Honeypot field for bot protection -->
680686 < div style ="display: none; ">
681687 < label > Don't fill this out if you're human: < input name ="bot-field " /> </ label >
@@ -698,11 +704,11 @@ <h3 class="font-semibold mb-6">Send a Message</h3>
698704 class ="w-full px-4 py-3 rounded-lg bg-gray-800 border border-gray-600 focus:border-orange-400 focus:outline-none transition-colors resize-none "
699705 style ="background: var(--bg-secondary); border-color: var(--border); "> </ textarea >
700706 </ div >
701- < button type ="button " onclick =" handleFormSubmit() "
707+ < button type ="submit " id =" submitBtn "
702708 class ="w-full accent-bg accent-hover text-white px-6 py-3 rounded-lg font-medium transition-all duration-300 hover:shadow-lg hover:-translate-y-1 ">
703709 Send Message
704710 </ button >
705- </ div >
711+ </ form >
706712 </ div >
707713
708714 <!-- Contact Info -->
@@ -807,129 +813,50 @@ <h4 class="font-medium mb-4">Follow Me</h4>
807813 const totalCerts = certificates . length ;
808814 let currentFilter = 'all' ;
809815
810- // Form submission handler - Multiple email service options
811- async function handleFormSubmit ( ) {
812- const name = document . getElementById ( 'name' ) . value ;
813- const email = document . getElementById ( 'email' ) . value ;
814- const message = document . getElementById ( 'message' ) . value ;
815- const button = document . querySelector ( '#contactForm button' ) ;
816- const originalText = button . textContent ;
817-
818- // Validate form
819- if ( ! name || ! email || ! message ) {
820- alert ( 'Please fill in all fields' ) ;
821- return ;
822- }
823-
824- button . textContent = 'Sending...' ;
825- button . disabled = true ;
826-
827- try {
828- // Option 1: EmailJS (Recommended - No backend required)
829- await sendEmailWithEmailJS ( name , email , message ) ;
830-
831- // Option 2: Formspree (Alternative service)
832- // await sendEmailWithFormspree(name, email, message);
833-
834- // Option 3: Netlify Forms (if hosting on Netlify)
835- // await sendEmailWithNetlify(name, email, message);
836-
837- button . textContent = 'Message Sent!' ;
838-
839- // Reset form
840- setTimeout ( ( ) => {
841- document . getElementById ( 'name' ) . value = '' ;
842- document . getElementById ( 'email' ) . value = '' ;
843- document . getElementById ( 'message' ) . value = '' ;
844- button . textContent = originalText ;
845- button . disabled = false ;
846- } , 2000 ) ;
847-
848- } catch ( error ) {
849- console . error ( 'Error sending email:' , error ) ;
850- button . textContent = 'Error - Try Again' ;
851- setTimeout ( ( ) => {
852- button . textContent = originalText ;
853- button . disabled = false ;
854- } , 3000 ) ;
855- }
856- }
857-
858- // EmailJS Implementation (Recommended)
859- async function sendEmailWithEmailJS ( name , email , message ) {
860- // You need to:
861- // 1. Sign up at https://www.emailjs.com/
862- // 2. Create an email service (Gmail, Outlook, etc.)
863- // 3. Create an email template
864- // 4. Replace the IDs below with your actual IDs
865-
866- const serviceID = 'service_63heqj5' ; // Your EmailJS service ID
867- const templateID = 'template_mavsf06' ; // Your EmailJS template ID
868- const publicKey = '1a0XajOl0aHeAdOiA' ; // Your EmailJS public key
869-
870- const templateParams = {
871- name : name , // This will populate {{name}} in your template
872- email : email , // This will populate {{email}} in your template
873- message : message // This will populate {{message}} in your template
874- } ;
875-
876- // Check if EmailJS is loaded
877- if ( typeof emailjs === 'undefined' ) {
878- throw new Error ( 'EmailJS not loaded. Please add the EmailJS script.' ) ;
879- }
880-
881- return await emailjs . send ( serviceID , templateID , templateParams , publicKey ) ;
882- }
883-
884- // Formspree Implementation (Alternative)
885- async function sendEmailWithFormspree ( name , email , message ) {
886- // You need to:
887- // 1. Sign up at https://formspree.io/
888- // 2. Create a form and get your form ID
889- // 3. Replace YOUR_FORM_ID below
890-
891- const formspreeURL = 'https://formspree.io/f/YOUR_FORM_ID' ; // Replace with your Formspree form ID
816+ // Initialize all functionality when DOM is loaded
817+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
818+ // Initialize certificates
819+ initializeCertificates ( ) ;
892820
893- const response = await fetch ( formspreeURL , {
894- method : 'POST' ,
895- headers : {
896- 'Content-Type' : 'application/json'
897- } ,
898- body : JSON . stringify ( {
899- name : name ,
900- email : email ,
901- message : message
902- } )
903- } ) ;
821+ // EmailJS form submission handler
822+ const contactForm = document . getElementById ( 'contactForm' ) ;
823+ const submitBtn = document . getElementById ( 'submitBtn' ) ;
904824
905- if ( ! response . ok ) {
906- throw new Error ( 'Failed to send email via Formspree' ) ;
825+ if ( contactForm && submitBtn ) {
826+ contactForm . addEventListener ( 'submit' , function ( event ) {
827+ event . preventDefault ( ) ;
828+
829+ const originalText = submitBtn . textContent ;
830+ submitBtn . textContent = 'Sending...' ;
831+ submitBtn . disabled = true ;
832+
833+ const serviceID = 'service_63heqj5' ;
834+ const templateID = 'template_mavsf06' ;
835+
836+ emailjs . sendForm ( serviceID , templateID , this )
837+ . then ( ( ) => {
838+ submitBtn . textContent = 'Message Sent!' ;
839+ contactForm . reset ( ) ; // Reset the form
840+
841+ // Reset button text after 3 seconds
842+ setTimeout ( ( ) => {
843+ submitBtn . textContent = originalText ;
844+ submitBtn . disabled = false ;
845+ } , 3000 ) ;
846+ } , ( err ) => {
847+ console . error ( 'EmailJS error:' , err ) ;
848+ submitBtn . textContent = 'Error - Try Again' ;
849+
850+ // Reset button text after 3 seconds
851+ setTimeout ( ( ) => {
852+ submitBtn . textContent = originalText ;
853+ submitBtn . disabled = false ;
854+ } , 3000 ) ;
855+ } ) ;
856+ } ) ;
907857 }
908-
909- return response . json ( ) ;
910- }
858+ } ) ;
911859
912- // Netlify Forms Implementation (if hosting on Netlify)
913- async function sendEmailWithNetlify ( name , email , message ) {
914- const response = await fetch ( '/' , {
915- method : 'POST' ,
916- headers : {
917- 'Content-Type' : 'application/x-www-form-urlencoded'
918- } ,
919- body : new URLSearchParams ( {
920- 'form-name' : 'contact' ,
921- name : name ,
922- email : email ,
923- message : message
924- } )
925- } ) ;
926-
927- if ( ! response . ok ) {
928- throw new Error ( 'Failed to send email via Netlify' ) ;
929- }
930-
931- return response ;
932- }
933860
934861 // Certificate filtering
935862 function filterCertificates ( category , buttonElement ) {
@@ -1039,8 +966,8 @@ <h4 class="font-medium mb-4">Follow Me</h4>
1039966 await Promise . all ( loadPromises ) ;
1040967 }
1041968
1042- // Event listeners
1043- document . addEventListener ( 'DOMContentLoaded' , function ( ) {
969+ // Certificate loading and filtering
970+ function initializeCertificates ( ) {
1044971 // Load certificates
1045972 loadAllCertificates ( ) ;
1046973
@@ -1051,7 +978,7 @@ <h4 class="font-medium mb-4">Follow Me</h4>
1051978 filterCertificates ( category , e . target ) ;
1052979 } ) ;
1053980 } ) ;
1054- } ) ;
981+ }
1055982
1056983 // Navbar scroll effect
1057984 window . addEventListener ( 'scroll' , ( ) => {
0 commit comments