diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx index c532932..7bc104d 100644 --- a/src/app/(auth)/login/page.tsx +++ b/src/app/(auth)/login/page.tsx @@ -2,7 +2,7 @@ import { Suspense, useState } from "react"; import { signIn } from "next-auth/react"; -import { useRouter, useSearchParams } from "next/navigation"; +import { useSearchParams } from "next/navigation"; import Link from "next/link"; import { ScanLine, Mail, Lock, Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; @@ -19,7 +19,6 @@ export default function LoginPage() { } function LoginForm() { - const router = useRouter(); const searchParams = useSearchParams(); const callbackUrl = searchParams.get("callbackUrl") || "/"; const error = searchParams.get("error"); @@ -47,8 +46,7 @@ function LoginForm() { setFormError("Invalid email or password"); setLoading(false); } else { - router.push(callbackUrl); - router.refresh(); + window.location.href = callbackUrl; } } @@ -60,7 +58,7 @@ function LoginForm() {
- Sign in to your Echo account + Digitize your connect cards
@@ -139,9 +137,15 @@ function LoginForm() {Don't have an account?{" "} - Sign up with an invite + Sign up
++ By signing in, you agree to our{" "} + Terms + {" "}and{" "} + Privacy Policy. +
); } diff --git a/src/app/(auth)/signup/page.tsx b/src/app/(auth)/signup/page.tsx index 3dc1445..93f8f14 100644 --- a/src/app/(auth)/signup/page.tsx +++ b/src/app/(auth)/signup/page.tsx @@ -1,10 +1,10 @@ "use client"; -import { Suspense, useState } from "react"; +import { Suspense, useEffect, useState } from "react"; import { useSearchParams } from "next/navigation"; import { signIn } from "next-auth/react"; import Link from "next/link"; -import { ScanLine, Mail, Lock, User, Loader2 } from "lucide-react"; +import { ScanLine, Mail, Lock, User, Loader2, Eye, EyeOff } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; @@ -17,9 +17,23 @@ export default function SignupPage() { ); } +function getPasswordStrength(pw: string): { level: number; label: string } { + if (!pw || pw.length < 8) return { level: 0, label: "Weak" }; + const hasUpper = /[A-Z]/.test(pw); + const hasLower = /[a-z]/.test(pw); + const hasNumber = /\d/.test(pw); + if (pw.length >= 12 && hasUpper && hasLower && hasNumber) { + return { level: 2, label: "Strong" }; + } + return { level: 1, label: "Fair" }; +} + +const strengthColors = ["bg-red-500", "bg-amber-500", "bg-emerald-500"]; + function SignupForm() { const searchParams = useSearchParams(); const token = searchParams.get("token") || ""; + const callbackUrl = searchParams.get("callbackUrl") || "/"; const [formData, setFormData] = useState({ displayName: "", @@ -29,6 +43,26 @@ function SignupForm() { }); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); + const [showPassword, setShowPassword] = useState(false); + const [showConfirm, setShowConfirm] = useState(false); + const [inviteInfo, setInviteInfo] = useState<{ + orgName: string; + email: string; + role: string; + } | null>(null); + + useEffect(() => { + if (!token) return; + fetch(`/api/invitations/verify?token=${token}`) + .then((r) => r.json()) + .then((data) => { + if (data.valid) { + setInviteInfo({ orgName: data.orgName, email: data.email, role: data.role }); + setFormData((prev) => ({ ...prev, email: data.email })); + } + }) + .catch(() => {}); + }, [token]); function update(field: string, value: string) { setFormData((prev) => ({ ...prev, [field]: value })); @@ -72,7 +106,7 @@ function SignupForm() { await signIn("credentials", { email: formData.email, password: formData.password, - callbackUrl: "/", + callbackUrl, }); } catch { setError("Something went wrong. Please try again."); @@ -80,6 +114,9 @@ function SignupForm() { } } + const strength = getPasswordStrength(formData.password); + const showStrength = formData.password.length > 0; + return (- {token - ? "Complete your account setup" - : "Get started with Echo"} + {inviteInfo + ? <>Join {inviteInfo.orgName}> + : token + ? "Complete your account setup" + : "Get started with Echo"}
+ By creating an account, you agree to our{" "} + Terms + {" "}and{" "} + Privacy Policy. +
); }