mywork / src /components /deployment /DeploymentCard.tsx
DeeCeeXxx's picture
Upload 114 files
e9d5b7d verified
import Link from 'next/link';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import type { Deployment, DeploymentStatus } from '@/lib/types';
import { ExternalLink, Zap, AlertTriangle, CheckCircle2, Hourglass, PowerOff, Layers } from 'lucide-react';
import { cn } from '@/lib/utils';
interface DeploymentCardProps {
deployment: Deployment;
}
function getStatusBadgeVariant(status: DeploymentStatus) {
switch (status) {
case 'succeeded':
return 'default';
case 'deploying':
return 'secondary';
case 'pending':
return 'outline';
case 'failed':
return 'destructive';
case 'stopped':
return 'outline';
default:
return 'outline';
}
}
function getStatusIcon(status: DeploymentStatus) {
switch (status) {
case 'succeeded':
return <CheckCircle2 className="h-5 w-5 text-green-500" />;
case 'deploying':
return <Hourglass className="h-5 w-5 text-blue-500 animate-spin" />;
case 'pending':
return <Hourglass className="h-5 w-5 text-yellow-500" />;
case 'failed':
return <AlertTriangle className="h-5 w-5 text-red-500" />;
case 'stopped':
return <PowerOff className="h-5 w-5 text-gray-500" />;
default:
return <Zap className="h-5 w-5 text-muted-foreground" />;
}
}
export function DeploymentCard({ deployment }: DeploymentCardProps) {
return (
<Card className="flex flex-col h-full shadow-md hover:shadow-xl transition-shadow duration-300 ease-in-out">
<CardHeader className="pb-3">
<div className="flex justify-between items-start gap-2">
<div className="flex-1">
<CardTitle className="text-xl font-semibold text-primary flex items-center">
<Layers className="mr-2.5 h-5 w-5" />
{deployment.appName}
</CardTitle>
<CardDescription className="text-xs mt-1">Deployed: {new Date(deployment.createdAt).toLocaleDateString()}</CardDescription>
</div>
<Badge variant={getStatusBadgeVariant(deployment.status)} className="capitalize flex items-center gap-1.5 px-3 py-1 text-xs shadow-sm">
{getStatusIcon(deployment.status)}
<span>{deployment.status}</span>
</Badge>
</div>
</CardHeader>
<CardContent className="space-y-3 flex-grow">
<p className="text-sm text-muted-foreground">
Region: <span className="font-medium text-foreground">{deployment.region || 'N/A'}</span>
</p>
{deployment.lastDeployedAt && (
<p className="text-sm text-muted-foreground">
Last Activity: <span className="font-medium text-foreground">{new Date(deployment.lastDeployedAt).toLocaleDateString()}</span>
</p>
)}
{deployment.url && (
<div className="mt-2">
<a
href={deployment.url}
target="_blank"
rel="noopener noreferrer"
className="text-sm text-accent hover:underline flex items-center font-medium"
>
Visit App <ExternalLink className="ml-1.5 h-4 w-4" />
</a>
</div>
)}
</CardContent>
<CardFooter className="flex justify-end pt-4 border-t mt-auto">
<Button asChild variant="outline" size="sm" className="shadow-sm hover:shadow-md">
<Link href={`/dashboard/deployments/${deployment.id}`}>Manage</Link>
</Button>
</CardFooter>
</Card>
);
}