-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathMessageInput.tsx
More file actions
65 lines (58 loc) · 1.91 KB
/
MessageInput.tsx
File metadata and controls
65 lines (58 loc) · 1.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
'use client';
import React, { startTransition, useActionState, useEffect, useRef, useState } from 'react';
import toast from 'react-hot-toast';
import { v4 as uuidv4 } from 'uuid';
import { submitMessage } from '@/data/actions/submitMessage';
import Button from '../ui/Button';
import type { OptimisticMessage } from './Messages';
type Props = {
addOptimisticMessage: (_message: OptimisticMessage) => void;
userId: string;
};
export default function MessageInput({ addOptimisticMessage, userId }: Props) {
const [state, submitMessageAction] = useActionState(submitMessage, {
success: false,
});
const [defaultValue, setDefaultValue] = useState(state.content);
const formRef = useRef<HTMLFormElement>(null);
useEffect(() => {
if (state.error) {
toast.error(state.error);
}
if (state.content) {
setDefaultValue(state.content);
}
}, [state.content, state.error, state.timestamp]);
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setDefaultValue('');
startTransition(async () => {
addOptimisticMessage({
content: e.currentTarget.content.value,
createdAt: new Date(),
createdById: userId,
id: uuidv4(),
});
submitMessageAction(new FormData(e.currentTarget));
formRef.current?.reset();
});
};
return (
<>
<form ref={formRef} onSubmit={onSubmit} action={submitMessageAction} className="flex flex-col gap-2 p-6">
<input
autoComplete="off"
required
defaultValue={defaultValue}
minLength={1}
name="content"
className="italic outline-none"
placeholder="Type a message..."
/>
<input type="hidden" name="createdById" value={userId} />
<Button>Send</Button>
</form>
{state.error && <noscript className="px-6 pb-6 text-end text-red-600">{state.error}</noscript>}
</>
);
}