1- import { useState , useContext } from "react" ;
1+ import { useState , useContext , useEffect } from "react" ;
22import {
33 Github ,
44 Mail ,
@@ -28,6 +28,17 @@ function Contact() {
2828 const { mode } = themeContext ;
2929 const isDark = mode === "dark" ;
3030
31+ // FIX: Correctly handle the auto-dismiss popup timer within an effect lifestyle cleanup pattern
32+ useEffect ( ( ) => {
33+ if ( ! showPopup ) return ;
34+
35+ const timer = setTimeout ( ( ) => {
36+ setShowPopup ( false ) ;
37+ } , 5000 ) ;
38+
39+ return ( ) => clearTimeout ( timer ) ;
40+ } , [ showPopup ] ) ;
41+
3142 const handleInputChange = ( e : React . ChangeEvent < HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement > ) => {
3243 const { name, value } = e . target ;
3344 setFormData ( ( prev ) => ( { ...prev , [ name ] : value } ) ) ;
@@ -37,21 +48,17 @@ function Contact() {
3748 e . preventDefault ( ) ;
3849 setIsSubmitting ( true ) ;
3950
40- // Simulate API pipeline delay (formData can now be passed safely to your API)
41- await new Promise ( ( resolve ) => setTimeout ( resolve , 1500 ) ) ;
42-
43- setIsSubmitting ( false ) ;
44- setShowPopup ( true ) ;
45-
46- // Reset Form fields safely
47- setFormData ( { name : "" , email : "" , subject : "" , message : "" } ) ;
48-
49- // Auto-dismiss success notification
50- const timer = setTimeout ( ( ) => {
51- setShowPopup ( false ) ;
52- } , 5000 ) ;
53-
54- return ( ) => clearTimeout ( timer ) ;
51+ // FIX: Wrapped logic inside a proper try/catch/finally block to ensure states reset safely on network failures
52+ try {
53+ // Simulate API pipeline delay
54+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1500 ) ) ;
55+ setShowPopup ( true ) ;
56+ setFormData ( { name : "" , email : "" , subject : "" , message : "" } ) ;
57+ } catch ( error ) {
58+ console . error ( "Failed to route contact payload data:" , error ) ;
59+ } finally {
60+ setIsSubmitting ( false ) ;
61+ }
5562 } ;
5663
5764 return (
@@ -102,7 +109,7 @@ function Contact() {
102109 < div className = { `w-10 h-10 rounded-xl flex items-center justify-center border shadow-sm ${
103110 isDark ? "bg-slate-900 border-slate-800" : "bg-white border-purple-100"
104111 } `} >
105- < img src = "/crl-icon.png" alt = "Logo" className = "w-6 h-6 object-contain" />
112+ < img src = "/crl-icon.png" alt = "GitHub Tracker Logo" className = "w-6 h-6 object-contain" />
106113 </ div >
107114 < h3 className = "text-xl font-bold tracking-tight bg-gradient-to-r from-purple-500 via-indigo-500 to-blue-500 bg-clip-text text-transparent" >
108115 GitHub Tracker
@@ -117,24 +124,30 @@ function Contact() {
117124 </ div >
118125 </ div >
119126
120- { /* Minimalist Actionable Communication Badges */ }
127+ { /* FIX: Swapped out empty <div> wrapper formats for functional semantic anchor link maps */ }
121128 < div className = "space-y-3 pt-8 lg:pt-0" >
122129 { [
123- { label : "Direct Support" , detail : "support@githubtracker.com" , Icon : Mail } ,
124- { label : "Community Hotline" , detail : "(123) 456-7890" , Icon : Phone } ,
125- { label : "Open-Source Hub" , detail : "github.com/yourorg/track" , Icon : Github } ,
126- ] . map ( ( { label, detail, Icon } ) => (
127- < div key = { label } className = "flex items-center gap-3 group cursor-pointer" >
130+ { label : "Direct Support" , detail : "support@githubtracker.com" , href : "mailto:support@githubtracker.com" , target : "_self" , Icon : Mail } ,
131+ { label : "Community Hotline" , detail : "(123) 456-7890" , href : "tel:+11234567890" , target : "_self" , Icon : Phone } ,
132+ { label : "Open-Source Hub" , detail : "github.com/yourorg/track" , href : "https://github.com/yourorg/track" , target : "_blank" , Icon : Github } ,
133+ ] . map ( ( { label, detail, href, target, Icon } ) => (
134+ < a
135+ key = { label }
136+ href = { href }
137+ target = { target }
138+ rel = { target === "_blank" ? "noopener noreferrer" : undefined }
139+ className = "flex items-center gap-3 group outline-none focus-visible:ring-2 focus-visible:ring-purple-500/50 rounded-xl p-1"
140+ >
128141 < div className = { `p-2 rounded-lg border transition-colors ${
129142 isDark ? "bg-slate-900/50 border-slate-800 text-slate-400 group-hover:text-purple-400 group-hover:border-purple-500/30" : "bg-white border-slate-200 text-slate-500 group-hover:text-purple-600 group-hover:border-purple-200"
130143 } `} >
131144 < Icon className = "w-4 h-4" />
132145 </ div >
133- < div >
146+ < div className = "overflow-hidden" >
134147 < p className = "text-[10px] uppercase font-bold tracking-wider text-slate-400" > { label } </ p >
135148 < p className = { `text-xs font-semibold truncate transition-colors ${ isDark ? "text-slate-300 group-hover:text-white" : "text-slate-700 group-hover:text-slate-950" } ` } > { detail } </ p >
136149 </ div >
137- </ div >
150+ </ a >
138151 ) ) }
139152 </ div >
140153 </ div >
0 commit comments