1
1
'use client' ;
2
- import React , { useRef } from 'react' ;
2
+ import React , { useEffect , useRef , useState } from 'react' ;
3
3
import Link from 'next/link' ;
4
4
import Image from 'next/image' ;
5
5
import { sendContactMeEmail } from '../lib/client.js' ;
6
6
import { motion , useAnimationControls } from 'framer-motion' ;
7
7
8
8
const EmailSection = ( ) => {
9
+ const [ messageSent , setMessageSent ] = useState ( null ) ;
10
+ const [ email , setEmail ] = useState ( null ) ;
11
+ const [ subject , setSubject ] = useState ( null ) ;
12
+ const [ message , setMessage ] = useState ( null ) ;
13
+ const [ errors , setErrors ] = useState ( {
14
+ email : '' ,
15
+ } ) ;
9
16
const formRef = useRef ( null ) ;
10
17
const controls = useAnimationControls ( ) ;
18
+ const [ isValidForm , setIsValidForm ] = useState ( false ) ;
19
+
20
+ const validateForm = ( ) => {
21
+ let tmp = { } ;
22
+ let anyError = false ;
23
+ if ( ! / \S + @ \S + \. \S + / . test ( email ) ) {
24
+ tmp . email = 'Email is invalid.' ;
25
+ anyError = true ;
26
+ } else {
27
+ tmp . email = '' ;
28
+ }
29
+ if ( ! subject || ! message || ! email ) {
30
+ anyError = true ;
31
+ }
32
+ setErrors ( tmp ) ;
33
+ setIsValidForm ( ! anyError ) ;
34
+ } ;
11
35
const handleSubmit = async ( e ) => {
12
36
e . preventDefault ( ) ;
13
37
await sendContactMeEmail (
@@ -16,24 +40,36 @@ const EmailSection = () => {
16
40
e . target . message . value ,
17
41
)
18
42
. then ( ( _ ) => {
43
+ setMessageSent ( false ) ;
19
44
formRef . current . reset ( ) ;
20
- } )
21
- . then ( ( _ ) => {
22
- controls . set ( { opacity : 0 , scale : 1 } ) ;
23
- controls . start ( {
24
- opacity : 1 ,
25
- scale : 1 ,
26
- transition : {
27
- repeat : 1 ,
28
- repeatType : 'reverse' ,
29
- duration : 2 ,
30
- } ,
31
- } ) ;
45
+ setEmail ( null ) ;
46
+ setSubject ( null ) ;
47
+ setMessage ( null ) ;
48
+ setIsValidForm ( false ) ;
32
49
} )
33
50
. catch ( ( err ) => {
51
+ setMessageSent ( true ) ;
34
52
console . log ( err ) ;
35
53
} ) ;
36
54
} ;
55
+ useEffect ( ( ) => {
56
+ if ( email !== null || subject !== null || message !== null ) {
57
+ validateForm ( ) ;
58
+ }
59
+ if ( messageSent !== null && ! messageSent ) {
60
+ controls . set ( { opacity : 0 , scale : 1 } ) ;
61
+ controls . start ( {
62
+ opacity : 1 ,
63
+ scale : 1 ,
64
+ transition : {
65
+ repeat : 1 ,
66
+ repeatType : 'reverse' ,
67
+ duration : 2 ,
68
+ } ,
69
+ } ) ;
70
+ setMessageSent ( null ) ;
71
+ }
72
+ } , [ messageSent , email , subject , message ] ) ;
37
73
return (
38
74
< section
39
75
id = "contact"
@@ -78,13 +114,17 @@ const EmailSection = () => {
78
114
>
79
115
Your email
80
116
</ label >
117
+ { errors . email && (
118
+ < p className = "text-red-500 text-sm mb-2 block" > { errors . email } </ p >
119
+ ) }
81
120
< input
82
121
name = "email"
83
122
type = "text"
84
123
id = "email"
85
124
required
86
125
className = "bg-secondaryBackgroud border border-primaryBorder placeholder-primaryPlaceholder text-gray-100 text-sm rounded-lg block w-full p-2.5"
87
126
placeholder = "lorem@ipsum.com"
127
+ onChange = { ( e ) => setEmail ( e . target . value ) }
88
128
/>
89
129
</ div >
90
130
< div className = "mb-6" >
@@ -101,6 +141,7 @@ const EmailSection = () => {
101
141
required
102
142
className = "bg-secondaryBackgroud border border-primaryBorder placeholder-primaryPlaceholder text-gray-100 text-sm rounded-lg block w-full p-2.5"
103
143
placeholder = "Just saying hi"
144
+ onChange = { ( e ) => setSubject ( e . target . value ) }
104
145
/>
105
146
</ div >
106
147
< div className = "mb-6" >
@@ -114,24 +155,32 @@ const EmailSection = () => {
114
155
name = "message"
115
156
id = "message"
116
157
required
117
- rows = "10"
158
+ rows = { 10 }
118
159
className = "bg-secondaryBackgroud border border-primaryBorder placeholder-primaryPlaceholder text-gray-100 text-sm rounded-lg block w-full p-2.5"
119
160
placeholder = "Leave your message here..."
161
+ onChange = { ( e ) => setMessage ( e . target . value ) }
120
162
/>
121
163
</ div >
122
164
< button
123
165
type = "submit"
124
- className = "rounded hover:bg-primary-400 bg-primary-600 text-primaryText w-full py-2.5 flex justify-center"
166
+ className = { `rounded ${ isValidForm ? 'hover:bg-primary-400' : '' } bg-primary-600 text-primaryText w-full py-2.5 flex justify-center` }
167
+ disabled = { ! isValidForm }
125
168
>
126
169
Send Message
127
170
</ button >
128
- < motion . p
129
- className = "text-primary-500 text-sm mt-2 block"
130
- initial = { { opacity : 0 , scale : 1 } }
131
- animate = { controls }
132
- >
133
- Email sent succesfully!
134
- </ motion . p >
171
+ { messageSent ? (
172
+ < p className = "text-red-500 text-sm mt-2 block" >
173
+ ❌ Message not set, sorry!
174
+ </ p >
175
+ ) : (
176
+ < motion . p
177
+ className = "text-primary-500 text-sm mt-2 block"
178
+ initial = { { opacity : 0 , scale : 1 } }
179
+ animate = { controls }
180
+ >
181
+ ✅ Email sent succesfully!
182
+ </ motion . p >
183
+ ) }
135
184
</ form >
136
185
</ div >
137
186
</ section >
0 commit comments