From 06b16064f8ea3292cc277fddc0b606e60445834b Mon Sep 17 00:00:00 2001 From: Daniel Noulet Date: Sun, 20 Sep 2026 08:36:54 +0200 Subject: [PATCH] feat: add recruitment dashboard Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- frontend/src/app/App.test.tsx | 29 +- frontend/src/app/AuthenticatedApp.tsx | 7 +- frontend/src/components/actions/Account.tsx | 2 +- frontend/src/components/layout/Logo.tsx | 2 +- frontend/src/components/layout/SideBar.tsx | 3 +- .../src/features/dashboard/DashboardPage.tsx | 232 +++++++++++ frontend/src/styles/global.css | 381 ++++++++++++++++++ 7 files changed, 647 insertions(+), 9 deletions(-) create mode 100644 frontend/src/features/dashboard/DashboardPage.tsx diff --git a/frontend/src/app/App.test.tsx b/frontend/src/app/App.test.tsx index 2d681eb..a5e0622 100644 --- a/frontend/src/app/App.test.tsx +++ b/frontend/src/app/App.test.tsx @@ -158,10 +158,33 @@ describe('Go Guess frontend', () => { await user.type(screen.getByLabelText(/password/i), 'admin123') await user.click(screen.getByRole('button', { name: /sign in/i })) - expect(await screen.findByRole('heading', { name: 'Job postings' })).toBeInTheDocument() - expect(await screen.findByRole('link', { name: 'Senior Go Engineer' })).toBeInTheDocument() + expect( + await screen.findByRole('heading', { name: 'Your hiring pipeline, at a glance.' }), + ).toBeInTheDocument() + expect(await screen.findByRole('link', { name: /Senior Go Engineer/ })).toBeInTheDocument() expect(sessionStorage.getItem('go-guess-token')).toBe('jwt-token') - expect(window.location.pathname).toBe('/jobs') + expect(window.location.pathname).toBe('/') + }) + + it('shows dashboard metrics, graphs, and links on the main page', async () => { + authenticate() + renderApp() + + expect( + await screen.findByRole('heading', { name: 'Your hiring pipeline, at a glance.' }), + ).toBeInTheDocument() + expect(screen.getByRole('link', { name: /Total jobs1/ })).toHaveAttribute('href', '/jobs') + expect(screen.getByRole('link', { name: /Participants1/ })).toHaveAttribute( + 'href', + '/participants', + ) + expect(screen.getByRole('meter', { name: 'Draft jobs' })).toHaveAttribute('aria-valuenow', '1') + expect(screen.getByRole('meter', { name: 'Go: 1 participants' })).toBeInTheDocument() + expect(screen.getByRole('link', { name: /Senior Go Engineer/ })).toHaveAttribute( + 'href', + '/jobs/7', + ) + expect(screen.getByRole('link', { name: 'Dashboard' })).toHaveAttribute('href', '/') }) it('returns to login when the active session expires', async () => { diff --git a/frontend/src/app/AuthenticatedApp.tsx b/frontend/src/app/AuthenticatedApp.tsx index c6df1d8..a9b4874 100644 --- a/frontend/src/app/AuthenticatedApp.tsx +++ b/frontend/src/app/AuthenticatedApp.tsx @@ -1,10 +1,11 @@ import { useState } from 'react' -import { Navigate, Route, Routes } from 'react-router-dom' +import { Route, Routes } from 'react-router-dom' import { authStorage } from '../api/client' import { AppFooter } from '../components/layout/AppFooter' import { GoGuessHeader } from '../components/layout/GoGuessHeader' import { WorkspaceUtilities } from '../components/layout/WorkspaceUtilities' import { NotFound } from '../components/ui/NotFound' +import { DashboardPage } from '../features/dashboard/DashboardPage' import { InboxPage, ScheduledInterviewPage } from '../features/interviews' import { CreateJobPage, JobDetailPage, JobsPage } from '../features/jobs' import { @@ -13,7 +14,7 @@ import { ParticipantsPage, } from '../features/participants' import { QuestionLibraryPage, QuestionPage } from '../features/questions' -import {CalendarPage, ProfilePage, UsersPage} from '../features/users' +import { CalendarPage, ProfilePage, UsersPage } from '../features/users' export function AuthenticatedApp({ onLogout }: { onLogout: () => void }) { const [open, setOpen] = useState(false) @@ -25,7 +26,7 @@ export function AuthenticatedApp({ onLogout }: { onLogout: () => void }) {
- } /> + } /> } /> } /> } /> diff --git a/frontend/src/components/actions/Account.tsx b/frontend/src/components/actions/Account.tsx index 4b9b51d..4b21720 100644 --- a/frontend/src/components/actions/Account.tsx +++ b/frontend/src/components/actions/Account.tsx @@ -34,7 +34,7 @@ export function useAuthSession() { function completeLogin() { setAuthenticated(true) setSessionExpired(false) - navigate('/jobs', { replace: true }) + navigate('/', { replace: true }) } function logout() { diff --git a/frontend/src/components/layout/Logo.tsx b/frontend/src/components/layout/Logo.tsx index b1d27dc..c2a868a 100644 --- a/frontend/src/components/layout/Logo.tsx +++ b/frontend/src/components/layout/Logo.tsx @@ -2,7 +2,7 @@ import { Link } from 'react-router-dom' function Logo() { return ( - + diff --git a/frontend/src/components/layout/SideBar.tsx b/frontend/src/components/layout/SideBar.tsx index 964bf78..d9e641e 100644 --- a/frontend/src/components/layout/SideBar.tsx +++ b/frontend/src/components/layout/SideBar.tsx @@ -1,7 +1,7 @@ import { BriefcaseBusiness, - CalendarDays, CircleHelp, + LayoutDashboard, LogOut, UserRound, UsersRound, @@ -30,6 +30,7 @@ export function SideBar({