demo login, super admin view, password reset
- Landing page: 'Try the Demo' button links to /login?demo=1 - Login page: 'Try the Demo — no signup needed' button auto-logs in as demo@pnpl.app - /login?demo=1: auto-triggers demo login on page load - Super Admin page (/dashboard/admin): platform stats, org list, user list, recent pledges - /api/admin: returns cross-org data, gated by super_admin role check - Sidebar shows 'Super Admin' link only for super_admin users - Password reset: omair@quikcue.com = Omair2026!, demo@pnpl.app = demo1234 - omair@quikcue.com confirmed as super_admin role
This commit is contained in:
@@ -1,25 +1,27 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { useState, useEffect, Suspense } from "react"
|
||||
import { signIn } from "next-auth/react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { useRouter, useSearchParams } from "next/navigation"
|
||||
import Link from "next/link"
|
||||
|
||||
export default function LoginPage() {
|
||||
function LoginForm() {
|
||||
const [email, setEmail] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
const [error, setError] = useState("")
|
||||
const [loading, setLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
const isDemo = searchParams.get("demo") === "1"
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
const doLogin = async (e?: React.FormEvent, demoEmail?: string, demoPass?: string) => {
|
||||
if (e) e.preventDefault()
|
||||
setError("")
|
||||
setLoading(true)
|
||||
|
||||
const result = await signIn("credentials", {
|
||||
email,
|
||||
password,
|
||||
email: demoEmail || email,
|
||||
password: demoPass || password,
|
||||
redirect: false,
|
||||
})
|
||||
|
||||
@@ -31,6 +33,12 @@ export default function LoginPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => doLogin(e)
|
||||
|
||||
// Auto-login as demo if ?demo=1
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
useEffect(() => { if (isDemo) doLogin(undefined, "demo@pnpl.app", "demo1234") }, [])
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-trust-blue/5 via-white to-warm-amber/5 p-4">
|
||||
<div className="w-full max-w-sm space-y-6">
|
||||
@@ -82,6 +90,20 @@ export default function LoginPage() {
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 flex items-center"><div className="w-full border-t" /></div>
|
||||
<div className="relative flex justify-center text-xs"><span className="bg-gradient-to-br from-trust-blue/5 via-white to-warm-amber/5 px-2 text-muted-foreground">or</span></div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => doLogin(undefined, "demo@pnpl.app", "demo1234")}
|
||||
disabled={loading}
|
||||
className="w-full rounded-xl border-2 border-dashed border-gray-200 px-4 py-3 text-sm font-medium text-muted-foreground hover:border-trust-blue hover:text-trust-blue disabled:opacity-50 transition-all"
|
||||
>
|
||||
🎮 Try the Demo — no signup needed
|
||||
</button>
|
||||
|
||||
<p className="text-center text-sm text-muted-foreground">
|
||||
Don't have an account?{" "}
|
||||
<Link href="/signup" className="text-trust-blue font-semibold hover:underline">
|
||||
@@ -92,3 +114,11 @@ export default function LoginPage() {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function LoginPage() {
|
||||
return (
|
||||
<Suspense fallback={<div className="min-h-screen flex items-center justify-center"><div className="animate-spin h-8 w-8 border-2 border-trust-blue border-t-transparent rounded-full" /></div>}>
|
||||
<LoginForm />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user