fix: store session token on signup and send it to /chat
Mirror to GitHub / mirror (push) Canceled after 0s
Mirror to GitHub / mirror (push) Canceled after 0s
- web: App stores sessionToken and passes to useChat; useChat sends Authorization header - web: ChatPanel adds wursor-message-user/agent test hooks - verified full UI flow (signup -> chat -> working -> reply -> approve -> preview)
This commit is contained in:
+20
-6
@@ -5,15 +5,29 @@ import { Preview } from './components/Preview.tsx';
|
|||||||
import { SignUp } from './components/SignUp.tsx';
|
import { SignUp } from './components/SignUp.tsx';
|
||||||
import { useChat } from './hooks/useChat.ts';
|
import { useChat } from './hooks/useChat.ts';
|
||||||
|
|
||||||
export function App() {
|
async function signUp(email: string, password: string): Promise<string> {
|
||||||
const [signedUp, setSignedUp] = useState(false);
|
const res = await fetch('/auth/signup', {
|
||||||
const [applied, setApplied] = useState(false);
|
method: 'POST',
|
||||||
const chat = useChat();
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ email, password }),
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
const body = (await res.json().catch(() => null)) as { error?: string } | null;
|
||||||
|
throw new Error(body?.error ?? 'Sign up failed');
|
||||||
|
}
|
||||||
|
const body = (await res.json()) as { sessionToken: string };
|
||||||
|
return body.sessionToken;
|
||||||
|
}
|
||||||
|
|
||||||
if (!signedUp) {
|
export function App() {
|
||||||
|
const [sessionToken, setSessionToken] = useState<string | null>(null);
|
||||||
|
const [applied, setApplied] = useState(false);
|
||||||
|
const chat = useChat(sessionToken);
|
||||||
|
|
||||||
|
if (sessionToken === null) {
|
||||||
return (
|
return (
|
||||||
<div className="auth-screen">
|
<div className="auth-screen">
|
||||||
<SignUp onSignUp={async () => setSignedUp(true)} />
|
<SignUp onSignUp={async (email, password) => setSessionToken(await signUp(email, password))} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export function ChatPanel({ messages, status, onSend }: ChatPanelProps) {
|
|||||||
) : (
|
) : (
|
||||||
<ul className="chat-list">
|
<ul className="chat-list">
|
||||||
{messages.map((message) => (
|
{messages.map((message) => (
|
||||||
<li key={message.id} className={`message message-${message.role}`}>
|
<li key={message.id} className={`message message-${message.role} wursor-message-${message.role}`}>
|
||||||
{message.text}
|
{message.text}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
+29
-23
@@ -14,35 +14,41 @@ function mockReply(text: string, heading: string | undefined): string {
|
|||||||
: 'Done — your change is ready to preview.';
|
: 'Done — your change is ready to preview.';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useChat() {
|
export function useChat(sessionToken: string | null) {
|
||||||
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
||||||
const [status, setStatus] = useState<ChatStatus>('idle');
|
const [status, setStatus] = useState<ChatStatus>('idle');
|
||||||
const [heading, setHeading] = useState('Welcome to our site');
|
const [heading, setHeading] = useState('Welcome to our site');
|
||||||
|
|
||||||
const send = useCallback(async (text: string) => {
|
const send = useCallback(
|
||||||
const nextHeading = extractHeading(text);
|
async (text: string) => {
|
||||||
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'user', text }]);
|
const nextHeading = extractHeading(text);
|
||||||
setStatus('working');
|
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'user', text }]);
|
||||||
|
setStatus('working');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/chat', {
|
const res = await fetch('/chat', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: {
|
||||||
body: JSON.stringify({ message: text }),
|
'Content-Type': 'application/json',
|
||||||
});
|
...(sessionToken !== null ? { Authorization: `Bearer ${sessionToken}` } : {}),
|
||||||
if (!res.ok) throw new Error('chat unavailable');
|
},
|
||||||
const body = (await res.json()) as { reply?: string };
|
body: JSON.stringify({ message: text }),
|
||||||
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'agent', text: body.reply ?? 'Done' }]);
|
});
|
||||||
} catch {
|
if (!res.ok) throw new Error('chat unavailable');
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1200));
|
const body = (await res.json()) as { reply?: string };
|
||||||
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'agent', text: mockReply(text, nextHeading) }]);
|
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'agent', text: body.reply ?? 'Done' }]);
|
||||||
}
|
} catch {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1200));
|
||||||
|
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'agent', text: mockReply(text, nextHeading) }]);
|
||||||
|
}
|
||||||
|
|
||||||
if (nextHeading !== undefined) {
|
if (nextHeading !== undefined) {
|
||||||
setHeading(nextHeading);
|
setHeading(nextHeading);
|
||||||
}
|
}
|
||||||
setStatus('done');
|
setStatus('done');
|
||||||
}, []);
|
},
|
||||||
|
[sessionToken],
|
||||||
|
);
|
||||||
|
|
||||||
return { messages, status, heading, send };
|
return { messages, status, heading, send };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user