feat: add full workbench login page
This commit is contained in:
@@ -1,16 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let apiBase: string;
|
||||
export let onLogin: (detail: { apiBase: string; account: string }) => void = () => {};
|
||||
|
||||
const dispatch = createEventDispatcher<{ serverChange: { apiBase: string } }>();
|
||||
let server = apiBase;
|
||||
|
||||
function saveServer() {
|
||||
const normalized = normalizeServer(server);
|
||||
server = normalized;
|
||||
dispatch('serverChange', { apiBase: normalized });
|
||||
}
|
||||
let account = '';
|
||||
let password = '';
|
||||
let error = '';
|
||||
|
||||
function normalizeServer(value: string) {
|
||||
const trimmed = value.trim();
|
||||
@@ -19,10 +14,50 @@
|
||||
}
|
||||
return `http://${trimmed}`;
|
||||
}
|
||||
|
||||
function submitLogin() {
|
||||
error = '';
|
||||
if (!account.trim() || !password.trim()) {
|
||||
error = 'Enter an account and password.';
|
||||
return;
|
||||
}
|
||||
|
||||
const normalized = normalizeServer(server);
|
||||
server = normalized;
|
||||
onLogin({ apiBase: normalized, account: account.trim() });
|
||||
}
|
||||
</script>
|
||||
|
||||
<form aria-label="服务器登录" class="server-login" on:submit|preventDefault={saveServer}>
|
||||
<label for="server-address">服务器 IP 或域名</label>
|
||||
<input id="server-address" name="server" bind:value={server} placeholder="http://localhost:8080" />
|
||||
<button type="submit">保存服务器</button>
|
||||
</form>
|
||||
<main class="login-page">
|
||||
<section class="login-panel" aria-labelledby="login-title">
|
||||
<div class="login-brand" aria-hidden="true">SA</div>
|
||||
<div class="login-heading">
|
||||
<p>Private workbench</p>
|
||||
<h1 id="login-title">SenlinAI Workbench</h1>
|
||||
</div>
|
||||
|
||||
<form class="server-login" aria-label="Server login" on:submit|preventDefault={submitLogin}>
|
||||
<label for="server-address">Server IP or domain</label>
|
||||
<input id="server-address" name="server" bind:value={server} placeholder="http://localhost:8080" />
|
||||
|
||||
<label for="login-account">Email or username</label>
|
||||
<input id="login-account" name="account" bind:value={account} autocomplete="username" />
|
||||
|
||||
<label for="login-password">Password</label>
|
||||
<input
|
||||
id="login-password"
|
||||
name="password"
|
||||
type="password"
|
||||
bind:value={password}
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
|
||||
{#if error}
|
||||
<p class="form-error" aria-live="polite">{error}</p>
|
||||
{/if}
|
||||
|
||||
<button type="submit">Log in</button>
|
||||
<p class="login-note">The server address is remembered on this device.</p>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user