"use client"; import Link from "next/link"; import { IconGitPullRequest, IconGitPullRequestClosed, IconGitMerge, IconExternalLink, } from "@tabler/icons-react"; import type { Icon } from "@tabler/icons-react"; import { Spinner } from "@kandev/ui/spinner"; import { cn, formatRelativeTime } from "@/lib/utils"; import type { MR } from "@/lib/types/gitlab"; type MRListProps = { items: MR[]; loading: boolean; error: string | null; }; function mrStateIcon(mr: MR): { Icon: Icon; className: string } { const state = mr.state === "opened" ? "open" : mr.state; if (state === "merged") return { Icon: IconGitMerge, className: "text-purple-600 dark:text-purple-400" }; if (state === "closed") return { Icon: IconGitPullRequestClosed, className: "text-red-600 dark:text-red-400" }; if (mr.draft) return { Icon: IconGitPullRequest, className: "text-muted-foreground" }; return { Icon: IconGitPullRequest, className: "text-emerald-600 dark:text-emerald-400" }; } function MRRow({ mr }: { mr: MR }) { const { Icon: StateIcon, className: stateIconClass } = mrStateIcon(mr); return (
{mr.title}
{mr.project_path}!{mr.iid} · {mr.head_branch} → {mr.base_branch} · by {mr.author_username} · opened {formatRelativeTime(mr.created_at)}
); } function MRListBody({ loading, error, items }: MRListProps) { if (loading) { return (
); } if (error) { return
{error}
; } if (items.length === 0) { return (
No merge requests match this filter.
); } return (
{items.map((mr) => ( ))}
); } export function MRList(props: MRListProps) { return (
); }