g3 console initial cut + error doesnt kill auto

This commit is contained in:
Dhanji Prasanna
2025-11-04 11:39:26 +11:00
parent 6913c5f72e
commit aaf918828f
53 changed files with 6796 additions and 23 deletions

View File

@@ -0,0 +1,132 @@
import React, { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import InstancePanel from '../components/InstancePanel'
import NewRunModal from '../components/NewRunModal'
function Home() {
const [instances, setInstances] = useState([])
const [loading, setLoading] = useState(true)
const [showModal, setShowModal] = useState(false)
const navigate = useNavigate()
const fetchInstances = async () => {
try {
const response = await fetch('/api/instances')
if (response.ok) {
const data = await response.json()
setInstances(data)
}
} catch (error) {
console.error('Failed to fetch instances:', error)
} finally {
setLoading(false)
}
}
useEffect(() => {
fetchInstances()
const interval = setInterval(fetchInstances, 5000) // Poll every 5 seconds
return () => clearInterval(interval)
}, [])
const handleInstanceClick = (id) => {
navigate(`/instance/${id}`)
}
const handleKill = async (id) => {
try {
const response = await fetch(`/api/instances/${id}/kill`, {
method: 'POST',
})
if (response.ok) {
fetchInstances()
}
} catch (error) {
console.error('Failed to kill instance:', error)
}
}
const handleRestart = async (id) => {
try {
const response = await fetch(`/api/instances/${id}/restart`, {
method: 'POST',
})
if (response.ok) {
fetchInstances()
}
} catch (error) {
console.error('Failed to restart instance:', error)
}
}
const handleLaunch = async (request) => {
try {
const response = await fetch('/api/instances/launch', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
})
if (response.ok) {
setShowModal(false)
setTimeout(fetchInstances, 2000) // Refresh after 2 seconds
}
} catch (error) {
console.error('Failed to launch instance:', error)
}
}
if (loading) {
return (
<div className="flex justify-center items-center h-64">
<div className="text-gray-600 dark:text-gray-400">Loading instances...</div>
</div>
)
}
return (
<div>
<div className="flex justify-between items-center mb-6">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">
Running Instances ({instances.length})
</h2>
<button
onClick={() => setShowModal(true)}
className="hero-button hero-button-primary"
>
+ New Run
</button>
</div>
{instances.length === 0 ? (
<div className="hero-card p-8 text-center">
<p className="text-gray-600 dark:text-gray-400">
No running instances. Click "New Run" to start a g3 instance.
</p>
</div>
) : (
<div className="space-y-4">
{instances.map((instance) => (
<InstancePanel
key={instance.instance.id}
instance={instance}
onClick={() => handleInstanceClick(instance.instance.id)}
onKill={() => handleKill(instance.instance.id)}
onRestart={() => handleRestart(instance.instance.id)}
/>
))}
</div>
)}
{showModal && (
<NewRunModal
onClose={() => setShowModal(false)}
onLaunch={handleLaunch}
/>
)}
</div>
)
}
export default Home