Fixed AI Auto Launch, Fixed Client Login not working
Build & Auto-Repair / build (push) Has been cancelled

This commit is contained in:
JCBSComputer
2026-07-01 16:36:48 +02:00
parent 7606af04ab
commit 4a33ca0368
4 changed files with 43 additions and 8 deletions
+1 -1
View File
@@ -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": {
+23 -1
View File
@@ -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>
+16 -3
View File
@@ -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"
if (loginData.user?.role === "client") {
window.location.href = "/client-portal/dashboard"
} else {
router.push(redirectTo) 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.")
+2 -2
View File
@@ -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" })