diff --git a/public/_assets/menu-close.svg b/public/_assets/menu-close.svg index bc1f97b7f..a96e8cd5c 100644 --- a/public/_assets/menu-close.svg +++ b/public/_assets/menu-close.svg @@ -1,6 +1,6 @@ - - + + diff --git a/public/_assets/menu.svg b/public/_assets/menu.svg index c5899153d..f495871d4 100644 --- a/public/_assets/menu.svg +++ b/public/_assets/menu.svg @@ -1,5 +1,3 @@ - - - - - + + + \ No newline at end of file diff --git a/src/components/customerCases/customerCase/CustomerCase.tsx b/src/components/customerCases/customerCase/CustomerCase.tsx index 441823ef5..ffd20306b 100644 --- a/src/components/customerCases/customerCase/CustomerCase.tsx +++ b/src/components/customerCases/customerCase/CustomerCase.tsx @@ -1,7 +1,10 @@ import { SanitySharedImage } from "src/components/image/SanityImage"; import { RichText } from "src/components/richText/RichText"; import Text from "src/components/text/Text"; -import { CustomerCase as CustomerCaseDocument } from "studioShared/lib/interfaces/customerCases"; +import { + CustomerCase as CustomerCaseDocument, + Delivery, +} from "studioShared/lib/interfaces/customerCases"; import styles from "./customerCase.module.css"; @@ -20,46 +23,81 @@ export default function CustomerCase({ customerCase }: CustomerCaseProps) {
- {customerCase.description} -
-
- Kunde - - {customerCase.projectInfo.customer} - -
-
- Prosjekt - - {customerCase.projectInfo.name} - -
-
- Varighet - - {customerCase.projectInfo.duration} - -
+
+ {customerCase.description}
-
- Bransje - - {customerCase.projectInfo.sector} - -
-
- Leveranse - - {customerCase.projectInfo.delivery} - -
-
- Konsulenter - - {customerCase.projectInfo.consultants.join(", ")} - -
+ {customerCase.projectInfo.customer && ( +
+ Kunde + + {customerCase.projectInfo.customer} + +
+ )} + {customerCase.projectInfo.name && ( +
+ Prosjekt + + {customerCase.projectInfo.name} + +
+ )} + {customerCase.projectInfo.duration && ( +
+ Varighet + + {customerCase.projectInfo.duration} + +
+ )} + {customerCase.projectInfo.sector && ( +
+ Bransje + + {customerCase.projectInfo.sector} + +
+ )} + {customerCase.projectInfo.deliveries && ( +
+ Leveranse + {customerCase.projectInfo.deliveries.map( + (delivery: Delivery) => ( + + {delivery.delivery} + + ), + )} +
+ )} + {customerCase.projectInfo.consultants && ( +
+ Konsulenter + + {customerCase.projectInfo.consultants.join(", ")} + +
+ )}
diff --git a/src/components/customerCases/customerCase/customerCase.module.css b/src/components/customerCases/customerCase/customerCase.module.css index fd68a9ba4..c5cec17bb 100644 --- a/src/components/customerCases/customerCase/customerCase.module.css +++ b/src/components/customerCases/customerCase/customerCase.module.css @@ -1,40 +1,88 @@ .wrapper { display: flex; flex-direction: column; - margin: 8rem 0; + margin: 4rem 0; align-items: center; + + @media (max-width: 1024px) { + margin: 2rem 0; + } } .content { display: flex; flex-direction: column; - max-width: 1200px; - gap: 2rem; - padding: 1rem; + max-width: 1400px; } .mainTitle { font-weight: 600; + gap: 1.62rem; +} + +.mainImageWrapper { + width: 100%; + height: 36.5rem; + overflow: hidden; + padding-bottom: 2rem; } .mainImageWrapper img { - border-radius: 12px; + border-radius: 0.75rem; + width: 100%; + height: 100%; + max-height: 100%; + min-width: 100%; } .ingress { display: flex; - flex-direction: column; - gap: 1.5rem; + flex-wrap: wrap; + flex-direction: row; + justify-content: space-between; + padding-bottom: 6rem; + + @media (max-width: 1024px) { + flex-direction: column; + gap: 1.5rem; + } +} + +.projectDescription { + flex: 4; + max-width: 40%; + + @media (max-width: 1024px) { + max-width: 100%; + } } .projectInfo { display: flex; + justify-content: space-between; + align-items: center; + flex: 6; + max-width: 50%; + flex-direction: row; + flex-wrap: wrap; + row-gap: 0rem; + column-gap: 0rem; gap: 1rem; - flex-grow: 1; + height: fit-content; + + @media (max-width: 1024px) { + flex-direction: column; + gap: 1.5rem; + max-width: 100%; + align-items: flex-start; + } } .projectInfoItem { display: flex; + height: fit-content; + flex-direction: row; + align-items: center; gap: 1rem; } @@ -43,10 +91,17 @@ white-space: nowrap; } +.projectInfoItemBadge { + compose: projectInfoItemValue; + padding: 0.375rem 0.75rem; + border: 1px solid var(--primary-black); + border-radius: 32.18156rem; +} + .sectionsWrapper { display: flex; flex-direction: column; - gap: 2rem; + gap: 4.5rem; } .imageBlockWrapper { diff --git a/src/components/customerCases/customerCases.module.css b/src/components/customerCases/customerCases.module.css index 4820c2987..1ad7a4eeb 100644 --- a/src/components/customerCases/customerCases.module.css +++ b/src/components/customerCases/customerCases.module.css @@ -8,9 +8,8 @@ .content { display: flex; flex-direction: column; + max-width: 1400px; gap: 5rem; - max-width: 1200px; - padding: 1rem; } .section { @@ -30,5 +29,5 @@ } .caseImageWrapper img { - border-radius: 12px; + border-radius: 0.75rem; } diff --git a/src/components/languageSwitcher/LanguageSwitcher.tsx b/src/components/languageSwitcher/LanguageSwitcher.tsx index 282e683dd..e61c0a096 100644 --- a/src/components/languageSwitcher/LanguageSwitcher.tsx +++ b/src/components/languageSwitcher/LanguageSwitcher.tsx @@ -22,13 +22,16 @@ export default function LanguageSwitcher({ return null; } const linkText = ( - {pathTranslation._key.toUpperCase()} + + {pathTranslation._key.toUpperCase()} + ); return (
  • {pathTranslation._key !== currentLanguage ? ( {linkText} diff --git a/src/components/languageSwitcher/languageSwitcher.module.css b/src/components/languageSwitcher/languageSwitcher.module.css index a5e6b5773..e0b6c917a 100644 --- a/src/components/languageSwitcher/languageSwitcher.module.css +++ b/src/components/languageSwitcher/languageSwitcher.module.css @@ -6,6 +6,10 @@ } .divider { - border-left: 1px solid var(--primary-black); + border-left: 1px solid var(--primary-white); flex-grow: 1; } + +.link { + color: var(--primary-white); +} diff --git a/src/components/link/link.module.css b/src/components/link/link.module.css index 646b160a0..5783bf234 100644 --- a/src/components/link/link.module.css +++ b/src/components/link/link.module.css @@ -53,19 +53,25 @@ } .headerLink { - color: var(--primary-black); + color: var(--primary-white); cursor: pointer; text-decoration: none; font-family: var(--font-britti-sans); - font-size: 1.25rem; + font-size: 1.125rem; font-weight: 500; &:hover { - color: var(--primary-dark); + font-size: 1.125rem; + font-style: normal; + font-weight: 600; + line-height: normal; } &:active { - color: var(--primary-darker); + font-size: 1.125rem; + font-style: normal; + font-weight: 700; + line-height: normal; } } @@ -87,5 +93,7 @@ } .selected { - color: var(--primary-dark); + color: var(--primary-white); + font-weight: 700; + line-height: normal; } diff --git a/src/components/navigation/header/header.module.css b/src/components/navigation/header/header.module.css index a7c0cd7a4..cf791ec85 100644 --- a/src/components/navigation/header/header.module.css +++ b/src/components/navigation/header/header.module.css @@ -3,13 +3,11 @@ top: 0; overflow: hidden; z-index: 9999; + background-color: var(--primary-black); +} - & > header { - padding: 1rem 2.5rem; - transition: background-color 0.4s ease; - position: sticky; - top: 0; - } +.scrolled { + background-color: var(--primary-black); } .isOpen { @@ -18,7 +16,7 @@ flex-direction: column; @media (max-width: 1024px) { - background: var(--primary-bg-dark); + background: var(--primary-black); & > header { flex: 1; @@ -37,8 +35,6 @@ } .wrapper { - background-color: var(--primary-white-bright); - border-radius: 1rem; display: flex; justify-content: space-between; align-items: center; diff --git a/src/components/text/text.module.css b/src/components/text/text.module.css index 118c21ba4..750297b3c 100644 --- a/src/components/text/text.module.css +++ b/src/components/text/text.module.css @@ -32,7 +32,7 @@ .h1 { font-size: 4.5rem; font-style: normal; - font-weight: 500; + font-weight: 600; line-height: 120%; @media (min-width: 1024px) { @@ -60,7 +60,10 @@ } } -/* TODO: we need to add sizes og h4-h6 */ +/* TODO: add font variables */ +/* .h4 */ +/* .h5 */ +/* .h6 */ .desktopLink { font-size: 10rem; @@ -84,7 +87,9 @@ .bodyBig { font-size: 1.5rem; + font-style: normal; font-weight: 400; + line-height: 130%; @media (min-width: 1024px) { font-size: 1.875rem; @@ -109,14 +114,31 @@ } } +/* TODO: add font variables */ +/* .bodyExtraSmall */ + .labelSmall { font-size: 1rem; font-weight: 500; color: var(--primary-dark); +} - @media (min-width: 1024px) { - font-size: 1.125rem; - } +.labelLight { + font-size: 1rem; + font-style: normal; + font-weight: 300; + line-height: 120%; +} + +.labelRegular { + font-size: 1rem; + font-style: normal; + font-weight: 400; + line-height: 120%; } -/* TODO: We need to add media sizes to all text styles */ +/* TODO: add font variables */ +/* .labelSemibold, */ +/* .labelBold, */ +/* .quoteItalic, */ +/* .quoteNormal, */ diff --git a/studioShared/lib/interfaces/customerCases.ts b/studioShared/lib/interfaces/customerCases.ts index 4e4d3c4a4..354f86920 100644 --- a/studioShared/lib/interfaces/customerCases.ts +++ b/studioShared/lib/interfaces/customerCases.ts @@ -9,10 +9,15 @@ export interface CustomerCaseProjectInfo { name: string; duration: string; sector: string; - delivery: string; + deliveries: Delivery[]; consultants: string[]; } +export interface Delivery { + delivery: string; + key: string; +} + export interface CustomerCaseBase { _id: string; language: string; diff --git a/studioShared/lib/queries/customerCases.ts b/studioShared/lib/queries/customerCases.ts index 005075555..a9fa028f1 100644 --- a/studioShared/lib/queries/customerCases.ts +++ b/studioShared/lib/queries/customerCases.ts @@ -36,7 +36,9 @@ export const CUSTOMER_CASE_QUERY = groq` "name": ${translatedFieldFragment("name")}, "duration": ${translatedFieldFragment("duration")}, "sector": ${translatedFieldFragment("sector")}, - "delivery": ${translatedFieldFragment("delivery")}, + "deliveries": deliveries[] { + "delivery": ${translatedFieldFragment("delivery")}, + }, consultants }, "sections": sections[] { diff --git a/studioShared/schemas/documents/customerCase.ts b/studioShared/schemas/documents/customerCase.ts index c211fffb4..7ee52261f 100644 --- a/studioShared/schemas/documents/customerCase.ts +++ b/studioShared/schemas/documents/customerCase.ts @@ -32,7 +32,28 @@ const customerCase = defineType({ type: "internationalizedArrayText", title: "Description", description: - "Short paragraph displayed at the top of the customer case page", + "Short paragraph displayed at the top of the customer case page. Description can not be more than 300 characters.", + validation: (rule) => + rule.custom<{ value: string; _type: string; _key: string }[]>( + (value) => { + if (!value) return true; + if (value) { + const invalidItems = value.filter( + (item) => + typeof item.value === "string" && item.value.length > 300, + ); + + if (invalidItems.length > 0) { + return invalidItems.map((item) => ({ + message: `Description can not be more than 300 characters.`, + path: [{ _key: item._key }, "value"], + })); + } + } + + return true; + }, + ), }), defineField({ ...internationalizedImage, diff --git a/studioShared/schemas/fields/customerCaseProjectInfo.ts b/studioShared/schemas/fields/customerCaseProjectInfo.ts index 358fb5e42..a9cfaf539 100644 --- a/studioShared/schemas/fields/customerCaseProjectInfo.ts +++ b/studioShared/schemas/fields/customerCaseProjectInfo.ts @@ -1,5 +1,8 @@ import { defineField } from "sanity"; +import { isInternationalizedString } from "studio/lib/interfaces/global"; +import { firstTranslation } from "studio/utils/i18n"; + export const customerCaseProjectInfo = defineField({ name: "projectInfo", title: "Project Info", @@ -29,9 +32,38 @@ export const customerCaseProjectInfo = defineField({ }), defineField({ // TODO: pick from global delivery tags - name: "delivery", - description: "The delivery of the project", - type: "internationalizedArrayString", + name: "deliveries", + description: "The deliveries of the project", + type: "array", + of: [ + { + type: "object", + title: "List Item", + name: "listItem", + fields: [ + { + name: "delivery", + title: "Delivery", + type: "internationalizedArrayString", + }, + ], + preview: { + select: { + item: "delivery", + }, + prepare({ delivery }) { + if (!isInternationalizedString(delivery)) { + throw new TypeError( + `Expected 'item' to be InternationalizedString, was ${typeof delivery}`, + ); + } + return { + title: firstTranslation(delivery) ?? undefined, + }; + }, + }, + }, + ], }), defineField({ // TODO: We should be able to select the consultants from a list diff --git a/studioShared/schemas/objects/listBlock.ts b/studioShared/schemas/objects/listBlock.ts index 465e6a551..dd9ecc92e 100644 --- a/studioShared/schemas/objects/listBlock.ts +++ b/studioShared/schemas/objects/listBlock.ts @@ -24,7 +24,7 @@ const listBlock = defineField({ type: "array", of: [ { - type: "object", // You need to define it as an object since it's a custom field + type: "object", title: "List Item", name: "listItem", fields: [