import React, { useState, useEffect } from "react"; import { Button } from '../ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card"; import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "../ui/select"; import { Input } from "../ui/input"; import { Label } from "../ui/label"; import Loader from "../ui/loader"; import { useToast } from "../ui/toast"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "../ui/tabs"; import { Textarea } from "../ui/textarea"; import { Switch } from "../ui/switch"; export default function NewHetznerInstance() { const { showToast } = useToast(); const [isLoading, setIsLoading] = useState(false); const [isFetchingData, setIsFetchingData] = useState(true); const [serverTypes, setServerTypes] = useState([]); const [locations, setLocations] = useState([]); const [images, setImages] = useState([]); const [sshKeys, setSshKeys] = useState([]); const [showAddSshKey, setShowAddSshKey] = useState(false); const PUBLIC_HETZNER_API_KEY = import.meta.env.PUBLIC_HETZNER_API_KEY; const [formData, setFormData] = useState({ name: "", server_type: "", image: "", location: "nbg1", // Default to Nuremberg ssh_keys: [], user_data: "", backups: false, start_after_create: true }); useEffect(() => { const fetchData = async () => { try { // Fetch all required data in parallel const [serverTypesResponse, locationsResponse, imagesResponse, sshKeysResponse] = await Promise.all([ fetch("https://api.hetzner.cloud/v1/server_types", { headers: { "Authorization": `Bearer ${PUBLIC_HETZNER_API_KEY}` } }), fetch("https://api.hetzner.cloud/v1/locations", { headers: { "Authorization": `Bearer ${PUBLIC_HETZNER_API_KEY}` } }), fetch("https://api.hetzner.cloud/v1/images", { headers: { "Authorization": `Bearer ${PUBLIC_HETZNER_API_KEY}` } }), fetch("https://api.hetzner.cloud/v1/ssh_keys", { headers: { "Authorization": `Bearer ${PUBLIC_HETZNER_API_KEY}` } }) ]); const serverTypesData = await serverTypesResponse.json(); const locationsData = await locationsResponse.json(); const imagesData = await imagesResponse.json(); const sshKeysData = await sshKeysResponse.json(); setServerTypes(serverTypesData.server_types || []); setLocations(locationsData.locations || []); setImages(imagesData.images.filter(img => img.type === "system") || []); setSshKeys(sshKeysData.ssh_keys || []); } catch (error) { showToast({ title: "Error", description: "Failed to load configuration data", variant: "destructive" }); } finally { setIsFetchingData(false); } }; fetchData(); }, []); const handleSubmit = async (e) => { e.preventDefault(); setIsLoading(true); try { const payload = { name: formData.name, server_type: formData.server_type, image: formData.image, location: formData.location, backups: formData.backups, ssh_keys: formData.ssh_keys, start_after_create: formData.start_after_create }; // Add user_data if provided if (formData.user_data) { payload.user_data = formData.user_data; } const response = await fetch("https://api.hetzner.cloud/v1/servers", { method: "POST", headers: { "Authorization": `Bearer ${PUBLIC_HETZNER_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify(payload) }); const data = await response.json(); if (data.server) { showToast({ title: "Deployment Started", description: `Server ${data.server.name} is being deployed`, variant: "success" }); // Reset form after successful deployment setFormData({ name: "", server_type: "", image: "", location: "nbg1", ssh_keys: [], user_data: "", backups: false, start_after_create: true }); } else { throw new Error(data.message || "Failed to deploy instance"); } } catch (error) { showToast({ title: "Deployment Failed", description: error.message, variant: "destructive" }); } finally { setIsLoading(false); } }; const handleChange = (e) => { const { name, value, type, checked } = e.target; setFormData(prev => ({ ...prev, [name]: type === "checkbox" ? checked : value })); }; const handleAddSshKey = async () => { try { const response = await fetch('https://api.hetzner.cloud/v1/ssh_keys', { method: "POST", headers: { "Authorization": `Bearer ${PUBLIC_HETZNER_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ name: formData.newSshKeyName, public_key: formData.newSshKeyValue }) }); const data = await response.json(); if (data.ssh_key) { // Refresh SSH keys list const sshResponse = await fetch("https://api.hetzner.cloud/v1/ssh_keys", { headers: { "Authorization": `Bearer ${PUBLIC_HETZNER_API_KEY}` } }); const sshData = await sshResponse.json(); setSshKeys(sshData.ssh_keys || []); showToast({ title: "SSH Key Added", description: "Your SSH key has been successfully added", variant: "success" }); setShowAddSshKey(false); } } catch (error) { showToast({ title: "Error", description: "Failed to add SSH key", variant: "destructive" }); } }; if (isFetchingData) { return ; } return ( Deploy New Hetzner Cloud Server Configure your cloud server with essential parameters

SSH Keys

{showAddSshKey && (