forked from Markeljan/web3gpt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlanding.tsx
144 lines (128 loc) · 5.49 KB
/
landing.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"use client"
import Image from "next/image"
import { useEffect, useState } from "react"
import Player from "react-lottie-player"
import { toast } from "sonner"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { getUserField, storeEmail } from "@/lib/actions/db"
import { useIsClient } from "@/lib/hooks/use-is-client"
import { useLocalStorage } from "@/lib/hooks/use-local-storage"
import { isValidEmail } from "@/lib/utils"
import web3GPTLogo from "@/public/web3gpt-logo-beta.svg"
type LandingProps = {
userId?: string
disableAnimations?: boolean
}
export function Landing({ userId, disableAnimations }: LandingProps) {
const [validationError, setValidationError] = useState<string | null>(null)
const [email, setEmail] = useState<string>("")
const [localIsSubscribed, setLocalIsSubscribed] = useLocalStorage("email_subscribed", false)
const isClient = useIsClient()
useEffect(() => {
const fetchIsEmailSubscribed = async () => {
const backendIsSubscribed = await getUserField("email_subscribed")
if (backendIsSubscribed === true) {
setLocalIsSubscribed(true)
}
}
if (localIsSubscribed !== true && userId && isClient) {
fetchIsEmailSubscribed()
}
}, [localIsSubscribed, setLocalIsSubscribed, userId, isClient])
async function handleSubscribe(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
if (!isValidEmail(email)) {
setValidationError("Please enter a valid email")
return
}
setValidationError(null)
await storeEmail(email)
setLocalIsSubscribed(true)
setEmail("")
toast.success("Thanks for subscribing!")
}
return (
<>
<div className="flex flex-col mx-auto max-w-2xl h-96 bg-background border-gray-600/25 text-center dark:border-gray-600/50 md:border rounded-2xl mb-8 md:mb-12 px-4 pt-8 pb-4">
<div className="flex w-full justify-center pb-4">
<Image src={web3GPTLogo} alt="web3gpt logo" priority={true} height={256} width={256} />
</div>
<p className="text-lg font-bold tracking-tight lg:text-2xl lg:font-normal">Deploy smart contracts with AI</p>
<div className="grid-row-3 py-4 grid grid-flow-row gap-1 md:grid-flow-col md:gap-4">
<div className="mx-3 grid grid-cols-3 content-center gap-1 md:grid-cols-1 md:gap-4">
<Player
play={!disableAnimations}
loop={false}
speed={0.5}
direction={-1}
path="/lotties/puzzle.json"
className="size-24 md:h-32 md:w-full"
/>
<div className="col-span-2 mt-4 text-left md:col-span-1 md:mt-0 md:text-center">
<h3 className="font-bold md:mb-2">Generate</h3>
<p className="text-sm text-gray-600 dark:text-gray-400">Generate custom smart contracts using prompts.</p>
</div>
</div>
<div className="mx-3 grid grid-cols-3 content-center gap-1 md:grid-cols-1 md:gap-4">
<Player
play={!disableAnimations}
loop={false}
speed={0.5}
direction={1}
path="/lotties/globe.json"
className="size-24 md:h-32 md:w-full"
/>
<div className="col-span-2 mt-4 text-left md:col-span-1 md:mt-0 md:text-center">
<h3 className="font-bold md:mb-2">Deploy</h3>
<p className="text-sm text-gray-600 dark:text-gray-400">Deploy smart contracts directly from the chat.</p>
</div>
</div>
<div className="mx-3 grid grid-cols-3 content-center gap-1 md:grid-cols-1 md:gap-4">
<Player
play={!disableAnimations}
loop={false}
speed={0.5}
path="/lotties/clock.json"
className="size-24 md:h-32 md:w-full"
/>
<div className="col-span-2 mt-4 text-left md:col-span-1 md:mt-0 md:text-center">
<h3 className="font-bold md:mb-2">Speed Up</h3>
<p className="text-sm text-gray-600 dark:text-gray-400">Skip the boilerplate, deploy in seconds.</p>
</div>
</div>
</div>
</div>
<hr className="mb-4 md:hidden" />
{isClient && localIsSubscribed === false ? (
<div className="mx-auto mb-16 max-w-2xl rounded-2xl border-gray-600/25 px-4 text-center dark:border-gray-600/50 md:border">
<div className="my-5 flex flex-col gap-4">
<p className="mt-8 scroll-m-20 text-2xl tracking-tight">Early Access</p>
<p className="px-4 text-sm text-gray-600 dark:text-gray-400">
Sign up for development updates and early access to latest features
</p>
<div className="flex justify-center gap-2">
<form className="flex justify-center gap-2" onSubmit={handleSubscribe}>
<Input
className="h-11 w-64 rounded-lg p-3"
type="text"
placeholder="Your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Button type="submit" className="h-11" size="sm">
Send
</Button>
</form>
</div>
{validationError ? (
<p className="text-xs text-red-500">{validationError}</p>
) : (
<p className="mb-8 text-xs text-gray-400">{"No spam, we promise :)"}</p>
)}
</div>
</div>
) : null}
</>
)
}