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:
Juan Sebastián Montoya 2025-03-04 01:08:52 -05:00
parent 8f3aa2fc26
commit 16731409df
81 changed files with 13585 additions and 1163 deletions

View 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>
);
}