refactor: migrate from Next.js to SolidJS and GraphQL
- Converted web application from Next.js to SolidJS with Vite - Replaced React components with SolidJS components - Implemented GraphQL client using URQL - Added authentication, room, and chat components - Updated project structure and configuration files - Removed unnecessary Next.js and docs-related files - Added Docker support for web and API applications
This commit is contained in:
parent
8f3aa2fc26
commit
16731409df
81 changed files with 13585 additions and 1163 deletions
118
apps/web/src/components/register-form.tsx
Normal file
118
apps/web/src/components/register-form.tsx
Normal file
|
@ -0,0 +1,118 @@
|
|||
import { createSignal } from 'solid-js';
|
||||
import { gql } from '@urql/core';
|
||||
import { createMutation } from '@urql/solid';
|
||||
|
||||
const REGISTER_MUTATION = gql`
|
||||
mutation Register($email: String!, $username: String!, $password: String!) {
|
||||
register(email: $email, username: $username, password: $password) {
|
||||
token
|
||||
user {
|
||||
id
|
||||
username
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface RegisterFormProps {
|
||||
onRegisterSuccess: (token: string, userId: string) => void;
|
||||
}
|
||||
|
||||
export function RegisterForm(props: RegisterFormProps) {
|
||||
const [email, setEmail] = createSignal('');
|
||||
const [username, setUsername] = createSignal('');
|
||||
const [password, setPassword] = createSignal('');
|
||||
const [confirmPassword, setConfirmPassword] = createSignal('');
|
||||
const [error, setError] = createSignal('');
|
||||
|
||||
const [state, executeMutation] = createMutation(REGISTER_MUTATION);
|
||||
|
||||
const handleSubmit = async (e: Event) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!email() || !username() || !password() || !confirmPassword()) {
|
||||
setError('Please fill in all fields');
|
||||
return;
|
||||
}
|
||||
|
||||
if (password() !== confirmPassword()) {
|
||||
setError('Passwords do not match');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await executeMutation({
|
||||
email: email(),
|
||||
username: username(),
|
||||
password: password(),
|
||||
});
|
||||
|
||||
if (result.error) {
|
||||
setError(result.error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.data?.register) {
|
||||
const { token, user } = result.data.register;
|
||||
localStorage.setItem('token', token);
|
||||
localStorage.setItem('userId', user.id);
|
||||
props.onRegisterSuccess(token, user.id);
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'An error occurred');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div class='register-form'>
|
||||
<h2>Register</h2>
|
||||
{error() && <div class='error'>{error()}</div>}
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div class='form-group'>
|
||||
<label for='email'>Email</label>
|
||||
<input
|
||||
type='email'
|
||||
id='email'
|
||||
value={email()}
|
||||
onInput={(e) => setEmail(e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='username'>Username</label>
|
||||
<input
|
||||
type='text'
|
||||
id='username'
|
||||
value={username()}
|
||||
onInput={(e) => setUsername(e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='password'>Password</label>
|
||||
<input
|
||||
type='password'
|
||||
id='password'
|
||||
value={password()}
|
||||
onInput={(e) => setPassword(e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='confirm-password'>Confirm Password</label>
|
||||
<input
|
||||
type='password'
|
||||
id='confirm-password'
|
||||
value={confirmPassword()}
|
||||
onInput={(e) => setConfirmPassword(e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button type='submit' disabled={state.fetching}>
|
||||
{state.fetching ? 'Registering...' : 'Register'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue