Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds option to override employee title for contact box #978

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions src/components/employeeCard/EmployeeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -51,16 +53,22 @@ export default function EmployeeCard({
</Text>

<div className={styles.employeeRole}>
{employee.competences.map((competence) => (
<Text
className={styles.employeeRoleDot}
type="labelRegular"
key={competence}
as="span"
>
{t(competence)}
{overrideTitle ? (
<Text type="labelRegular" as="span">
{overrideTitle}
</Text>
))}
) : (
employee.competences.map((competence) => (
<Text
className={styles.employeeRoleDot}
type="labelRegular"
key={competence}
as="span"
>
{t(competence)}
</Text>
))
)}
</div>

<Text type="bodyExtraSmall" className={styles.employeeEmail}>
Expand Down
8 changes: 8 additions & 0 deletions src/components/employeeCard/employeeCard.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
flex-direction: column;
justify-content: space-between;
gap: 0.375rem;

overflow: hidden;
}

.contactInfo {
Expand All @@ -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;
Expand Down
44 changes: 8 additions & 36 deletions src/components/sections/contact-box/ContactBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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"] : "";
Expand Down Expand Up @@ -68,20 +57,3 @@ export default async function ContactBox({
</section>
);
}

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, "-");
}
11 changes: 3 additions & 8 deletions src/components/sections/contact-box/ContactSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<EmployeeAndTag[]>;
contactPoints: Promise<EmployeeAndMetadata[]>;
employeesPageSlug: string;
language: string;
background?: "dark" | "light";
Expand Down Expand Up @@ -68,6 +62,7 @@ export default function ContactSelector({
employee={contactPoint.employee}
employeePageSlug={employeesPageSlug}
language={language}
overrideTitle={contactPoint.overrideTitle}
/>
</div>
))}
Expand Down
58 changes: 58 additions & 0 deletions src/components/sections/contact-box/api.ts
Original file line number Diff line number Diff line change
@@ -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<string | undefined> {
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, "-");
}
8 changes: 8 additions & 0 deletions src/components/sections/contact-box/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ChewbaccaEmployee } from "src/types/employees";

export type EmployeeAndMetadata = {
employee: ChewbaccaEmployee;
tag: string;
tagSlug: string;
overrideTitle: string;
};
1 change: 1 addition & 0 deletions studio/lib/interfaces/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export interface ContactBoxSection {
_key: string;
_type: string;
tag: string;
overrideTitle?: string;
email: string;
}[];
}
Expand Down
6 changes: 5 additions & 1 deletion studio/lib/queries/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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")},
Expand Down
7 changes: 7 additions & 0 deletions studio/schemas/objects/sections/contact-box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading