-
-
+
{t("show")}{" "}
{filteredEmployees.length}
{" "}
- {t("of")}{" "}
- {employees.length}{" "}
- {t("consultants")}
+ {t("of")} {employees.length} {t("consultants")}
-
-
- {filteredEmployees.map((employee) => (
-
- ))}
+
+ {filteredEmployees.map((employee) => (
+
+ ))}
+
>
);
}
+
+function shuffleEmployees(employees: ChewbaccaEmployee[]) {
+ return employees.sort(() => Math.random() - 0.5);
+}
diff --git a/src/components/sections/employees/Employees.tsx b/src/components/sections/employees/Employees.tsx
index ef1d07748..1f0c51426 100644
--- a/src/components/sections/employees/Employees.tsx
+++ b/src/components/sections/employees/Employees.tsx
@@ -1,9 +1,9 @@
import { headers } from "next/headers";
+import { Suspense } from "react";
-import {
- domainFromEmail,
- fetchAllChewbaccaEmployees,
-} from "src/utils/employees";
+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";
import { EmployeesSection } from "studio/lib/interfaces/pages";
import { EMPLOYEE_PAGE_SLUG_QUERY } from "studio/lib/queries/siteSettings";
@@ -11,6 +11,7 @@ import { loadStudioQuery } from "studio/lib/store";
import EmployeeList from "./EmployeeList";
import styles from "./employees.module.css";
+
export interface EmployeesProps {
language: string;
section: EmployeesSection;
@@ -25,29 +26,32 @@ export default async function Employees({ language, section }: EmployeesProps) {
);
const employeesPageSlug = employeesPageRes.data.slug;
- const employeesResult = await fetchAllChewbaccaEmployees();
-
- if (!employeesResult.ok) {
- console.error("Failed to fetch employees: ", employeesResult.error);
- return;
- }
-
- const domain = domainFromHostname(headers().get("host"));
- const employees = employeesResult.value.filter(
- (employee) =>
- employee.email != null && domainFromEmail(employee.email) === domain,
- );
+ const countryTld = domainFromHostname(headers().get("host")).split(".")[1];
+ const employees = fetchAllChewbaccaEmployees(countryTld);
return (
-
{section.basicTitle}
-
+ {section.basicTitle}
+
+ }>
+
+
);
}
+
+function EmployeeListSkeleton() {
+ return (
+
+ {[...Array(4)].map((_, index) => (
+
+ ))}
+
+ );
+}
diff --git a/src/components/sections/employees/employees.module.css b/src/components/sections/employees/employees.module.css
index e51a5801b..01a0e1ebf 100644
--- a/src/components/sections/employees/employees.module.css
+++ b/src/components/sections/employees/employees.module.css
@@ -3,8 +3,19 @@
display: flex;
flex-direction: column;
align-items: center;
- margin: 5rem 0;
+ margin: 5rem 1rem;
flex-wrap: wrap;
+
+ max-width: var(--max-content-width-large);
+ margin: 0 auto;
+
+ background: var(--background-bg-light-secondary);
+ padding: 3rem;
+ border-radius: var(--radius-large, 24px);
+
+ @media (max-width: 375px) {
+ padding: 1.5rem;
+ }
}
.header {
@@ -42,12 +53,16 @@
.employeeFilterLabel {
flex-shrink: 0;
- min-width: 4.5rem;
- width: 4.5rem;
+ @media (min-width: 375px) {
+ min-width: 4.5rem;
+ width: 4.5rem;
+ }
}
-.employeeCountWrapper {
- width: 100%;
+.peopleCountWrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
}
.employeeCount {
@@ -59,7 +74,7 @@
}
.peopleContainer {
- display: flex;
- flex-wrap: wrap;
- gap: 1rem;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 1.5rem;
}
diff --git a/src/components/tag/index.tsx b/src/components/tag/index.tsx
new file mode 100644
index 000000000..18f16130e
--- /dev/null
+++ b/src/components/tag/index.tsx
@@ -0,0 +1,37 @@
+import Link from "next/link";
+
+import Text from "src/components/text/Text";
+
+import styles from "./tag.module.css";
+
+type TagInner =
+ | {
+ type: "button";
+ onClick?: () => void;
+ }
+ | {
+ type: "link";
+ href: string;
+ };
+
+type TagProps = {
+ active?: boolean;
+ text: string;
+} & TagInner;
+
+export const Tag = ({ text, active = false, ...props }: TagProps) => {
+ const className = `${styles.tag} ${active ? styles["tag--active"] : ""}`;
+ if (props.type === "button") {
+ return (
+
+ );
+ }
+
+ return (
+
+
{text}
+
+ );
+};
diff --git a/src/components/tag/tag.module.css b/src/components/tag/tag.module.css
new file mode 100644
index 000000000..bb02f5306
--- /dev/null
+++ b/src/components/tag/tag.module.css
@@ -0,0 +1,26 @@
+.tag {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.375rem 0.75rem;
+ border: 1px solid var(--text-primary, #222424);
+ background: transparent;
+ border-radius: 9999px;
+}
+
+.tag:hover {
+ background: var(--background-bg-light-secondary, #eaeaea);
+}
+.tag:active {
+ background: var(--background-bg-light-secondary, #eaeaea);
+}
+.tag:focus {
+ outline: 2px solid var(--surface-yellow, #ffd02f);
+}
+.tag--active {
+ background: var(--background-bg-dark, #2d2d2d);
+ color: var(--text-primary-light);
+}
+.tag--active:hover {
+ background: var(--background-bg-dark, #2d2d2d);
+}
diff --git a/src/components/text/Text.tsx b/src/components/text/Text.tsx
index cb8c83341..ce7ad46e3 100644
--- a/src/components/text/Text.tsx
+++ b/src/components/text/Text.tsx
@@ -79,13 +79,15 @@ const Text = ({
children,
id,
className,
+ as: asElement,
}: {
type?: TextType;
children: React.ReactNode;
id?: string;
+ as?: React.ElementType;
className?: string;
}) => {
- const Element = elementMap[type];
+ const Element = asElement ?? elementMap[type];
const generatedClassName = `${classMap[type]} ${className ?? ""}`;
return (
diff --git a/src/utils/employees.ts b/src/utils/employees.ts
index 1e0720140..38bdf5e25 100644
--- a/src/utils/employees.ts
+++ b/src/utils/employees.ts
@@ -8,10 +8,13 @@ import { domainFromHostname } from "./url";
const CHEWBACCA_URL = "https://chewie-webapp-ld2ijhpvmb34c.azurewebsites.net";
-export async function fetchAllChewbaccaEmployees(): Promise<
- Result
-> {
- const employeesRes = await fetch(new URL("employees", CHEWBACCA_URL));
+export async function fetchAllChewbaccaEmployees(
+ countryCode?: string,
+): Promise> {
+ const url = countryCode
+ ? `${CHEWBACCA_URL}/employees?country=${countryCode}`
+ : `${CHEWBACCA_URL}/employees`;
+ const employeesRes = await fetch(url);
if (!employeesRes.ok) {
return ResultError(
`Fetch returned status ${employeesRes.status} ${employeesRes.statusText}`,