Fixed AI Auto Launch, Fixed Client Login not working
Build & Auto-Repair / build (push) Has been cancelled
Build & Auto-Repair / build (push) Has been cancelled
This commit is contained in:
+1
-1
@@ -20,7 +20,7 @@
|
|||||||
"repair:ci": "node scripts/code-repair-agent.mjs --ci",
|
"repair:ci": "node scripts/code-repair-agent.mjs --ci",
|
||||||
"build:fix": "npm run build 2>&1 || node scripts/code-repair-agent.mjs --ci",
|
"build:fix": "npm run build 2>&1 || node scripts/code-repair-agent.mjs --ci",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start -p 3006",
|
"start": "node scripts/ensure-ollama.mjs && concurrently -n AI,NEXT -c cyan,green \"npm run dev:rust\" \"next start -p 3006\"",
|
||||||
"lint": "eslint"
|
"lint": "eslint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -14,16 +14,26 @@ export default function ClientLoginPage() {
|
|||||||
const [checking, setChecking] = useState(true)
|
const [checking, setChecking] = useState(true)
|
||||||
const [debugInfo, setDebugInfo] = useState("")
|
const [debugInfo, setDebugInfo] = useState("")
|
||||||
|
|
||||||
|
const [sessionUser, setSessionUser] = useState<{ email: string; role: string } | null>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("/api/auth/me", { credentials: "include" })
|
fetch("/api/auth/me", { credentials: "include" })
|
||||||
.then((r) => r.json())
|
.then((r) => r.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.user?.role === "client") router.push("/client-portal/dashboard")
|
if (data.user?.role === "client") router.push("/client-portal/dashboard")
|
||||||
else setChecking(false)
|
else {
|
||||||
|
if (data.user) setSessionUser({ email: data.user.email, role: data.user.role })
|
||||||
|
setChecking(false)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => setChecking(false))
|
.catch(() => setChecking(false))
|
||||||
}, [router])
|
}, [router])
|
||||||
|
|
||||||
|
const handleSignOut = async () => {
|
||||||
|
await fetch("/api/auth/logout", { method: "POST" })
|
||||||
|
setSessionUser(null)
|
||||||
|
}
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
@@ -83,6 +93,18 @@ export default function ClientLoginPage() {
|
|||||||
<p className="text-sm text-muted-foreground">Sign in to view your projects and invoices</p>
|
<p className="text-sm text-muted-foreground">Sign in to view your projects and invoices</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{sessionUser && (
|
||||||
|
<div className="mb-4 bg-card border border-border rounded-lg p-3 flex items-center justify-between">
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
Signed in as <span className="text-foreground font-medium">{sessionUser.email}</span>
|
||||||
|
<span className="ml-1.5 text-[10px] px-1.5 py-0.5 rounded bg-primary/10 text-primary uppercase">{(sessionUser.role || "").replace("_", " ")}</span>
|
||||||
|
</div>
|
||||||
|
<button onClick={handleSignOut} className="text-xs text-destructive hover:text-destructive/80 font-medium">
|
||||||
|
Sign Out
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="space-y-4">
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-muted-foreground mb-1.5">Email</label>
|
<label className="block text-sm text-muted-foreground mb-1.5">Email</label>
|
||||||
|
|||||||
+17
-4
@@ -42,9 +42,17 @@ function LoginForm() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("/api/auth/me", { credentials: "include" })
|
fetch("/api/auth/me", { credentials: "include" })
|
||||||
.then((r) => {
|
.then(async (r) => {
|
||||||
if (r.ok) router.push("/dashboard")
|
if (r.ok) {
|
||||||
else setCheckingSession(false)
|
const data = await r.json().catch(() => ({}))
|
||||||
|
if (data.user?.role === "client") {
|
||||||
|
window.location.href = "/client-portal/dashboard"
|
||||||
|
} else {
|
||||||
|
router.push("/dashboard")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCheckingSession(false)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => setCheckingSession(false))
|
.catch(() => setCheckingSession(false))
|
||||||
}, [router])
|
}, [router])
|
||||||
@@ -239,11 +247,16 @@ function LoginForm() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
const loginData = await res.json().catch(() => ({}))
|
||||||
localStorage.removeItem(WEBSITE_THEME_KEY)
|
localStorage.removeItem(WEBSITE_THEME_KEY)
|
||||||
const root = document.documentElement
|
const root = document.documentElement
|
||||||
root.className = root.className.split(" ").filter((c) => !c.startsWith("theme-")).join(" ").trim()
|
root.className = root.className.split(" ").filter((c) => !c.startsWith("theme-")).join(" ").trim()
|
||||||
const redirectTo = searchParams.get("redirect") || "/dashboard"
|
const redirectTo = searchParams.get("redirect") || "/dashboard"
|
||||||
router.push(redirectTo)
|
if (loginData.user?.role === "client") {
|
||||||
|
window.location.href = "/client-portal/dashboard"
|
||||||
|
} else {
|
||||||
|
router.push(redirectTo)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const data = await res.json().catch(() => ({}))
|
const data = await res.json().catch(() => ({}))
|
||||||
setError(data.error || "Invalid email or password.")
|
setError(data.error || "Invalid email or password.")
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ export const AIChat = forwardRef<{ fillInput: (text: string) => void }, AIChatPr
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkServer()
|
setBootState("ready")
|
||||||
}, [checkServer])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
|
||||||
|
|||||||
Reference in New Issue
Block a user