import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import {
GitBranch,
CheckCircle,
XCircle,
Clock,
ArrowSquareOut,
Warning,
Copy,
CheckSquare,
} from '@phosphor-icons/react'
import { Skeleton } from '@/components/ui/skeleton'
import copy from '@/data/github-build-status.json'
import { useGithubBuildStatus, Workflow, WorkflowRun } from '@/hooks/use-github-build-status'
interface GitHubBuildStatusProps {
owner: string
repo: string
defaultBranch?: string
}
interface WorkflowRunStatusProps {
status: string
conclusion: string | null
}
interface WorkflowRunDetailsProps {
branch: string
updatedAt: string
event: string
}
interface WorkflowRunItemProps {
workflow: WorkflowRun
renderStatus: (status: string, conclusion: string | null) => React.ReactNode
renderBadge: (status: string, conclusion: string | null) => React.ReactNode
formatTime: (dateString: string) => string
}
interface WorkflowBadgeListProps {
workflows: Workflow[]
copiedBadge: string | null
defaultBranch: string
onCopyBadge: (workflowPath: string, workflowName: string, branch?: string) => void
getBadgeUrl: (workflowPath: string, branch?: string) => string
getBadgeMarkdown: (workflowPath: string, workflowName: string, branch?: string) => string
}
interface BranchBadgeListProps {
branches: string[]
workflows: Workflow[]
copiedBadge: string | null
onCopyBadge: (workflowPath: string, workflowName: string, branch: string) => void
getBadgeUrl: (workflowPath: string, branch?: string) => string
}
const WorkflowRunStatus = ({ status, conclusion }: WorkflowRunStatusProps) => {
const getStatusIcon = () => {
if (status === 'completed') {
if (conclusion === 'success') {
return
}
if (conclusion === 'failure') {
return
}
if (conclusion === 'cancelled') {
return
}
}
return
}
return
{getStatusIcon()}
}
const WorkflowRunBadge = ({ status, conclusion }: WorkflowRunStatusProps) => {
if (status === 'completed') {
if (conclusion === 'success') {
return (
{copy.status.success}
)
}
if (conclusion === 'failure') {
return {copy.status.failed}
}
if (conclusion === 'cancelled') {
return {copy.status.cancelled}
}
}
return (
{copy.status.running}
)
}
const WorkflowRunDetails = ({ branch, updatedAt, event }: WorkflowRunDetailsProps) => (
{branch}
•
{updatedAt}
•
{event}
)
const WorkflowRunItem = ({ workflow, renderStatus, renderBadge, formatTime }: WorkflowRunItemProps) => (
{renderStatus(workflow.status, workflow.conclusion)}
{workflow.name}
{renderBadge(workflow.status, workflow.conclusion)}
)
const WorkflowBadgeList = ({
workflows,
copiedBadge,
defaultBranch,
onCopyBadge,
getBadgeUrl,
getBadgeMarkdown,
}: WorkflowBadgeListProps) => (
{copy.sections.workflowBadges}
{workflows.map((workflow) => (
{workflow.name}
{getBadgeMarkdown(workflow.path, workflow.name)}
))}
)
const BranchBadgeList = ({
branches,
workflows,
copiedBadge,
onCopyBadge,
getBadgeUrl,
}: BranchBadgeListProps) => (
{copy.sections.branchBadges}
{branches.slice(0, 3).map((branch) => (
{workflows.slice(0, 2).map((workflow) => (
{workflow.name}
))}
))}
)
export function GitHubBuildStatus({ owner, repo, defaultBranch = 'main' }: GitHubBuildStatusProps) {
const {
workflows,
allWorkflows,
loading,
error,
copiedBadge,
actions,
} = useGithubBuildStatus({ owner, repo, defaultBranch })
const { refresh, copyBadgeMarkdown, getBadgeUrl, getBadgeMarkdown, formatTime } = actions
if (loading) {
return (
{copy.title}
{copy.loading.description}
{[...Array(3)].map((_, i) => (
))}
)
}
if (error) {
return (
{copy.title}
{copy.error.description}
{error}
)
}
if (workflows.length === 0 && allWorkflows.length === 0) {
return (
{copy.title}
{copy.empty.description}
{copy.empty.body}
)
}
const uniqueBranches = Array.from(new Set(workflows.map((workflow) => workflow.head_branch)))
return (
{copy.title}
{copy.header.description}
{copy.tabs.badges}
{copy.tabs.runs}
{uniqueBranches.length > 0 && (
)}
{workflows.map((workflow) => (
(
)}
renderBadge={(status, conclusion) => (
)}
formatTime={formatTime}
/>
))}
)
}