This commit is contained in:
gili8420 2026-08-14 00:01:49 +09:00
commit b43955e0d9
162 changed files with 15425 additions and 0 deletions

View file

@ -0,0 +1,107 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { authStore } from '$auth';
import { t } from '$i18n';
let username = $state('');
let email = $state('');
let password = $state('');
let passwordConfirm = $state('');
let error = $state('');
let isLoading = $state(false);
const emailOk = (v: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
function validate(): string {
if (!username || !email || !password || !passwordConfirm) return $t('register.fieldsRequired');
if (username.trim().length < 3) return $t('register.usernameShort');
if (!emailOk(email)) return $t('register.emailInvalid');
if (password.length < 8) return $t('register.passwordShort');
if (password !== passwordConfirm) return $t('register.passwordMismatch');
return '';
}
async function handleSubmit(e: Event) {
e.preventDefault();
error = '';
const msg = validate();
if (msg) {
error = msg;
return;
}
isLoading = true;
try {
await authStore.register(username, email, password);
goto('/app');
} catch (err) {
error = (err as Error).message || $t('register.failed');
} finally {
isLoading = false;
}
}
</script>
<div class="card shadow-sm">
<div class="card-body p-4">
<h5 class="card-title mb-4">{$t('register.heading')}</h5>
{#if error}
<div class="alert alert-danger py-2" role="alert" data-testid="register-error">{error}</div>
{/if}
<form onsubmit={handleSubmit} novalidate>
<div class="form-floating mb-3">
<input
type="text"
class="form-control"
id="rg-username"
placeholder={$t('register.username')}
autocomplete="username"
bind:value={username} />
<label for="rg-username">{$t('register.username')}</label>
</div>
<div class="form-floating mb-3">
<input
type="email"
class="form-control"
id="rg-email"
placeholder={$t('register.email')}
autocomplete="email"
bind:value={email} />
<label for="rg-email">{$t('register.email')}</label>
</div>
<div class="form-floating mb-3">
<input
type="password"
class="form-control"
id="rg-password"
placeholder={$t('register.password')}
autocomplete="new-password"
bind:value={password} />
<label for="rg-password">{$t('register.password')}</label>
</div>
<div class="form-floating mb-3">
<input
type="password"
class="form-control"
id="rg-password2"
placeholder={$t('register.passwordConfirm')}
autocomplete="new-password"
bind:value={passwordConfirm} />
<label for="rg-password2">{$t('register.passwordConfirm')}</label>
</div>
<button type="submit" class="btn btn-primary w-100" disabled={isLoading}>
{#if isLoading}
<span class="spinner-border spinner-border-sm me-2" role="status"></span>
{$t('register.submitting')}
{:else}
{$t('register.submit')}
{/if}
</button>
</form>
<p class="text-center text-muted small mt-4 mb-0">
{$t('register.haveAccount')} <a href="/login">{$t('register.loginLink')}</a>
</p>
</div>
</div>