Spaces:
Sleeping
Sleeping
| import { Search, Shield, Users } from 'lucide-react'; | |
| import { useMemo } from 'react'; | |
| import { Badge } from '@/components/ui/badge'; | |
| import { | |
| Card, | |
| CardDescription, | |
| CardHeader, | |
| CardTitle, | |
| } from '@/components/ui/card'; | |
| import { isUserActive } from '@/lib/admin'; | |
| import type { AdminUser, RagConfig } from '@/types/admin'; | |
| export function AdminOverviewCards({ | |
| ragConfig, | |
| users = [], | |
| }: { | |
| ragConfig?: RagConfig | null; | |
| users?: AdminUser[]; | |
| }) { | |
| const userStats = useMemo(() => { | |
| const activeCount = users.filter(isUserActive).length; | |
| const adminCount = users.filter((user) => user.role === 'admin').length; | |
| return { | |
| activeCount, | |
| adminCount, | |
| total: users.length, | |
| }; | |
| }, [users]); | |
| return ( | |
| <section className="grid gap-4 md:grid-cols-3"> | |
| <Card className="border-(--lecturer-border) bg-(--lecturer-surface)"> | |
| <CardHeader className="gap-3"> | |
| <div className="flex items-center justify-between gap-3"> | |
| <span className="rounded-xl bg-[var(--lecturer-primary-soft)] p-3 text-[var(--lecturer-primary)]"> | |
| <Shield className="size-5" /> | |
| </span> | |
| <Badge variant="outline">LLM</Badge> | |
| </div> | |
| <div> | |
| <CardDescription>Model aktif</CardDescription> | |
| <CardTitle className="mt-2 text-2xl"> | |
| {ragConfig?.llm_config?.active_model ?? '-'} | |
| </CardTitle> | |
| </div> | |
| </CardHeader> | |
| </Card> | |
| <Card className="border-(--lecturer-border) bg-(--lecturer-surface)"> | |
| <CardHeader className="gap-3"> | |
| <div className="flex items-center justify-between gap-3"> | |
| <span className="rounded-xl bg-[var(--lecturer-primary-soft)] p-3 text-[var(--lecturer-primary)]"> | |
| <Search className="size-5" /> | |
| </span> | |
| <Badge variant="outline">Retrieval</Badge> | |
| </div> | |
| <div> | |
| <CardDescription>Top K</CardDescription> | |
| <CardTitle className="mt-2 text-2xl"> | |
| {ragConfig?.retrieval?.top_k ?? '-'} | |
| </CardTitle> | |
| </div> | |
| </CardHeader> | |
| </Card> | |
| <Card className="border-(--lecturer-border) bg-(--lecturer-surface)"> | |
| <CardHeader className="gap-3"> | |
| <div className="flex items-center justify-between gap-3"> | |
| <span className="rounded-xl bg-[var(--lecturer-primary-soft)] p-3 text-[var(--lecturer-primary)]"> | |
| <Users className="size-5" /> | |
| </span> | |
| <Badge variant="outline">User</Badge> | |
| </div> | |
| <div> | |
| <CardDescription>User aktif</CardDescription> | |
| <CardTitle className="mt-2 text-2xl"> | |
| {userStats.activeCount}/{userStats.total} | |
| </CardTitle> | |
| </div> | |
| </CardHeader> | |
| </Card> | |
| </section> | |
| ); | |
| } | |