foundry-component-library 0.2.31 → 0.2.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/lib/components/Capabilities/index.tsx +5 -2
  2. package/lib/components/Footer/index.tsx +20 -12
  3. package/lib/components/Footer/styles.module.scss +1 -1
  4. package/lib/components/GetInTouch/index.tsx +6 -2
  5. package/lib/components/Header/Menu.tsx +15 -6
  6. package/lib/components/Header/index.tsx +8 -0
  7. package/lib/components/Header/styles.module.scss +3 -3
  8. package/lib/components/Hero/index.tsx +0 -2
  9. package/lib/components/HubsAccordion/Hub.tsx +1 -1
  10. package/lib/components/ImageTitle/index.tsx +8 -2
  11. package/lib/components/LogoSection/Dropdown.tsx +0 -2
  12. package/lib/components/LogoSection/Logos.tsx +0 -2
  13. package/lib/components/QuoteSection/index.tsx +38 -36
  14. package/lib/components/QuoteSection/styles.module.scss +12 -0
  15. package/lib/components/TextSection/index.tsx +12 -2
  16. package/lib/components/case/Other/index.tsx +6 -2
  17. package/lib/queries/client.ts +22 -7
  18. package/lib/queries/getAboutPage.ts +8 -4
  19. package/lib/queries/getBrands.ts +3 -4
  20. package/lib/queries/getCaseById.ts +3 -4
  21. package/lib/queries/getCaseBySlug.ts +3 -4
  22. package/lib/queries/getCases.ts +3 -4
  23. package/lib/queries/getCasesPage.ts +3 -4
  24. package/lib/queries/getCategories.ts +3 -4
  25. package/lib/queries/getContactPage.ts +3 -4
  26. package/lib/queries/getHomePage.ts +3 -4
  27. package/lib/queries/getHubBySlug.ts +4 -4
  28. package/lib/queries/getHubs.ts +3 -4
  29. package/lib/queries/getHubsPage.ts +3 -4
  30. package/lib/queries/getMetadataBySlug.ts +3 -4
  31. package/lib/queries/getNewsPage.ts +3 -4
  32. package/lib/queries/getPageBySlug.ts +3 -4
  33. package/lib/queries/getPeoplePage.ts +3 -4
  34. package/lib/queries/getPerformanceHubPage.ts +3 -4
  35. package/lib/queries/getPostBySlug.ts +3 -4
  36. package/lib/queries/getPosts.ts +3 -4
  37. package/lib/types/index.ts +1 -0
  38. package/lib/utils.ts +75 -2
  39. package/package.json +1 -2
@@ -5,12 +5,15 @@ import styles from "./styles.module.scss";
5
5
  import type { Case, NextImage } from "../../types";
6
6
  import Item from "./Item";
7
7
  import LinkType from "next/link";
8
+ import { translate } from "../../utils";
8
9
 
