File size: 3,635 Bytes
e9d5b7d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
89
90
91
92
93
94
95
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>
  );
}