Spaces:
Sleeping
Sleeping
File size: 2,645 Bytes
05c5ed5 | 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | "use client";
import { useState } from "react";
import { Button } from "ui/button";
import MentionInput from "../mention-input";
import { TipTapMentionJsonContent } from "app-types/util";
import { LoaderIcon, SendIcon } from "lucide-react";
import { useSWRConfig } from "swr";
export default function CommentForm({
exportId,
parentId,
onSubmit,
}: {
exportId: string;
parentId?: string;
onSubmit?: () => void;
}) {
const [content, setContent] = useState<
TipTapMentionJsonContent | undefined | string
>();
const [isSubmitting, setIsSubmitting] = useState(false);
const { mutate } = useSWRConfig();
const handleSubmit = async () => {
if (!content) return;
try {
setIsSubmitting(true);
const trimContent = (content as TipTapMentionJsonContent).content?.filter(
(item) => {
if (item.type == "paragraph" && !item.content) return false;
return true;
},
);
if ((content as TipTapMentionJsonContent).content) {
(content as TipTapMentionJsonContent).content = trimContent;
}
const response = await fetch(`/api/export/${exportId}/comments`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
content,
parentId,
}),
});
if (!response.ok) {
throw new Error("Failed to create comment");
}
// Reset form
setContent("");
// Refresh comments
mutate(`/api/export/${exportId}/comments`);
onSubmit?.();
} catch (error) {
console.error("Failed to create comment:", error);
} finally {
setIsSubmitting(false);
}
};
const handleContentChange = ({
json,
}: {
json: TipTapMentionJsonContent;
mentions: { label: string; id: string }[];
}) => {
setContent(json);
};
return (
<div className="flex gap-2 items-end w-full" data-testid="comment-form">
<div className="flex-1 bg-secondary rounded-lg p-0.5">
<MentionInput
className="text-sm"
placeholder="Write a comment..."
content={content}
onChange={handleContentChange}
onEnter={handleSubmit}
disabledMention={true}
/>
</div>
<Button
size="icon"
variant="ghost"
onClick={handleSubmit}
disabled={!content || isSubmitting}
data-testid="comment-submit"
>
{isSubmitting ? (
<LoaderIcon className="mr-1 animate-spin" />
) : (
<SendIcon className="mr-1" />
)}
</Button>
</div>
);
}
|