mirror of
https://github.com/System-End/scraps.git
synced 2026-04-19 22:05:09 +00:00
admin stuff
This commit is contained in:
parent
519abfe02f
commit
90209361b9
2 changed files with 42 additions and 3 deletions
|
|
@ -33,7 +33,7 @@ admin.get('/stats', async ({ headers, status }) => {
|
|||
return status(401, { error: 'Unauthorized' })
|
||||
}
|
||||
|
||||
const [usersCount, projectsCount, totalHoursResult] = await Promise.all([
|
||||
const [usersCount, projectsCount, totalHoursResult, pendingHoursResult] = await Promise.all([
|
||||
db.select({ count: sql<number>`count(*)` }).from(usersTable),
|
||||
db.select({ count: sql<number>`count(*)` })
|
||||
.from(projectsTable)
|
||||
|
|
@ -43,19 +43,29 @@ admin.get('/stats', async ({ headers, status }) => {
|
|||
.where(and(
|
||||
eq(projectsTable.status, 'shipped'),
|
||||
or(eq(projectsTable.deleted, 0), sql`${projectsTable.deleted} IS NULL`)
|
||||
)),
|
||||
db.select({ total: sql<number>`COALESCE(SUM(COALESCE(${projectsTable.hoursOverride}, ${projectsTable.hours})), 0)` })
|
||||
.from(projectsTable)
|
||||
.where(and(
|
||||
eq(projectsTable.status, 'waiting_for_review'),
|
||||
or(eq(projectsTable.deleted, 0), sql`${projectsTable.deleted} IS NULL`)
|
||||
))
|
||||
])
|
||||
|
||||
const totalUsers = Number(usersCount[0]?.count || 0)
|
||||
const totalProjects = Number(projectsCount[0]?.count || 0)
|
||||
const totalHours = Number(totalHoursResult[0]?.total || 0)
|
||||
const pendingHours = Number(pendingHoursResult[0]?.total || 0)
|
||||
const weightedGrants = Math.round(totalHours / 10 * 100) / 100
|
||||
const pendingWeightedGrants = Math.round(pendingHours / 10 * 100) / 100
|
||||
|
||||
return {
|
||||
totalUsers,
|
||||
totalProjects,
|
||||
totalHours: Math.round(totalHours * 10) / 10,
|
||||
weightedGrants
|
||||
weightedGrants,
|
||||
pendingHours: Math.round(pendingHours * 10) / 10,
|
||||
pendingWeightedGrants
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { Users, FolderKanban, Clock, Scale } from '@lucide/svelte';
|
||||
import { Users, FolderKanban, Clock, Scale, Hourglass } from '@lucide/svelte';
|
||||
import { getUser } from '$lib/auth-client';
|
||||
import { API_URL } from '$lib/config';
|
||||
|
||||
|
|
@ -10,6 +10,8 @@
|
|||
totalProjects: number;
|
||||
totalHours: number;
|
||||
weightedGrants: number;
|
||||
pendingHours: number;
|
||||
pendingWeightedGrants: number;
|
||||
}
|
||||
|
||||
let stats = $state<Stats | null>(null);
|
||||
|
|
@ -90,6 +92,33 @@
|
|||
<p class="text-xs text-gray-400">total hours ÷ 10</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4 rounded-2xl border-4 border-yellow-500 bg-yellow-50 p-6">
|
||||
<div
|
||||
class="flex h-16 w-16 items-center justify-center rounded-full bg-yellow-500 text-white"
|
||||
>
|
||||
<Hourglass size={32} />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold text-gray-500">pending hours</p>
|
||||
<p class="text-4xl font-bold text-yellow-600">{stats.pendingHours.toLocaleString()}h</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4 rounded-2xl border-4 border-yellow-500 bg-yellow-50 p-6">
|
||||
<div
|
||||
class="flex h-16 w-16 items-center justify-center rounded-full bg-yellow-500 text-white"
|
||||
>
|
||||
<Scale size={32} />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold text-gray-500">pending weighted grants</p>
|
||||
<p class="text-4xl font-bold text-yellow-600">
|
||||
{stats.pendingWeightedGrants.toLocaleString()}
|
||||
</p>
|
||||
<p class="text-xs text-gray-400">pending hours ÷ 10</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue