diff --git a/messages/en.json b/messages/en.json
index 0f562f822..4583d4a0e 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -35,6 +35,7 @@
"Design": "Design",
"Utvikling": "Development",
"Administasjon": "Administration",
- "field": "Field"
+ "field": "Field",
+ "showMore": "Show all"
}
}
diff --git a/messages/no.json b/messages/no.json
index 37abbeeef..9c3bdf35a 100644
--- a/messages/no.json
+++ b/messages/no.json
@@ -35,6 +35,7 @@
"Design": "Design",
"Utvikling": "Utvikling",
"Administasjon": "Administrasjon",
- "field": "Fag"
+ "field": "Fag",
+ "showMore": "Vis alle"
}
}
diff --git a/messages/se.json b/messages/se.json
index 0436b4dea..8a549f44a 100644
--- a/messages/se.json
+++ b/messages/se.json
@@ -35,6 +35,7 @@
"Design": "Design",
"Utvikling": "Utveckling",
"Administasjon": "Administration",
- "field": "Fält"
+ "field": "Fält",
+ "showMore": "Vis alla"
}
}
diff --git a/public/_assets/arrow-down.svg b/public/_assets/arrow-down.svg
new file mode 100644
index 000000000..4d5727fd9
--- /dev/null
+++ b/public/_assets/arrow-down.svg
@@ -0,0 +1,6 @@
+
diff --git a/src/components/employeeCard/EmployeeCard.tsx b/src/components/employeeCard/EmployeeCard.tsx
index 056c5b765..9d69236db 100644
--- a/src/components/employeeCard/EmployeeCard.tsx
+++ b/src/components/employeeCard/EmployeeCard.tsx
@@ -24,53 +24,52 @@ export default function EmployeeCard({
employee.name &&
employee.email && (
-
-
-
-
-
-
-
-
-
- {employee.name}
-
-
-
-
- {employee.competences.map((competence) => (
-
- {competence}
-
- ))}
-
+
+
+
+
+
+
)
diff --git a/src/components/sections/employees/EmployeeList.tsx b/src/components/sections/employees/EmployeeList.tsx
index 4e8a73a76..19b2217f6 100644
--- a/src/components/sections/employees/EmployeeList.tsx
+++ b/src/components/sections/employees/EmployeeList.tsx
@@ -1,7 +1,10 @@
"use client";
+import Image from "next/image";
+import Link from "next/link";
+import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useTranslations } from "next-intl";
-import { use, useState } from "react";
+import { use, useState, useTransition } from "react";
import EmployeeCard from "src/components/employeeCard/EmployeeCard";
import { Tag } from "src/components/tag";
@@ -10,6 +13,7 @@ import { ChewbaccaEmployee, Competence } from "src/types/employees";
import { Result } from "studio/utils/result";
import styles from "./employees.module.css";
+import { EmployeeListSkeleton } from "./EmployeeSkeleton";
const competences: Competence[] = [
"Utvikling",
@@ -29,6 +33,8 @@ interface EmployeeFilters {
locationFilter: string | null;
}
+const DEFAULT_LIMIT = 4 * 2;
+
export default function EmployeeList({
employees: employeesPromise,
language,
@@ -39,6 +45,14 @@ export default function EmployeeList({
const [filteredEmployees, setFilteredEmployees] =
useState
(employees);
+ const {
+ showShowMoreButton,
+ isShowMorePending,
+ limitedEmployees,
+ showMoreHandler,
+ showMoreHref,
+ } = useShowAll(filteredEmployees);
+
const locations = Array.from(new Set(employees.map((e) => e.officeName)));
const t = useTranslations("employee_card");
@@ -95,7 +109,7 @@ export default function EmployeeList({
text={t("all")}
/>
- {competences.map((competence) => {
+ {sortCompetenceAlphabetically(competences).map((competence) => {
const active = employeeFilters.competenceFilter == competence;
return (
- {locations.map((location) => {
+ {sortAlphabetically(locations).map((location) => {
if (!location) return null;
const active = employeeFilters.locationFilter == location;
return (
@@ -147,7 +161,7 @@ export default function EmployeeList({
- {filteredEmployees.map((employee) => (
+ {limitedEmployees.map((employee) => (
))}
+ {isShowMorePending && }
+
+ {showShowMoreButton && (
+
+ )}
>
);
}
+
+function ShowMoreButton({
+ showMoreHandler,
+ showMoreHref,
+}: {
+ showMoreHandler: () => void;
+ showMoreHref: string;
+}) {
+ const t = useTranslations("employee_card");
+
+ // @TODO Replace with Button component when actually implemented
+ return (
+
+
+ {t("showMore")}{" "}
+
+
+
+ );
+}
+
+function useShowAll(filteredEmployees: ChewbaccaEmployee[]) {
+ const [isPending, startTransition] = useTransition();
+
+ const currentPath = usePathname();
+ const searchParams = useSearchParams();
+ const { replace } = useRouter();
+ const limitEmployees = !searchParams.has("showAll");
+ const limitedEmployees = limitEmployees
+ ? filteredEmployees.slice(0, DEFAULT_LIMIT)
+ : filteredEmployees;
+
+ const showMoreHandler = () =>
+ startTransition(() => {
+ replace(`${currentPath}?showAll`);
+ });
+
+ return {
+ limitedEmployees,
+ showMoreHandler,
+ isShowMorePending: isPending,
+ showShowMoreButton:
+ limitEmployees && !isPending && filteredEmployees.length > DEFAULT_LIMIT,
+ showMoreHref: `${currentPath}?showAll`,
+ };
+}
+
+function sortAlphabetically(filter: (string | null | undefined)[]) {
+ return filter.sort((a, b) => a?.localeCompare(b ?? "") ?? 0);
+}
+
+function sortCompetenceAlphabetically(competences: Competence[]) {
+ return competences.sort((a, b) => a?.localeCompare(b ?? "") ?? 0);
+}
diff --git a/src/components/sections/employees/EmployeeSkeleton.tsx b/src/components/sections/employees/EmployeeSkeleton.tsx
new file mode 100644
index 000000000..dbed3219b
--- /dev/null
+++ b/src/components/sections/employees/EmployeeSkeleton.tsx
@@ -0,0 +1,13 @@
+import { EmployeeCardSkeleton } from "src/components/employeeCard/EmployeeCard";
+
+import styles from "./employees.module.css";
+
+export function EmployeeListSkeleton() {
+ return (
+
+ {[...Array(4)].map((_, index) => (
+
+ ))}
+
+ );
+}
diff --git a/src/components/sections/employees/Employees.tsx b/src/components/sections/employees/Employees.tsx
index 6bf7d83f7..6559b3cc1 100644
--- a/src/components/sections/employees/Employees.tsx
+++ b/src/components/sections/employees/Employees.tsx
@@ -1,7 +1,6 @@
import { headers } from "next/headers";
import { Suspense } from "react";
-import { EmployeeCardSkeleton } from "src/components/employeeCard/EmployeeCard";
import Text from "src/components/text/Text";
import { fetchAllChewbaccaEmployees } from "src/utils/employees";
import { domainFromHostname } from "src/utils/url";
@@ -11,6 +10,7 @@ import { loadStudioQuery } from "studio/lib/store";
import EmployeeList from "./EmployeeList";
import styles from "./employees.module.css";
+import { EmployeeListSkeleton } from "./EmployeeSkeleton";
export interface EmployeesProps {
language: string;
@@ -47,13 +47,3 @@ export default async function Employees({ language, section }: EmployeesProps) {
);
}
-
-function EmployeeListSkeleton() {
- return (
-