← 返回
未分类 Key

Supabase Dashboard Builder

Build admin dashboards and command centers backed by Supabase REST API with D3.js force graphs, Chart.js visualizations, and vanilla JS. Use when creating da...
Build admin dashboards and command centers backed by Supabase REST API with D3.js force graphs, Chart.js visualizations, and vanilla JS. Use when creating da...
brandonwadepackard-cell
未分类 clawhub v1.0.0 1 版本 100000 Key: 需要
★ 0
Stars
📥 239
下载
💾 0
安装
1
版本
#latest

概述

Supabase Dashboard Builder

Build rich admin dashboards using Supabase PostgREST API + vanilla JS + D3/Chart.js. No build step, no framework — just HTML files served by FastAPI StaticFiles.

Architecture

FastAPI Server
├── api.py (thin proxy to Supabase REST)
├── static/
│   ├── shell.js + shell.css (shared theme)
│   ├── dashboard/
│   │   ├── index.html (main page)
│   │   ├── agents.html
│   │   ├── skills.html
│   │   └── ...

Step 1: API Layer

Create a thin FastAPI proxy that wraps Supabase REST calls. This keeps the Supabase key server-side.

import httpx
from fastapi import FastAPI

SUPABASE_URL = os.environ["SUPABASE_URL"]
SUPABASE_KEY = os.environ["SUPABASE_SERVICE_KEY"]
HEADERS = {"apikey": SUPABASE_KEY, "Authorization": f"Bearer {SUPABASE_KEY}"}

app = FastAPI()

@app.get("/api/mc/{table}")
async def get_table(table: str, select: str = "*", limit: int = 100, offset: int = 0):
    allowed = {"ai_agents", "skills", "knowledge_vault", "tools", "workflows"}
    if table not in allowed:
        raise HTTPException(403, "Table not allowed")
    url = f"{SUPABASE_URL}/rest/v1/{table}?select={select}&limit={limit}&offset={offset}"
    async with httpx.AsyncClient() as client:
        r = await client.get(url, headers={**HEADERS, "Prefer": "count=exact"})
    return r.json()

Key pattern: Lightweight selects

Tables with large text columns (system_prompt, embeddings) will timeout if you SELECT *. Always specify columns:

?select=id,name,type,status,created_at

Add select parameter to every API endpoint and default to lightweight fields.

Step 2: Shared Shell

Create shell.js and shell.css that every page imports:

// shell.js
function createShell(pageTitle, navItems) {
    // Returns: sidebar (collapsible) + top bar + main content area
    // navItems: [{label, href, icon, active}]
}

function createCard(title, content, footer) {
    // Dark-themed card with header, body, optional footer
}

function createTable(headers, rows, options) {
    // Sortable, searchable table with pagination
}

function mcFetch(endpoint, params = {}) {
    // Wrapper: fetch(`/api/mc/${endpoint}?${new URLSearchParams(params)}`)
    // Handles errors, loading states
}

function createSearchBar(placeholder, onSearch) {
    // Debounced search input
}

CSS variables for consistent theming:

:root {
    --bg-primary: #0a0a0f;
    --bg-card: #12121a;
    --bg-hover: #1a1a2e;
    --text-primary: #e0e0e0;
    --text-secondary: #888;
    --accent: #6c63ff;
    --accent-glow: rgba(108, 99, 255, 0.3);
    --border: #2a2a3e;
    --success: #4caf50;
    --warning: #ff9800;
    --danger: #f44336;
}

Step 3: Page Patterns

Data Grid Page (Agents, Skills, Tools)

┌─────────────────────────────┐
│ Search bar + Filter chips    │
├─────────────────────────────┤
│ Stats row (total, active,    │
│ by type)                     │
├─────────────────────────────┤
│ Sortable table or card grid  │
│ with pagination              │
└─────────────────────────────┘

Force Graph Page (System Overview)

Use D3.js force-directed graph:

  • Nodes = entities (agents, tools, skills)
  • Edges = relationships (agent uses tool, skill teaches concept)
  • Color by category, size by importance
  • Click node → side panel with details
  • Zoom + pan + drag

Chart Page (Analytics, Metrics)

Use Chart.js:

  • Radar charts for multi-dimensional scores
  • Line charts for time series
  • Bar charts for comparisons
  • Doughnut for category breakdown

Step 4: FastAPI Static Mount

from fastapi.staticfiles import StaticFiles

# Mount AFTER API routes
app.mount("/static/mc", StaticFiles(directory="static/mc"), name="mc-static")

# Convenience page routes
@app.get("/mc/{page}")
async def serve_mc_page(page: str):
    return FileResponse(f"static/mc/{page}")

@app.get("/mc/")
async def serve_mc_index():
    return FileResponse("static/mc/index.html")

Common Bugs & Fixes

  1. Double-prefix in mcFetch: Agents write mcFetch('/api/mc/agents') when mcFetch already prepends /api/mc/. Fix: mcFetch('agents') or make mcFetch accept both.
  1. CORS issues in dev: Add CORS middleware if frontend is on different port:

```python

app.add_middleware(CORSMiddleware, allow_origins=[""], allow_methods=[""], allow_headers=["*"])

```

  1. Supabase timeout on large tables: Use select parameter + limit + offset. Never SELECT * on tables with 1000+ rows or text columns > 1KB.
  1. Chart.js canvas reuse: Destroy previous chart instance before creating new one on the same canvas, or charts stack invisibly.

Deployment

Works on any platform that serves Python (Railway, Fly, Render):

  • Static files are served by FastAPI — no separate CDN needed
  • Supabase key stays server-side in env vars
  • No build step — edit HTML, refresh browser

版本历史

共 1 个版本

  • v1.0.0 当前
    2026-05-12 05:51 安全 安全

安全检测

腾讯云安全 (Keen)

安全,无风险
查看报告

腾讯云安全 (Sanbu)

安全,无风险
查看报告

🔗 相关推荐

security-compliance

Platform API Connector

brandonwadepackard-cell
{"answer":"访问开发者门户、创建应用、获取OAuth令牌并存储凭证,以连接社交媒体和内容平台API。涵盖Fac..."}
★ 0 📥 1,015
communication-collaboration

Domain Email Forwarding

brandonwadepackard-cell
为自定义域名设置邮件转发,接收验证码、密码重置及其他邮件到您拥有但不常用于邮件收发的域名。
★ 0 📥 735

Hume EVI + LangGraph Integration

brandonwadepackard-cell
使用 interrupt/resume 模式将 Hume EVI 语音 AI 与 LangGraph 集成。适用于需要 Twilio 电话处理和 Hume EVI 的语音 AI 代理开发。
★ 0 📥 287