mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-06-05 20:15:31 -04:00
5a1636baa3
- Replace Biome with oxlint + oxfmt (OXC toolchain) for linting and formatting - Add .oxlintrc.json and .oxfmtrc.json configuration files - Update VS Code settings and devcontainer to use oxc-vscode extension - Remove contact form, Resend email integration, and related server action/schema - Remove unused UI components (accordion, alert, card, tabs, toggle, etc.)
73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
import Link from "next/link";
|
|
import Markdown from "react-markdown";
|
|
|
|
import { RelativeTime } from "@/components/relative-time";
|
|
import { rehypeExternalLinks } from "@/lib/rehype";
|
|
import { remarkGfm, remarkSmartypants } from "@/lib/remark";
|
|
import type { CommentWithUser } from "@/lib/server/comments";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
import { CommentActions } from "./comment-actions";
|
|
import { CommentAvatar } from "./comment-avatar";
|
|
|
|
const CommentSingle = ({ comment }: { comment: CommentWithUser }) => {
|
|
const divId = `comment-${comment.id.substring(0, 8)}`;
|
|
|
|
return (
|
|
<div className="group scroll-mt-4" id={divId}>
|
|
<div className="flex gap-4">
|
|
<div className="shrink-0">
|
|
<CommentAvatar
|
|
name={comment.user.name}
|
|
image={comment.user.image}
|
|
className="size-8 md:size-10"
|
|
/>
|
|
</div>
|
|
|
|
<div className="min-w-0 flex-1">
|
|
<div className="mb-1 flex items-center gap-2">
|
|
<a
|
|
href={`https://github.com/${comment.user.name}`}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="font-medium hover:no-underline"
|
|
>
|
|
@{comment.user.name}
|
|
</a>
|
|
<Link
|
|
href={`#${divId}`}
|
|
className="text-muted-foreground text-xs leading-none hover:no-underline"
|
|
>
|
|
<RelativeTime date={comment.createdAt} />
|
|
</Link>
|
|
</div>
|
|
|
|
<div
|
|
className={cn(
|
|
"isolate max-w-none text-[0.875rem] leading-relaxed",
|
|
"[&_p]:my-5 [&_p]:first:mt-0 [&_p]:last:mb-0",
|
|
"[&_a]:text-primary [&_a]:decoration-primary/40 [&_a]:no-underline [&_a]:decoration-2 [&_a]:underline-offset-4 [&_a]:hover:underline",
|
|
"[&_code]:bg-muted [&_code]:rounded-sm [&_code]:px-[0.3rem] [&_code]:py-[0.2rem] [&_code]:font-medium",
|
|
"group-has-data-[intent=edit]:hidden", // hides the rendered comment when its own edit form is active
|
|
)}
|
|
>
|
|
<Markdown
|
|
remarkPlugins={[remarkGfm, remarkSmartypants]}
|
|
rehypePlugins={[
|
|
[rehypeExternalLinks, { target: "_blank", rel: "noopener noreferrer nofollow" }],
|
|
]}
|
|
allowedElements={["p", "a", "em", "strong", "code", "pre", "blockquote", "del"]}
|
|
>
|
|
{comment.content}
|
|
</Markdown>
|
|
</div>
|
|
|
|
<CommentActions comment={comment} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export { CommentSingle };
|