diff --git a/frontend/src/app/planner/[slug]/components/ProjectHeader.tsx b/frontend/src/app/planner/[slug]/components/ProjectHeader.tsx new file mode 100644 index 000000000..2f24e1005 --- /dev/null +++ b/frontend/src/app/planner/[slug]/components/ProjectHeader.tsx @@ -0,0 +1,108 @@ +import Box from '@mui/joy/Box' +import Chip from '@mui/joy/Chip' + +import Grid from '@mui/joy/Grid' +import Typography from '@mui/joy/Typography' +import { Project, ProjectStats } from '@/domain/Project' + +type ProjectHeaderProps = { + project: Project + projectStats: ProjectStats +} + +export const ProjectHeader = ({ project, projectStats }: ProjectHeaderProps) => { + return ( + + + {project.description} + + {project.isActive ? 'Active' : 'Inactive'} + + + + + + h + + } + > + {Number(projectStats.loggedHours)}/{Number(projectStats.plannedHours)} + + Actuals vs Planned + + + + h + + } + sx={{ alignItems: 'flex-start' }} + > + {Number(projectStats.plannedHours)}/{Number(project.estimatedHours)} + + Planned vs Sold + + + + {Number(projectStats.avgFTE)} + + + Average FTEs + + + + + ) +} diff --git a/frontend/src/app/planner/[slug]/page.tsx b/frontend/src/app/planner/[slug]/page.tsx index aa25bd3be..abb37a42e 100644 --- a/frontend/src/app/planner/[slug]/page.tsx +++ b/frontend/src/app/planner/[slug]/page.tsx @@ -1,21 +1,19 @@ -import { Breadcrumbs, Chip, Typography } from '@mui/joy' -import Link from 'next/link' - -import { getProjectAllocation } from '@/infra/projectAllocation/getProjectAllocation' -import { getProjects } from '@/infra/project/getProjects' +import { Breadcrumbs, Chip, Link, Typography } from '@mui/joy' +import { makeGetProject } from '@/infra/project/getProject' import { serverFetch } from '@/infra/lib/serverFetch' +import { Planner } from './components/Planner' +import { makeGetProjectStats } from '@/infra/project/getProjectStats' const getPageData = async (id: string) => { const apiClient = await serverFetch() - return await Promise.all([getProjectAllocation(apiClient, id), getProjects(apiClient)]) + const getProject = makeGetProject(apiClient) + const getProjectStats = makeGetProjectStats(apiClient) + return await Promise.all([getProject(id), getProjectStats(id)]) } export default async function Page({ params }: { params: { slug: string } }) { - const [projectAllocations, projects] = await getPageData(params.slug) - - const project = projects.find((p) => p.id === Number(params.slug)) - const projectStats = { plannedHours: projectAllocations?.plannedHours } + const [project, projectStats] = await getPageData(params.slug) return ( <> @@ -31,6 +29,16 @@ export default async function Page({ params }: { params: { slug: string } }) { Resource Planner + {project ? ( + + ) : ( +
+

Project not found.

+ + Please select a Project. + +
+ )} ) } diff --git a/frontend/src/domain/Project.ts b/frontend/src/domain/Project.ts index c6273cb54..11ac36941 100644 --- a/frontend/src/domain/Project.ts +++ b/frontend/src/domain/Project.ts @@ -12,3 +12,9 @@ export type Project = { projectType: string | null scheduleType: string | null } + +export type ProjectStats = { + loggedHours: number + plannedHours: number + avgFTE: number +} diff --git a/frontend/src/infra/project/getProjectStats.ts b/frontend/src/infra/project/getProjectStats.ts index cf0e47ce5..c93afb306 100644 --- a/frontend/src/infra/project/getProjectStats.ts +++ b/frontend/src/infra/project/getProjectStats.ts @@ -1,9 +1,10 @@ import { format } from 'date-fns' import { ApiClient } from '@/infra/lib/apiClient' +import { ProjectStats } from '@/domain/Project' export const makeGetProjectStats = (apiClient: ApiClient) => - async (projectId: string): Promise => { + async (projectId: string): Promise => { const today = new Date() // TODO start getting the date range dynamically const firstDayOfYear = new Date(today.getFullYear(), 0, 1)