-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathContributionCard.tsx
More file actions
88 lines (84 loc) · 3.19 KB
/
Copy pathContributionCard.tsx
File metadata and controls
88 lines (84 loc) · 3.19 KB
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
"use client";
import { useState } from "react";
import { ChevronRight, ExternalLink } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { cn, stateColors } from "@/lib/utils";
import { formatDate } from "@/lib/date-utils";
import { ExpandedPRDetail } from "@/components/ExpandedPRDetail";
import { ExpandedReviewDetail } from "@/components/ExpandedReviewDetail";
import { ExpandedIssueDetail } from "@/components/ExpandedIssueDetail";
import type { ContributionDetail } from "@/lib/types";
interface ContributionCardProps {
item: ContributionDetail;
}
export function ContributionCard({ item }: ContributionCardProps) {
const [expanded, setExpanded] = useState(false);
const canExpand = item.type === "pr" || item.type === "review" || item.type === "issue";
const [owner, repo] = item.repoNameWithOwner.split("/");
return (
<Card className="md:hidden">
<CardContent className="p-4">
<div
className={cn(
"flex items-start gap-2",
canExpand && "cursor-pointer"
)}
onClick={() => canExpand && setExpanded(!expanded)}
role={canExpand ? "button" : undefined}
aria-expanded={canExpand ? expanded : undefined}
>
{canExpand && (
<ChevronRight
className={cn(
"mt-0.5 h-4 w-4 flex-shrink-0 text-zinc-400 transition-transform",
expanded && "rotate-90"
)}
/>
)}
<div className="min-w-0 flex-1">
<p className="truncate font-medium text-zinc-900 dark:text-zinc-50">
{item.title}
</p>
<p className="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
{item.repoNameWithOwner}
</p>
<div className="mt-2 flex items-center gap-2">
<Badge className={stateColors[item.state]} variant="outline">
{item.state}
</Badge>
<span className="text-xs text-zinc-500 dark:text-zinc-400">
{formatDate(item.createdAt)}
</span>
</div>
</div>
<a
href={item.url}
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
className="flex-shrink-0 text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200"
aria-label={`Open #${item.number} on GitHub`}
>
<ExternalLink className="h-4 w-4" />
</a>
</div>
{expanded && canExpand && item.type === "pr" && (
<div className="mt-3">
<ExpandedPRDetail owner={owner} repo={repo} number={item.number} />
</div>
)}
{expanded && canExpand && item.type === "review" && (
<div className="mt-3">
<ExpandedReviewDetail owner={owner} repo={repo} number={item.number} />
</div>
)}
{expanded && canExpand && item.type === "issue" && (
<div className="mt-3">
<ExpandedIssueDetail owner={owner} repo={repo} number={item.number} />
</div>
)}
</CardContent>
</Card>
);
}