transform admin panel with comprehensive professional UI

- migrate from SQLite to PostgreSQL with Drizzle ORM
- implement comprehensive AdminLayout with expandable sidebar navigation
- create professional dashboard with real-time charts and metrics
- add advanced monitoring, reporting, and export functionality
- fix menu alignment and remove non-existent pages
- eliminate duplicate headers and improve UI consistency
- add Tailwind CSS v3 for professional styling
- expand database schema from 6 to 15 tables
- implement role-based access control and API key management
- create comprehensive settings, monitoring, and system info pages
This commit is contained in:
2025-09-06 15:14:20 +02:00
parent 860070a302
commit 249a672cd7
36 changed files with 8212 additions and 1434 deletions

View File

@@ -1,28 +1,25 @@
import type { NextApiRequest, NextApiResponse } from "next"
import sqlite3 from "sqlite3"
import path from "path"
import { db, schema } from '../../../lib/db/connection'
import { count, gte, eq } from 'drizzle-orm'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "GET") return res.status(405).json({ error: "Method not allowed" })
const dbPath = path.join(process.cwd(), "database", "antihoax.db")
const db = new sqlite3.Database(dbPath)
try {
// Get performance metrics
const stats = await new Promise<any>((resolve, reject) => {
db.get(`
SELECT
COUNT(*) as total_sources,
COUNT(CASE WHEN status = 'verified' THEN 1 END) as verified_sources,
COUNT(CASE WHEN risk_level >= 4 THEN 1 END) as high_risk_sources,
COUNT(CASE WHEN created_at >= date('now', '-7 days') THEN 1 END) as sources_last_week
FROM sources
`, (err, row) => {
if (err) reject(err)
else resolve(row)
})
})
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
const [
totalSources,
verifiedSources,
highRiskSources,
sourcesLastWeek
] = await Promise.all([
db.select({ count: count() }).from(schema.sources),
db.select({ count: count() }).from(schema.sources).where(eq(schema.sources.status, 'verified')),
db.select({ count: count() }).from(schema.sources).where(gte(schema.sources.riskLevel, 4)),
db.select({ count: count() }).from(schema.sources).where(gte(schema.sources.createdAt, weekAgo))
])
// Get API usage simulation
const apiUsage = {
@@ -32,7 +29,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
res.json({
database_stats: stats,
database_stats: {
total_sources: totalSources[0].count,
verified_sources: verifiedSources[0].count,
high_risk_sources: highRiskSources[0].count,
sources_last_week: sourcesLastWeek[0].count
},
api_performance: apiUsage,
last_updated: new Date().toISOString()
})
@@ -40,7 +42,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
} catch (error) {
console.error('Analytics error:', error)
res.status(500).json({ error: "Failed to fetch analytics" })
} finally {
db.close()
}
}