@@ -17,6 +17,56 @@ const InputBox: React.FC<{
1717 isTablet : boolean ;
1818 isDesktop : boolean ;
1919} > = ( { isMobile, isTablet, isDesktop } ) => {
20+ const [ email , setEmail ] = React . useState < string > ( "" ) ;
21+ const [ status , setStatus ] = React . useState < "idle" | "loading" | "success" | "error" > ( "idle" ) ;
22+
23+ const handleSubmit = async ( ) => {
24+
25+ setStatus ( "loading" ) ;
26+
27+ try {
28+ const response = await fetch ( '/api/joinMailingList' , {
29+ method : 'POST' ,
30+ headers : {
31+ 'Content-Type' : 'application/json' ,
32+ } ,
33+ body : JSON . stringify ( { email } ) ,
34+ } ) ;
35+
36+ if ( response . ok ) {
37+ setStatus ( "success" ) ;
38+ setEmail ( "" ) ;
39+
40+ setTimeout ( ( ) => {
41+ setStatus ( "idle" ) ;
42+ } , 3000 ) ;
43+ } else {
44+ setStatus ( "error" ) ;
45+ }
46+ } catch ( error ) {
47+ console . error ( 'Network error:' , error ) ;
48+ setStatus ( "error" ) ;
49+ }
50+
51+ } ;
52+
53+ const handleKeyPress = ( e : React . KeyboardEvent ) => {
54+ if ( e . key === 'Enter' ) {
55+ handleSubmit ( ) ;
56+ }
57+ } ;
58+
59+ const getButtonText = ( ) => {
60+ switch ( status ) {
61+ case "loading" :
62+ return "Submitting..." ;
63+ case "success" :
64+ return "Subscribed!" ;
65+ default :
66+ return "Notify Me" ;
67+ }
68+ } ;
69+
2070 const containerClass = clsx (
2171 "relative grid grid-cols-2" ,
2272 isDesktop && "top-[-185%]" ,
@@ -28,19 +78,35 @@ const InputBox: React.FC<{
2878 "font-DMSans-Regular border border-heather border-4 pl-4 bg-[#FEF9F2] h-[5.5vh]" ,
2979 isDesktop && "rounded-lg w-[20vw] text-xl" ,
3080 isTablet && "rounded-xl w-[42vw] text-xl" ,
31- isMobile && "rounded-lg w-[85%] border-2 h-[5vh] col-span-3"
81+ isMobile && "rounded-lg w-[85%] border-2 h-[5vh] col-span-3" ,
3282 ) ;
3383
3484 const buttonClass = clsx (
35- "hover:scale-105 transition-transform transition-duration-300 hover:bg-darkSeaFoam font-GT-Walsheim-Regular text-bold bg-seaFoam text-white h-[5vh]" ,
85+ "hover:scale-105 transition-transform transition-duration-300 hover:bg-darkSeaFoam font-GT-Walsheim-Regular text-bold bg-seaFoam text-white h-[5vh] disabled:opacity-50 disabled:cursor-not-allowed " ,
3686 isDesktop && "text-xl rounded-lg w-[8vw]" ,
3787 isTablet && "text-xl rounded-xl w-[15vw]" ,
3888 isMobile && "relative rounded-lg w-[25vw] left-[-30%]"
3989 ) ;
90+
4091 return (
41- < div className = { containerClass } >
42- < input className = { inputClass } placeholder = "Start your journey..." />
43- < button className = { buttonClass } > Notify Me</ button >
92+ < div className = "relative" >
93+ < div className = { containerClass } >
94+ < input
95+ className = { inputClass }
96+ placeholder = "Start your journey..."
97+ value = { email }
98+ onChange = { ( e ) => setEmail ( e . target . value ) }
99+ onKeyDown = { handleKeyPress }
100+ disabled = { status === "loading" }
101+ />
102+ < button
103+ className = { buttonClass }
104+ onClick = { handleSubmit }
105+ disabled = { status === "loading" }
106+ >
107+ { getButtonText ( ) }
108+ </ button >
109+ </ div >
44110 </ div >
45111 ) ;
46112} ;
@@ -104,7 +170,7 @@ export default function Placeholder(): React.ReactNode {
104170 const contactWrapperClass = "absolute bottom-10 left-10 text-l" ;
105171 const emailClass =
106172 "font-GT-Walsheim-Regular underline hover:no-underline transition-transform transition-duration-300" ;
107-
173+
108174 return (
109175 < div className = { wrapperClass } >
110176 < div className = { leftCloudClass } >
0 commit comments