61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import { useState, type FormEvent } from 'react';
|
|
import { z } from 'zod/v4';
|
|
|
|
export default function Login({ setToken } : {setToken: (token: string) => void})
|
|
{
|
|
const [username, setUsername] = useState<string>("");
|
|
const [password, setPassword] = useState<string>("");
|
|
|
|
async function doLogin(event: FormEvent<HTMLFormElement>)
|
|
{
|
|
event.preventDefault();
|
|
|
|
const token = await loginUser({username, password});
|
|
|
|
setToken(token);
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<form className="login-form" onSubmit={e => void doLogin(e)} method="action">
|
|
<label>
|
|
Email:
|
|
<input type="text" name="username" placeholder="Username" required onChange={event => setUsername(event.target.value)} />
|
|
</label>
|
|
<label>
|
|
Password:
|
|
<input type="password" name="password" placeholder="Password" required onChange={event => setPassword(event.target.value)} />
|
|
</label>
|
|
|
|
<button type="submit">Login</button>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const LoginResponse = z.object({
|
|
token: z.string()
|
|
});
|
|
|
|
async function loginUser(credentials : {username: string, password: string}): Promise<string>
|
|
{
|
|
// Get a session token for OpenAI Realtime API
|
|
const response = await fetch('login', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(credentials)
|
|
});
|
|
|
|
if (!response.ok)
|
|
{
|
|
throw new Error(response.statusText);
|
|
}
|
|
|
|
const responseJson:unknown = await response.json();
|
|
const parsedToken = LoginResponse.parse(responseJson);
|
|
|
|
return parsedToken.token;
|
|
}
|