1
1
import { useTranslation } from 'next-i18next'
2
- import { Button , Flex , Input } from 'dd360-ds'
2
+ import { useCallback , useEffect , useMemo , useState } from 'react'
3
+ import {
4
+ Button ,
5
+ Flex ,
6
+ Input ,
7
+ Callout ,
8
+ CalloutProps ,
9
+ Transition
10
+ } from 'dd360-ds'
3
11
import { composeClasses } from 'dd360-ds/lib'
4
12
import { useTheme } from '@/store/theme-store'
5
13
@@ -8,30 +16,105 @@ function Newsletter() {
8
16
const {
9
17
themeObject : { extendedPalette }
10
18
} = useTheme ( )
19
+ const [ emailVal , setEmailVal ] = useState ( '' )
20
+ const [ isLoading , setIsLoading ] = useState ( false )
21
+ const [ isMessageShown , setIsMessageShown ] = useState ( false )
22
+ const [ messageType , setMessageType ] = useState ( '' )
23
+
24
+ const isDisabledBtn = emailVal === '' || isMessageShown
25
+
26
+ const sendSubmit = useCallback ( async ( ) => {
27
+ setIsLoading ( true )
28
+ try {
29
+ const res = await fetch ( '/api/newsletter' , {
30
+ method : 'POST' ,
31
+ body : emailVal
32
+ } )
33
+
34
+ const data = await res . json ( )
35
+ if ( data . status !== 'success' ) {
36
+ throw new Error ( 'Failed' )
37
+ }
38
+ setMessageType ( 'success' )
39
+ } catch ( e ) {
40
+ setMessageType ( 'error' )
41
+ } finally {
42
+ setIsMessageShown ( true )
43
+ setIsLoading ( false )
44
+ }
45
+ } , [ emailVal ] )
46
+
47
+ const calloutProps = useMemo ( ( ) => {
48
+ return {
49
+ title :
50
+ messageType === 'success'
51
+ ? 'Thanks for subscribing!'
52
+ : 'Something went wrong!' ,
53
+ description :
54
+ messageType === 'success'
55
+ ? "We'll send you an email when we have news."
56
+ : "Oops, there was an error and we couldn't subscribe you. Please try again." ,
57
+ variant :
58
+ messageType === 'success'
59
+ ? 'success'
60
+ : ( 'error' as CalloutProps [ 'variant' ] )
61
+ }
62
+ } , [ messageType ] )
63
+
64
+ useEffect ( ( ) => {
65
+ if ( isMessageShown ) {
66
+ const timer = setTimeout ( ( ) => {
67
+ setIsMessageShown ( false )
68
+ setMessageType ( '' )
69
+ } , 5000 )
70
+
71
+ return ( ) => clearTimeout ( timer )
72
+ }
73
+ } , [ isMessageShown ] )
11
74
12
75
return (
13
- < Flex gap = "3" className = "flex-col sm:flex-row mt-8" >
14
- < Input
15
- placeholder = "hello@dd360.mx"
16
- className = { composeClasses (
17
- 'sm:mt-0 inline-block border-gray-500 w-full sm:max-w-[287px]' ,
18
- extendedPalette . primaryText
19
- ) }
20
- style = { {
21
- background : extendedPalette . inputBackground ,
22
- borderColor : extendedPalette . inputBorderHex
23
- } }
24
- />
25
- < Button
26
- className = "leading-none text-gray-50 min-w-max"
27
- rounded = "lg"
28
- paddingX = "8"
29
- paddingY = "4"
30
- style = { { maxWidth : 124 } }
31
- >
32
- { t ( 'subscribe' ) }
33
- </ Button >
34
- </ Flex >
76
+ < >
77
+ < Flex gap = "3" className = "flex-col sm:flex-row mt-8" >
78
+ < Input
79
+ placeholder = "hello@dd360.mx"
80
+ type = "email"
81
+ className = { composeClasses (
82
+ 'sm:mt-0 inline-block border-gray-500 w-full sm:max-w-[287px]' ,
83
+ extendedPalette . primaryText
84
+ ) }
85
+ onChange = { ( e ) => setEmailVal ( e . target . value ) }
86
+ onSubmit = { ( e ) => {
87
+ e . preventDefault ( )
88
+ sendSubmit ( )
89
+ } }
90
+ value = { emailVal }
91
+ style = { {
92
+ background : extendedPalette . inputBackground ,
93
+ borderColor : extendedPalette . inputBorderHex
94
+ } }
95
+ />
96
+ < Button
97
+ className = "leading-none text-gray-50 min-w-max"
98
+ rounded = "lg"
99
+ paddingX = "8"
100
+ paddingY = "4"
101
+ style = { { maxWidth : 124 } }
102
+ disabled = { isDisabledBtn || isLoading }
103
+ isLoading = { isLoading }
104
+ onClick = { ( e ) => {
105
+ e . preventDefault ( )
106
+ sendSubmit ( )
107
+ } }
108
+ >
109
+ { t ( 'subscribe' ) }
110
+ </ Button >
111
+ </ Flex >
112
+ { isMessageShown && (
113
+ < Transition show >
114
+ < Callout className = "w-96 mt-4" { ...calloutProps } />
115
+ </ Transition >
116
+ ) }
117
+ </ >
35
118
)
36
119
}
37
120
0 commit comments