100 lines
5 KiB
TypeScript
100 lines
5 KiB
TypeScript
import { Query } from 'appwrite'
|
|
import { useEffect, useState } from 'react'
|
|
import { appwriteDatabaseId, databases } from '../lib/appwrite'
|
|
|
|
const statCard = (label: string, value: string | number, helper?: string) => (
|
|
<div className="rounded-xl border border-slate-800/70 bg-slate-900/70 p-4 shadow-inner shadow-slate-950/60">
|
|
<p className="text-xs uppercase tracking-[0.25em] text-cyan-300">{label}</p>
|
|
<p className="mt-2 text-3xl font-semibold text-slate-50">{value}</p>
|
|
{helper ? <p className="mt-1 text-xs text-slate-400">{helper}</p> : null}
|
|
</div>
|
|
)
|
|
|
|
export default function Home() {
|
|
const [projectsTotal, setProjectsTotal] = useState<number | null>(null)
|
|
const [activeWorkers, setActiveWorkers] = useState<number | null>(null)
|
|
const [lastDeployment, setLastDeployment] = useState<string>('---')
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
useEffect(() => {
|
|
const fetchMetrics = async () => {
|
|
if (!appwriteDatabaseId) {
|
|
setError('Defina VITE_APPWRITE_DATABASE_ID para consultar métricas.')
|
|
return
|
|
}
|
|
|
|
try {
|
|
const [projects, cloudAccounts, deployments] = await Promise.all([
|
|
databases.listDocuments(appwriteDatabaseId, 'projects', [Query.limit(1)]),
|
|
databases.listDocuments(appwriteDatabaseId, 'cloud_accounts', [Query.limit(1)]),
|
|
databases.listDocuments(appwriteDatabaseId, 'audit_logs', [Query.orderDesc('timestamp'), Query.limit(1)]),
|
|
])
|
|
|
|
setProjectsTotal(projects.total)
|
|
setActiveWorkers(cloudAccounts.total)
|
|
const lastTimestamp = deployments.documents[0]?.timestamp as string | undefined
|
|
setLastDeployment(lastTimestamp ? new Date(lastTimestamp).toLocaleString() : 'Sem deploys registrados')
|
|
} catch (err) {
|
|
console.error(err)
|
|
setError('Não foi possível carregar as métricas do painel.')
|
|
}
|
|
}
|
|
|
|
fetchMetrics()
|
|
}, [])
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="rounded-xl border border-slate-800/80 bg-slate-900/60 p-6 shadow-lg shadow-slate-950/50">
|
|
<p className="text-xs uppercase tracking-[0.3em] text-cyan-300">Overview</p>
|
|
<h1 className="mt-2 text-2xl font-semibold text-slate-50">Saúde do Projeto</h1>
|
|
<p className="mt-2 text-sm text-slate-400">
|
|
Consolidação das integrações com GitHub, Cloudflare e Appwrite para acompanhar deploys e automações.
|
|
</p>
|
|
</div>
|
|
|
|
{error ? <div className="rounded-lg border border-red-500/40 bg-red-500/10 p-3 text-sm text-red-200">{error}</div> : null}
|
|
|
|
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
{statCard('Total Repos', projectsTotal ?? '---', 'Quantidade de projetos cadastrados no Appwrite')}
|
|
{statCard('Active Workers', activeWorkers ?? '---', 'Workers monitorados pelo Cloudflare')}
|
|
{statCard('Last Deployment', lastDeployment)}
|
|
</div>
|
|
|
|
<div className="grid gap-4 lg:grid-cols-2">
|
|
<div className="rounded-xl border border-slate-800/70 bg-slate-900/70 p-5">
|
|
<h3 className="text-lg font-semibold text-slate-100">Deploys recentes</h3>
|
|
<p className="mt-2 text-sm text-slate-400">Acompanhe as últimas execuções registradas no Appwrite.</p>
|
|
<ul className="mt-4 space-y-3 text-sm text-slate-300">
|
|
<li className="flex items-center justify-between rounded-lg border border-slate-800/70 bg-slate-950/60 px-3 py-2">
|
|
<span>Build & Deploy</span>
|
|
<span className="text-xs text-emerald-300">{lastDeployment}</span>
|
|
</li>
|
|
<li className="flex items-center justify-between rounded-lg border border-slate-800/70 bg-slate-950/60 px-3 py-2">
|
|
<span>Sync GitHub</span>
|
|
<span className="text-xs text-emerald-300">{projectsTotal ?? '---'} repositórios</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div className="rounded-xl border border-slate-800/70 bg-slate-900/70 p-5">
|
|
<h3 className="text-lg font-semibold text-slate-100">Status de integrações</h3>
|
|
<div className="mt-4 space-y-3 text-sm text-slate-300">
|
|
<div className="flex items-center justify-between rounded-lg border border-slate-800/70 bg-slate-950/60 px-3 py-2">
|
|
<span>Appwrite Database</span>
|
|
<span className="text-xs text-cyan-300">{appwriteDatabaseId ? 'Configurado' : 'Pendente'}</span>
|
|
</div>
|
|
<div className="flex items-center justify-between rounded-lg border border-slate-800/70 bg-slate-950/60 px-3 py-2">
|
|
<span>Cloud Accounts</span>
|
|
<span className="text-xs text-cyan-300">{activeWorkers ?? '---'} credenciais</span>
|
|
</div>
|
|
<div className="flex items-center justify-between rounded-lg border border-slate-800/70 bg-slate-950/60 px-3 py-2">
|
|
<span>Realtime Logs</span>
|
|
<span className="text-xs text-emerald-300">Monitorando audit_logs</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|