feat: initial project scaffold
- React 19 + Vite + TailwindCSS frontend - Express + TypeScript backend API - PostgreSQL schema and migrations - Docker Compose orchestration - Drone CI/CD pipeline - Pages: Dashboard, Servers, Containers, Services, Logs, Metrics, Settings
This commit is contained in:
50
frontend/src/pages/Services.tsx
Normal file
50
frontend/src/pages/Services.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { api } from '@/lib/api'
|
||||
import { Layers } from 'lucide-react'
|
||||
|
||||
export default function Services() {
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['services'],
|
||||
queryFn: () => api.get('/services').then(r => r.data),
|
||||
})
|
||||
const services = data?.services ?? []
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-xl border border-[hsl(217.2_32.6%_17.5%)] bg-[hsl(222.2_84%_6%)] overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="border-b border-[hsl(217.2_32.6%_17.5%)]">
|
||||
{['Service', 'Type', 'Port', 'Status'].map(h => (
|
||||
<th key={h} className="text-left px-5 py-3 text-xs font-medium text-[hsl(215_20.2%_65.1%)] uppercase tracking-wider">{h}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{isLoading ? (
|
||||
<tr><td colSpan={4} className="text-center py-10 text-sm text-[hsl(215_20.2%_65.1%)]">Loading...</td></tr>
|
||||
) : services.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan={4} className="py-12 text-center">
|
||||
<Layers className="w-10 h-10 mx-auto mb-3 text-[hsl(215_20.2%_40%)]" />
|
||||
<p className="text-sm text-[hsl(215_20.2%_65.1%)]">No services configured yet.</p>
|
||||
</td>
|
||||
</tr>
|
||||
) : services.map((s: any) => (
|
||||
<tr key={s.id} className="border-t border-[hsl(217.2_32.6%_17.5%)] hover:bg-[hsl(217.2_32.6%_10%)]">
|
||||
<td className="px-5 py-4 text-sm font-medium text-white">{s.name}</td>
|
||||
<td className="px-5 py-4 text-sm text-[hsl(215_20.2%_65.1%)]">{s.type}</td>
|
||||
<td className="px-5 py-4 text-sm text-[hsl(215_20.2%_65.1%)]">{s.port ?? '—'}</td>
|
||||
<td className="px-5 py-4">
|
||||
<span className={`text-xs px-2 py-1 rounded ${s.status === 'active' ? 'bg-green-500/10 text-green-400' : 'bg-red-500/10 text-red-400'}`}>
|
||||
{s.status ?? 'unknown'}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user