1'use client'
2
3import React, { useState } from 'react'
4import { motion, AnimatePresence } from 'framer-motion'
5import { X } from 'lucide-react'
6
7type Origin = { x: number; y: number }
8
9const Page = () => {
10 const [isOpen, setIsOpen] = useState(true);
11 const [mode, setMode] = useState<"signup" | "signin">("signup");
12 const [origin, setOrigin] = useState<Origin>({ x: 0, y: 0 });
13 const closeModal = () => setIsOpen(false);
14
15 return (
16 <div className="min-h-screen bg-black flex items-center justify-center overflow-hidden p-4">
17
18 <motion.div
19 className="absolute inset-0 z-0"
20 style={{
21 background:
22 "radial-gradient(125% 125% at var(--x) var(--y), #000 40%, #7c3aed 100%)",
23 }}
24 animate={{
25 "--x": ["50%", "60%", "40%", "50%"],
26 "--y": ["10%", "20%", "15%", "10%"],
27 }}
28 transition={{
29 duration: 15,
30 repeat: Infinity,
31 ease: "easeInOut",
32 }}
33 />
34 <AnimatePresence>
35 <motion.div
36 key="modal"
37 initial={{ opacity: 0, scale: 0.7, x: origin.x, y: origin.y }}
38 animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}
39 exit={{ opacity: 0, scale: 0.7, x: origin.x, y: origin.y }}
40 transition={{ duration: 0.4, ease: 'easeOut' }}
41 className="fixed inset-0 flex items-center justify-center z-10"
42 >
43 <motion.div
44 key="overlay"
45 initial={{ opacity: 0 }}
46 animate={{ opacity: 1 }}
47 exit={{ opacity: 0 }}
48 className="fixed inset-0 backdrop-blur-[1px] w-full overflow-hidden z-0"
49 />
50 <div className="bg-white/10 backdrop-blur-[5px] text-white shadow-lg max-w-sm px-6 py-6 min-w-[400px] rounded-xl">
51 <div className='absolute z-[9999] top-6 right-6'>
52 <button onClick={closeModal} className='text-white/70 hover:text-white transition'>
53 <X size={20} />
54 </button>
55 </div>
56 <div className="flex bg-black/50 p-1 rounded-full mb-6 w-fit">
57 <button
58 onClick={() => setMode("signup")}
59 className={`px-6 py-2 rounded-full transition-all duration-300 ${mode === "signup"
60 ? "bg-white/10"
61 : "text-white/60 hover:text-white"
62 }`}
63 >
64 Sign up
65 </button>
66
67 <button
68 onClick={() => setMode("signin")}
69 className={`px-6 py-2 rounded-full transition-all duration-300 ${mode === "signin"
70 ? "bg-white/10"
71 : "text-white/60 hover:text-white"
72 }`}
73 >
74 Sign in
75 </button>
76 </div>
77 <AnimatePresence mode="wait">
78 {mode === "signup" ? (
79 <motion.div
80 initial={{ opacity: 0, y: 10 }}
81 animate={{ opacity: 1, y: 0 }}
82 exit={{ opacity: 0, y: -10 }}
83 transition={{ duration: 0.25 }}
84 className="flex flex-col mb-3"
85 >
86 <div className='mb-5 font-semibold text-xl'>
87 <p>Create an account</p>
88 </div>
89 <div className='flex gap-3'>
90 <input
91 type="text"
92 placeholder="First name"
93 className="w-full mb-4 px-3 py-2 rounded-lg bg-white/8 placeholder-white/70 text-white focus:outline-none focus:shadow-[inset_0px_-1px_0px_0px_rgba(255,255,255,0.35)]"
94 />
95 <input
96 type="text"
97 placeholder="Last name"
98 className="w-full mb-4 px-3 py-2 rounded-lg bg-white/8 placeholder-white/70 text-white focus:outline-none focus:shadow-[inset_0px_-1px_0px_0px_rgba(255,255,255,0.35)]"
99 />
100 </div>
101 <input
102 type="text"
103 placeholder="Enter your email"
104 className="w-full mb-4 px-3 py-2 rounded-lg bg-white/8 placeholder-white/70 text-white focus:outline-none focus:shadow-[inset_0px_-1px_0px_0px_rgba(255,255,255,0.35)]"
105 />
106 <div className="relative mb-4">
107 <div className="absolute inset-y-0 left-3 flex items-center gap-2 text-white">
108 <svg
109 viewBox="0 0 36 36"
110 className="w-5 h-5 rounded-sm"
111 aria-hidden="true"
112 role="img"
113 >
114 <path fill="#138808" d="M0 27a4 4 0 0 0 4 4h28a4 4 0 0 0 4-4v-4H0v4z" />
115 <path fill="#EEE" d="M0 13h36v10H0z" />
116 <path fill="#F93" d="M36 13V9a4 4 0 0 0-4-4H4a4 4 0 0 0-4 4v4h36z" />
117 <circle fill="navy" cx="18" cy="18" r="4" />
118 <circle fill="#EEE" cx="18" cy="18" r="3" />
119 <path
120 fill="#6666B3"
121 d="M18 15l.146 2.264l1.001-2.035l-.73 2.147l1.704-1.498l-1.497 1.705l2.147-.731l-2.035 1.002L21 18l-2.264.146l2.035 1.001l-2.147-.73l1.497 1.704l-1.704-1.497l.73 2.147l-1.001-2.035L18 21l-.146-2.264l-1.002 2.035l.731-2.147l-1.705 1.497l1.498-1.704l-2.147.73l2.035-1.001L15 18l2.264-.146l-2.035-1.002l2.147.731l-1.498-1.705l1.705 1.498l-.731-2.147l1.002 2.035z"
122 />
123 <circle fill="navy" cx="18" cy="18" r="1" />
124 </svg>
125 <svg
126 className="w-4 h-4 opacity-70"
127 fill="none"
128 stroke="currentColor"
129 viewBox="0 0 24 24"
130 >
131 <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
132 </svg>
133 </div>
134 <input
135 type="tel"
136 placeholder="(775) 555-1212"
137 className="w-full pl-16 pr-4 py-3 rounded-lg outline-none bg-white/8 placeholder-white/70 text-white focus:shadow-[inset_0px_-1px_0px_0px_rgba(255,255,255,0.35)] transition-all duration-200"
138 />
139 </div>
140 <div className="flex gap-2 text-white p-1 rounded-lg shadow-sm">
141 <button className='bg-white text-black font-semibold text-md px-5 py-2 rounded-md w-full'>
142 Create an account
143 </button>
144 </div>
145 </motion.div>
146 ) : (
147 <motion.div
148 initial={{ opacity: 0, y: 10 }}
149 animate={{ opacity: 1, y: 0 }}
150 exit={{ opacity: 0, y: -10 }}
151 transition={{ duration: 0.25 }}
152 className="flex flex-col mb-3"
153 >
154 <div className="mb-5 font-semibold text-xl">
155 <p>Welcome back</p>
156 </div>
157
158 <input
159 type="email"
160 placeholder="Email address"
161 className="w-full mb-4 px-3 py-2 rounded-lg bg-white/8 placeholder-white/70 text-white focus:outline-none focus:shadow-[inset_0px_-1px_0px_rgba(255,255,255,0.35)]"
162 />
163
164 <input
165 type="password"
166 placeholder="Password"
167 className="w-full mb-4 px-3 py-2 rounded-lg bg-white/8 placeholder-white/70 text-white focus:outline-none focus:shadow-[inset_0px_-1px_0px_rgba(255,255,255,0.35)]"
168 />
169
170 <button className="text-sm text-white/70 text-right hover:underline">
171 Forgot password?
172 </button>
173 <div className="flex gap-2 text-white p-1 rounded-lg shadow-sm">
174 <button className='bg-white text-black font-semibold text-md px-5 py-2 rounded-md w-full'>
175 Sign in
176 </button>
177 </div>
178 </motion.div>
179 )}
180 </AnimatePresence>
181 <div className="text-white/70 flex items-center gap-3 mt-6 text-sm">
182 <div className="flex-1 h-px bg-white/70" />
183 or {mode == "signup" ? "sign up" : "sign in"} with
184 <div className="flex-1 h-px bg-white/70" />
185 </div>
186
187 <div className='flex gap-3 w-full justify-center mt-4'>
188 <button className='px-2 py-3 bg-white/10 w-full shadow-[inset_0px_1px_1px_rgba(255,255,255,0.35)] rounded-lg flex justify-center hover:bg-white/20 transition duration-200'>
189 <svg className='w-5 h-5' viewBox="-3 0 262 262" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" fill="#000000"><g id="SVGRepo_bgCarrier" strokeWidth="0"></g><g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027" fill="#4285F4"></path><path d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1" fill="#34A853"></path><path d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782" fill="#FBBC05"></path><path d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251" fill="#EB4335"></path></g></svg>
190 </button>
191 <button className='px-2 py-3 bg-white/10 w-full shadow-[inset_0px_1px_1px_rgba(255,255,255,0.35)] rounded-lg flex justify-center hover:bg-white/20 transition duration-200'>
192 <svg className='w-5 h-5' viewBox="-1.5 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="#000000"><g id="SVGRepo_bgCarrier" strokeWidth="0"></g><g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g><g id="SVGRepo_iconCarrier"> <title>apple [#173]</title> <desc>Created with Sketch.</desc> <defs> </defs> <g id="Page-1" stroke="none" strokeWidth
193 ="1" fill="none" fillRule="evenodd"> <g id="Dribbble-Light-Preview" transform="translate(-102.000000, -7439.000000)" fill="#ffffff"> <g id="icons" transform="translate(56.000000, 160.000000)"> <path d="M57.5708873,7282.19296 C58.2999598,7281.34797 58.7914012,7280.17098 58.6569121,7279 C57.6062792,7279.04 56.3352055,7279.67099 55.5818643,7280.51498 C54.905374,7281.26397 54.3148354,7282.46095 54.4735932,7283.60894 C55.6455696,7283.69593 56.8418148,7283.03894 57.5708873,7282.19296 M60.1989864,7289.62485 C60.2283111,7292.65181 62.9696641,7293.65879 63,7293.67179 C62.9777537,7293.74279 62.562152,7295.10677 61.5560117,7296.51675 C60.6853718,7297.73474 59.7823735,7298.94772 58.3596204,7298.97372 C56.9621472,7298.99872 56.5121648,7298.17973 54.9134635,7298.17973 C53.3157735,7298.17973 52.8162425,7298.94772 51.4935978,7298.99872 C50.1203933,7299.04772 49.0738052,7297.68074 48.197098,7296.46676 C46.4032359,7293.98379 45.0330649,7289.44985 46.8734421,7286.3899 C47.7875635,7284.87092 49.4206455,7283.90793 51.1942837,7283.88393 C52.5422083,7283.85893 53.8153044,7284.75292 54.6394294,7284.75292 C55.4635543,7284.75292 57.0106846,7283.67793 58.6366882,7283.83593 C59.3172232,7283.86293 61.2283842,7284.09893 62.4549652,7285.8199 C62.355868,7285.8789 60.1747177,7287.09489 60.1989864,7289.62485" id="apple-[#173]"> </path> </g> </g> </g> </g></svg>
194 </button>
195 </div>
196 {mode == "signup" && <div className='text-[11px] pt-5 text-white/70 text-center w-full'>
197 <p>By creating an account, you agree to our Terms & Service</p>
198 </div>}
199 </div>
200 </motion.div>
201 </AnimatePresence>
202 </div>
203 )
204}
205
206export default Page
207