Skip to content

Commit a608f00

Browse files
committed
fix auth look
1 parent 949a33d commit a608f00

File tree

1 file changed

+209
-115
lines changed

1 file changed

+209
-115
lines changed

junction-app/app/auth/page.tsx

Lines changed: 209 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"use client";
22

3-
import { useEffect, useState } from "react";
3+
import { useEffect, useMemo, useState } from "react";
44
import { useAuth } from "@/contexts/AuthContext";
55
import { useRouter } from "next/navigation";
6+
import { Loader2 } from "lucide-react";
67

78
export default function AuthPage() {
89
const [isLogin, setIsLogin] = useState(true);
@@ -15,6 +16,8 @@ export default function AuthPage() {
1516

1617
const { user, signIn, signUp, signInWithGoogle } = useAuth();
1718
const router = useRouter();
19+
const inputClassName =
20+
"w-full rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-base text-white placeholder:text-white/50 focus:border-emerald-400 focus:ring-2 focus:ring-emerald-400/30 focus:outline-none";
1821

1922
// if logged in, redirect to dashboard
2023
useEffect(() => {
@@ -56,135 +59,226 @@ export default function AuthPage() {
5659
}
5760
};
5861

62+
const pageStats = useMemo(
63+
() => [
64+
{
65+
value: "~2 min",
66+
label: "Average approval time",
67+
},
68+
{
69+
value: "15+",
70+
label: "Signals per assessment",
71+
},
72+
{
73+
value: "0–100",
74+
label: "Transparent trust score",
75+
},
76+
],
77+
[],
78+
);
79+
5980
return (
60-
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
61-
<div className="max-w-md w-full space-y-8">
62-
<div>
63-
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
64-
{isLogin ? "Sign in to your account" : "Create new account"}
65-
</h2>
66-
</div>
81+
<div className="relative min-h-screen overflow-hidden bg-zinc-950 text-white">
82+
<div className="absolute inset-0 opacity-30">
83+
<div
84+
className="absolute inset-0"
85+
style={{
86+
backgroundImage:
87+
"linear-gradient(rgba(255,255,255,0.04) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.04) 1px, transparent 1px)",
88+
backgroundSize: "64px 64px",
89+
}}
90+
/>
91+
</div>
92+
<div className="absolute -right-32 top-0 h-[600px] w-[600px] rounded-full bg-emerald-500/20 blur-[160px]" />
93+
<div className="absolute -left-32 bottom-0 h-[500px] w-[500px] rounded-full bg-blue-500/20 blur-[160px]" />
6794

68-
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
69-
{error && (
70-
<div className="rounded-md bg-red-50 p-4">
71-
<p className="text-sm text-red-800">{error}</p>
95+
<div className="relative mx-auto flex min-h-screen w-full items-center justify-center px-4 py-16 sm:px-6 lg:px-8">
96+
<div className="grid w-full max-w-6xl gap-12 lg:grid-cols-2">
97+
<div className="space-y-8">
98+
<div className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-4 py-2 text-sm text-white/70 backdrop-blur">
99+
Junction One • Zero-trust intake
72100
</div>
73-
)}
74-
75-
<div className="rounded-md shadow-sm -space-y-px">
76-
{!isLogin && (
77-
<>
78-
<div>
79-
<label htmlFor="first-name" className="sr-only">
80-
First Name
81-
</label>
82-
<input
83-
id="first-name"
84-
name="firstName"
85-
type="text"
86-
required={!isLogin}
87-
value={firstName}
88-
onChange={(e) => setFirstName(e.target.value)}
89-
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
90-
placeholder="First Name"
91-
/>
92-
</div>
93-
<div>
94-
<label htmlFor="last-name" className="sr-only">
95-
Last Name
96-
</label>
97-
<input
98-
id="last-name"
99-
name="lastName"
100-
type="text"
101-
required={!isLogin}
102-
value={lastName}
103-
onChange={(e) => setLastName(e.target.value)}
104-
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
105-
placeholder="Last Name"
106-
/>
107-
</div>
108-
</>
109-
)}
110-
111101
<div>
112-
<label htmlFor="email-address" className="sr-only">
113-
Email address
114-
</label>
115-
<input
116-
id="email-address"
117-
name="email"
118-
type="email"
119-
autoComplete="email"
120-
required
121-
value={email}
122-
onChange={(e) => setEmail(e.target.value)}
123-
className={`appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 ${isLogin ? "rounded-t-md" : ""} focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm`}
124-
placeholder="Email address"
125-
/>
102+
<h1 className="text-4xl font-semibold leading-tight tracking-tight sm:text-5xl">
103+
Join the trust layer for{" "}
104+
<span className="bg-gradient-to-r from-emerald-400 to-blue-400 bg-clip-text text-transparent">
105+
security decisions
106+
</span>
107+
</h1>
108+
<p className="mt-6 text-lg text-white/70">
109+
One login gives you SOC 2 ready assessments, audit trails, and
110+
explainable AI recommendations so your team never ships blind.
111+
</p>
126112
</div>
127113

128-
<div>
129-
<label htmlFor="password" className="sr-only">
130-
Password
131-
</label>
132-
<input
133-
id="password"
134-
name="password"
135-
type="password"
136-
autoComplete="current-password"
137-
required
138-
value={password}
139-
onChange={(e) => setPassword(e.target.value)}
140-
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
141-
placeholder="Password"
142-
/>
114+
<div className="grid gap-4 sm:grid-cols-3">
115+
{pageStats.map((stat) => (
116+
<div
117+
key={stat.label}
118+
className="rounded-2xl border border-white/10 bg-white/5 p-5"
119+
>
120+
<div className="text-2xl font-semibold">{stat.value}</div>
121+
<p className="mt-2 text-sm text-white/60">{stat.label}</p>
122+
</div>
123+
))}
143124
</div>
144-
</div>
145125

146-
<div>
147-
<button
148-
type="submit"
149-
disabled={loading}
150-
className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50"
151-
>
152-
{loading ? "Loading..." : isLogin ? "Sign in" : "Sign up"}
153-
</button>
126+
<p className="text-sm uppercase tracking-[0.3em] text-white/40">
127+
Trusted by security teams in EMEA &amp; the Nordics
128+
</p>
154129
</div>
155130

156-
<div className="relative">
157-
<div className="absolute inset-0 flex items-center">
158-
<div className="w-full border-t border-gray-300" />
131+
<div className="rounded-3xl border border-white/10 bg-zinc-900/70 p-8 shadow-2xl backdrop-blur">
132+
<div className="flex items-center justify-between">
133+
<div>
134+
<p className="text-sm uppercase tracking-widest text-emerald-400">
135+
Access portal
136+
</p>
137+
<h2 className="mt-2 text-2xl font-semibold">
138+
{isLogin ? "Welcome back" : "Create your account"}
139+
</h2>
140+
</div>
141+
<button
142+
type="button"
143+
onClick={() => setIsLogin(!isLogin)}
144+
className="text-sm text-white/60 transition hover:text-white"
145+
>
146+
{isLogin ? "Need access?" : "Have an account?"}
147+
</button>
159148
</div>
160-
<div className="relative flex justify-center text-sm">
161-
<span className="px-2 bg-gray-50 text-gray-500">Or</span>
149+
150+
<div className="mt-6 flex rounded-full bg-white/5 p-1 text-sm text-white/70">
151+
<button
152+
type="button"
153+
onClick={() => setIsLogin(true)}
154+
className={`flex-1 rounded-full px-4 py-2 transition ${
155+
isLogin ? "bg-white text-zinc-900" : "text-white/60"
156+
}`}
157+
>
158+
Sign in
159+
</button>
160+
<button
161+
type="button"
162+
onClick={() => setIsLogin(false)}
163+
className={`flex-1 rounded-full px-4 py-2 transition ${
164+
!isLogin ? "bg-white text-zinc-900" : "text-white/60"
165+
}`}
166+
>
167+
Create account
168+
</button>
162169
</div>
163-
</div>
164170

165-
<div>
166-
<button
167-
type="button"
168-
onClick={handleGoogleSignIn}
169-
disabled={loading}
170-
className="group relative w-full flex justify-center py-2 px-4 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50"
171-
>
172-
Sign in with Google
173-
</button>
174-
</div>
171+
<form className="mt-8 space-y-5" onSubmit={handleSubmit}>
172+
{error && (
173+
<div className="rounded-2xl border border-red-500/40 bg-red-500/10 px-4 py-3 text-sm text-red-200">
174+
{error}
175+
</div>
176+
)}
177+
178+
{!isLogin && (
179+
<div className="grid gap-4 sm:grid-cols-2">
180+
<div>
181+
<label
182+
htmlFor="first-name"
183+
className="mb-2 block text-sm text-white/70"
184+
>
185+
First name
186+
</label>
187+
<input
188+
id="first-name"
189+
name="firstName"
190+
type="text"
191+
required
192+
value={firstName}
193+
onChange={(e) => setFirstName(e.target.value)}
194+
className={inputClassName}
195+
placeholder="Alex"
196+
/>
197+
</div>
198+
<div>
199+
<label
200+
htmlFor="last-name"
201+
className="mb-2 block text-sm text-white/70"
202+
>
203+
Last name
204+
</label>
205+
<input
206+
id="last-name"
207+
name="lastName"
208+
type="text"
209+
required
210+
value={lastName}
211+
onChange={(e) => setLastName(e.target.value)}
212+
className={inputClassName}
213+
placeholder="Choi"
214+
/>
215+
</div>
216+
</div>
217+
)}
175218

176-
<div className="text-center">
177-
<button
178-
type="button"
179-
onClick={() => setIsLogin(!isLogin)}
180-
className="text-blue-600 hover:text-blue-500 text-sm"
181-
>
182-
{isLogin
183-
? "Need an account? Sign up"
184-
: "Already have an account? Sign in"}
185-
</button>
219+
<div className="space-y-2">
220+
<label
221+
htmlFor="email-address"
222+
className="text-sm text-white/70"
223+
>
224+
Work email
225+
</label>
226+
<input
227+
id="email-address"
228+
name="email"
229+
type="email"
230+
autoComplete="email"
231+
required
232+
value={email}
233+
onChange={(e) => setEmail(e.target.value)}
234+
className={inputClassName}
235+
placeholder="[email protected]"
236+
/>
237+
</div>
238+
239+
<div className="space-y-2">
240+
<label htmlFor="password" className="text-sm text-white/70">
241+
Password
242+
</label>
243+
<input
244+
id="password"
245+
name="password"
246+
type="password"
247+
autoComplete={isLogin ? "current-password" : "new-password"}
248+
required
249+
value={password}
250+
onChange={(e) => setPassword(e.target.value)}
251+
className={inputClassName}
252+
placeholder="••••••••"
253+
/>
254+
</div>
255+
256+
<button
257+
type="submit"
258+
disabled={loading}
259+
className="group flex w-full items-center justify-center gap-2 rounded-2xl bg-white px-4 py-3 text-base font-semibold text-zinc-950 transition hover:bg-zinc-100 disabled:cursor-not-allowed disabled:opacity-60"
260+
>
261+
{loading && <Loader2 className="size-5 animate-spin" />}
262+
{isLogin ? "Secure sign in" : "Create secure access"}
263+
</button>
264+
265+
<div className="flex items-center gap-3 text-sm text-white/50">
266+
<div className="h-px flex-1 bg-white/10" />
267+
Or continue with
268+
<div className="h-px flex-1 bg-white/10" />
269+
</div>
270+
271+
<button
272+
type="button"
273+
onClick={handleGoogleSignIn}
274+
disabled={loading}
275+
className="flex w-full items-center justify-center gap-2 rounded-2xl border border-white/10 bg-black/50 px-4 py-3 text-sm font-medium text-white/90 transition hover:border-white/30 hover:bg-black/60 disabled:cursor-not-allowed disabled:opacity-60"
276+
>
277+
Google Workspace
278+
</button>
279+
</form>
186280
</div>
187-
</form>
281+
</div>
188282
</div>
189283
</div>
190284
);

0 commit comments

Comments
 (0)