Files
web-boilerplate/src/components/CommentForm.tsx
JonLuca De Caro 5ff5ef65c3 boilerplate
2026-03-03 18:43:35 -08:00

70 lines
2.2 KiB
TypeScript

import { useState } from "react";
import { api } from "~/utils/api";
type CommentFormProps = {
postId: string;
};
const inputClassName =
"w-full rounded-[18px] border border-white/12 bg-[#0b1320] px-4 py-3 text-sm text-white outline-none transition placeholder:text-[#6c7790] focus:border-[#9db6ff] focus:bg-[#101928]";
export const CommentForm = ({ postId }: CommentFormProps) => {
const utils = api.useUtils();
const [body, setBody] = useState("");
const [message, setMessage] = useState<string | null>(null);
const createComment = api.comment.create.useMutation({
onSuccess: async () => {
setBody("");
setMessage("Comment created.");
await utils.post.byId.invalidate({ postId });
},
onError: (error) => {
setMessage(error.message);
},
});
return (
<section className="rounded-[26px] border border-white/12 bg-[#0a1220]/85 p-5">
<div className="flex flex-col gap-2">
<p className="font-mono text-[#99b6ff] text-[11px] uppercase tracking-[0.24em]">Protected write route</p>
<h2 className="text-xl tracking-[-0.04em]">Add a comment</h2>
</div>
<form
className="mt-5 space-y-4"
onSubmit={(event) => {
event.preventDefault();
setMessage(null);
createComment.mutate({
body,
postId,
});
}}
>
<textarea
className={`${inputClassName} min-h-32 resize-y`}
maxLength={4000}
onChange={(event) => setBody(event.target.value)}
placeholder="Leave a short note on the post."
required
value={body}
/>
{message ? (
<div className="rounded-[18px] border border-white/10 bg-white/[0.04] px-4 py-3 text-[#dbe4ff] text-sm">{message}</div>
) : null}
<button
className="rounded-[18px] bg-[#9db6ff] px-4 py-3 font-mono text-[#09111d] text-[11px] uppercase tracking-[0.24em] transition hover:bg-[#b8cbff] disabled:cursor-not-allowed disabled:bg-[#556888] disabled:text-[#d4def8]"
disabled={createComment.isPending}
type="submit"
>
{createComment.isPending ? "Posting..." : "Post comment"}
</button>
</form>
</section>
);
};