diff --git a/frontend/src/components/ForBuilders/Hero.tsx b/frontend/src/components/ForBuilders/Hero.tsx new file mode 100644 index 0000000..4c3ace1 --- /dev/null +++ b/frontend/src/components/ForBuilders/Hero.tsx @@ -0,0 +1,62 @@ +import React from "react"; + +import Image from "next/image"; +import Link from "next/link"; + +import LinkArrow from "@/assets/svgs/icons/link-arrow.svg"; +import Button from "@/components/Button"; +import { HeroQueryType } from "@/queries/for-builders/hero"; + +interface IHero { + heroData: HeroQueryType["forBuildersPageHero"]; +} + +const Hero: React.FC = ({ heroData }) => { + return ( +
+
+

{heroData.title}

+

{heroData.subtitle}

+
+ + + +
+
+ {heroData.arrowLink.map((arrowLink) => ( + + {arrowLink.text} + Arrow link image + + ))} +
+
+ Hero Image Background +
+ ); +}; + +export default Hero; diff --git a/frontend/src/components/ForBuilders/IntegrateSection/GetInTouch.tsx b/frontend/src/components/ForBuilders/IntegrateSection/GetInTouch.tsx new file mode 100644 index 0000000..fb40caf --- /dev/null +++ b/frontend/src/components/ForBuilders/IntegrateSection/GetInTouch.tsx @@ -0,0 +1,43 @@ +import React from "react"; + +import Link from "next/link"; +// import Image from "next/image"; + +import Button from "@/components/Button"; + +import { IntegrateQueryType } from "@/queries/for-builders/integrate"; + +interface IGetInTouch { + integrateData: IntegrateQueryType["forBuildersPageIntegrateSection"]; +} + +const GetInTouch: React.FC = ({ integrateData }) => { + return ( + <> +
+

+ {integrateData.getInTouchSection.header} +

