Viewing File: /home/markqprx/iniasli.pro/client/comments/new-comment-form.tsx
import {Commentable} from '@common/comments/commentable';
import {Comment} from '@common/comments/comment';
import {useTrans} from '@common/i18n/use-trans';
import {useAuth} from '@common/auth/use-auth';
import {useCreateComment} from '@common/comments/requests/use-create-comment';
import {RefObject, useState} from 'react';
import clsx from 'clsx';
import {TextField} from '@common/ui/forms/input-field/text-field/text-field';
import {Avatar} from '@common/ui/images/avatar';
import {message} from '@common/i18n/message';
import {Trans} from '@common/i18n/trans';
import {useObjectRef} from '@react-aria/utils';
import {Button} from '@common/ui/buttons/button';
export interface NewCommentFormProps {
commentable: Commentable;
inReplyTo?: Comment;
onSuccess?: () => void;
className?: string;
autoFocus?: boolean;
inputRef?: RefObject<HTMLInputElement>;
// additional data that should be sent to backend when creating comments
payload?: Record<string, number | string>;
}
export function NewCommentForm({
commentable,
inReplyTo,
onSuccess,
className,
autoFocus,
payload,
...props
}: NewCommentFormProps) {
const {trans} = useTrans();
const {user} = useAuth();
const createComment = useCreateComment();
const inputRef = useObjectRef<HTMLInputElement>(props.inputRef);
const [inputIsExpanded, setInputIsExpanded] = useState(false);
const [inputValue, setInputValue] = useState('');
const clearInput = () => {
setInputIsExpanded(false);
if (inputRef.current) {
inputRef.current.blur();
setInputValue('');
}
};
return (
<form
className={clsx('py-6 flex gap-24', className)}
onSubmit={e => {
e.preventDefault();
if (inputValue && !createComment.isPending) {
createComment.mutate(
{
...payload,
commentable,
content: inputValue,
inReplyTo,
},
{
onSuccess: () => {
clearInput();
onSuccess?.();
},
},
);
}
}}
>
<Avatar size="xl" circle src={user?.avatar} label={user?.display_name} />
<div className="flex-auto">
<div className="text-xs text-muted mb-10">
<Trans
message="Comment as :name"
values={{
name: (
<span className="font-medium text">{user?.display_name}</span>
),
}}
/>
</div>
<TextField
inputRef={inputRef}
autoFocus={autoFocus}
inputElementType="textarea"
inputClassName="resize-none"
value={inputValue}
onChange={e => setInputValue(e.target.value)}
onFocus={() => setInputIsExpanded(true)}
onBlur={() => {
if (!inputValue) {
setInputIsExpanded(false);
}
}}
minLength={3}
rows={inputIsExpanded ? 3 : 1}
placeholder={
inReplyTo
? trans(message('Write a reply'))
: trans(message('Leave a comment'))
}
/>
{inputIsExpanded && (
<div className="flex items-center gap-12 justify-end mt-12">
<Button variant="outline" onClick={() => clearInput()}>
<Trans message="Cancel" />
</Button>
<Button
variant="outline"
color="primary"
type="submit"
disabled={createComment.isPending || inputValue.length < 3}
>
<Trans message="Comment" />
</Button>
</div>
)}
</div>
</form>
);
}
Back to Directory
File Manager