feat: redesign sites + generation queue pages
This commit is contained in:
@@ -1,27 +1,77 @@
|
||||
---
|
||||
import AdminLayout from '../../../layouts/AdminLayout.astro';
|
||||
import CollectionTable from '../../../components/admin/CollectionTable';
|
||||
import AdminLayout from '../../../components/admin/PageHeader.astro';
|
||||
import PageHeader from '../../../components/admin/PageHeader.astro';
|
||||
import StatCard from '../../../components/admin/StatCard.astro';
|
||||
|
||||
const endpoint = '/api/collections/generation_jobs';
|
||||
const columns = ['job_type', 'status', 'created_at'];
|
||||
---
|
||||
|
||||
<AdminLayout title="Generation Queue">
|
||||
<div class="space-y-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-gold-500">⚙️ Generation Jobs</h1>
|
||||
<p class="text-gray-400 mt-1">Content generation queue monitoring</p>
|
||||
<PageHeader
|
||||
icon="⚙️"
|
||||
title="Generation Queue"
|
||||
description="Monitor and manage content generation jobs"
|
||||
/>
|
||||
|
||||
<div class="grid grid-cols-5 gap-6 mb-8">
|
||||
<StatCard icon="📊" label="Total Jobs" value="0" />
|
||||
<StatCard icon="🟡" label="Pending" value="0" color="gold" />
|
||||
<StatCard icon="🔵" label="Processing" value="0" color="blue" />
|
||||
<StatCard icon="🟢" label="Completed" value="0" color="green" />
|
||||
<StatCard icon="🔴" label="Failed" value="0" color="red" />
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<button class="px-4 py-2 bg-graphite border border-edge-normal rounded-lg text-sm hover:bg-jet" onclick="location.reload()">
|
||||
|
||||
<div class="bg-titanium border border-edge-normal rounded-xl overflow-hidden">
|
||||
<div class="p-6 border-b border-edge-subtle">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white">Recent Jobs</h2>
|
||||
<button onclick="location.reload()" class="px-4 py-2 bg-graphite border border-edge-normal rounded-lg hover:bg-jet transition-colors">
|
||||
🔄 Refresh
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CollectionTable
|
||||
endpoint="/api/collections/generation_jobs"
|
||||
columns={['job_type', 'status', 'created_at']}
|
||||
title="Jobs Queue"
|
||||
client:load
|
||||
/>
|
||||
<table class="w-full">
|
||||
<thead class="bg-graphite border-b border-edge-subtle">
|
||||
<tr>
|
||||
{columns.map(col => (
|
||||
<th class="px-6 py-4 text-left text-sm font-semibold text-gray-300 uppercase">{col.replace(/_/g, ' ')}</th>
|
||||
))}
|
||||
<th class="px-6 py-4 text-right text-sm font-semibold text-gray-300 uppercase">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-body" class="divide-y divide-edge-subtle">
|
||||
<tr><td colspan={columns.length + 1} class="px-6 py-12 text-center text-gray-400">Loading...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script define:vars={{ endpoint, columns }}>
|
||||
async function loadData() {
|
||||
try {
|
||||
const token = localStorage.getItem('godToken') || 'jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA';
|
||||
const response = await fetch(endpoint, { headers: { 'X-God-Token': token } });
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
|
||||
const result = await response.json();
|
||||
const data = result.data || [];
|
||||
|
||||
const tbody = document.getElementById('table-body');
|
||||
tbody.innerHTML = data.length === 0
|
||||
? `<tr><td colspan="${columns.length + 1}" class="px-6 py-12 text-center text-gray-400">Queue is empty</td></tr>`
|
||||
: data.map(item => `
|
||||
<tr class="hover:bg-graphite/50 transition-colors">
|
||||
${columns.map(col => `<td class="px-6 py-4 text-sm text-gray-200">${item[col] || '-'}</td>`).join('')}
|
||||
<td class="px-6 py-4 text-right">
|
||||
<button class="text-gold-500 hover:text-gold-400 text-sm font-medium">View</button>
|
||||
</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} catch (err) {
|
||||
document.getElementById('table-body').innerHTML = `<tr><td colspan="${columns.length + 1}" class="px-6 py-12 text-center text-red-400">Error: ${err.message}</td></tr>`;
|
||||
}
|
||||
}
|
||||
loadData();
|
||||
</script>
|
||||
</AdminLayout>
|
||||
|
||||
@@ -1,13 +1,75 @@
|
||||
---
|
||||
import AdminLayout from '../../layouts/AdminLayout.astro';
|
||||
import CollectionTable from '../../components/admin/CollectionTable';
|
||||
import PageHeader from '../../components/admin/PageHeader.astro';
|
||||
import StatCard from '../../components/admin/StatCard.astro';
|
||||
|
||||
const endpoint = '/api/collections/sites';
|
||||
const columns = ['name', 'domain', 'status', 'created_at'];
|
||||
---
|
||||
|
||||
<AdminLayout title="Sites & Deployments">
|
||||
<CollectionTable
|
||||
endpoint="/api/collections/sites"
|
||||
columns={['name', 'domain', 'status', 'created_at']}
|
||||
title="Sites"
|
||||
client:load
|
||||
<AdminLayout title="Sites">
|
||||
<PageHeader
|
||||
icon="🌐"
|
||||
title="Sites & Deployments"
|
||||
description="Manage websites and deployment configurations"
|
||||
/>
|
||||
|
||||
<div class="grid grid-cols-3 gap-6 mb-8">
|
||||
<StatCard icon="🚀" label="Total Sites" value="1" color="gold" />
|
||||
<StatCard icon="✅" label="Active" value="1" color="green" />
|
||||
<StatCard icon="📊" label="Total Traffic" value="0" color="blue" />
|
||||
</div>
|
||||
|
||||
<div class="bg-titanium border border-edge-normal rounded-xl overflow-hidden">
|
||||
<div class="p-6 border-b border-edge-subtle">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white">All Sites</h2>
|
||||
<button class="px-4 py-2 bg-gold-500 text-black rounded-lg font-medium hover:bg-gold-400">
|
||||
+ New Site
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="w-full">
|
||||
<thead class="bg-graphite border-b border-edge-subtle">
|
||||
<tr>
|
||||
{columns.map(col => (
|
||||
<th class="px-6 py-4 text-left text-sm font-semibold text-gray-300 uppercase">{col.replace(/_/g, ' ')}</th>
|
||||
))}
|
||||
<th class="px-6 py-4 text-right text-sm font-semibold text-gray-300 uppercase">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-body" class="divide-y divide-edge-subtle">
|
||||
<tr><td colspan={columns.length + 1} class="px-6 py-12 text-center text-gray-400">Loading...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script define:vars={{ endpoint, columns }}>
|
||||
async function loadData() {
|
||||
try {
|
||||
const token = localStorage.getItem('godToken') || 'jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA';
|
||||
const response = await fetch(endpoint, { headers: { 'X-God-Token': token } });
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
|
||||
const result = await response.json();
|
||||
const data = result.data || [];
|
||||
|
||||
const tbody = document.getElementById('table-body');
|
||||
tbody.innerHTML = data.length === 0
|
||||
? `<tr><td colspan="${columns.length + 1}" class="px-6 py-12 text-center text-gray-400">No sites configured</td></tr>`
|
||||
: data.map(item => `
|
||||
<tr class="hover:bg-graphite/50 transition-colors">
|
||||
${columns.map(col => `<td class="px-6 py-4 text-sm text-gray-200">${item[col] || '-'}</td>`).join('')}
|
||||
<td class="px-6 py-4 text-right">
|
||||
<button class="text-gold-500 hover:text-gold-400 text-sm font-medium">Manage</button>
|
||||
</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} catch (err) {
|
||||
document.getElementById('table-body').innerHTML = `<tr><td colspan="${columns.length + 1}" class="px-6 py-12 text-center text-red-400">Error: ${err.message}</td></tr>`;
|
||||
}
|
||||
}
|
||||
loadData();
|
||||
</script>
|
||||
</AdminLayout>
|
||||
|
||||
Reference in New Issue
Block a user