import Link from "next/link";
import type { ReactNode } from "react";
import { Surface } from "@unlocalhosted/metalui";
import { ActorAvatar, ActorName } from "./agent";
import { Markdown } from "./markdown";
import { Label } from "./ui";
import { formatDate, timeAgo } from "@/lib/format";
// The parts of an issue's or pull request's conversation: comments on raised plates beside their
// author, and events as lines on the activity rail.
export function CommentBox({
author,
agent,
createdAt,
body,
verb = "commented",
badge,
children,
}: {
author: string;
agent?: string | null;
createdAt: number;
body: string;
verb?: ReactNode;
badge?: ReactNode;
children?: ReactNode;
}) {
return (
<div className="flex gap-3">
<Link href={`/${author}`} className="shrink-0">
<ActorAvatar name={author} agent={agent} size={32} />
</Link>
<Surface material="raise-lite" radius="plate" className="min-w-0 flex-1">
<div className="rule-b flex min-h-10 flex-wrap items-center gap-x-2 gap-y-1 px-4 py-2 type-ui">
<ActorName person={author} agent={agent} />
<span className="type-label engraved" title={formatDate(createdAt)}>
{verb} {timeAgo(createdAt)}
</span>
{badge && <span className="ml-auto">{badge}</span>}
</div>
{body.trim() ? (
<div className="px-5 py-4">
<Markdown>{body}</Markdown>
</div>
) : (
!children && <p className="px-5 py-4 type-body text-ink3 italic">No description.</p>
)}
{children && <div className={body.trim() ? "rule-t space-y-3 px-4 py-3" : "space-y-3 px-4 py-3"}>{children}</div>}
</Surface>
</div>
);
}
/** A point on the activity rail: a small sunk well on the page, holding the event's glyph or an unlit dot. */
export function TimelineDot({ children }: { children?: ReactNode }) {
return (
<span className="well flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-full -ml-[3px]">
{children ?? <span className="h-1.5 w-1.5 rounded-full bg-ink3" />}
</span>
);
}
/** One line on the rail: who did what, when. */
export function TimelineEvent({ icon, actor, agent, at, children }: { icon?: ReactNode; actor: string | null; agent?: string | null; at: number; children: ReactNode }) {
return (
<p className="relative flex flex-wrap items-center gap-x-1.5 gap-y-1 pl-2.5 type-body text-ink2">
<TimelineDot>{icon}</TimelineDot>
{actor ? <ActorName person={actor} agent={agent} /> : <strong className="font-medium text-ink">Someone</strong>} {children} ·{" "}
<span title={formatDate(at)}>{timeAgo(at)}</span>
</p>
);
}
/** The rail the timeline hangs on. */
export function Timeline({ children }: { children: ReactNode }) {
return <div className="relative space-y-4 before:absolute before:top-2 before:bottom-2 before:left-4 before:w-px before:bg-line">{children}</div>;
}
export const AuthorBadge = () => <Label tone="accent">Author</Label>;