+ + + +
+ {/* Get In Touch Image Background */} + + ); +}; +export default GetInTouch; diff --git a/frontend/src/components/ForBuilders/IntegrateSection/LearnMore.tsx b/frontend/src/components/ForBuilders/IntegrateSection/LearnMore.tsx new file mode 100644 index 0000000..1278706 --- /dev/null +++ b/frontend/src/components/ForBuilders/IntegrateSection/LearnMore.tsx @@ -0,0 +1,35 @@ +import React from "react"; + +import Link from "next/link"; +import Image from "next/image"; + +import LinkArrow from "@/assets/svgs/icons/link-arrow.svg"; + +import { IntegrateQueryType } from "@/queries/for-builders/integrate"; + +interface ILearnMore { + integrateData: IntegrateQueryType["forBuildersPageIntegrateSection"]; +} + +const LearnMore: React.FC = ({ integrateData }) => { + return ( + + + {integrateData.arrowLink.text} + + Arrow link image + + ); +}; +export default LearnMore; diff --git a/frontend/src/components/ForBuilders/IntegrateSection/index.tsx b/frontend/src/components/ForBuilders/IntegrateSection/index.tsx new file mode 100644 index 0000000..1707bbf --- /dev/null +++ b/frontend/src/components/ForBuilders/IntegrateSection/index.tsx @@ -0,0 +1,27 @@ +import React from "react"; + +import AppsDropdownContent from "@/components/Navbar/AppsDropdownContent"; + +import { IntegrateQueryType } from "@/queries/for-builders/integrate"; +import GetInTouch from "./GetInTouch"; +import LearnMore from "./LearnMore"; + +interface IIntegrateSection { + integrateData: IntegrateQueryType["forBuildersPageIntegrateSection"]; +} + +const IntegrateSection: React.FC = ({ integrateData }) => { + return ( +
+

+ {integrateData.header} +

+

{integrateData.title}

+

{integrateData.description}

+ + + +
+ ); +}; +export default IntegrateSection; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/Header.tsx b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/Header.tsx new file mode 100644 index 0000000..80dc352 --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/Header.tsx @@ -0,0 +1,29 @@ +import React from "react"; + +import Image from "next/image"; + +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; + +interface IHeader { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const Header: React.FC = ({ useCasesData }) => { + return ( +
+

+ {useCasesData.useCaseTitle} +

+

+ {useCasesData.useCaseDescription} +

+ UseCaseBanner mobile +
+ ); +}; +export default Header; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/Header.tsx b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/Header.tsx new file mode 100644 index 0000000..2756931 --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/Header.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; + +interface IHeader { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const Header: React.FC = ({ useCasesData }) => { + return ( +
+

+ {useCasesData.keyChallenges.title} +

+

+ {useCasesData.keyChallenges.description} +

+
+ ); +}; +export default Header; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/HowKlerosSolvesIt.tsx b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/HowKlerosSolvesIt.tsx new file mode 100644 index 0000000..cf7d64f --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/HowKlerosSolvesIt.tsx @@ -0,0 +1,64 @@ +import React from "react"; + +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; +import Card from "@/components/Navbar/AppsDropdownContent/Card"; +import Image from "next/image"; +import clsx from "clsx"; +import Link from "next/link"; + +const hoverEffect = clsx( + "hover:scale-[1.03] transform transition duration-100" +); + +interface IHowKlerosSolvesIt { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const HowKlerosSolvesIt: React.FC = ({ useCasesData }) => { + return ( +
+

+ {useCasesData.solutionSections.header} +

+
+

{useCasesData.solutionSections.title}

+
+ {useCasesData.solutionSections.description} +
+
+ {useCasesData.solutionSections.solutionHeader} +
+
+ +
+
+ {useCasesData.solutionSections.partnersHeader} +
+
+ {useCasesData.solutionSections.partners.map((partner) => ( + + {partner?.name} + + ))} +
+
+
+ ); +}; +export default HowKlerosSolvesIt; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/index.tsx b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/index.tsx new file mode 100644 index 0000000..dfb53d6 --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/KeyChallenges/index.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; +import Header from "./Header"; +import HowKlerosSolvesIt from "./HowKlerosSolvesIt"; + +interface IKeyChallenges { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const KeyChallenges: React.FC = ({ useCasesData }) => { + return ( +
+
+ +
+ ); +}; +export default KeyChallenges; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/LearnMore.tsx b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/LearnMore.tsx new file mode 100644 index 0000000..5c2ed35 --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/LearnMore.tsx @@ -0,0 +1,33 @@ +import React from "react"; + +import Link from "next/link"; +import Image from "next/image"; + +import LinkArrow from "@/assets/svgs/icons/link-arrow.svg"; + +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; + +interface ILearnMore { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const LearnMore: React.FC = ({ useCasesData }) => { + return ( + + {useCasesData.arrowLink.text} + Arrow link image + + ); +}; +export default LearnMore; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/index.tsx b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/index.tsx new file mode 100644 index 0000000..9baab6f --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/DAOSection/index.tsx @@ -0,0 +1,22 @@ +import React from "react"; + +import KeyChallenges from "./KeyChallenges"; +import Header from "./Header"; +import LearnMore from "./LearnMore"; + +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; + +interface IDAOSection { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const DAOSection: React.FC = ({ useCasesData }) => { + return ( +
+
+ + +
+ ); +}; +export default DAOSection; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/UseCasesCards.tsx b/frontend/src/components/ForBuilders/UseCasesSection/UseCasesCards.tsx new file mode 100644 index 0000000..9f137c5 --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/UseCasesCards.tsx @@ -0,0 +1,26 @@ +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; +import React from "react"; + +interface IUseCasesCards { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const UseCasesCards: React.FC = ({ useCasesData }) => { + return ( +
+ {useCasesData.useCases.map((useCase, index) => ( +
+ {useCase.name} +
+ ))} +
+ ); +}; +export default UseCasesCards; diff --git a/frontend/src/components/ForBuilders/UseCasesSection/index.tsx b/frontend/src/components/ForBuilders/UseCasesSection/index.tsx new file mode 100644 index 0000000..2120e58 --- /dev/null +++ b/frontend/src/components/ForBuilders/UseCasesSection/index.tsx @@ -0,0 +1,24 @@ +import React from "react"; + +import { UseCasesQueryType } from "@/queries/for-builders/use-cases"; + +import DAOSection from "./DAOSection"; +import UseCasesCards from "./UseCasesCards"; + +interface IUseCasesSection { + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; +} + +const UseCasesSection: React.FC = ({ useCasesData }) => { + return ( +
+

+ {useCasesData.sectionHeader} +

+ + +
+ ); +}; + +export default UseCasesSection; diff --git a/frontend/src/components/Navbar/AppsDropdownContent/Card.tsx b/frontend/src/components/Navbar/AppsDropdownContent/Card.tsx index 72cbdc9..5dbdb29 100644 --- a/frontend/src/components/Navbar/AppsDropdownContent/Card.tsx +++ b/frontend/src/components/Navbar/AppsDropdownContent/Card.tsx @@ -7,7 +7,7 @@ const hoverEffect = clsx( "hover:scale-[1.01] transform transition duration-100" ); const cardBaseStyle = clsx( - "bg-background-2 rounded-lg border border-stroke text-wrap", + "bg-background-2 rounded-2xl border border-stroke text-wrap", "p-4 flex gap-4 h-full lg:items-start" ); const headerTextStyle = clsx("text-primary-purple font-bold text-base"); diff --git a/frontend/src/components/Navbar/AppsDropdownContent/index.tsx b/frontend/src/components/Navbar/AppsDropdownContent/index.tsx index 486b06d..7857190 100644 --- a/frontend/src/components/Navbar/AppsDropdownContent/index.tsx +++ b/frontend/src/components/Navbar/AppsDropdownContent/index.tsx @@ -3,7 +3,7 @@ import Card from "./Card"; import LinkArrow from "@/assets/svgs/icons/link-arrow.svg"; import Image from "next/image"; import clsx from "clsx"; -import Link from "next/link" +import Link from "next/link"; interface AppsDropdownContentProps { appsSection: AppsSection; diff --git a/frontend/src/components/Navbar/index.tsx b/frontend/src/components/Navbar/index.tsx index 08697c0..c6ebf75 100644 --- a/frontend/src/components/Navbar/index.tsx +++ b/frontend/src/components/Navbar/index.tsx @@ -20,7 +20,7 @@ export const overlayStyle = clsx( const headerBaseStyle = clsx( "flex fixed top-0 left-0 right-0 z-50 h-20 w-full", - "justify-between items-center text-white shadow-sm", + "justify-between items-center text-white", "py-2 text-base transition-colors duration-500" ); diff --git a/frontend/src/pages/for-builders.tsx b/frontend/src/pages/for-builders.tsx new file mode 100644 index 0000000..e49ffde --- /dev/null +++ b/frontend/src/pages/for-builders.tsx @@ -0,0 +1,67 @@ +import { graphQLClient } from "@/utils/graphQLClient"; +import Footer from "@/components/Footer"; +import Hero from "@/components/ForBuilders/Hero"; +import Navbar from "@/components/Navbar"; +import UseCasesSection from "@/components/ForBuilders/UseCasesSection"; +import IntegrateSection from "@/components/ForBuilders/IntegrateSection"; +import { footerQuery, FooterQueryType } from "@/queries/footer"; +import { navbarQuery, NavbarQueryType } from "@/queries/navbar"; +import { heroQuery, HeroQueryType } from "@/queries/for-builders/hero"; +import { + useCasesQuery, + UseCasesQueryType, +} from "@/queries/for-builders/use-cases"; +import { + integrateQuery, + IntegrateQueryType, +} from "@/queries/for-builders/integrate"; + +interface IForBuilders { + navbarData: NavbarQueryType; + footerData: FooterQueryType; + heroData: HeroQueryType["forBuildersPageHero"]; + useCasesData: UseCasesQueryType["forBuildersPageUseCasesSection"]; + integrateData: IntegrateQueryType["forBuildersPageIntegrateSection"]; +} + +const ForBuilders: React.FC = ({ + footerData, + heroData, + navbarData, + useCasesData, + integrateData, +}) => { + return ( +
+ + + + +
+
+ ); +}; + +export const getStaticProps = async () => { + const navbarData = await graphQLClient.request(navbarQuery); + const footerData = await graphQLClient.request(footerQuery); + const heroData = await graphQLClient.request(heroQuery); + const useCasesData = await graphQLClient.request( + useCasesQuery + ); + const integrateData = await graphQLClient.request( + integrateQuery + ); + + return { + props: { + navbarData, + footerData, + heroData: heroData.forBuildersPageHero, + useCasesData: useCasesData.forBuildersPageUseCasesSection, + integrateData: integrateData.forBuildersPageIntegrateSection, + }, + }; +}; + +export default ForBuilders; diff --git a/frontend/src/queries/for-builders/hero.tsx b/frontend/src/queries/for-builders/hero.tsx new file mode 100644 index 0000000..a1c37a2 --- /dev/null +++ b/frontend/src/queries/for-builders/hero.tsx @@ -0,0 +1,47 @@ +import { gql } from "graphql-request"; + +export const heroQuery = gql` + { + forBuildersPageHero { + title + subtitle + button { + text + link { + url + } + } + arrowLink { + text + link { + url + } + } + background { + url + } + } + } +`; + +export type HeroQueryType = { + forBuildersPageHero: { + title: string; + subtitle: string; + button: { + text: string; + link: { + url: string; + }; + }; + arrowLink: { + text: string; + link: { + url: string; + }; + }[]; + background: { + url: string; + }; + }; +}; diff --git a/frontend/src/queries/for-builders/integrate.tsx b/frontend/src/queries/for-builders/integrate.tsx new file mode 100644 index 0000000..dd3749a --- /dev/null +++ b/frontend/src/queries/for-builders/integrate.tsx @@ -0,0 +1,78 @@ +import { gql } from "graphql-request"; +import { AppsSection } from "../navbar"; + +export const integrateQuery = gql` + { + forBuildersPageIntegrateSection { + header + title + description + appsSection { + solutions { + solution_name + header_title + header_description + logo_svg { + url + } + url + } + arrowLink { + text + link { + url + } + } + } + getInTouchSection { + header + button { + text + link { + name + url + } + } + background { + url + } + } + arrowLink { + text + link { + name + url + } + } + } + } +`; + +export type IntegrateQueryType = { + forBuildersPageIntegrateSection: { + header: string; + title: string; + description: string; + appsSection: AppsSection; + getInTouchSection: { + header: string; + button: { + text: string; + link: { + name: string; + url: string; + }; + }; + background: { + url: string; + }; + }; + arrowLink: { + text: string; + link: { + name: string; + url: string; + }; + }; + }; +}; diff --git a/frontend/src/queries/for-builders/use-cases.tsx b/frontend/src/queries/for-builders/use-cases.tsx new file mode 100644 index 0000000..07fd2a7 --- /dev/null +++ b/frontend/src/queries/for-builders/use-cases.tsx @@ -0,0 +1,97 @@ +import { gql } from "graphql-request"; + +export const useCasesQuery = gql` + { + forBuildersPageUseCasesSection { + sectionHeader + useCases { + name + } + useCaseTitle + useCaseDescription + useCaseBanner { + url + } + keyChallenges { + title + description + } + solutionSections { + header + title + description + solutionHeader + solution { + solution_name + header_title + logo_svg { + url + } + url + } + partnersHeader + partners { + name + icon_svg { + url + } + url + } + } + arrowLink { + text + link { + name + url + } + } + } + } +`; + +export type UseCasesQueryType = { + forBuildersPageUseCasesSection: { + sectionHeader: string; + useCases: { + name: string; + }[]; + useCaseTitle: string; + useCaseDescription: string; + useCaseBanner: { + url: string; + }; + keyChallenges: { + title: string; + description: string; + }; + solutionSections: { + header: string; + title: string; + description: string; + solutionHeader: string; + solution: { + solution_name: string; + header_title: string; + logo_svg: { + url: string; + }; + url: string; + }; + partnersHeader: string; + partners: { + name: string; + icon_svg: { + url: string; + }; + url: string; + }[]; + }; + arrowLink: { + text: string; + link: { + name: string; + url: string; + }; + }; + }; +}; diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css index 0a8d866..623269b 100644 --- a/frontend/src/styles/globals.css +++ b/frontend/src/styles/globals.css @@ -64,3 +64,25 @@ body { max-height: 332px; opacity: 1; } + +.border-gradient-purple-blue { + position: relative; + border-radius: 9999px; + z-index: 1; +} + +.border-gradient-purple-blue::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: inherit; + padding: 2px; + background: linear-gradient(to bottom, #9747ff, #27cdfe); + -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); + mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); + mask-composite: exclude; + z-index: -1; +}