diff --git a/frontend/src/app/r-and-d/page.tsx b/frontend/src/app/r-and-d/page.tsx new file mode 100644 index 0000000..b44f583 --- /dev/null +++ b/frontend/src/app/r-and-d/page.tsx @@ -0,0 +1,21 @@ +import Hero from "@/components/ResearchDevelopment/Hero"; +import TabSection from "@/components/ResearchDevelopment/TabSection"; +import { heroQuery, HeroQueryType } from "@/queries/research-development/hero"; +import { + tabSectionQuery, + TabSectionQueryType, +} from "@/queries/research-development/tabs-data"; +import { request } from "@/utils/graphQLClient"; + +const ResearchDevelopment: React.FC = async () => { + const heroData = await request(heroQuery); + const tabsData = await request(tabSectionQuery); + return ( + <> + + + + ); +}; + +export default ResearchDevelopment; diff --git a/frontend/src/components/Earn/TabSection/CuratorTabContent/KlerosScoutSection.tsx b/frontend/src/components/Earn/TabSection/CuratorTabContent/KlerosScoutSection.tsx index d99d726..1c1d62c 100644 --- a/frontend/src/components/Earn/TabSection/CuratorTabContent/KlerosScoutSection.tsx +++ b/frontend/src/components/Earn/TabSection/CuratorTabContent/KlerosScoutSection.tsx @@ -39,7 +39,7 @@ const KlerosScoutSection: React.FC = ({ style={{ backgroundImage: `url(${background.url})` }} className={clsx( "relative h-[308px] rounded-2xl md:h-[380px]", - "bg-[#bca2df] bg-cover bg-[-314px] bg-blend-luminosity md:bg-[0px]", + "bg-cover bg-[-314px] md:bg-[0px]", "flex items-center justify-center pt-3 md:pt-0", )} > diff --git a/frontend/src/components/Pagination.tsx b/frontend/src/components/Pagination.tsx new file mode 100644 index 0000000..9da6a1d --- /dev/null +++ b/frontend/src/components/Pagination.tsx @@ -0,0 +1,34 @@ +import clsx from "clsx"; + +interface IPagination { + currentPage: number; + numPages: number; + callback: (newPage: number) => void; + className?: string; +} + +const Pagination: React.FC = ({ + currentPage, + numPages, + callback, + className, +}) => { + return ( +
+ {Array.from(Array(numPages), (_, index) => ( + + ))} +
+ ); +}; + +export default Pagination; diff --git a/frontend/src/components/ResearchDevelopment/Hero.tsx b/frontend/src/components/ResearchDevelopment/Hero.tsx new file mode 100644 index 0000000..30f15c7 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/Hero.tsx @@ -0,0 +1,60 @@ +import React from "react"; + +import Image from "next/image"; +import Link from "next/link"; + +import Button from "@/components/Button"; +import { HeroQueryType } from "@/queries/research-development/hero"; + +import ExternalLink from "../ExternalLink"; + +interface IHero { + heroData: HeroQueryType; +} + +const Hero: React.FC = ({ heroData }) => { + const { header, subtitle, buttons, arrowLink, background } = + heroData.rAndDPageHero; + return ( +
+
+

+ {header} +

+

{subtitle}

+
+ {buttons.map((button) => ( + + + + ))} +
+
+ {arrowLink.map((link) => ( + + ))} +
+
+ Hero Image Background +
+ ); +}; + +export default Hero; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Fellows/FellowCard.tsx b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Fellows/FellowCard.tsx new file mode 100644 index 0000000..177343a --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Fellows/FellowCard.tsx @@ -0,0 +1,44 @@ +import Image from "next/image"; + +import Divider from "@/components/Divider"; +import ExternalLink from "@/components/ExternalLink"; +import { Fellow } from "@/queries/research-development/tabs-data"; + +const FellowCard: React.FC = ({ + name, + profession, + profilePic, + workText, + reportUrl, + arrowLinkText, +}) => { + return ( +
+ Profile pic + +

{name}

+ + + +

{workText}

+
+ + +
+
+ ); +}; + +export default FellowCard; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Fellows/index.tsx b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Fellows/index.tsx new file mode 100644 index 0000000..ab2fa0e --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Fellows/index.tsx @@ -0,0 +1,45 @@ +import { useMemo, useState } from "react"; + +import Pagination from "@/components/Pagination"; +import { useScreenSize } from "@/hooks/useScreenSize"; +import { Fellow } from "@/queries/research-development/tabs-data"; + +import FellowCard from "./FellowCard"; + +const Fellows: React.FC<{ fellows: Fellow[] }> = ({ fellows }) => { + const [page, setPage] = useState(1); + + const screenSize = useScreenSize(); + + const itemsPerPage = useMemo( + () => (screenSize === "sm" ? 1 : 2), + [screenSize], + ); + + const items = useMemo( + () => + fellows.slice( + itemsPerPage * (page - 1), + Math.min(fellows.length, itemsPerPage * page), + ), + [itemsPerPage, page], + ); + + return ( +
+
+ {items.map((fellow) => ( + + ))} +
+ setPage(val)} + className="w-full justify-center" + /> +
+ ); +}; + +export default Fellows; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Testimonials/TestimonialCard.tsx b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Testimonials/TestimonialCard.tsx new file mode 100644 index 0000000..795e3d3 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Testimonials/TestimonialCard.tsx @@ -0,0 +1,19 @@ +import Image from "next/image"; +import Link from "next/link"; + +import { Testimonial } from "@/queries/research-development/tabs-data"; + +const TestimonialCard: React.FC = ({ url, thumbnail }) => ( + +
+ Thumbnail +
+ +); + +export default TestimonialCard; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Testimonials/index.tsx b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Testimonials/index.tsx new file mode 100644 index 0000000..b4d78d1 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/Testimonials/index.tsx @@ -0,0 +1,47 @@ +import { useMemo, useState } from "react"; + +import Pagination from "@/components/Pagination"; +import { useScreenSize } from "@/hooks/useScreenSize"; +import { Testimonial } from "@/queries/research-development/tabs-data"; + +import TestimonialCard from "./TestimonialCard"; + +const Testimonials: React.FC<{ testimonials: Testimonial[] }> = ({ + testimonials, +}) => { + const [page, setPage] = useState(1); + + const screenSize = useScreenSize(); + + const itemsPerPage = useMemo( + () => (screenSize === "sm" ? 1 : 3), + [screenSize], + ); + + const items = useMemo( + () => + testimonials.slice( + itemsPerPage * (page - 1), + Math.min(testimonials.length, itemsPerPage * page), + ), + [itemsPerPage, page], + ); + + return ( +
+
+ {items.map((testimonial, i) => ( + + ))} +
+ setPage(val)} + className="w-full justify-center" + /> +
+ ); +}; + +export default Testimonials; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/WaitlistSection.tsx b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/WaitlistSection.tsx new file mode 100644 index 0000000..71d1d3b --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/WaitlistSection.tsx @@ -0,0 +1,45 @@ +import clsx from "clsx"; +import Image from "next/image"; +import Link from "next/link"; + +import Button from "@/components/Button"; +import ExternalLink from "@/components/ExternalLink"; +import { RAndDPageWaitlistSection } from "@/queries/research-development/tabs-data"; + +const WaitlistSection: React.FC = ({ + header, + applyButton, + arrowLink, + icon, +}) => { + return ( +
+
+

+ {header} +

+
+ + + + +
+
+
+ Icon +
+
+ ); +}; + +export default WaitlistSection; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/index.tsx b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/index.tsx new file mode 100644 index 0000000..a20cfe6 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/FellowshipTabContent/index.tsx @@ -0,0 +1,39 @@ +import { + Fellow, + RAndDPageFellowshipTabSection, + Testimonial, +} from "@/queries/research-development/tabs-data"; + +import Fellows from "./Fellows"; +import Testimonials from "./Testimonials"; + +interface IFellowshipTabContent extends RAndDPageFellowshipTabSection { + testimonials: Testimonial[]; + fellows: Fellow[]; +} + +const FellowshipTabContent: React.FC = ({ + header, + subtitle, + testimonialsHeader, + fellowsHeader, + testimonials, + fellows, +}) => { + return ( +
+

+ {header} +

+

{subtitle}

+ +

{testimonialsHeader}

+ + +

{fellowsHeader}

+ +
+ ); +}; + +export default FellowshipTabContent; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/KlerosBook.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/KlerosBook.tsx new file mode 100644 index 0000000..b07eaa6 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/KlerosBook.tsx @@ -0,0 +1,47 @@ +import clsx from "clsx"; +import Image from "next/image"; +import Link from "next/link"; + +import Button from "@/components/Button"; +import { KlerosBook as IKlerosBook } from "@/queries/research-development/tabs-data"; + +const KlerosBook: React.FC = ({ + bookCover, + subtitle, + bookTitle, + downloadFormats, +}) => { + return ( +
+
+ Book Cover +
+
+
+

{subtitle}

+

{bookTitle}

+
+
+ {downloadFormats.map((format) => ( + + + + ))} +
+
+
+ ); +}; + +export default KlerosBook; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/PublicationCard.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/PublicationCard.tsx new file mode 100644 index 0000000..90e7562 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/PublicationCard.tsx @@ -0,0 +1,38 @@ +import Divider from "@/components/Divider"; +import ExternalLink from "@/components/ExternalLink"; +import { + TeamPublication, + ThirdPartyPublication, +} from "@/queries/research-development/tabs-data"; + +interface IPublicationCard { + publication: TeamPublication | ThirdPartyPublication; +} + +const PublicationCard: React.FC = ({ publication }) => { + return ( +
+ {(publication as TeamPublication)?.authors ? ( + <> +

+ {publication.topic} +

+

+ {(publication as TeamPublication).authors} +

+ + ) : ( +

{publication.topic}

+ )} +
+ + +
+
+ ); +}; +export default PublicationCard; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/TeamPublications.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/TeamPublications.tsx new file mode 100644 index 0000000..218b4c0 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/TeamPublications.tsx @@ -0,0 +1,47 @@ +import { useMemo, useState } from "react"; + +import Pagination from "@/components/Pagination"; +import { useScreenSize } from "@/hooks/useScreenSize"; +import { TeamPublication } from "@/queries/research-development/tabs-data"; + +import PublicationCard from "./PublicationCard"; + +const TeamPublications: React.FC<{ teamPublications: TeamPublication[] }> = ({ + teamPublications, +}) => { + const [page, setPage] = useState(1); + + const screenSize = useScreenSize(); + + const itemsPerPage = useMemo( + () => (screenSize === "sm" ? 1 : 3), + [screenSize], + ); + + const items = useMemo( + () => + teamPublications.slice( + itemsPerPage * (page - 1), + Math.min(teamPublications.length, itemsPerPage * page), + ), + [itemsPerPage, page], + ); + + return ( +
+
+ {items.map((publication) => ( + + ))} +
+ setPage(val)} + className="w-full justify-center" + /> +
+ ); +}; + +export default TeamPublications; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/ThirdPartyPublications.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/ThirdPartyPublications.tsx new file mode 100644 index 0000000..3105959 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/ThirdPartyPublications.tsx @@ -0,0 +1,47 @@ +import { useMemo, useState } from "react"; + +import Pagination from "@/components/Pagination"; +import { useScreenSize } from "@/hooks/useScreenSize"; +import { ThirdPartyPublication } from "@/queries/research-development/tabs-data"; + +import PublicationCard from "./PublicationCard"; + +const ThirdPartyPublications: React.FC<{ + thirdPartyPublications: ThirdPartyPublication[]; +}> = ({ thirdPartyPublications }) => { + const [page, setPage] = useState(1); + + const screenSize = useScreenSize(); + + const itemsPerPage = useMemo( + () => (screenSize === "sm" ? 1 : 6), + [screenSize], + ); + + const items = useMemo( + () => + thirdPartyPublications.slice( + itemsPerPage * (page - 1), + Math.min(thirdPartyPublications.length, itemsPerPage * page), + ), + [itemsPerPage, page], + ); + + return ( +
+
+ {items.map((publication) => ( + + ))} +
+ setPage(val)} + className="w-full justify-center" + /> +
+ ); +}; + +export default ThirdPartyPublications; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/index.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/index.tsx new file mode 100644 index 0000000..e63fc64 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/PublicationsSection/index.tsx @@ -0,0 +1,46 @@ +import { + RAndDPageResearchTabSection, + TeamPublication, + ThirdPartyPublication, +} from "@/queries/research-development/tabs-data"; + +import TeamPublications from "./TeamPublications"; +import ThirdPartyPublications from "./ThirdPartyPublications"; + +interface IPublicationSection + extends Pick< + RAndDPageResearchTabSection, + | "publicationsHeader" + | "publicationsTeamHeader" + | "publications3rdPartyHeader" + > { + teamPublications: TeamPublication[]; + thirdPartyPublications: ThirdPartyPublication[]; +} + +const PublicationSection: React.FC = ({ + publicationsHeader, + publicationsTeamHeader, + publications3rdPartyHeader, + teamPublications, + thirdPartyPublications, +}) => { + return ( +
+

+ {publicationsHeader} +

+ +

+ {publicationsTeamHeader} +

+ + +

+ {publications3rdPartyHeader} +

+ +
+ ); +}; +export default PublicationSection; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/ResearchSection/ResearchCard.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/ResearchSection/ResearchCard.tsx new file mode 100644 index 0000000..7c17ea0 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/ResearchSection/ResearchCard.tsx @@ -0,0 +1,22 @@ +import clsx from "clsx"; +import Image from "next/image"; + +import { Research } from "@/queries/research-development/tabs-data"; + +const ResearchCard: React.FC = ({ field, icon }) => { + return ( +
+ document + +
+ ); +}; + +export default ResearchCard; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/ResearchSection/index.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/ResearchSection/index.tsx new file mode 100644 index 0000000..791b513 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/ResearchSection/index.tsx @@ -0,0 +1,43 @@ +import { + RAndDPageResearchTabSection, + Research, +} from "@/queries/research-development/tabs-data"; + +import ResearchCard from "./ResearchCard"; + +interface IResearchSection + extends Pick< + RAndDPageResearchTabSection, + | "researchHeader" + | "researchSecondaryHeader" + | "researchParagraph" + | "researchCardLabel" + > { + researches: Research[]; +} + +const ResearchSection: React.FC = ({ + researchHeader, + researchParagraph, + researchSecondaryHeader, + researchCardLabel, + researches, +}) => { + return ( +
+

+ {researchHeader} +

+

{researchSecondaryHeader}

+

{researchParagraph}

+ +
+ {researches.map((research) => ( + + ))} +
+
+ ); +}; + +export default ResearchSection; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/index.tsx b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/index.tsx new file mode 100644 index 0000000..ed247f5 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/ResearchTabContent/index.tsx @@ -0,0 +1,25 @@ +import { + RAndDPageResearchTabSection, + Research, + TeamPublication, + ThirdPartyPublication, +} from "@/queries/research-development/tabs-data"; + +import PublicationSection from "./PublicationsSection"; +import ResearchSection from "./ResearchSection"; + +interface IResearchTabContent extends RAndDPageResearchTabSection { + researches: Research[]; + teamPublications: TeamPublication[]; + thirdPartyPublications: ThirdPartyPublication[]; +} +const ResearchTabContent: React.FC = (props) => { + return ( +
+ + +
+ ); +}; + +export default ResearchTabContent; diff --git a/frontend/src/components/ResearchDevelopment/TabSection/index.tsx b/frontend/src/components/ResearchDevelopment/TabSection/index.tsx new file mode 100644 index 0000000..4ee2b03 --- /dev/null +++ b/frontend/src/components/ResearchDevelopment/TabSection/index.tsx @@ -0,0 +1,61 @@ +"use client"; + +import { useMemo, useState } from "react"; + +import Tab from "@/components/Tab"; +import { TabSectionQueryType } from "@/queries/research-development/tabs-data"; + +import FellowshipTabContent from "./FellowshipTabContent"; +import WaitlistSection from "./FellowshipTabContent/WaitlistSection"; +import ResearchTabContent from "./ResearchTabContent"; +import KlerosBook from "./ResearchTabContent/KlerosBook"; + +interface ITabSection { + tabsData: TabSectionQueryType; +} + +const TabSection: React.FC = ({ tabsData }) => { + const [activeTab, setActiveTab] = useState(0); + + const tabItems = useMemo( + () => [ + { text: tabsData.rAndDPageResearchTabSection.tabName, value: 0 }, + { text: tabsData.rAndDPageFellowshipTabSection.tabName, value: 1 }, + ], + [tabsData], + ); + + return ( + <> +
+ { + setActiveTab(val); + }} + /> + {activeTab === 1 ? ( + + ) : ( + + )} +
+ + {activeTab === 1 ? ( + + ) : ( + + )} + + ); +}; +export default TabSection; diff --git a/frontend/src/hooks/useScreenSize.tsx b/frontend/src/hooks/useScreenSize.tsx new file mode 100644 index 0000000..6a344c5 --- /dev/null +++ b/frontend/src/hooks/useScreenSize.tsx @@ -0,0 +1,27 @@ +"use client"; + +import { useEffect, useState } from "react"; + +type ScreenSize = "sm" | "md" | "lg"; + +export const useScreenSize = () => { + const [screenSize, setScreenSize] = useState(); + + useEffect(() => { + const handleResize = () => { + if (window.innerWidth < 768) { + setScreenSize("sm"); + } else if (window.innerWidth >= 768 && window.innerWidth < 1024) { + setScreenSize("md"); + } else if (window.innerWidth >= 1024) { + setScreenSize("lg"); + } + }; + + window.addEventListener("resize", handleResize); + handleResize(); + + return () => window.removeEventListener("resize", handleResize); + }, []); + return screenSize; +}; diff --git a/frontend/src/queries/research-development/hero.ts b/frontend/src/queries/research-development/hero.ts new file mode 100644 index 0000000..6c0bc68 --- /dev/null +++ b/frontend/src/queries/research-development/hero.ts @@ -0,0 +1,39 @@ +import { gql } from "graphql-request"; + +import { ArrowLink } from "../navbar"; + +export const heroQuery = gql` + { + rAndDPageHero { + header + subtitle + buttons { + text + link { + url + } + } + arrowLink { + text + link { + url + } + } + background { + url + } + } + } +`; + +export type HeroQueryType = { + rAndDPageHero: { + header: string; + subtitle: string; + buttons: ArrowLink[]; + arrowLink: ArrowLink[]; + background: { + url: string; + }; + }; +}; diff --git a/frontend/src/queries/research-development/tabs-data.ts b/frontend/src/queries/research-development/tabs-data.ts new file mode 100644 index 0000000..a682593 --- /dev/null +++ b/frontend/src/queries/research-development/tabs-data.ts @@ -0,0 +1,187 @@ +import { gql } from "graphql-request"; + +import { ArrowLink } from "../navbar"; + +export const tabSectionQuery = gql` + { + rAndDPageResearchTabSection { + tabName + + researchHeader + researchSecondaryHeader + researchParagraph + researchCardLabel + + publicationsHeader + publicationsTeamHeader + publications3rdPartyHeader + + klerosBook { + subtitle + bookTitle + downloadFormats { + text + link { + url + } + } + bookCover { + url + } + } + } + + rAndDPageFellowshipTabSection { + tabName + header + subtitle + testimonialsHeader + fellowsHeader + waitlistSection { + header + applyButton { + text + link { + url + } + } + arrowLink { + text + link { + url + } + } + icon { + url + } + } + } + + researches(pagination: { limit: 50 }) { + field + icon { + url + } + } + + teamPublications(pagination: { limit: 50 }) { + topic + authors + paperLink { + text + link { + url + } + } + } + + thirdPartyPublications(pagination: { limit: 50 }) { + topic + paperLink { + text + link { + url + } + } + } + + testimonials(pagination: { limit: 50 }) { + url + thumbnail { + url + } + } + + fellows(pagination: { limit: 50 }) { + name + profession + workText + arrowLinkText + reportUrl + profilePic { + url + } + } + } +`; + +export type Research = { + field: string; + icon: { url: string }; +}; + +export type TeamPublication = { + topic: string; + authors: string; + paperLink: ArrowLink; +}; + +export type ThirdPartyPublication = { + topic: string; + paperLink: ArrowLink; +}; + +export type Testimonial = { + url: string; + thumbnail: { url: string }; +}; + +export type Fellow = { + name: string; + profession: string; + workText: string; + arrowLinkText: string; + reportUrl: string; + profilePic: { + url: string; + }; +}; + +export type KlerosBook = { + subtitle: string; + bookTitle: string; + downloadFormats: ArrowLink[]; + bookCover: { + url: string; + }; +}; + +export type RAndDPageResearchTabSection = { + tabName: string; + researchHeader: string; + researchSecondaryHeader: string; + researchParagraph: string; + researchCardLabel: string; + publicationsHeader: string; + publicationsTeamHeader: string; + publications3rdPartyHeader: string; + klerosBook: KlerosBook; +}; + +export type RAndDPageWaitlistSection = { + header: string; + applyButton: ArrowLink; + arrowLink: ArrowLink; + icon: { + url: string; + }; +}; + +export type RAndDPageFellowshipTabSection = { + tabName: string; + header: string; + subtitle: string; + testimonialsHeader: string; + fellowsHeader: string; + waitlistSection: RAndDPageWaitlistSection; +}; + +export type TabSectionQueryType = { + rAndDPageResearchTabSection: RAndDPageResearchTabSection; + rAndDPageFellowshipTabSection: RAndDPageFellowshipTabSection; + researches: Research[]; + teamPublications: TeamPublication[]; + thirdPartyPublications: ThirdPartyPublication[]; + testimonials: Testimonial[]; + fellows: Fellow[]; +};