Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat navbar improves #183

Merged
merged 4 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/CascadingMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export const NavMenuTopLevel = ({ item }: { item: NavItem }) => {

export const NavMenuList = ({ item }: { item: NavItem }) => {
const [open, setOpen] = useState(false)

let button = (
<ListItemButton
onClick={() => {
Expand Down
12 changes: 12 additions & 0 deletions src/components/HeaderNavbar/Card/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react"
import clsx from "clsx"

const HeaderCard = ({ show, children, customRef, ...props }) => {
return (
<div ref={customRef} className={clsx("header-card", show && "show")} {...props}>
{children}
</div>
)
}

export default HeaderCard
35 changes: 35 additions & 0 deletions src/components/HeaderNavbar/CardItem/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react"
import { Link } from "gatsby"
import { OutboundLink } from "gatsby-plugin-google-gtag"
import { isDesktop } from "react-device-detect"

const ItemLink = ({ name, description, Image, to }) => {
const LinkElement: any = to[0] === '/' ? Link : OutboundLink
const linkProps = to[0] === '/' ? { to } : { href: to }

return (
<LinkElement {...linkProps}>
<div className="card-item">
{Image && <div className="icon"><Image /></div>}
<div>
<p className="title">{name}</p>
{description && <p className="description">{description}</p>}
</div>
</div>
</LinkElement>
)
}

const HeaderCardItem = ({ title, items = [], children, onlyContent, ...props }: any) => {
return (
<div {...props}>
{(!onlyContent || isDesktop) && <p className="card-title">{title}</p>}
<div className="content">
{items.map((item, index) => <ItemLink key={index} {...item} />)}
{children}
</div>
</div>
)
}

export default HeaderCardItem
70 changes: 70 additions & 0 deletions src/components/HeaderNavbar/Product/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { useRef, useEffect } from "react"
import clsx from "clsx"
import { Link } from "gatsby"
import { isDesktop } from "react-device-detect"

import Chevron from "@mui/icons-material/ChevronRight"
import NavbarImage from "../../../svgs/navbar-image-1.svg"

import { products, compare } from "./items"

import Card from "../Card"
import CardItem from "../CardItem"

const HeaderNavbarProduct = ({ active, setActive }) => {
const wrapperRef = useRef(null);

const onClick = (ev) => {
ev.preventDefault()
if (!isDesktop) setActive((prev) => prev === 'product' ? '' : 'product')
}

const onMouseEnter = (ev) => {
ev.preventDefault()
if (isDesktop) setActive('product')
}

const onMouseLeave = (ev) => {
ev.preventDefault()
if (isDesktop) setActive('')
}

useEffect(() => {
function handleClickOutside(event) {
if (isDesktop && wrapperRef.current && !wrapperRef.current.contains(event.target) && !event.target.className?.includes?.('active')) {
setActive('')
}
}

if (active) document.addEventListener("mousedown", handleClickOutside)

return () => {
document.removeEventListener("mousedown", handleClickOutside)
};
}, [active]);

return (
<>
<Link className={clsx("global-header-link", active && "active")} to="#" onClick={onClick} onMouseEnter={onMouseEnter}>
Product
<Chevron className="menu-chevron" fontSize="small" />
</Link>
<Card customRef={wrapperRef} show={active} onMouseLeave={onMouseLeave}>
<CardItem title="PRODUCT" onlyContent items={products} />
<CardItem title="COMPARE" items={compare} />
<CardItem className="hide-on-mobile" title="CASE STUDY">
<NavbarImage />
<Link
target="_blank"
to="/customers/connectngo"
className="cta-button"
>
Read Customer Story
</Link>
</CardItem>
</Card>
</>
)
}

export default HeaderNavbarProduct
30 changes: 30 additions & 0 deletions src/components/HeaderNavbar/Product/items.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react"
import { StaticImage } from "gatsby-plugin-image"

export const products = [
{
name: "Estuary Flow",
to: "/product",
description: "Build fully managed real-time data pipelines in minutes.",
Image: () => <StaticImage src="../../../images/header-book.png" width={20} height={20} alt="book" />
},
]

export const compare = [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should pull from Strapi like the current comparison links in the navbar do

{
name: "Estuary vs. Fivetran",
to: "/vs-fivetran",
},
{
name: "Estuary vs. Confluent",
to: "/vs-confluent",
},
{
name: "Estuary vs. Airbyte",
to: "/vs-airbyte",
},
{
name: "Estuary vs. Debezium",
to: "/vs-debezium",
},
]
72 changes: 72 additions & 0 deletions src/components/HeaderNavbar/Resources/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useState, useRef, useEffect } from "react"
import clsx from "clsx"
import { Link } from "gatsby"
import { OutboundLink } from "gatsby-plugin-google-gtag"
import { isDesktop } from "react-device-detect"

import Chevron from "@mui/icons-material/ChevronRight"
import NavbarImage from "../../../svgs/navbar-image-2.svg"

import { read, listen, tour, caseStudies } from "./items"

import Card from "../Card"
import CardItem from "../CardItem"

const HeaderNavbarResources = ({ active, setActive }) => {
const wrapperRef = useRef(null);

const onClick = (ev) => {
ev.preventDefault()
if (!isDesktop) setActive((prev) => prev === 'resources' ? '' : 'resources')
}

const onMouseEnter = (ev) => {
ev.preventDefault()
if (isDesktop) setActive('resources')
}

const onMouseLeave = (ev) => {
ev.preventDefault()
if (isDesktop) setActive('')
}

useEffect(() => {
function handleClickOutside(event) {
if (wrapperRef.current && !wrapperRef.current.contains(event.target) && !event.target.className?.includes?.('active')) {
setActive('')
}
}

if (active) document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [active]);

return (
<>
<Link className={clsx("global-header-link", active && "active")} to="#" onClick={onClick} onMouseEnter={onMouseEnter}>
Resources
<Chevron className="menu-chevron" fontSize="small" />
</Link>
<Card customRef={wrapperRef} show={active} onMouseLeave={onMouseLeave}>
<CardItem title="READ" onlyContent items={read} />
<CardItem className="no-padding" title="LISTEN" onlyContent items={listen} />
<CardItem className="hide-on-mobile" title="TOUR" items={tour} />
<CardItem className="hide-on-mobile" title="CASE STUDIES" items={caseStudies} />
<CardItem className="hide-on-mobile" title="WEBINAR">
<NavbarImage />
<OutboundLink
target="_blank"
href="https://try.estuary.dev/webinar-estuary101-ondemand"
className="cta-button"
>
Watch Estuary 101
</OutboundLink>
</CardItem>
</Card>
</>
)
}

export default HeaderNavbarResources
55 changes: 55 additions & 0 deletions src/components/HeaderNavbar/Resources/items.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export const read = [
{
name: "Blog",
to: "/blog/data-engineering",
},
{
name: "Docs",
to: "https://docs.estuary.dev",
},
{
name: "About Us",
to: "/about",
},
]

export const listen = [
{
name: "Podcasts",
to: "/podcasts",
},
{
name: "YouTube",
to: "https://www.youtube.com/watch?v=Ys5BoNqKljc",
},
{
name: "Webinars",
to: "https://try.estuary.dev/webinar-estuary101-ondemand",
},
]

export const tour = [
{
name: "Product Tour [2 min]",
to: "/why",
},
{
name: "Real-time 101 [30 min]",
to: "https://try.estuary.dev/webinar-estuary101-ondemand",
},
]

export const caseStudies = [
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should also pull from Strapi so when we publish more case studies they automatically show up

name: "True Platform",
to: "/customers/casestudy/trueplatform/",
},
{
name: "Soli & Company",
to: "/customers/casestudy/soli_&_company/",
},
{
name: "Connect&GO",
to: "/customers/connectngo/",
},
]
22 changes: 22 additions & 0 deletions src/components/HeaderNavbar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { useState } from "react"
import { Link } from "gatsby"
import { OutboundLink } from "gatsby-plugin-google-gtag"

import LinkProduct from "./Product"
import LinkResources from "./Resources"

const HeaderNavbar = () => {
const [current, setCurrent] = useState('')

return (
<div className="global-header-links">
<LinkProduct active={current === 'product'} setActive={setCurrent} />
<Link className="global-header-link" to="/pricing">Pricing</Link>
<Link className="global-header-link" to="/integrations">Connectors</Link>
<LinkResources active={current === 'resources'} setActive={setCurrent} />
<OutboundLink className="global-header-link" href="https://docs.estuary.dev">Docs</OutboundLink>
</div>
)
}

export default HeaderNavbar
Loading
Loading