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)