diff --git a/src/components/buttons/Button.tsx b/src/components/buttons/Button.tsx
index 75edfd9f9..1a0b77f68 100644
--- a/src/components/buttons/Button.tsx
+++ b/src/components/buttons/Button.tsx
@@ -2,8 +2,8 @@ import React from "react";
import styles from "./button.module.css";
-type ButtonType = "primary" | "secondary";
-type ButtonSize = "large" | "small";
+type ButtonType = "primary" | "secondary" | "secondaryFilled";
+type ButtonSize = "large" | "small" | "extraSmall";
interface IButton {
size?: ButtonSize;
@@ -18,11 +18,13 @@ interface IButton {
const sizeClassMap: { [key in ButtonSize]: string } = {
large: styles.large,
small: styles.small,
+ extraSmall: styles.extraSmall,
};
const typeClassMap: { [key in ButtonType]: string } = {
primary: styles.primary,
secondary: styles.secondary,
+ secondaryFilled: styles.secondaryFilled,
};
const Button = ({
diff --git a/src/components/buttons/button.module.css b/src/components/buttons/button.module.css
index 06ef56415..8ff950baf 100644
--- a/src/components/buttons/button.module.css
+++ b/src/components/buttons/button.module.css
@@ -37,6 +37,17 @@
}
}
+.extraSmall {
+ composes: button;
+ padding: 0.375rem 1.25rem;
+ font-size: 1rem;
+ font-weight: 400;
+
+ @media (min-width: 1024px) {
+ font-size: 1.125rem;
+ }
+}
+
.primary {
background: var(--primary-dark);
color: var(--primary-white);
@@ -65,6 +76,20 @@
}
}
+.secondaryFilled {
+ background: var(--primary-black);
+ color: var(--primary-white);
+ border: 1px solid var(--primary-black);
+
+ &:hover {
+ background: var(--primary-black-darker);
+ }
+
+ &:active {
+ background: var(--primary-black-darker);
+ }
+}
+
.back {
composes: secondary;
diff --git a/src/components/consultantCard/ConsultantCard.tsx b/src/components/consultantCard/ConsultantCard.tsx
new file mode 100644
index 000000000..046cde83a
--- /dev/null
+++ b/src/components/consultantCard/ConsultantCard.tsx
@@ -0,0 +1,74 @@
+import Image from "next/image";
+import Link from "next/link";
+
+import CustomLink from "src/components/link/CustomLink";
+import { ChewbaccaEmployee } from "src/types/employees";
+import { aliasFromEmail } from "src/utils/employees";
+import { LinkType } from "studio/lib/interfaces/navigation";
+
+import styles from "./consultantCard.module.css";
+
+export interface ConsultantCardProps {
+ currentLanguage: string;
+ consultant: ChewbaccaEmployee;
+ employeePageSlug?: string;
+}
+
+export default function ConsultantCard({
+ currentLanguage,
+ consultant,
+ employeePageSlug,
+}: ConsultantCardProps) {
+ const title =
{consultant.name}
;
+ return (
+ consultant.imageThumbUrl &&
+ consultant.name &&
+ consultant.email && (
+
+
+
+
+
+ {employeePageSlug !== undefined ? (
+
+ {title}
+
+ ) : (
+ title
+ )}
+ {consultant.officeName && (
+
{consultant.officeName}
+ )}
+ {consultant.email && (
+
{consultant.email}
+ )}
+ {consultant.telephone && (
+
{consultant.telephone}
+ )}
+ {employeePageSlug && (
+
+ )}
+
+
+ )
+ );
+}
diff --git a/src/components/consultantCard/consultantCard.module.css b/src/components/consultantCard/consultantCard.module.css
new file mode 100644
index 000000000..b9df285ca
--- /dev/null
+++ b/src/components/consultantCard/consultantCard.module.css
@@ -0,0 +1,43 @@
+.consultant {
+ display: flex;
+ width: 100%;
+ gap: 1rem;
+}
+
+.consultantImage {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background-color: var(--primary-black);
+ border-radius: 12px;
+ height: 125px;
+ width: 50%;
+ padding: 1rem;
+ position: relative;
+}
+
+.consultantInfo {
+ display: flex;
+ flex-direction: column;
+ width: 50%;
+ gap: 0.5rem;
+}
+
+.consultantName {
+ color: var(--primary-black);
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.consultantRole {
+ color: var(--primary-black);
+ font-size: 16px;
+ font-weight: 300;
+}
+
+.consultantEmail,
+.consultantTelephone {
+ color: var(--primary-black);
+ font-size: 14px;
+ font-weight: 300;
+}
diff --git a/src/components/customerCases/customerCase/CustomerCase.tsx b/src/components/customerCases/customerCase/CustomerCase.tsx
index a1ae4e072..7e55c09d2 100644
--- a/src/components/customerCases/customerCase/CustomerCase.tsx
+++ b/src/components/customerCases/customerCase/CustomerCase.tsx
@@ -6,6 +6,7 @@ import {
Delivery,
} from "studioShared/lib/interfaces/customerCases";
+import ContactInformation from "./contactInformation/ContactInformation";
import styles from "./customerCase.module.css";
import FeaturedCases from "./featuredCases/FeaturedCases";
import CustomerCaseConsultants from "./sections/customerCaseConsultants/CustomerCaseConsultants";
@@ -129,6 +130,7 @@ export default async function CustomerCase({
customerCasesPath={customerCasesPagePath}
/>
)}
+
);
diff --git a/src/components/customerCases/customerCase/contactInformation/ContactInformation.tsx b/src/components/customerCases/customerCase/contactInformation/ContactInformation.tsx
new file mode 100644
index 000000000..71651ad57
--- /dev/null
+++ b/src/components/customerCases/customerCase/contactInformation/ContactInformation.tsx
@@ -0,0 +1,75 @@
+import Text from "src/components/text/Text";
+import { fetchEmployeesByEmails } from "src/utils/employees";
+import { CompanyLocation } from "studio/lib/interfaces/companyDetails";
+import { COMPANY_LOCATIONS_QUERY } from "studio/lib/queries/admin";
+import { EMPLOYEE_PAGE_SLUG_QUERY } from "studio/lib/queries/siteSettings";
+import { loadStudioQuery } from "studio/lib/store";
+
+import styles from "./contactInformation.module.css";
+import ContactSelector, {
+ ContactByLocationMap,
+} from "./contactSelector/ContactSelector";
+
+interface ContactInformationProps {
+ language: string;
+}
+
+async function fetchContactByLocationMap(
+ companyLocations: CompanyLocation[],
+): Promise {
+ const contactByLocation: ContactByLocationMap = {};
+ for (const location of companyLocations) {
+ if (
+ location.contactPerson === undefined ||
+ location.contactPerson.length === 0
+ ) {
+ continue;
+ }
+ const contactRes = await fetchEmployeesByEmails([location.contactPerson]);
+ if (!contactRes.ok || contactRes.value.length === 0) {
+ continue;
+ }
+ contactByLocation[location._id] = contactRes.value[0];
+ }
+ return contactByLocation;
+}
+
+export default async function ContactInformation({
+ language,
+}: ContactInformationProps) {
+ const employeePageSlug = (
+ await loadStudioQuery<{ slug: string } | null>(EMPLOYEE_PAGE_SLUG_QUERY, {
+ language,
+ })
+ ).data?.slug;
+ const companyLocations = (
+ await loadStudioQuery(COMPANY_LOCATIONS_QUERY, {})
+ ).data;
+ const contactByLocation = await fetchContactByLocationMap(companyLocations);
+ const locationIdsWithContact = Object.keys(contactByLocation);
+ const locationsWithContact = companyLocations.filter((location) =>
+ locationIdsWithContact.includes(location._id),
+ );
+
+ return (
+
+
+
+ {/* TODO: translation */}
+
+ Trenger du hjelp med lignende eller noe helt annet?
+
+ Kontakt salg!
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/customerCases/customerCase/contactInformation/contactInformation.module.css b/src/components/customerCases/customerCase/contactInformation/contactInformation.module.css
new file mode 100644
index 000000000..e86f6bf9c
--- /dev/null
+++ b/src/components/customerCases/customerCase/contactInformation/contactInformation.module.css
@@ -0,0 +1,32 @@
+.wrapper {
+ display: flex;
+ flex-direction: column;
+ margin: 4rem 0;
+
+ @media (min-width: 1024px) {
+ align-items: center;
+ }
+}
+
+.content {
+ display: flex;
+ flex-direction: row;
+ gap: 1rem;
+ max-width: 960px;
+
+ @media (max-width: 1024px) {
+ flex-direction: column;
+ gap: 2rem;
+ }
+}
+
+.titleSection {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.contactSection {
+ display: flex;
+ gap: 1.5rem;
+}
diff --git a/src/components/customerCases/customerCase/contactInformation/contactSelector/ContactSelector.tsx b/src/components/customerCases/customerCase/contactInformation/contactSelector/ContactSelector.tsx
new file mode 100644
index 000000000..479bb362e
--- /dev/null
+++ b/src/components/customerCases/customerCase/contactInformation/contactSelector/ContactSelector.tsx
@@ -0,0 +1,68 @@
+"use client";
+
+import { useState } from "react";
+
+import Button from "src/components/buttons/Button";
+import ConsultantCard from "src/components/consultantCard/ConsultantCard";
+import { ChewbaccaEmployee } from "src/types/employees";
+import { CompanyLocation } from "studio/lib/interfaces/companyDetails";
+
+import styles from "./contactSelector.module.css";
+
+export type ContactByLocationMap = {
+ [locationId: string]: ChewbaccaEmployee;
+};
+
+export interface ContactSelectorProps {
+ language: string;
+ locations: CompanyLocation[];
+ contactByLocation: ContactByLocationMap;
+ employeePageSlug?: string;
+}
+
+export default function ContactSelector({
+ language,
+ locations,
+ contactByLocation,
+ employeePageSlug,
+}: ContactSelectorProps) {
+ const locationIds = Object.keys(contactByLocation);
+
+ const [selectedLocationId, setSelectedLocationId] = useState(
+ locationIds.length === 0 ? locationIds[0] : null,
+ );
+
+ if (locationIds.length === 0) {
+ return;
+ }
+
+ const selectedOrDefaultLocationId = selectedLocationId ?? locationIds[0];
+
+ return (
+ <>
+
+ {locations.map((location) => (
+
+ ))}
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/customerCases/customerCase/contactInformation/contactSelector/contactSelector.module.css b/src/components/customerCases/customerCase/contactInformation/contactSelector/contactSelector.module.css
new file mode 100644
index 000000000..e0f2ce2ef
--- /dev/null
+++ b/src/components/customerCases/customerCase/contactInformation/contactSelector/contactSelector.module.css
@@ -0,0 +1,9 @@
+.locationSection {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.consultantSection {
+ min-width: 400px;
+}
diff --git a/src/components/customerCases/customerCase/sections/customerCaseConsultants/CustomerCaseConsultants.tsx b/src/components/customerCases/customerCase/sections/customerCaseConsultants/CustomerCaseConsultants.tsx
index 385872e7d..ed91f8204 100644
--- a/src/components/customerCases/customerCase/sections/customerCaseConsultants/CustomerCaseConsultants.tsx
+++ b/src/components/customerCases/customerCase/sections/customerCaseConsultants/CustomerCaseConsultants.tsx
@@ -1,11 +1,6 @@
-import Image from "next/image";
-import Link from "next/link";
-
-import CustomLink from "src/components/link/CustomLink";
+import ConsultantCard from "src/components/consultantCard/ConsultantCard";
import Text from "src/components/text/Text";
import { ChewbaccaEmployee } from "src/types/employees";
-import { aliasFromEmail } from "src/utils/employees";
-import { LinkType } from "studio/lib/interfaces/navigation";
import { EMPLOYEE_PAGE_SLUG_QUERY } from "studio/lib/queries/siteSettings";
import { loadStudioQuery } from "studio/lib/store";
@@ -32,63 +27,14 @@ export default async function CustomerCaseConsultants({
Varianter på prosjektet
- {consultants.map((consultant) => {
- const title = (
-
{consultant.name}
- );
- return (
- consultant.imageThumbUrl &&
- consultant.name &&
- consultant.email && (
-
-
-
-
-
- {employeePageSlug !== undefined ? (
-
- {title}
-
- ) : (
- title
- )}
- {consultant.officeName && (
-
- {consultant.officeName}
-
- )}
- {consultant.email && (
-
{consultant.email}
- )}
- {consultant.telephone && (
-
- {consultant.telephone}
-
- )}
-
-
-
- )
- );
- })}
+ {consultants.map((consultant) => (
+
+ ))}
);
diff --git a/src/components/customerCases/customerCase/sections/customerCaseConsultants/customerCaseConsulants.module.css b/src/components/customerCases/customerCase/sections/customerCaseConsultants/customerCaseConsulants.module.css
index 09d000704..0745727f4 100644
--- a/src/components/customerCases/customerCase/sections/customerCaseConsultants/customerCaseConsulants.module.css
+++ b/src/components/customerCases/customerCase/sections/customerCaseConsultants/customerCaseConsulants.module.css
@@ -14,47 +14,3 @@
grid-template-columns: repeat(auto-fit, 350px);
justify-content: space-between;
}
-
-.consultant {
- display: flex;
- width: 100%;
- gap: 1rem;
-}
-
-.consultantImage {
- display: flex;
- flex-direction: column;
- align-items: center;
- background-color: var(--primary-black);
- border-radius: 12px;
- height: 125px;
- width: 50%;
- padding: 1rem;
- position: relative;
-}
-
-.consultantInfo {
- display: flex;
- flex-direction: column;
- width: 50%;
- gap: 0.5rem;
-}
-
-.consultantName {
- color: var(--primary-black);
- font-size: 16px;
- font-weight: 600;
-}
-
-.consultantRole {
- color: var(--primary-black);
- font-size: 16px;
- font-weight: 300;
-}
-
-.consultantEmail,
-.consultantTelephone {
- color: var(--primary-black);
- font-size: 14px;
- font-weight: 300;
-}
diff --git a/src/components/text/text.module.css b/src/components/text/text.module.css
index ea365fbd9..d30fe116c 100644
--- a/src/components/text/text.module.css
+++ b/src/components/text/text.module.css
@@ -73,7 +73,7 @@
.bodyNormal {
font-size: 20px;
- font-weight: 400;
+ font-weight: 300;
}
.bodySmall {
diff --git a/src/styles/global.css b/src/styles/global.css
index d20a2e753..e266074ff 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -18,6 +18,7 @@ html {
--primary-white-bright: #ffffff;
--primary-white: #faf8f5;
--primary-black: #2d2d2d;
+ --primary-black-darker: #000000;
--secondary-off-white1: #f4efe8;
--secondary-off-white2: #ece1d3;
diff --git a/studio/lib/interfaces/companyDetails.ts b/studio/lib/interfaces/companyDetails.ts
index 81dec6502..5cd64b12c 100644
--- a/studio/lib/interfaces/companyDetails.ts
+++ b/studio/lib/interfaces/companyDetails.ts
@@ -10,4 +10,5 @@ export interface CompanyLocation {
_id: string;
_updatedAt: string;
companyLocationName: string;
+ contactPerson?: string;
}
diff --git a/studio/schemas/documents/admin/companyLocation.ts b/studio/schemas/documents/admin/companyLocation.ts
index f2bad4951..04ee26a6b 100644
--- a/studio/schemas/documents/admin/companyLocation.ts
+++ b/studio/schemas/documents/admin/companyLocation.ts
@@ -4,6 +4,7 @@ import { StringInputWithCharacterCount } from "studio/components/stringInputWith
export const companyLocationID = "companyLocation";
export const companyLocationNameID = "companyLocationName";
+export const companyLocationContactPersonID = "contactPerson";
const companyLocation = defineType({
name: companyLocationID,
@@ -21,6 +22,12 @@ const companyLocation = defineType({
StringInputWithCharacterCount({ ...props, maxCount: 50 }),
},
}),
+ defineField({
+ name: companyLocationContactPersonID,
+ type: "email",
+ title: "Contact person for Sales",
+ description: "Add the email of the contact person for Sales",
+ }),
],
});