9
10
  const Capabilities = ({
11
+ heading,
10
12
  items,
11
13
  Link,
12
14
  Image,
13
15
  }: {
16
+ heading: string;
14
17
  items: {
15
18
  heading: string;
16
19
  text: string;
@@ -26,9 +29,9 @@ const Capabilities = ({
26
29
  return (
27
30
  <Container>
28
31
  <a className={styles.button} href="#get-in-touch">
29
- Get in touch
32
+ {translate("Get in touch", "DE")}
30
33
  </a>
31
- <div className={styles.heading}>Our capabilities</div>
34
+ <div className={styles.heading}>{heading}</div>
32
35
  <div className={styles.items}>
33
36
  {items.map((item) => {
34
37
  return (
@@ -10,6 +10,7 @@ function Footer({
10
10
  facebook,
11
11
  linkedin,
12
12
  instagram,
13
+ lang,
13
14
  }: {
14
15
  details: {
15
16
  berlinEmail: string;
@@ -20,6 +21,7 @@ function Footer({
20
21
  facebook: string;
21
22
  linkedin: string;
22
23
  instagram: string;
24
+ lang?: "DE" | "EN";
23
25
  }) {
24
26
  const { berlinEmail, zurichEmail, newyorkEmail } = details;
25
27
  const year = new Date().getFullYear();
@@ -38,7 +40,7 @@ function Footer({
38
40
  <div className={styles.offices}>
39
41
  {berlinEmail && (
40
42
  <div className={styles.office}>
41
- <div className={styles.city}>{translate("Berlin")}</div>
43
+ <div className={styles.city}>{translate("Berlin", lang)}</div>
42
44
  <div className={styles.email}>
43
45
  <a href={`mailto:${berlinEmail}`}>{berlinEmail}</a>
44
46
  </div>
@@ -46,7 +48,7 @@ function Footer({
46
48
  )}
47
49
  {zurichEmail && (
48
50
  <div className={styles.office}>
49
- <div className={styles.city}>{translate("Zurich")}</div>
51
+ <div className={styles.city}>{translate("Zurich", lang)}</div>
50
52
  <div className={styles.email}>
51
53
  <a href={`mailto:${zurichEmail}`}>{zurichEmail}</a>
52
54
  </div>
@@ -54,7 +56,9 @@ function Footer({
54
56
  )}
55
57
  {newyorkEmail && (
56
58
  <div className={styles.office}>
57
- <div className={styles.city}>{translate("New York")}</div>
59
+ <div className={styles.city}>
60
+ {translate("New York", lang)}
61
+ </div>
58
62
  <div className={styles.email}>
59
63
  <a href={`mailto:${newyorkEmail}`}>{newyorkEmail}</a>
60
64
  </div>
@@ -65,26 +69,28 @@ function Footer({
65
69
  <div className={styles.right}>
66
70
  <ul className={styles.menu}>
67
71
  <li className={styles.menuItem}>
68
- <Link href="/hubs">Service Hubs</Link>
72
+ <Link href="/hubs">{translate("Service Hubs", lang)}</Link>
69
73
  </li>
70
74
  <li className={styles.menuItem}>
71
- <Link href="/about-us">About Us</Link>
75
+ <Link href="/about-us">{translate("About Us", lang)}</Link>
72
76
  </li>
73
77
  <li className={styles.menuItem}>
74
- <Link href="/cases">Case Studies</Link>
78
+ <Link href="/cases">{translate("Case Studies", lang)}</Link>
75
79
  </li>
76
80
  {/* <li className={styles.menuItem}>
77
81
  <Link href="/team">Team & Careers</Link>
78
82
  </li> */}
79
83
  <li className={styles.menuItem}>
80
- <Link href="/news">News & Insights</Link>
84
+ <Link href="/news">{translate("News & Insights", lang)}</Link>
81
85
  </li>
82
86
  <li className={styles.menuItem}>
83
- <Link href="/contact">Contact</Link>
87
+ <Link href="/contact">{translate("Contact", lang)}</Link>
84
88
  </li>
85
89
  </ul>
86
90
  <div className={styles.social}>
87
- <div className={styles.socialHeading}>Follow Us</div>
91
+ <div className={styles.socialHeading}>
92
+ {translate("Follow Us", lang)}
93
+ </div>
88
94
  <ul className={styles.menuSocial}>
89
95
  <li className={styles.menuItem}>
90
96
  <Link href={instagram} target="_blank">
@@ -108,9 +114,11 @@ function Footer({
108
114
  <div className={styles.bottom}>
109
115
  <div>FOUNDRY © {year}</div>
110
116
  <div className={styles.bottomLinks}>
111
- <Link href="/imprint">{translate("Imprint")}</Link>
112
- <Link href="/terms">{translate("Terms")}</Link>
113
- <Link href="/privacy-policy">{translate("Privacy policy")}</Link>
117
+ <Link href="/imprint">{translate("Imprint", lang)}</Link>
118
+ <Link href="/terms">{translate("Terms", lang)}</Link>
119
+ <Link href="/privacy-policy">
120
+ {translate("Privacy policy", lang)}
121
+ </Link>
114
122
  </div>
115
123
  </div>
116
124
  </Container>
@@ -189,7 +189,7 @@
189
189
  gap: 24px;
190
190
  text-transform: none;
191
191
  font-size: 16px;
192
- width: 335px;
192
+ max-width: 370px;
193
193
  max-width: 100%;
194
194
 
195
195
  @media screen and (max-width: 1000px) {
@@ -3,6 +3,7 @@ import React from "react";
3
3
  import { useActionState, useState } from "react";
4
4
  import { useRouter } from "next/navigation";
5
5
  import styles from "./styles.module.scss";
6
+ import { translate } from "../../utils";
6
7
 
7
8
  type LeadResult =
8
9
  | { success: true }
@@ -43,9 +44,12 @@ const GetInTouch = ({
43
44
  return (
44
45
  <section id="get-in-touch" className={styles.formSection}>
45
46
  <div className={styles.container}>
46
- <h2 className={styles.heading}>Get in touch</h2>
47
+ <h2 className={styles.heading}>{translate("Get in touch", "DE")}</h2>
47
48
  <p className={styles.subtitle}>
48
- Tell us about your brand and discover how we can help.
49
+ {translate(
50
+ "Tell us about your brand and discover how we can help.",
51
+ "DE",
52
+ )}
49
53
  </p>
50
54
  <form
51
55
  action={formAction}
@@ -34,17 +34,26 @@ function Menu({
34
34
  <div className={styles.menuWrapper}>
35
35
  <ul className={styles.menuList}>
36
36
  <li className={styles.menuListItem}>
37
- <Link href={`${langPrefix}/hubs`}>{translate("Service Hubs")}</Link>
37
+ <Link href={`${langPrefix}`}>{translate("Home", currentLang)}</Link>
38
38
  </li>
39
39
  <li className={styles.menuListItem}>
40
- <Link href={`${langPrefix}/cases`}>{translate("Cases")}</Link>
40
+ <Link href={`${langPrefix}/hubs`}>
41
+ {translate("Service Hubs", currentLang)}
42
+ </Link>
41
43
  </li>
42
44
  <li className={styles.menuListItem}>
43
- <Link href={`${langPrefix}/about-us`}>{translate("About Us")}</Link>
45
+ <Link href={`${langPrefix}/cases`}>
46
+ {translate("Cases", currentLang)}
47
+ </Link>
48
+ </li>
49
+ <li className={styles.menuListItem}>
50
+ <Link href={`${langPrefix}/about-us`}>
51
+ {translate("About Us", currentLang)}
52
+ </Link>
44
53
  </li>
45
54
  <li className={styles.menuListItem}>
46
55
  <Link href={`${langPrefix}/contact`}>
47
- {translate("Contact Us")}
56
+ {translate("Contact Us", currentLang)}
48
57
  </Link>
49
58
  </li>
50
59
  </ul>
@@ -67,13 +76,13 @@ function Menu({
67
76
  </li> */}
68
77
  <li className={styles.secondaryMenuItem}>
69
78
  <Link href={`${langPrefix}/team`}>
70
- {translate("Team & Careers")}
79
+ {translate("Team & Careers", currentLang)}
71
80
  <Arrow />
72
81
  </Link>
73
82
  </li>
74
83
  <li className={styles.secondaryMenuItem}>
75
84
  <Link href={`${langPrefix}/news`}>
76
- {translate("News & Insights")}
85
+ {translate("News & Insights", currentLang)}
77
86
  <Arrow />
78
87
  </Link>
79
88
  </li>
@@ -29,6 +29,14 @@ function Header({ Link }: { Link: NextLink }) {
29
29
  };
30
30
  }, [logo]);
31
31
 
32
+ useEffect(() => {
33
+ if (!isMenuOpen) return;
34
+
35
+ const onScroll = () => setMenuOpen(false);
36
+ window.addEventListener("scroll", onScroll, { once: true });
37
+ return () => window.removeEventListener("scroll", onScroll);
38
+ }, [isMenuOpen, setMenuOpen]);
39
+
32
40
  return (
33
41
  <>
34
42
  <header className={styles.header}>
@@ -176,18 +176,18 @@
176
176
 
177
177
  .langBtn {
178
178
  text-transform: uppercase;
179
- opacity: 0.6;
179
+ opacity: 1;
180
180
  }
181
181
  .divider {
182
182
  margin: 3px 1px;
183
183
  width: 2px;
184
184
  height: calc(100% - 6px);
185
185
  background-color: $color-text;
186
- opacity: 0.6;
186
+ opacity: 1;
187
187
  }
188
188
 
189
189
  .langBtn.active {
190
- opacity: 1;
190
+ opacity: 0.6;
191
191
  }
192
192
 
193
193
  .logo {
@@ -35,8 +35,6 @@ const Hero = ({
35
35
 
36
36
  if (!image && !video) return;
37
37
 
38
- console.log("video", video);
39
-
40
38
  if (isFullWidth) {
41
39
  return (
42
40
  <div
@@ -42,7 +42,7 @@ const Hub = ({
42
42
  <div className={`${styles.hub} ${isActive ? styles.active : ""}`}>
43
43
  <div className={styles.top}>
44
44
  <div className={styles.title}>{hub.title}</div>
45
- <div className={styles.text}>{customFields.subheading}</div>
45
+ <div className={styles.text}>{customFields.approach}</div>
46
46
  <button className={styles.icon} onClick={() => setIsActive(!isActive)}>
47
47
  {isActive ? <Minus /> : <Plus />}
48
48
  </button>
@@ -22,8 +22,14 @@ const ImageTitle = ({
22
22
  <div className={`${styles.imageTitle} ${inverseStyle}`}>
23
23
  <div className={styles.texts}>
24
24
  <div>
25
- <div className={styles.heading}>{heading}</div>
26
- <div className={styles.text}>{text}</div>
25
+ <div
26
+ className={styles.heading}
27
+ dangerouslySetInnerHTML={{ __html: heading || "" }}
28
+ />
29
+ <div
30
+ className={styles.text}
31
+ dangerouslySetInnerHTML={{ __html: text || "" }}
32
+ />
27
33
  </div>
28
34
  </div>
29
35
  {image && (
@@ -42,8 +42,6 @@ const Dropdown = ({
42
42
  currentDisplay = selected.tag;
43
43
  }
44
44
 
45
- console.log("pp", displayLabels);
46
-
47
45
  return (
48
46
  <div
49
47
  className={`${styles.dropdown} ${isOpen ? styles.active : ""}`}
@@ -93,8 +93,6 @@ const Logos = ({
93
93
  }
94
94
  }, [selected]);
95
95
 
96
- console.log("qwe", selected);
97
-
98
96
  return (
99
97
  <Container>
100
98
  {!withoutFilters && (
@@ -32,45 +32,47 @@ const QuoteSection = ({
32
32
  return (
33
33
  <div className={styles.quote}>
34
34
  <Container>
35
- {items.map((item, i) => {
36
- return (
37
- <div
38
- key={item?.name || i}
39
- className={`${styles.content} ${
40
- active === i ? styles.active : ""
41
- }`}>
42
- <div className={styles.person}>
43
- <div>
44
- <div className={styles.name}>{item.name}</div>
45
- <div className={styles.position}>{item.position}</div>
46
- </div>
47
- </div>
35
+ <div className={styles.quoteWrapper}>
36
+ {items.map((item, i) => {
37
+ return (
48
38
  <div
49
- className={styles.text}
50
- onMouseEnter={() => setPaused(true)}
51
- onMouseLeave={() => setPaused(false)}>
52
- {item.text}
39
+ key={item?.name || i}
40
+ className={`${styles.content} ${
41
+ active === i ? styles.active : ""
42
+ }`}>
43
+ <div className={styles.person}>
44
+ <div>
45
+ <div className={styles.name}>{item.name}</div>
46
+ <div className={styles.position}>{item.position}</div>
47
+ </div>
48
+ </div>
49
+ <div
50
+ className={styles.text}
51
+ onMouseEnter={() => setPaused(true)}
52
+ onMouseLeave={() => setPaused(false)}>
53
+ {item.text}
54
+ </div>
53
55
  </div>
56
+ );
57
+ })}
58
+ {items.length > 1 && (
59
+ <div className={`${styles.indicators} ${styles.desktop}}`}>
60
+ {items.map((el, i) => {
61
+ return (
62
+ <div
63
+ key={el.name}
64
+ className={`${styles.indicator} ${
65
+ active === i ? styles.active : ""
66
+ }`}
67
+ onClick={() => {
68
+ setActive(i);
69
+ }}
70
+ />
71
+ );
72
+ })}
54
73
  </div>
55
- );
56
- })}
57
- {items.length > 1 && (
58
- <div className={`${styles.indicators} ${styles.desktop}}`}>
59
- {items.map((el, i) => {
60
- return (
61
- <div
62
- key={el.name}
63
- className={`${styles.indicator} ${
64
- active === i ? styles.active : ""
65
- }`}
66
- onClick={() => {
67
- setActive(i);
68
- }}
69
- />
70
- );
71
- })}
72
- </div>
73
- )}
74
+ )}
75
+ </div>
74
76
  </Container>
75
77
  </div>
76
78
  );
@@ -10,6 +10,17 @@
10
10
  }
11
11
  }
12
12
 
13
+ .quoteWrapper {
14
+ display: flex;
15
+ flex-direction: column;
16
+ justify-content: space-between;
17
+ min-height: 432px;
18
+
19
+ @media #{$QUERY-sm} {
20
+ min-height: 350px;
21
+ }
22
+ }
23
+
13
24
  .logo {
14
25
  width: 180px;
15
26
  height: 64px;
@@ -89,6 +100,7 @@
89
100
  align-items: center;
90
101
  justify-content: flex-start;
91
102
  gap: 16px;
103
+ margin-top: auto;
92
104
 
93
105
  @media #{$QUERY-sm} {
94
106
  padding-top: 30px;
@@ -32,8 +32,18 @@ const TextSection = ({
32
32
  dangerouslySetInnerHTML={{ __html: heading }}
33
33
  />
34
34
  )}
35
- {subheading && <div className={styles.subheading}>{subheading}</div>}
36
- {text && <div className={styles.text}>{text}</div>}
35
+ {subheading && (
36
+ <div
37
+ className={styles.subheading}
38
+ dangerouslySetInnerHTML={{ __html: subheading }}
39
+ />
40
+ )}
41
+ {text && (
42
+ <div
43
+ className={styles.text}
44
+ dangerouslySetInnerHTML={{ __html: text }}
45
+ />
46
+ )}
37
47
  </div>
38
48
  </Container>
39
49
  );
@@ -11,10 +11,12 @@ function Other({
11
11
  cases,
12
12
  Link,
13
13
  Image,
14
+ lang,
14
15
  }: {
15
16
  cases: Case[];
16
17
  Link: NextLink;
17
18
  Image: NextImage;
19
+ lang?: "EN" | "DE";
18
20
  }) {
19
21
  const sectionRef = useRef(null);
20
22
  const { handleMouseDown, handleMouseMove, handleMouseUp, dragStyle } =
@@ -26,9 +28,11 @@ function Other({
26
28
  <Container noMobilePadding>
27
29
  <div className={styles.other}>
28
30
  <div className={styles.top}>
29
- <div className={styles.caption}>{translate("Case Studies")}</div>
31
+ <div className={styles.caption}>
32
+ {translate("Case Studies", lang)}
33
+ </div>
30
34
  <h3 className={styles.heading}>
31
- {translate("Success stories.\nWith proven results.")}
35
+ {translate("Success stories.\nWith proven results.", lang)}
32
36
  </h3>
33
37
  </div>
34
38
  <div
@@ -1,5 +1,3 @@
1
- import { GraphQLClient } from "graphql-request";
2
-
3
1
  const baseUrl = process.env.WORDPRESS_URL || "https://data.foundry.ch";
4
2
 
5
3
  const headers: Record<string, string> = {
@@ -13,9 +11,26 @@ if (process.env.WP_PREVIEW_USER && process.env.WP_PREVIEW_PASS) {
13
11
  headers["Authorization"] = `Basic ${auth}`;
14
12
  }
15
13
 
16
- const graphqlClient = new GraphQLClient(`${baseUrl}/graphql`, {
17
- headers,
18
- errorPolicy: "all",
19
- });
14
+ export async function request<T>(
15
+ query: string,
16
+ variables?: Record<string, unknown>,
17
+ ): Promise<T> {
18
+ const response = await fetch(`${baseUrl}/graphql`, {
19
+ method: "POST",
20
+ headers,
21
+ body: JSON.stringify({ query, variables }),
22
+ next: {
23
+ revalidate: 60 * 3,
24
+ },
25
+ } as RequestInit & { next?: { revalidate?: number } });
26
+
27
+ if (!response.ok) {
28
+ throw new Error(`GraphQL request failed: ${response.statusText}`);
29
+ }
20
30
 
21
- export default graphqlClient;
31
+ const json = await response.json();
32
+ if (json.errors) {
33
+ throw new Error(json.errors[0]?.message || "GraphQL error");
34
+ }
35
+ return json.data as T;
36
+ }
@@ -1,5 +1,4 @@
1
- import { gql } from "graphql-request";
2
- import client from "./client";
1
+ import { request } from "./client";
3
2
 
4
3
  type AboutPage = {
5
4
  aboutPage: {
@@ -104,7 +103,7 @@ export default async function getAboutPage({
104
103
  const homePage = language === "DE" ? "home-berlin-de" : "home-berlin";
105
104
  const contactPage = language === "DE" ? "contact-de" : "contact";
106
105
 
107
- const query = gql`
106
+ const query = `
108
107
  query GetPageBySlug($slug: ID!) {
109
108
  aboutPage: page(id: $slug, idType: URI) {
110
109
  customFieldsAboutBerlin {
@@ -203,11 +202,16 @@ export default async function getAboutPage({
203
202
  `;
204
203
 
205
204
  const variables = { slug: slug };
205
+
206
+ console.time("graphql");
207
+
206
208
  const data: {
207
209
  aboutPage: AboutPage["aboutPage"];
208
210
  homePage: AboutPage["homePage"];
209
211
  contactPage: AboutPage["contactPage"];
210
- } = await client.request(query, variables);
212
+ } = await request(query, variables);
213
+
214
+ console.timeEnd("graphql");
211
215
 
212
216
  return {
213
217
  aboutPage: data.aboutPage,
@@ -1,11 +1,10 @@
1
- import { gql } from "graphql-request";
2
1
  import { Page } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
 
5
4
  export default async function getBrands(): Promise<
6
5
  Page["customFields"]["brands"] | null
7
6
  > {
8
- const query = gql`
7
+ const query = `
9
8
  query GetBrands($slug: ID!) {
10
9
  page(id: $slug, idType: URI) {
11
10
  customFields {
@@ -21,6 +20,6 @@ export default async function getBrands(): Promise<
21
20
  `;
22
21
 
23
22
  const variables = { slug: "home", language: "EN" };
24
- const data: { page: Page } = await client.request(query, variables);
23
+ const data: { page: Page } = await request(query, variables);
25
24
  return data.page.customFields.brands;
26
25
  }
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Case } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { type ContactPage } from "./getContactPage";
5
4
 
6
5
  type HomePage = {
@@ -30,7 +29,7 @@ export default async function getCaseBySlug({
30
29
  const homePage = language === "DE" ? "home-berlin-de" : "home-berlin";
31
30
  const contactPage = language === "DE" ? "contact-de" : "contact";
32
31
 
33
- const query = gql`
32
+ const query = `
34
33
  query GetCaseBySlug($id: ID!) {
35
34
  case(id: $id, idType: ID) {
36
35
  id
@@ -277,7 +276,7 @@ export default async function getCaseBySlug({
277
276
  case: Case;
278
277
  contactPage: ContactPage;
279
278
  homePage: HomePage;
280
- } = await client.request(query, variables);
279
+ } = await request(query, variables);
281
280
 
282
281
  return {
283
282
  case: data.case,
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Case } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { type ContactPage } from "./getContactPage";
5
4
 
6
5
  type HomePage = {
@@ -30,7 +29,7 @@ export default async function getCaseBySlug({
30
29
  const homePage = language === "DE" ? "home-berlin-de" : "home-berlin";
31
30
  const contactPage = language === "DE" ? "contact-de" : "contact";
32
31
 
33
- const query = gql`
32
+ const query = `
34
33
  query GetCaseBySlug($slug: String, $language: LanguageCodeFilterEnum!) {
35
34
  cases(where: { name: $slug, language: $language }) {
36
35
  nodes {
@@ -280,7 +279,7 @@ export default async function getCaseBySlug({
280
279
  };
281
280
  contactPage: ContactPage;
282
281
  homePage: HomePage;
283
- } = await client.request(query, variables);
282
+ } = await request(query, variables);
284
283
 
285
284
  return {
286
285
  case: data?.cases.nodes[0],
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Case, Variables } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
 
5
4
  type Params = {
6
5
  perPage?: number;
@@ -55,7 +54,7 @@ export default async function getCases({
55
54
  const whereClause =
56
55
  whereConditions.length > 0 ? `where: { ${whereConditions.join(", ")}}` : "";
57
56
 
58
- const query = gql`
57
+ const query = `
59
58
  query GetCases(${variableDefinitions}) {
60
59
  cases(
61
60
  ${isPrevious ? "last: $perPage" : "first: $perPage"},
@@ -117,7 +116,7 @@ export default async function getCases({
117
116
  hasPreviousPage: boolean;
118
117
  };
119
118
  };
120
- } = await client.request(query, variables);
119
+ } = await request(query, variables);
121
120
 
122
121
  return {
123
122
  cases: data.cases.nodes,
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Case, Variables } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { type ContactPage } from "./getContactPage";
5
4
 
6
5
  export const casesPerPage = 10;
@@ -113,7 +112,7 @@ export default async function getCasesPage({
113
112
  const whereClause =
114
113
  whereConditions.length > 0 ? `where: { ${whereConditions.join(", ")}}` : "";
115
114
 
116
- const query = gql`
115
+ const query = `
117
116
  query GetCasesPage(${variableDefinitions}) {
118
117
  casesPage: page(id: "${casesPage}", idType: DATABASE_ID) {
119
118
  customFieldsCases {
@@ -241,7 +240,7 @@ export default async function getCasesPage({
241
240
  };
242
241
  contactPage: ContactPage;
243
242
  homePage: HomePage;
244
- } = await client.request(query, variables);
243
+ } = await request(query, variables);
245
244
 
246
245
  return {
247
246
  casesPage: data.casesPage,
@@ -1,9 +1,8 @@
1
- import { gql } from "graphql-request";
2
1
  import { Category } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
 
5
4
  export default async function getCategories(): Promise<Category[]> {
6
- const query = gql`
5
+ const query = `
7
6
  query getCategories {
8
7
  caseCategories(where: { language: EN }) {
9
8
  nodes {
@@ -16,7 +15,7 @@ export default async function getCategories(): Promise<Category[]> {
16
15
  }
17
16
  `;
18
17
 
19
- const data: { caseCategories: { nodes: Category[] } } = await client.request(
18
+ const data: { caseCategories: { nodes: Category[] } } = await request(
20
19
  query
21
20
  );
22
21
  return data.caseCategories.nodes;
@@ -1,5 +1,4 @@
1
- import { gql } from "graphql-request";
2
- import client from "./client";
1
+ import { request } from "./client";
3
2
 
4
3
  export type ContactPage = {
5
4
  title: string;
@@ -55,7 +54,7 @@ export default async function getContactPage({
55
54
  }: {
56
55
  slug: string;
57
56
  }): Promise<ContactPage | null> {
58
- const query = gql`
57
+ const query = `
59
58
  query GetPageBySlug($slug: ID!) {
60
59
  page(id: $slug, idType: URI) {
61
60
  title
@@ -107,6 +106,6 @@ export default async function getContactPage({
107
106
  `;
108
107
 
109
108
  const variables = { slug: slug };
110
- const data: { page: ContactPage } = await client.request(query, variables);
109
+ const data: { page: ContactPage } = await request(query, variables);
111
110
  return data.page;
112
111
  }
@@ -1,5 +1,4 @@
1
- import { gql } from "graphql-request";
2
- import client from "./client";
1
+ import { request } from "./client";
3
2
  import { Hub, PostPreview } from "../types";
4
3
  import { type ContactPage } from "./getContactPage";
5
4
 
@@ -133,7 +132,7 @@ export default async function getHomePage({
133
132
  const contactPage = language === "EN" ? "contact" : "contact-de";
134
133
  const aboutPage = language === "EN" ? "about-berlin" : "about-berlin-de";
135
134
 
136
- const query = gql`
135
+ const query = `
137
136
  query GetPageBySlug($slug: ID!) {
138
137
  page(id: $slug, idType: URI) {
139
138
  title
@@ -284,7 +283,7 @@ export default async function getHomePage({
284
283
  posts: { nodes: PostPreview[] };
285
284
  contactPage: ContactPage;
286
285
  aboutPage: HomePage["aboutPage"];
287
- } = await client.request(query, variables);
286
+ } = await request(query, variables);
288
287
 
289
288
  return {
290
289
  homePage: data.page,
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Case, Hub } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { type ContactPage } from "./getContactPage";
5
4
 
6
5
  type HomePage = {
@@ -33,7 +32,7 @@ export default async function getHubBySlug({
33
32
  const homePage = language === "DE" ? "home-berlin-de" : "home-berlin";
34
33
  const contactPage = language === "DE" ? "contact-de" : "contact";
35
34
 
36
- const query = gql`
35
+ const query = `
37
36
  query GetHubBySlug($slug: ID!) {
38
37
  hub(id: $slug, idType: SLUG) {
39
38
  id
@@ -62,6 +61,7 @@ export default async function getHubBySlug({
62
61
  }
63
62
  }
64
63
  }
64
+ capabilitiesHeading
65
65
  capabilities {
66
66
  heading
67
67
  text
@@ -170,7 +170,7 @@ export default async function getHubBySlug({
170
170
  contactPage: ContactPage;
171
171
  cases: { nodes: Case[] };
172
172
  homePage: HomePage;
173
- } = await client.request(query, variables);
173
+ } = await request(query, variables);
174
174
 
175
175
  return {
176
176
  hub: data.hub,
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Hub } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
 
5
4
  export default async function getCases(): Promise<{
6
5
  hubs: Hub[];
@@ -33,7 +32,7 @@ export default async function getCases(): Promise<{
33
32
  };
34
33
  };
35
34
  }> {
36
- const query = gql`
35
+ const query = `
37
36
  query GetHubs {
38
37
  hubs(where: { language: EN }) {
39
38
  nodes {
@@ -127,7 +126,7 @@ export default async function getCases(): Promise<{
127
126
  }>;
128
127
  };
129
128
  };
130
- } = await client.request(query);
129
+ } = await request(query);
131
130
 
132
131
  return {
133
132
  hubs: data.hubs.nodes,
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Variables, Hub } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { type ContactPage } from "./getContactPage";
5
4
 
6
5
  type HomePage = {
@@ -111,7 +110,7 @@ export default async function getCasesPage(
111
110
  const whereClause =
112
111
  whereConditions.length > 0 ? `where: { ${whereConditions.join(", ")}}` : "";
113
112
 
114
- const query = gql`
113
+ const query = `
115
114
  query GetNewsPage(${variableDefinitions}) {
116
115
  hubsPage: page(id: $slug, idType: URI) {
117
116
  title
@@ -256,7 +255,7 @@ export default async function getCasesPage(
256
255
  contactPage: ContactPage;
257
256
  homePage: HomePage;
258
257
  aboutPage: AboutPage;
259
- } = await client.request(query, variables);
258
+ } = await request(query, variables);
260
259
 
261
260
  return {
262
261
  hubsPage: data.hubsPage,
@@ -1,12 +1,11 @@
1
- import { gql } from "graphql-request";
2
1
  import { Metadata, Variables } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
 
5
4
  export default async function getMetadataBySlug(
6
5
  slug: string,
7
6
  language: string = "EN"
8
7
  ) {
9
- const query = gql`
8
+ const query = `
10
9
  query getMetadata($slug: String, $language: LanguageCodeFilterEnum) {
11
10
  pages(where: { name: $slug, language: $language }) {
12
11
  nodes {
@@ -40,7 +39,7 @@ export default async function getMetadataBySlug(
40
39
  };
41
40
 
42
41
  const data: { pages: { nodes: Metadata[] }; posts: { nodes: Metadata[] } } =
43
- await client.request(query, variables);
42
+ await request(query, variables);
44
43
  const pages = data.pages.nodes;
45
44
  const posts = data.posts.nodes;
46
45
 
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Variables, Post } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { type ContactPage } from "./getContactPage";
5
4
 
6
5
  type NewsPage = {
@@ -73,7 +72,7 @@ export default async function getNewsPage(options: Params): Promise<{
73
72
  const whereClause =
74
73
  whereConditions.length > 0 ? `where: { ${whereConditions.join(", ")}}` : "";
75
74
 
76
- const query = gql`
75
+ const query = `
77
76
  query GetNewsPage(${variableDefinitions}) {
78
77
  newsPage: page(id: $slug, idType: URI) {
79
78
  title
@@ -178,7 +177,7 @@ export default async function getNewsPage(options: Params): Promise<{
178
177
  };
179
178
  };
180
179
  contactPage: ContactPage;
181
- } = await client.request(query, variables);
180
+ } = await request(query, variables);
182
181
 
183
182
  return {
184
183
  newsPage: data.newsPage,
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Page } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { ContactPage } from "./getContactPage";
5
4
 
6
5
  export default async function getPageBySlug(
@@ -9,7 +8,7 @@ export default async function getPageBySlug(
9
8
  ): Promise<{ page: Page; contactPage: ContactPage }> {
10
9
  const contactPage = language === "DE" ? "contact-de" : "contact";
11
10
 
12
- const query = gql`
11
+ const query = `
13
12
  query GetPageBySlug($slug: ID!) {
14
13
  page(id: $slug, idType: URI) {
15
14
  title
@@ -46,7 +45,7 @@ export default async function getPageBySlug(
46
45
  `;
47
46
 
48
47
  const variables = { slug };
49
- const data: { page: Page; contactPage: ContactPage } = await client.request(
48
+ const data: { page: Page; contactPage: ContactPage } = await request(
50
49
  query,
51
50
  variables
52
51
  );
@@ -1,5 +1,4 @@
1
- import { gql } from "graphql-request";
2
- import client from "./client";
1
+ import { request } from "./client";
3
2
  import { type ContactPage } from "./getContactPage";
4
3
  import { Person } from "../types";
5
4
 
@@ -79,7 +78,7 @@ export default async function getContactPage({
79
78
  }): Promise<PeoplePage> {
80
79
  const contactPage = language === "DE" ? "contact-de" : "contact";
81
80
 
82
- const query = gql`
81
+ const query = `
83
82
  query GetPageBySlug($slug: ID!) {
84
83
  page(id: $slug, idType: URI) {
85
84
  title
@@ -161,7 +160,7 @@ export default async function getContactPage({
161
160
  const data: {
162
161
  page: PeoplePage["peoplePage"];
163
162
  contactPage: ContactPage;
164
- } = await client.request(query, variables);
163
+ } = await request(query, variables);
165
164
 
166
165
  return {
167
166
  peoplePage: data.page,
@@ -1,5 +1,4 @@
1
- import { gql } from "graphql-request";
2
- import client from "./client";
1
+ import { request } from "./client";
3
2
 
4
3
  type PerformancePage = {
5
4
  homePage: {
@@ -81,7 +80,7 @@ type PerformancePage = {
81
80
  };
82
81
 
83
82
  export default async function getPerformanceHubPage(): Promise<PerformancePage> {
84
- const query = gql`
83
+ const query = `
85
84
  query GetPageBySlug($slug: ID!) {
86
85
  homePage: page(id: "home-berlin", idType: URI) {
87
86
  customFieldsBerlin {
@@ -170,7 +169,7 @@ export default async function getPerformanceHubPage(): Promise<PerformancePage>
170
169
  homePage: PerformancePage["homePage"];
171
170
  performancePage: PerformancePage["performancePage"];
172
171
  contactPage: PerformancePage["contactPage"];
173
- } = await client.request(query, variables);
172
+ } = await request(query, variables);
174
173
 
175
174
  return {
176
175
  homePage: data.homePage,
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Post } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
  import { ContactPage } from "./getContactPage";
5
4
 
6
5
  export default async function getPostBySlug({
@@ -15,7 +14,7 @@ export default async function getPostBySlug({
15
14
  }> {
16
15
  const contactPage = language === "DE" ? "contact-de" : "contact";
17
16
 
18
- const query = gql`
17
+ const query = `
19
18
  query GetPostBySlug($slug: ID!) {
20
19
  post(id: $slug, idType: SLUG) {
21
20
  id
@@ -133,7 +132,7 @@ export default async function getPostBySlug({
133
132
  `;
134
133
 
135
134
  const variables = { slug };
136
- const data: { post: Post; contactPage: ContactPage } = await client.request(
135
+ const data: { post: Post; contactPage: ContactPage } = await request(
137
136
  query,
138
137
  variables
139
138
  );
@@ -1,6 +1,5 @@
1
- import { gql } from "graphql-request";
2
1
  import { Post, Variables } from "../../lib/types";
3
- import client from "./client";
2
+ import { request } from "./client";
4
3
 
5
4
  interface Params {
6
5
  searchTerm?: string;
@@ -55,7 +54,7 @@ export default async function getPosts(
55
54
  const whereClause =
56
55
  whereConditions.length > 0 ? `where: { ${whereConditions.join(", ")}}` : "";
57
56
 
58
- const query = gql`
57
+ const query = `
59
58
  query GetPosts(${variableDefinitions}) {
60
59
  posts(
61
60
  ${isPrevious ? "last: $perPage" : "first: $perPage"},
@@ -116,7 +115,7 @@ export default async function getPosts(
116
115
  hasPreviousPage: boolean;
117
116
  };
118
117
  };
119
- } = await client.request(query, variables);
118
+ } = await request(query, variables);
120
119
 
121
120
  return {
122
121
  posts: data.posts.nodes,
@@ -330,6 +330,7 @@ export type Hub = {
330
330
  }[];
331
331
  approach: string;
332
332
  relatedWork: Case[];
333
+ capabilitiesHeading: string;
333
334
  capabilities: {
334
335
  heading: string;
335
336
  text: string;
package/lib/utils.ts CHANGED
@@ -1,3 +1,76 @@
1
- export const translate = (text: string) => {
2
- return text;
1
+ type Translations = Record<string, { DE?: string; EN?: string }>;
2
+
3
+ const strings: Translations = {
4
+ "Get in touch": {
5
+ DE: "Kontakt aufnehmen",
6
+ },
7
+ "Tell us about your brand and discover how we can help.": {
8
+ DE: "Erzählen Sie uns von Ihrer Marke und entdecken Sie, wie wir Ihnen helfen können.",
9
+ },
10
+ "Success stories.\nWith proven results.": {
11
+ DE: "Erfolgsgeschichten.\nMit messbaren Ergebnissen.",
12
+ },
13
+ Berlin: {
14
+ DE: "Berlin",
15
+ },
16
+ Zurich: {
17
+ DE: "Zürich",
18
+ },
19
+ "Service Hubs": {
20
+ DE: "Hubs",
21
+ },
22
+ "About Us": {
23
+ DE: "Über uns",
24
+ },
25
+ "Case Studies": {
26
+ DE: "Cases",
27
+ },
28
+ Contact: {
29
+ DE: "Kontakt",
30
+ },
31
+ "Contact Us": {
32
+ DE: "Kontakt",
33
+ },
34
+ "Follow Us": {
35
+ DE: "Folge uns",
36
+ },
37
+ Imprint: {
38
+ DE: "Impressum",
39
+ },
40
+ Terms: {
41
+ DE: "Terms & Conditions",
42
+ },
43
+ "Privacy policy": {
44
+ DE: "Datenschutz",
45
+ },
46
+ "Team & Careers": {
47
+ DE: "Team & Karriere",
48
+ },
49
+ "News & Insights": {
50
+ DE: "News & Insights",
51
+ },
52
+ "": {
53
+ DE: "",
54
+ },
55
+ "": {
56
+ DE: "",
57
+ },
58
+ "": {
59
+ DE: "",
60
+ },
61
+ };
62
+
63
+ export const translate = (text: string, lang: "DE" | "EN" = "EN") => {
64
+ if (lang === "EN") return text;
65
+
66
+ let trans: string | undefined = "";
67
+
68
+ Object.keys(strings).forEach((key: string) => {
69
+ if (key === text) {
70
+ trans = strings[key][lang];
71
+ return;
72
+ }
73
+ });
74
+
75
+ return trans || text;
3
76
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foundry-component-library",
3
- "version": "0.2.31",
3
+ "version": "0.2.33",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -67,7 +67,6 @@
67
67
  "@react-three/drei": "^10.7.7",
68
68
  "@react-three/fiber": "^9.4.2",
69
69
  "@react-three/postprocessing": "^3.0.4",
70
- "graphql-request": "^7.1.2",
71
70
  "three": "^0.182.0"
72
71
  }
73
72
  }