laconic-deployer-frontend/apps/deploy-fe/src/components/DeploymentTest.tsx

171 lines
5.6 KiB
TypeScript

'use client'
import { useState } from 'react'
import { Button } from '@workspace/ui/components/button'
import { Input } from '@workspace/ui/components/input'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@workspace/ui/components/card'
import { Label } from '@workspace/ui/components/label'
import { useDeployment, type DeploymentConfig } from '@/hooks/useDeployment'
import { Loader2 } from 'lucide-react'
interface DeploymentFormProps {
organizationSlug: string
}
export function DeploymentForm({ organizationSlug }: DeploymentFormProps) {
const { deployRepository, isDeploying, deploymentResult } = useDeployment()
const [formData, setFormData] = useState<Omit<DeploymentConfig, 'organizationSlug'>>({
projectId: '',
repository: '',
branch: 'main',
name: '',
environmentVariables: []
})
const [envVars, setEnvVars] = useState<Array<{ key: string; value: string }>>([])
const [currentEnvVar, setCurrentEnvVar] = useState({ key: '', value: '' })
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target
setFormData(prev => ({ ...prev, [name]: value }))
}
const handleAddEnvVar = () => {
if (currentEnvVar.key && currentEnvVar.value) {
setEnvVars(prev => [...prev, { ...currentEnvVar }])
setCurrentEnvVar({ key: '', value: '' })
}
}
const handleDeploy = async () => {
try {
// Convert the env vars to the format expected by the API
const environmentVariables = envVars.map(ev => ({
key: ev.key,
value: ev.value,
environments: ['Production', 'Preview'] // Default to both environments
}))
await deployRepository({
...formData,
organizationSlug,
environmentVariables
})
} catch (error) {
console.error('Deployment failed:', error)
}
}
return (
<Card className="w-full">
<CardHeader>
<CardTitle>Deploy Repository</CardTitle>
<CardDescription>
Enter the details for deploying a GitHub repository
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="name">Project Name</Label>
<Input
id="name"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="my-awesome-project"
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="repository">Repository URL</Label>
<Input
id="repository"
name="repository"
value={formData.repository}
onChange={handleChange}
placeholder="https://github.com/username/repo"
required
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="branch">Branch</Label>
<Input
id="branch"
name="branch"
value={formData.branch}
onChange={handleChange}
placeholder="main"
/>
</div>
<div className="space-y-2">
<Label>Environment Variables</Label>
<div className="grid grid-cols-2 gap-2">
<Input
placeholder="KEY"
value={currentEnvVar.key}
onChange={(e) => setCurrentEnvVar(prev => ({ ...prev, key: e.target.value }))}
/>
<Input
placeholder="value"
value={currentEnvVar.value}
onChange={(e) => setCurrentEnvVar(prev => ({ ...prev, value: e.target.value }))}
/>
</div>
<Button
variant="outline"
type="button"
onClick={handleAddEnvVar}
disabled={!currentEnvVar.key || !currentEnvVar.value}
className="mt-2"
>
Add Environment Variable
</Button>
</div>
{envVars.length > 0 && (
<div className="border rounded p-2">
<h4 className="font-medium mb-2">Environment Variables:</h4>
<ul className="space-y-1">
{envVars.map((ev, index) => (
<li key={index} className="flex justify-between">
<span className="font-mono">{ev.key}</span>
<span className="font-mono text-gray-500">{ev.value}</span>
</li>
))}
</ul>
</div>
)}
</div>
</CardContent>
<CardFooter>
<Button
onClick={handleDeploy}
disabled={isDeploying || !formData.name || !formData.repository}
className="w-full"
>
{isDeploying ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Deploying...
</>
) : 'Deploy Repository'}
</Button>
</CardFooter>
{deploymentResult && (
<div className="mt-4 p-4 border-t">
<h3 className="font-medium mb-2">Deployment Result:</h3>
<p>Status: <span className="font-medium">{deploymentResult.status}</span></p>
{deploymentResult.url && (
<p className="mt-2">
URL: <a href={deploymentResult.url} target="_blank" rel="noopener noreferrer" className="text-blue-500 underline">{deploymentResult.url}</a>
</p>
)}
</div>
)}
</Card>
)
}