Features Added: • Docker containerization with multi-stage Python 3.12 build • Caddy reverse proxy integration with automatic SSL • File upload interface for .claude.json imports with preview • Comprehensive hook system with 39+ hook types across 9 categories • Complete documentation system with Docker and import guides Technical Improvements: • Enhanced database models with hook tracking capabilities • Robust file validation and error handling for uploads • Production-ready Docker compose configuration • Health checks and resource limits for containers • Database initialization scripts for containerized deployments Documentation: • Docker Deployment Guide with troubleshooting • Data Import Guide with step-by-step instructions • Updated Getting Started guide with new features • Enhanced documentation index with responsive grid layout 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
"""
|
|
Dashboard web interface routes.
|
|
"""
|
|
|
|
from fastapi import APIRouter, Request, Depends
|
|
from fastapi.templating import Jinja2Templates
|
|
from fastapi.responses import HTMLResponse
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database.connection import get_db
|
|
|
|
dashboard_router = APIRouter()
|
|
templates = Jinja2Templates(directory="app/dashboard/templates")
|
|
|
|
|
|
@dashboard_router.get("/dashboard", response_class=HTMLResponse)
|
|
async def dashboard_home(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Main dashboard page."""
|
|
return templates.TemplateResponse("dashboard.html", {
|
|
"request": request,
|
|
"title": "Claude Code Project Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/projects", response_class=HTMLResponse)
|
|
async def dashboard_projects(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Projects overview page."""
|
|
return templates.TemplateResponse("projects.html", {
|
|
"request": request,
|
|
"title": "Projects - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/analytics", response_class=HTMLResponse)
|
|
async def dashboard_analytics(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Analytics and insights page."""
|
|
return templates.TemplateResponse("analytics.html", {
|
|
"request": request,
|
|
"title": "Analytics - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/conversations", response_class=HTMLResponse)
|
|
async def dashboard_conversations(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Conversation search and history page."""
|
|
return templates.TemplateResponse("conversations.html", {
|
|
"request": request,
|
|
"title": "Conversations - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/import", response_class=HTMLResponse)
|
|
async def dashboard_import(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Data import page."""
|
|
return templates.TemplateResponse("import.html", {
|
|
"request": request,
|
|
"title": "Import Data - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/projects/{project_id}/timeline", response_class=HTMLResponse)
|
|
async def dashboard_project_timeline(request: Request, project_id: int, db: AsyncSession = Depends(get_db)):
|
|
"""Project timeline page."""
|
|
return templates.TemplateResponse("project_timeline.html", {
|
|
"request": request,
|
|
"title": f"Timeline - Project {project_id}",
|
|
"project_id": project_id
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/projects/{project_id}/stats", response_class=HTMLResponse)
|
|
async def dashboard_project_stats(request: Request, project_id: int, db: AsyncSession = Depends(get_db)):
|
|
"""Project statistics page."""
|
|
return templates.TemplateResponse("project_stats.html", {
|
|
"request": request,
|
|
"title": f"Statistics - Project {project_id}",
|
|
"project_id": project_id
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/docs", response_class=HTMLResponse)
|
|
async def dashboard_docs(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Documentation overview page."""
|
|
return templates.TemplateResponse("docs/index.html", {
|
|
"request": request,
|
|
"title": "Documentation - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/docs/{section}", response_class=HTMLResponse)
|
|
async def dashboard_docs_section(request: Request, section: str, db: AsyncSession = Depends(get_db)):
|
|
"""Documentation section pages."""
|
|
# Map section names to templates and titles
|
|
sections = {
|
|
"getting-started": {
|
|
"template": "docs/getting-started.html",
|
|
"title": "Getting Started - Claude Code Tracker"
|
|
},
|
|
"data-import": {
|
|
"template": "docs/data-import.html",
|
|
"title": "Data Import Guide - Claude Code Tracker"
|
|
},
|
|
"docker-deployment": {
|
|
"template": "docs/docker-deployment.html",
|
|
"title": "Docker Deployment Guide - Claude Code Tracker"
|
|
},
|
|
"hook-setup": {
|
|
"template": "docs/hook-setup.html",
|
|
"title": "Hook Setup Guide - Claude Code Tracker"
|
|
},
|
|
"hook-reference": {
|
|
"template": "docs/hook-reference.html",
|
|
"title": "Complete Hook Reference - Claude Code Tracker"
|
|
},
|
|
"api-reference": {
|
|
"template": "docs/api-reference.html",
|
|
"title": "API Reference - Claude Code Tracker"
|
|
},
|
|
"faq": {
|
|
"template": "docs/faq.html",
|
|
"title": "FAQ - Claude Code Tracker"
|
|
}
|
|
}
|
|
|
|
if section not in sections:
|
|
from fastapi import HTTPException
|
|
raise HTTPException(status_code=404, detail=f"Documentation section '{section}' not found")
|
|
|
|
section_info = sections[section]
|
|
return templates.TemplateResponse(section_info["template"], {
|
|
"request": request,
|
|
"title": section_info["title"],
|
|
"section": section
|
|
}) |