|
|
@@ -1,240 +0,0 @@
|
|
|
-<script>
|
|
|
- import favicon from '$lib/assets/favicon.png';
|
|
|
- import { page } from '$app/stores';
|
|
|
-
|
|
|
- let name = $state('');
|
|
|
- let email = $state('');
|
|
|
- let password = $state('');
|
|
|
- let confirm_password = $state('');
|
|
|
- let url = $derived($page.url.searchParams.get('url') ?? '');
|
|
|
-
|
|
|
- let errors = $state({});
|
|
|
- let submitting = $state(false);
|
|
|
-
|
|
|
- function validate() {
|
|
|
- const e = {};
|
|
|
- if (!name.trim()) e.name = 'Name is required.';
|
|
|
- if (!email.trim()) e.email = 'Email is required.';
|
|
|
- else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = 'Enter a valid email.';
|
|
|
- if (!password) e.password = 'Password is required.';
|
|
|
- else if (password.length < 8) e.password = 'Password must be at least 8 characters.';
|
|
|
- if (!confirm_password) e.confirm_password = 'Please confirm your password.';
|
|
|
- else if (password !== confirm_password) e.confirm_password = 'Passwords do not match.';
|
|
|
- return e;
|
|
|
- }
|
|
|
-
|
|
|
- function handleSubmit(e) {
|
|
|
- errors = validate();
|
|
|
- if (Object.keys(errors).length > 0) {
|
|
|
- e.preventDefault();
|
|
|
- } else {
|
|
|
- submitting = true;
|
|
|
- }
|
|
|
- }
|
|
|
-</script>
|
|
|
-
|
|
|
-<svelte:head>
|
|
|
- <title>Create Account — ChatRPG</title>
|
|
|
-</svelte:head>
|
|
|
-
|
|
|
-<div class="page">
|
|
|
- <div class="card">
|
|
|
- <a href="/" class="logo" aria-label="ChatRPG home">
|
|
|
- <img src={favicon} alt="ChatRPG logo" width="28" height="28" />
|
|
|
- <span class="logo-text">ChatRPG</span>
|
|
|
- </a>
|
|
|
-
|
|
|
- <h1>Create your account</h1>
|
|
|
- <p class="subtitle">Start your adventure today.</p>
|
|
|
-
|
|
|
- <form method="POST" action="/api/register" onsubmit={handleSubmit} novalidate>
|
|
|
- <input type="hidden" name="url" value={url} />
|
|
|
-
|
|
|
- <div class="field">
|
|
|
- <label for="name">Name</label>
|
|
|
- <input
|
|
|
- id="name"
|
|
|
- name="name"
|
|
|
- type="text"
|
|
|
- autocomplete="name"
|
|
|
- placeholder="Your name"
|
|
|
- bind:value={name}
|
|
|
- class:error={errors.name}
|
|
|
- />
|
|
|
- {#if errors.name}<span class="error-msg">{errors.name}</span>{/if}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="field">
|
|
|
- <label for="email">Email</label>
|
|
|
- <input
|
|
|
- id="email"
|
|
|
- name="email"
|
|
|
- type="email"
|
|
|
- autocomplete="email"
|
|
|
- placeholder="you@example.com"
|
|
|
- bind:value={email}
|
|
|
- class:error={errors.email}
|
|
|
- />
|
|
|
- {#if errors.email}<span class="error-msg">{errors.email}</span>{/if}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="field">
|
|
|
- <label for="password">Password</label>
|
|
|
- <input
|
|
|
- id="password"
|
|
|
- name="password"
|
|
|
- type="password"
|
|
|
- autocomplete="new-password"
|
|
|
- placeholder="At least 8 characters"
|
|
|
- bind:value={password}
|
|
|
- class:error={errors.password}
|
|
|
- />
|
|
|
- {#if errors.password}<span class="error-msg">{errors.password}</span>{/if}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="field">
|
|
|
- <label for="confirm_password">Confirm Password</label>
|
|
|
- <input
|
|
|
- id="confirm_password"
|
|
|
- name="confirm_password"
|
|
|
- type="password"
|
|
|
- autocomplete="new-password"
|
|
|
- placeholder="Repeat your password"
|
|
|
- bind:value={confirm_password}
|
|
|
- class:error={errors.confirm_password}
|
|
|
- />
|
|
|
- {#if errors.confirm_password}<span class="error-msg">{errors.confirm_password}</span>{/if}
|
|
|
- </div>
|
|
|
-
|
|
|
- <button type="submit" class="btn btn-primary large full" disabled={submitting}>
|
|
|
- {submitting ? 'Creating account…' : 'Create Account'}
|
|
|
- </button>
|
|
|
- </form>
|
|
|
-
|
|
|
- <p class="signin">Already have an account? <a href="/login">Sign in</a></p>
|
|
|
- </div>
|
|
|
-</div>
|
|
|
-
|
|
|
-<style>
|
|
|
- .page {
|
|
|
- min-height: 100vh;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- padding: 40px 18px;
|
|
|
- background: #0b0b10;
|
|
|
- }
|
|
|
-
|
|
|
- .card {
|
|
|
- width: 100%;
|
|
|
- max-width: 420px;
|
|
|
- background: #121218;
|
|
|
- border: 1px solid #2a2a35;
|
|
|
- border-radius: 16px;
|
|
|
- padding: 40px 36px;
|
|
|
- }
|
|
|
-
|
|
|
- .logo {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 10px;
|
|
|
- text-decoration: none;
|
|
|
- color: #e5e5ea;
|
|
|
- font-weight: 700;
|
|
|
- font-size: 21px;
|
|
|
- margin-bottom: 28px;
|
|
|
- }
|
|
|
- .logo-text {
|
|
|
- letter-spacing: -0.5px;
|
|
|
- }
|
|
|
-
|
|
|
- h1 {
|
|
|
- font-size: 1.6rem;
|
|
|
- color: #e5e5ea;
|
|
|
- margin-bottom: 6px;
|
|
|
- }
|
|
|
-
|
|
|
- .subtitle {
|
|
|
- color: #a1a1aa;
|
|
|
- font-size: 0.95rem;
|
|
|
- margin: 0 0 28px;
|
|
|
- }
|
|
|
-
|
|
|
- form {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- gap: 18px;
|
|
|
- }
|
|
|
-
|
|
|
- .field {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- gap: 6px;
|
|
|
- }
|
|
|
-
|
|
|
- label {
|
|
|
- font-size: 13.5px;
|
|
|
- font-weight: 600;
|
|
|
- color: #c8c8d0;
|
|
|
- }
|
|
|
-
|
|
|
- input[type="text"],
|
|
|
- input[type="email"],
|
|
|
- input[type="password"] {
|
|
|
- background: #0b0b10;
|
|
|
- border: 1px solid #3f3f4a;
|
|
|
- border-radius: 9px;
|
|
|
- color: #e5e5ea;
|
|
|
- font-size: 15px;
|
|
|
- padding: 11px 14px;
|
|
|
- outline: none;
|
|
|
- transition: border-color 0.15s ease;
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- input::placeholder {
|
|
|
- color: #52525b;
|
|
|
- }
|
|
|
-
|
|
|
- input:focus {
|
|
|
- border-color: #c084fc;
|
|
|
- }
|
|
|
-
|
|
|
- input.error {
|
|
|
- border-color: #f87171;
|
|
|
- }
|
|
|
-
|
|
|
- .error-msg {
|
|
|
- font-size: 12.5px;
|
|
|
- color: #f87171;
|
|
|
- }
|
|
|
-
|
|
|
- button[type="submit"]:disabled {
|
|
|
- opacity: 0.6;
|
|
|
- cursor: not-allowed;
|
|
|
- transform: none;
|
|
|
- }
|
|
|
-
|
|
|
- .signin {
|
|
|
- text-align: center;
|
|
|
- font-size: 13.5px;
|
|
|
- color: #a1a1aa;
|
|
|
- margin: 22px 0 0;
|
|
|
- }
|
|
|
-
|
|
|
- .signin a {
|
|
|
- color: #c084fc;
|
|
|
- text-decoration: none;
|
|
|
- font-weight: 600;
|
|
|
- }
|
|
|
-
|
|
|
- .signin a:hover {
|
|
|
- text-decoration: underline;
|
|
|
- }
|
|
|
-
|
|
|
- @media (max-width: 480px) {
|
|
|
- .card {
|
|
|
- padding: 32px 22px;
|
|
|
- }
|
|
|
- }
|
|
|
-</style>
|