Skip to content

Commit

Permalink
Add page-content for interactivity (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasbjoralt authored Dec 4, 2023
1 parent 8f597b8 commit 6578d11
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 129 deletions.
15 changes: 4 additions & 11 deletions frontend/src/app/[organisation]/bemanning/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import StaffingSidebar from "@/components/StaffingSidebar";
import FilteredConsultantsList from "@/components/FilteredConsultantsList";
import { fetchWithToken } from "@/data/apiCallsWithToken";
import { Consultant, Department } from "@/types";
import { ConsultantFilterProvider } from "@/hooks/ConsultantFilterProvider";
import { parseYearWeekFromUrlString } from "@/data/urlUtils";
import InfoPillDescriptions from "@/components/InfoPillDescriptions";
import React from "react";
import { StaffingContent } from "@/pagecontent/StaffingContent";
import { fetchWithToken } from "@/data/apiCallsWithToken";

export default async function Bemanning({
params,
Expand Down Expand Up @@ -37,13 +36,7 @@ export default async function Bemanning({
consultants={consultants}
departments={departments}
>
<StaffingSidebar />

<div className="main p-4 w-full flex flex-col gap-8">
<h1>Bemanning</h1>
<FilteredConsultantsList />
<InfoPillDescriptions />
</div>
<StaffingContent />
</ConsultantFilterProvider>
);
}
4 changes: 2 additions & 2 deletions frontend/src/components/ActiveFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useDepartmentFilter } from "@/hooks/staffing/useDepartmentFilter";
import { useYearsXpFilter } from "@/hooks/staffing/useYearsXpFilter";
import { useAvailabilityFilter } from "@/hooks/staffing/useAvailabilityFilter";

export default function ActiveFilters() {
export default function ActiveFilters({ showIcon }: { showIcon: boolean }) {
const filterTextComponents: string[] = [];

const { searchFilter } = useUrlRouteFilter();
Expand Down Expand Up @@ -36,7 +36,7 @@ export default function ActiveFilters() {
<div className="h-4">
{filterSummaryText != "" && (
<div className="flex flex-row gap-3 text-primary items-center">
<Filter size="12" />{" "}
{showIcon && <Filter size="12" />}
<p className="small-medium"> {filterSummaryText} </p>
</div>
)}
Expand Down
182 changes: 85 additions & 97 deletions frontend/src/components/FilteredConsultantsList.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
"use client";
import ConsultantRows from "./ConsultantRow";
import ActiveFilters from "./ActiveFilters";
import WeekSelection from "@/components/WeekSelection";
import { isCurrentWeek } from "@/hooks/staffing/dateTools";
import { useConsultantsFilter } from "@/hooks/staffing/useConsultantsFilter";
import { useUrlRouteFilter } from "@/hooks/staffing/useUrlRouteFilter";
import InfoPill from "./InfoPill";
import { Calendar } from "react-feather";
import StaffingSums from "./StaffingSums";

export default function FilteredConsultantList() {
export default function StaffingTable() {
const {
filteredConsultants,
weeklyTotalBillable,
Expand All @@ -20,103 +18,93 @@ export default function FilteredConsultantList() {
const { weekSpan } = useUrlRouteFilter();

return (
<div className="flex flex-col gap-8">
<div className="flex flex-row justify-between items-center">
<ActiveFilters />
<WeekSelection />
</div>
<table
className={`w-full ${
weekSpan > 23
? "min-w-[1400px]"
: weekSpan > 11
? "min-w-[850px]"
: "min-w-[700px]"
} table-fixed`}
>
<colgroup>
<col span={1} className="w-14" />
<col span={1} className="w-[190px]" />
{filteredConsultants
.at(0)
?.bookings?.map((booking, index) => <col key={index} span={1} />)}
</colgroup>
<thead>
<tr className="sticky -top-6 bg-white z-10">
<th colSpan={2} className="pt-3 pl-2 -left-2 relative bg-white">
<div className="flex flex-row gap-3 pb-4 items-center">
<p className="normal-medium ">Konsulenter</p>
<p className="text-primary small-medium rounded-full bg-primary/5 px-2 py-1">
{filteredConsultants?.length}
</p>
</div>
</th>
{filteredConsultants.at(0)?.bookings?.map((booking) => (
<th key={booking.weekNumber} className=" px-2 py-1 pt-3 ">
<div className="flex flex-col gap-1">
{isCurrentWeek(booking.weekNumber, booking.year) ? (
<div className="flex flex-row gap-2 items-center justify-end">
{booking.bookingModel.totalHolidayHours > 0 && (
<InfoPill
text={booking.bookingModel.totalHolidayHours.toFixed(
1,
)}
icon={<Calendar size="12" />}
colors={"bg-holiday text-holiday_darker w-fit"}
variant={weekSpan < 24 ? "wide" : "medium"}
/>
)}
<div className="h-2 w-2 rounded-full bg-primary" />

<p className="normal-medium text-right">
{booking.weekNumber}
</p>
</div>
) : (
<div
className={`flex justify-end ${
weekSpan >= 26
? "min-h-[30px] flex-col mb-2 gap-[1px] items-end"
: "flex-row gap-2"
}`}
>
{booking.bookingModel.totalHolidayHours > 0 && (
<InfoPill
text={booking.bookingModel.totalHolidayHours.toFixed(
1,
)}
icon={<Calendar size="12" />}
colors={"bg-holiday text-holiday_darker w-fit"}
variant={weekSpan < 24 ? "wide" : "medium"}
/>
)}
<p className="normal text-right">{booking.weekNumber}</p>
</div>
)}
<table
className={`w-full ${
weekSpan > 23
? "min-w-[1400px]"
: weekSpan > 11
? "min-w-[850px]"
: "min-w-[700px]"
} table-fixed`}
>
<colgroup>
<col span={1} className="w-14" />
<col span={1} className="w-[190px]" />
{filteredConsultants
.at(0)
?.bookings?.map((booking, index) => <col key={index} span={1} />)}
</colgroup>
<thead>
<tr className="sticky -top-6 bg-white z-10">
<th colSpan={2} className="pt-3 pl-2 -left-2 relative bg-white">
<div className="flex flex-row gap-3 pb-4 items-center">
<p className="normal-medium ">Konsulenter</p>
<p className="text-primary small-medium rounded-full bg-primary/5 px-2 py-1">
{filteredConsultants?.length}
</p>
</div>
</th>
{filteredConsultants.at(0)?.bookings?.map((booking) => (
<th key={booking.weekNumber} className=" px-2 py-1 pt-3 ">
<div className="flex flex-col gap-1">
{isCurrentWeek(booking.weekNumber, booking.year) ? (
<div className="flex flex-row gap-2 items-center justify-end">
{booking.bookingModel.totalHolidayHours > 0 && (
<InfoPill
text={booking.bookingModel.totalHolidayHours.toFixed(1)}
icon={<Calendar size="12" />}
colors={"bg-holiday text-holiday_darker w-fit"}
variant={weekSpan < 24 ? "wide" : "medium"}
/>
)}
<div className="h-2 w-2 rounded-full bg-primary" />

<p
className={`xsmall text-black/75 text-right ${
weekSpan >= 26 && "hidden"
<p className="normal-medium text-right">
{booking.weekNumber}
</p>
</div>
) : (
<div
className={`flex justify-end ${
weekSpan >= 26
? "min-h-[30px] flex-col mb-2 gap-[1px] items-end"
: "flex-row gap-2"
}`}
>
{booking.dateString}
</p>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{filteredConsultants?.map((consultant) => (
<ConsultantRows key={consultant.id} consultant={consultant} />
{booking.bookingModel.totalHolidayHours > 0 && (
<InfoPill
text={booking.bookingModel.totalHolidayHours.toFixed(1)}
icon={<Calendar size="12" />}
colors={"bg-holiday text-holiday_darker w-fit"}
variant={weekSpan < 24 ? "wide" : "medium"}
/>
)}
<p className="normal text-right">{booking.weekNumber}</p>
</div>
)}

<p
className={`xsmall text-black/75 text-right ${
weekSpan >= 26 && "hidden"
}`}
>
{booking.dateString}
</p>
</div>
</th>
))}
</tbody>
<StaffingSums
weeklyTotalBillable={weeklyTotalBillable}
weeklyTotalBillableAndOffered={weeklyTotalBillableAndOffered}
weeklyInvoiceRates={weeklyInvoiceRates}
/>
</table>
</div>
</tr>
</thead>
<tbody>
{filteredConsultants?.map((consultant) => (
<ConsultantRows key={consultant.id} consultant={consultant} />
))}
</tbody>
<StaffingSums
weeklyTotalBillable={weeklyTotalBillable}
weeklyTotalBillableAndOffered={weeklyTotalBillableAndOffered}
weeklyInvoiceRates={weeklyInvoiceRates}
/>
</table>
);
}
30 changes: 11 additions & 19 deletions frontend/src/components/StaffingSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
"use client";
import { useState } from "react";
import DepartmentFilter from "./DepartmentFilter";
import AvailabilityFilter from "./AvailabilityFilter";
import SearchBarComponent from "./SearchBarComponent";
import { ArrowLeft, Filter } from "react-feather";
import { ArrowLeft } from "react-feather";
import ExperienceFilter from "./ExperienceFilter";

export default function StaffingSidebar() {
const [isSidebarHidden, setIsSidebarHidden] = useState(true);

// @ts-ignore
export default function StaffingSidebar({
isSidebarOpen,
closeSidebar,
}: {
isSidebarOpen: boolean;
closeSidebar: () => void;
}) {
return (
<div className="sidebar z-10">
{!isSidebarHidden ? (
{isSidebarOpen && (
<div className=" bg-primary/5 h-full flex flex-col gap-6 p-4 w-[300px]">
<div className="flex flex-row justify-between items-center">
<h1 className="">Filter</h1>
<button
onClick={() => setIsSidebarHidden(true)}
onClick={closeSidebar}
className="p-2 text-primary rounded-lg hover:bg-primary hover:bg-opacity-10"
>
<ArrowLeft className="text-primary" size="24" />
Expand All @@ -27,18 +31,6 @@ export default function StaffingSidebar() {
<DepartmentFilter />
<ExperienceFilter />
</div>
) : (
<>
<button
onClick={() => setIsSidebarHidden(false)}
className="bg-primary/5 rounded-r p-2 mt-16 hover:bg-primary hover:bg-opacity-20"
>
<Filter className="text-primary" size="20" />
</button>
<div style={{ width: "0px", height: "0px" }}>
<SearchBarComponent hidden />
</div>
</>
)}
</div>
);
Expand Down
44 changes: 44 additions & 0 deletions frontend/src/pagecontent/StaffingContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use client";

import StaffingSidebar from "@/components/StaffingSidebar";
import FilteredConsultantsList from "@/components/FilteredConsultantsList";
import InfoPillDescriptions from "@/components/InfoPillDescriptions";
import { useState } from "react";
import IconActionButton from "@/components/Buttons/IconActionButton";
import { Filter } from "react-feather";
import ActiveFilters from "@/components/ActiveFilters";
import WeekSelection from "@/components/WeekSelection";

export function StaffingContent() {
const [isSideBarOpen, setIsSidebarOpen] = useState<boolean>(false);

return (
<>
<StaffingSidebar
isSidebarOpen={isSideBarOpen}
closeSidebar={() => setIsSidebarOpen(false)}
/>

<div className="main p-4 w-full flex flex-col gap-8">
<h1>Bemanning</h1>

<div className="flex flex-row justify-between items-center">
<div className="flex flex-row items-center gap-3">
{!isSideBarOpen && (
<IconActionButton
variant={"secondary"}
icon={<Filter />}
onClick={() => setIsSidebarOpen(true)}
/>
)}
<ActiveFilters showIcon={isSideBarOpen} />
</div>

<WeekSelection />
</div>
<FilteredConsultantsList />
<InfoPillDescriptions />
</div>
</>
);
}

0 comments on commit 6578d11

Please sign in to comment.