diff --git a/src/components/employeeCard/EmployeeCard.tsx b/src/components/employeeCard/EmployeeCard.tsx
index f380657a9..0573f789e 100644
--- a/src/components/employeeCard/EmployeeCard.tsx
+++ b/src/components/employeeCard/EmployeeCard.tsx
@@ -13,12 +13,14 @@ export interface EmployeeCardProps {
employee: ChewbaccaEmployee;
employeePageSlug?: string;
language: string;
+ overrideTitle?: string;
}
export default function EmployeeCard({
employee,
employeePageSlug,
language,
+ overrideTitle,
}: EmployeeCardProps) {
const t = useTranslations("employee_card");
return (
@@ -51,16 +53,22 @@ export default function EmployeeCard({
- {employee.competences.map((competence) => (
-
- {t(competence)}
+ {overrideTitle ? (
+
+ {overrideTitle}
- ))}
+ ) : (
+ employee.competences.map((competence) => (
+
+ {t(competence)}
+
+ ))
+ )}
diff --git a/src/components/employeeCard/employeeCard.module.css b/src/components/employeeCard/employeeCard.module.css
index a068f41e1..ab5b04a37 100644
--- a/src/components/employeeCard/employeeCard.module.css
+++ b/src/components/employeeCard/employeeCard.module.css
@@ -9,6 +9,8 @@
flex-direction: column;
justify-content: space-between;
gap: 0.375rem;
+
+ overflow: hidden;
}
.contactInfo {
@@ -27,6 +29,12 @@
.employeePhone a {
color: currentColor;
}
+.employeeEmail a {
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
.employeeWrapper {
container-type: inline-size;
diff --git a/src/components/sections/contact-box/ContactBox.tsx b/src/components/sections/contact-box/ContactBox.tsx
index 57989e386..bb08c98e1 100644
--- a/src/components/sections/contact-box/ContactBox.tsx
+++ b/src/components/sections/contact-box/ContactBox.tsx
@@ -2,14 +2,11 @@ import { Suspense } from "react";
import { EmployeeCardSkeleton } from "src/components/employeeCard/EmployeeCard";
import Text from "src/components/text/Text";
-import { ChewbaccaEmployee } from "src/types/employees";
-import { fetchEmployeesByEmails } from "src/utils/employees";
import { ContactBoxSection } from "studio/lib/interfaces/pages";
-import { EMPLOYEE_PAGE_SLUG_QUERY } from "studio/lib/queries/siteSettings";
-import { loadStudioQuery } from "studio/lib/store";
+import { fetchEmployeesWithTags, getEmployeesPageSlug } from "./api";
import styles from "./contact-box.module.css";
-import ContactSelector, { EmployeeAndTag } from "./ContactSelector";
+import ContactSelector from "./ContactSelector";
export interface ContactBoxProps {
section: ContactBoxSection;
@@ -20,21 +17,13 @@ export default async function ContactBox({
section,
language,
}: ContactBoxProps) {
- const employeesPageRes = await loadStudioQuery<{ slug: string }>(
- EMPLOYEE_PAGE_SLUG_QUERY,
- {
- language,
- },
- );
- const employeesPageSlug = employeesPageRes.data.slug;
+ const employeesPageSlug = await getEmployeesPageSlug(language);
- const contactPoints = fetchEmployeesByEmails(
- section.contactPoints.map((contactPoint) => contactPoint.email),
- ).then((result) =>
- result.ok
- ? result.value.map((e) => employeeAndTag(e, section.contactPoints))
- : [],
- );
+ if (!employeesPageSlug) {
+ return null;
+ }
+
+ const contactPoints = fetchEmployeesWithTags(section.contactPoints);
const backgroundClass =
section.background === "light" ? styles["contactBox__inner--light"] : "";
@@ -68,20 +57,3 @@ export default async function ContactBox({
);
}
-
-function employeeAndTag(
- employee: ChewbaccaEmployee,
- contactPoints: ContactBoxSection["contactPoints"],
-): EmployeeAndTag {
- const tag =
- contactPoints.find((contactPoint) => contactPoint.email === employee.email)
- ?.tag ?? "";
- return {
- employee,
- tag,
- tagSlug: slugify(tag),
- };
-}
-function slugify(tag: string) {
- return tag.toLowerCase().replace(/ /g, "-");
-}
diff --git a/src/components/sections/contact-box/ContactSelector.tsx b/src/components/sections/contact-box/ContactSelector.tsx
index 01e988a7f..5bdb25905 100644
--- a/src/components/sections/contact-box/ContactSelector.tsx
+++ b/src/components/sections/contact-box/ContactSelector.tsx
@@ -4,18 +4,12 @@ import { use, useState } from "react";
import EmployeeCard from "src/components/employeeCard/EmployeeCard";
import { Tag } from "src/components/tag";
-import { ChewbaccaEmployee } from "src/types/employees";
import styles from "./contact-box.module.css";
-
-export type EmployeeAndTag = {
- employee: ChewbaccaEmployee;
- tag: string;
- tagSlug: string;
-};
+import { EmployeeAndMetadata } from "./types";
export type ContactSelectorProps = {
- contactPoints: Promise;
+ contactPoints: Promise;
employeesPageSlug: string;
language: string;
background?: "dark" | "light";
@@ -68,6 +62,7 @@ export default function ContactSelector({
employee={contactPoint.employee}
employeePageSlug={employeesPageSlug}
language={language}
+ overrideTitle={contactPoint.overrideTitle}
/>
))}
diff --git a/src/components/sections/contact-box/api.ts b/src/components/sections/contact-box/api.ts
new file mode 100644
index 000000000..b7da795f0
--- /dev/null
+++ b/src/components/sections/contact-box/api.ts
@@ -0,0 +1,58 @@
+import { ChewbaccaEmployee } from "src/types/employees";
+import { fetchEmployeesByEmails } from "src/utils/employees";
+import { ContactBoxSection } from "studio/lib/interfaces/pages";
+import { EMPLOYEE_PAGE_SLUG_QUERY } from "studio/lib/queries/siteSettings";
+import { loadStudioQuery } from "studio/lib/store";
+
+import { EmployeeAndMetadata } from "./types";
+
+export async function getEmployeesPageSlug(
+ language: string,
+): Promise {
+ const employeesPageRes = await loadStudioQuery<{ slug: string }>(
+ EMPLOYEE_PAGE_SLUG_QUERY,
+ {
+ language,
+ },
+ {
+ cache: "force-cache",
+ next: {
+ // Cache for 1 day.. Not likely to change (or is it???)
+ revalidate: 60 * 60 * 24,
+ },
+ },
+ );
+
+ return employeesPageRes.data?.slug;
+}
+
+export async function fetchEmployeesWithTags(
+ contactPoints: ContactBoxSection["contactPoints"],
+) {
+ const contacts = fetchEmployeesByEmails(
+ contactPoints.map((contactPoint) => contactPoint.email),
+ ).then((result) =>
+ result.ok
+ ? result.value.map((e) => employeeAndMetadata(e, contactPoints))
+ : [],
+ );
+ return contacts;
+}
+
+function employeeAndMetadata(
+ employee: ChewbaccaEmployee,
+ contactPoints: ContactBoxSection["contactPoints"],
+): EmployeeAndMetadata {
+ const metadata = contactPoints.find(
+ (contactPoint) => contactPoint.email === employee.email,
+ );
+ return {
+ employee,
+ tag: metadata?.tag ?? "",
+ tagSlug: slugify(metadata?.tag ?? ""),
+ overrideTitle: metadata?.overrideTitle ?? "",
+ };
+}
+function slugify(tag: string) {
+ return tag.toLowerCase().replace(/ /g, "-");
+}
diff --git a/src/components/sections/contact-box/types.ts b/src/components/sections/contact-box/types.ts
new file mode 100644
index 000000000..bf454fc68
--- /dev/null
+++ b/src/components/sections/contact-box/types.ts
@@ -0,0 +1,8 @@
+import { ChewbaccaEmployee } from "src/types/employees";
+
+export type EmployeeAndMetadata = {
+ employee: ChewbaccaEmployee;
+ tag: string;
+ tagSlug: string;
+ overrideTitle: string;
+};
diff --git a/studio/lib/interfaces/pages.ts b/studio/lib/interfaces/pages.ts
index f42b81e66..5c08a1420 100644
--- a/studio/lib/interfaces/pages.ts
+++ b/studio/lib/interfaces/pages.ts
@@ -106,6 +106,7 @@ export interface ContactBoxSection {
_key: string;
_type: string;
tag: string;
+ overrideTitle?: string;
email: string;
}[];
}
diff --git a/studio/lib/queries/pages.ts b/studio/lib/queries/pages.ts
index 7b05dc448..cdb02762c 100644
--- a/studio/lib/queries/pages.ts
+++ b/studio/lib/queries/pages.ts
@@ -74,7 +74,11 @@ const SECTIONS_FRAGMENT = groq`
},
_type == "contactBox" => {
"basicTitle": ${translatedFieldFragment("basicTitle")},
- "optionalSubtitle": ${translatedFieldFragment("optionalSubtitle")}
+ "optionalSubtitle": ${translatedFieldFragment("optionalSubtitle")},
+ "contactPoints": contactPoints[] {
+ ...,
+ "overrideTitle": ${translatedFieldFragment("overrideTitle")}
+ }
},
_type == "jobs" => {
"basicTitle": ${translatedFieldFragment("basicTitle")},
diff --git a/studio/schemas/objects/sections/contact-box.ts b/studio/schemas/objects/sections/contact-box.ts
index 0cfcd1771..12035fbdf 100644
--- a/studio/schemas/objects/sections/contact-box.ts
+++ b/studio/schemas/objects/sections/contact-box.ts
@@ -67,6 +67,13 @@ export const contactBox = defineField({
StringInputWithCharacterCount({ ...props, maxCount: 30 }),
},
}),
+ defineField({
+ name: "overrideTitle",
+ title: "Override title",
+ type: "internationalizedArrayString",
+ description:
+ "Specify a title for the contact point. If left empty, the employee's default title will be used.",
+ }),
defineField({
name: "email",
title: "Enter the email address for contact point",