import React, { useMemo } from 'react'; import { useApplications, useJobPostings, useStaff } from '@/lib/krowHooks'; import { AdminPage } from '@/components/admin/PageShell'; import { UiTreeRenderer } from '@/components/ui-tree/UiTreeRenderer'; import { useUiEditing } from '@/components/ui-tree/UiEditingProvider'; import { UiEditor } from '@/components/ui-editor/UiEditor'; import { composePage } from '@/lib/ui/composition'; import '@/components/ui-tree/nodeTypes'; import '@/pages/admin/analytics/nodes'; import { buildEfficiency, buildFunnel, buildInsights, buildTrend, byDepartment, byPosition, hiresWithFill, summarise, } from '@/lib/hiringRecords'; /** * Admin Analytics — how hiring is performing. * * This page and Hired History used to be the same component rendered twice with * a different title, which is why they read as duplicates: identical sections, * identical tabs, identical figures. They are not the same question. * * **Analytics asks "how is our hiring performing?"** — it is metrics, trends, * comparison and what to do about them. Every section here is an aggregate: a * rate, a distribution, a shape over time. No individual hire is named anywhere * on this page, because a name is a record and records are Hired History's job. * * It is also structurally different, not just differently coloured. Analytics is * one scrolling dashboard — the seven readings are meant to be taken together, * and a comparison you have to remember across a tab switch is not a comparison. * Hired History is a filtered record you search, so it keeps its controls and its * table. Same design system, same blue, same cards; different jobs. * * Both read `lib/hiringRecords.js`, so a total here and the same total there * cannot disagree. */ export default function AdminAnalytics() { const { data: staff = [], isLoading } = useStaff(); const { data: applications = [] } = useApplications(); const { data: postings = [] } = useJobPostings(); const hires = useMemo( () => hiresWithFill({ staff, applications, postings }), [staff, applications, postings] ); const summary = useMemo(() => summarise(hires), [hires]); const funnel = useMemo(() => buildFunnel(applications), [applications]); const trend = useMemo(() => buildTrend(hires), [hires]); const departments = useMemo(() => byDepartment(hires), [hires]); const positions = useMemo(() => byPosition(hires), [hires]); const efficiency = useMemo(() => buildEfficiency(hires), [hires]); const insights = useMemo( () => buildInsights({ hires, departments, positions, funnel, efficiency }), [hires, departments, positions, funnel, efficiency] ); const context = useMemo(() => ({ summary, funnel, trend, departments, positions, efficiency, insights, hires, isLoading, applications, }), [summary, funnel, trend, departments, positions, efficiency, insights, hires, isLoading, applications]); return ( ); } /** The composed page. */ function AnalyticsComposition({ context }) { const editing = useUiEditing(); const tree = editing?.tree || composePage('analytics').tree; return ; }