unreal-chat/apps/web/src/components/create-room.tsx
Juan Sebastian Montoya 16731409df 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
2025-03-04 01:08:52 -05:00

112 lines
3.1 KiB
TypeScript

import { createSignal } from 'solid-js';
import { gql } from '@urql/core';
import { createMutation } from '@urql/solid';
const CREATE_ROOM_MUTATION = gql`
mutation CreateRoom(
$name: String!
$description: String
$isPrivate: Boolean
) {
createRoom(name: $name, description: $description, isPrivate: $isPrivate) {
id
name
description
isPrivate
}
}
`;
interface CreateRoomProps {
onRoomCreated: (roomId: string) => void;
}
export function CreateRoom(props: CreateRoomProps) {
const [name, setName] = createSignal('');
const [description, setDescription] = createSignal('');
const [isPrivate, setIsPrivate] = createSignal(false);
const [error, setError] = createSignal('');
const [isOpen, setIsOpen] = createSignal(false);
const [state, executeMutation] = createMutation(CREATE_ROOM_MUTATION);
const handleSubmit = async (e: Event) => {
e.preventDefault();
if (!name().trim()) {
setError('Room name is required');
return;
}
try {
const result = await executeMutation({
name: name(),
description: description(),
isPrivate: isPrivate(),
});
if (result.error) {
setError(result.error.message);
return;
}
if (result.data?.createRoom) {
setName('');
setDescription('');
setIsPrivate(false);
setIsOpen(false);
props.onRoomCreated(result.data.createRoom.id);
}
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
}
};
return (
<div class='create-room'>
<button class='create-room-button' onClick={() => setIsOpen(!isOpen())}>
{isOpen() ? 'Cancel' : 'Create Room'}
</button>
{isOpen() && (
<div class='create-room-form'>
<h3>Create a New Room</h3>
{error() && <div class='error'>{error()}</div>}
<form onSubmit={handleSubmit}>
<div class='form-group'>
<label for='room-name'>Room Name</label>
<input
type='text'
id='room-name'
value={name()}
onInput={(e) => setName(e.currentTarget.value)}
required
/>
</div>
<div class='form-group'>
<label for='room-description'>Description (optional)</label>
<textarea
id='room-description'
value={description()}
onInput={(e) => setDescription(e.currentTarget.value)}
/>
</div>
<div class='form-group checkbox'>
<label>
<input
type='checkbox'
checked={isPrivate()}
onChange={(e) => setIsPrivate(e.currentTarget.checked)}
/>
Private Room
</label>
</div>
<button type='submit' disabled={state.fetching}>
{state.fetching ? 'Creating...' : 'Create Room'}
</button>
</form>
</div>
)}
</div>
);
}