11import * as Popover from '@radix-ui/react-popover' ;
2- import * as React from 'react' ;
2+ import { useId , useRef , useState } from 'react' ;
33import { toast } from 'sonner' ;
4- import { sendTestEmail } from '../actions/send-test-email' ;
54import { Button } from './button' ;
65import { Text } from './text' ;
76
87const useTimer = ( startingSeconds : number , onStop ?: ( ) => void ) => {
9- const [ isActive , setIsActive ] = React . useState ( false ) ;
10- const [ secondsRemaining , setSecondsRemaining ] =
11- React . useState ( startingSeconds ) ;
8+ const [ isActive , setIsActive ] = useState ( false ) ;
9+ const [ secondsRemaining , setSecondsRemaining ] = useState ( startingSeconds ) ;
1210
13- const interval = React . useRef < NodeJS . Timeout | undefined > ( undefined ) ;
11+ const interval = useRef < NodeJS . Timeout | undefined > ( undefined ) ;
1412
1513 return {
1614 isActive,
@@ -37,33 +35,41 @@ const useTimer = (startingSeconds: number, onStop?: () => void) => {
3735} ;
3836
3937export const Send = ( { markup } : { markup : string } ) => {
40- const [ to , setTo ] = React . useState ( '' ) ;
41- const [ subject , setSubject ] = React . useState ( 'Testing React Email' ) ;
42- const [ isSending , setIsSending ] = React . useState ( false ) ;
43- const [ isPopOverOpen , setIsPopOverOpen ] = React . useState ( false ) ;
38+ const [ to , setTo ] = useState ( '' ) ;
39+ const [ subject , setSubject ] = useState ( 'Testing React Email' ) ;
40+ const [ isSending , setIsSending ] = useState ( false ) ;
41+ const [ isPopOverOpen , setIsPopOverOpen ] = useState ( false ) ;
4442
45- const rateLimiter = useTimer ( 60 ) ;
43+ const [ isRateLimited , setIsRateLimited ] = useState ( false ) ;
44+ const rateLimiter = useTimer ( 60 , ( ) => {
45+ setIsRateLimited ( false ) ;
46+ } ) ;
4647
4748 const onFormSubmit = async ( e : React . FormEvent ) => {
4849 e . preventDefault ( ) ;
4950 setIsSending ( true ) ;
5051
5152 try {
52- const { status, ok } = await sendTestEmail ( {
53- to,
54- subject,
55- markup,
53+ const response = await fetch ( 'https://react.email/api/send/test' , {
54+ method : 'POST' ,
55+ headers : { 'Content-Type' : 'application/json' } ,
56+ body : JSON . stringify ( {
57+ to,
58+ subject,
59+ html : markup ,
60+ } ) ,
5661 } ) ;
5762
5863 if ( ! rateLimiter . isActive ) {
5964 rateLimiter . start ( ) ;
6065 }
6166
62- if ( ok ) {
67+ if ( response . ok ) {
6368 toast . success ( 'Email sent! Check your inbox.' ) ;
64- } else if ( status === 429 ) {
69+ } else if ( response . status === 429 ) {
6570 toast . error ( 'Too many requests.' ) ;
6671 rateLimiter . start ( ) ;
72+ setIsRateLimited ( true ) ;
6773 } else {
6874 toast . error ( 'Something went wrong. Please try again.' ) ;
6975 }
@@ -73,8 +79,8 @@ export const Send = ({ markup }: { markup: string }) => {
7379 setIsSending ( false ) ;
7480 } ;
7581
76- const toId = React . useId ( ) ;
77- const subjectId = React . useId ( ) ;
82+ const toId = useId ( ) ;
83+ const subjectId = useId ( ) ;
7884
7985 return (
8086 < Popover . Root
@@ -162,14 +168,12 @@ export const Send = ({ markup }: { markup: string }) => {
162168 subject . length === 0 ||
163169 to . length === 0 ||
164170 isSending ||
165- rateLimiter . isActive
171+ isRateLimited
166172 }
167173 type = "submit"
168174 >
169175 Send
170- { rateLimiter . isActive
171- ? ` ${ rateLimiter . secondsRemaining } s`
172- : null }
176+ { isRateLimited ? ` ${ rateLimiter . secondsRemaining } s` : null }
173177 </ Button >
174178 </ div >
175179 </ form >
0 commit comments