1
- import { VercelInviteUserEmail } from '../emails/vercel-invite-user' ;
2
- import { Resend } from 'resend' ;
1
+ "use client" ;
3
2
4
- export default function Page ( ) {
5
- async function send ( formData : FormData ) {
6
- 'use server' ;
7
-
8
- const resend = new Resend ( process . env . RESEND_API_KEY ) ;
9
- const email = formData . get ( 'email' ) as string ;
10
-
11
- const { data, error } = await resend . emails . send ( {
12
- from :
'Vercel <[email protected] >' ,
13
- to : [ email ] ,
14
- subject : 'Join team on Vercel' ,
15
- react : VercelInviteUserEmail ( { } ) ,
16
- } ) ;
3
+ import clsx from "clsx" ;
4
+ import { useFormState , useFormStatus } from "react-dom" ;
5
+ import { send } from "./lib/actions" ;
6
+ import React from "react" ;
17
7
18
- if ( error ) {
19
- console . log ( error ) ;
20
- }
21
-
22
- console . log ( data ) ;
23
- }
8
+ export default function Page ( ) {
9
+ const [ , dispatch ] = useFormState ( send , undefined ) ;
24
10
25
11
return (
26
- < div className = "bg-zinc-950 py-16 sm:py-24 h-[100vh] " >
27
- < div className = "mx-auto max-w-7xl sm:px-6 lg:px-8" >
28
- < div className = "relative isolate overflow-hidden bg-gray-900 px-6 py-24 shadow-2xl sm:rounded-3xl sm:px-24 xl:py-32" >
29
- < h2 className = "mx-auto max-w-2xl text-center text-3xl font-bold tracking-tight text-white sm:text-4xl" >
12
+ < div className = "bg-zinc-950 p-8 min-h-screen flex justify-center items-center sm:items-start sm:p-24 " >
13
+ < div className = "mx-auto w-full max-w-5xl sm:px-6 lg:px-8" >
14
+ < div className = "relative isolate overflow-hidden bg-gray-900 px-6 py-24 shadow-2xl rounded-lg sm:rounded-3xl sm:px-24 xl:py-32 flex items-center flex-col " >
15
+ < h2 className = "max-w-2xl text-center text-3xl font-bold tracking-tight text-white sm:text-4xl" >
30
16
Get invited to a team
31
17
</ h2 >
32
- < p className = "mx-auto mt-2 max-w-xl text-center text-lg leading-8 text-gray-300" >
18
+
19
+ < p className = "mt-2 max-w-xl text-center text-lg leading-8 text-gray-300" >
33
20
Type your email address to get invited to a team.
34
21
</ p >
35
- < form className = "mx-auto mt-10 flex max-w-md gap-x-4" action = { send } >
22
+
23
+ < form
24
+ className = "mt-10 flex max-w-md gap-4 items-start w-full"
25
+ action = { dispatch }
26
+ >
36
27
< label htmlFor = "email" className = "sr-only" >
37
28
Email address
38
29
</ label >
30
+
39
31
< input
40
32
id = "email"
41
33
name = "email"
@@ -44,21 +36,25 @@ export default function Page() {
44
36
45
37
46
38
autoComplete = "email"
47
- className = "min-w-0 flex-auto rounded-md border-0 bg-white/5 px-3.5 py-2 text-white shadow-sm ring-1 ring-inset ring-white/10 focus:ring-2 focus:ring-inset focus:ring-white sm:text-sm sm:leading-6"
39
+ className = "w-full rounded-md border-0 bg-white/5 px-3.5 py-2 text-white shadow-sm ring-1 ring-inset ring-white/10 focus:ring-2 focus:ring-inset focus:ring-white sm:text-sm sm:leading-6"
48
40
/>
49
- < button
50
- type = "submit"
51
- className = "flex-none rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
52
- >
53
- Invite
54
- </ button >
41
+
42
+ < SubmitButton />
55
43
</ form >
44
+
56
45
< svg
57
46
viewBox = "0 0 1024 1024"
58
47
aria-hidden = "true"
59
48
className = "absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-x-1/2"
60
49
>
61
- < circle r = { 512 } cx = { 512 } cy = { 512 } fill = "url(#759c1415-0410-454c-8f7c-9a820de03641)" fillOpacity = "0.7" />
50
+ < circle
51
+ r = { 512 }
52
+ cx = { 512 }
53
+ cy = { 512 }
54
+ fill = "url(#759c1415-0410-454c-8f7c-9a820de03641)"
55
+ fillOpacity = "0.7"
56
+ />
57
+
62
58
< defs >
63
59
< radialGradient
64
60
r = { 1 }
@@ -77,4 +73,20 @@ export default function Page() {
77
73
</ div >
78
74
</ div >
79
75
) ;
80
- }
76
+ }
77
+
78
+ function SubmitButton ( ) {
79
+ const { pending } = useFormStatus ( ) ;
80
+
81
+ return (
82
+ < button
83
+ type = "submit"
84
+ className = { clsx (
85
+ "flex-none rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white" ,
86
+ pending && "opacity-50 cursor-not-allowed"
87
+ ) }
88
+ >
89
+ Invite
90
+ </ button >
91
+ ) ;
92
+ }
0 commit comments