From 2c21d5f6c57562ba6a6b456826a76da782ac6803 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Mon, 6 Feb 2023 22:01:49 -0500 Subject: [PATCH] feat: Extract reusable block & add catalog section to home page Signed-off-by: Carlos Esteban Lopez --- .../banner-section-columns.module.scss | 43 +++++ .../banner-section/banner-section-columns.tsx | 34 ++++ .../banner-section/banner-section.module.scss | 29 ++++ .../banner-section/banner-section.tsx | 27 ++++ .../content-block/content-block.module.scss | 22 +++ .../content-block/content-block.tsx | 55 +++++++ microsite-next/src/pages/home/_home.tsx | 152 ++++++++++++++---- .../src/pages/home/home.module.scss | 44 +++-- 8 files changed, 360 insertions(+), 46 deletions(-) create mode 100644 microsite-next/src/components/banner-section/banner-section-columns.module.scss create mode 100644 microsite-next/src/components/banner-section/banner-section-columns.tsx create mode 100644 microsite-next/src/components/banner-section/banner-section.module.scss create mode 100644 microsite-next/src/components/banner-section/banner-section.tsx create mode 100644 microsite-next/src/components/content-block/content-block.module.scss create mode 100644 microsite-next/src/components/content-block/content-block.tsx diff --git a/microsite-next/src/components/banner-section/banner-section-columns.module.scss b/microsite-next/src/components/banner-section/banner-section-columns.module.scss new file mode 100644 index 0000000000..32cc53eb5e --- /dev/null +++ b/microsite-next/src/components/banner-section/banner-section-columns.module.scss @@ -0,0 +1,43 @@ +.bannerSection { + display: block; + + &:global(.greyBackground) { + background: linear-gradient(90.49deg, #121212 15.36%, #282828 70.44%); + } + + &:global(.greenGradientBackground) { + background: linear-gradient( + 178.64deg, + hsla(0, 0%, 100%, 0) 57.61%, + hsla(0, 0%, 100%, 0.17) 127.71% + ), + linear-gradient( + 144.35deg, + rgba(98, 197, 179, 0) 56.68%, + rgba(98, 197, 179, 0.59) 109.25% + ), + linear-gradient( + 192.29deg, + rgba(155, 240, 225, 0) 54.17%, + rgba(155, 240, 225, 0.67) 137.34% + ); + } + + &:global(.greenBottomGradientBackground) { + background: linear-gradient( + 178.64deg, + hsla(0, 0%, 100%, 0) 57.61%, + hsla(0, 0%, 100%, 0.17) 127.71% + ), + linear-gradient( + 144.35deg, + rgba(98, 197, 179, 0) 56.68%, + rgba(98, 197, 179, 0.59) 109.25% + ), + linear-gradient( + 192.29deg, + rgba(155, 240, 225, 0) 54.17%, + rgba(155, 240, 225, 0.67) 137.34% + ); + } +} diff --git a/microsite-next/src/components/banner-section/banner-section-columns.tsx b/microsite-next/src/components/banner-section/banner-section-columns.tsx new file mode 100644 index 0000000000..db33b52961 --- /dev/null +++ b/microsite-next/src/components/banner-section/banner-section-columns.tsx @@ -0,0 +1,34 @@ +import clsx from 'clsx'; +import React, { PropsWithChildren, ReactNode } from 'react'; + +import bannerColumnStyles from './banner-section-columns.module.scss'; + +export type IBannerSectionColumnsProps = PropsWithChildren<{ + header?: ReactNode; + // children: ReactNode | ReactNode[]; +}>; + +export const BannerSectionColumns = ({ + header, + children, +}: IBannerSectionColumnsProps) => ( + <> + {header && ( +
+
{header}
+
+ )} + + {Array.isArray(children) ? ( +
+ {children.map((child, index) => ( +
+ {child} +
+ ))} +
+ ) : ( + children + )} + +); diff --git a/microsite-next/src/components/banner-section/banner-section.module.scss b/microsite-next/src/components/banner-section/banner-section.module.scss new file mode 100644 index 0000000000..478790877c --- /dev/null +++ b/microsite-next/src/components/banner-section/banner-section.module.scss @@ -0,0 +1,29 @@ +.bannerSection { + display: block; + + &:global(.greyBackground) { + background: linear-gradient(90.49deg, #121212 15.36%, #282828 70.44%); + } + + &:global(.greenGradientBackground) { + background: linear-gradient(70.44deg, #121212 55%, #5d817b); + } + + &:global(.greenBottomGradientBackground) { + background: linear-gradient( + 178.64deg, + hsla(0, 0%, 100%, 0) 57.61%, + hsla(0, 0%, 100%, 0.17) 127.71% + ), + linear-gradient( + 144.35deg, + rgba(98, 197, 179, 0) 56.68%, + rgba(98, 197, 179, 0.59) 109.25% + ), + linear-gradient( + 192.29deg, + rgba(155, 240, 225, 0) 54.17%, + rgba(155, 240, 225, 0.67) 137.34% + ); + } +} diff --git a/microsite-next/src/components/banner-section/banner-section.tsx b/microsite-next/src/components/banner-section/banner-section.tsx new file mode 100644 index 0000000000..d3530d7e49 --- /dev/null +++ b/microsite-next/src/components/banner-section/banner-section.tsx @@ -0,0 +1,27 @@ +import clsx from 'clsx'; +import React, { PropsWithChildren } from 'react'; + +import bannerStyles from './banner-section.module.scss'; + +export type IBannerSectionProps = PropsWithChildren<{ + greyBackground?: boolean; + greenGradientBackground?: boolean; + greenBottomGradientBackground?: boolean; +}>; + +export const BannerSection = ({ + children, + greyBackground = false, + greenGradientBackground = false, + greenBottomGradientBackground = false, +}: IBannerSectionProps) => ( +
+
{children}
+
+); diff --git a/microsite-next/src/components/content-block/content-block.module.scss b/microsite-next/src/components/content-block/content-block.module.scss new file mode 100644 index 0000000000..77f98400f7 --- /dev/null +++ b/microsite-next/src/components/content-block/content-block.module.scss @@ -0,0 +1,22 @@ +.contentBlock { + gap: 1.5rem; + display: grid; + + > *, + h1, + h2 { + margin: 0; + padding: 0; + } + + :global(.bulletLine) { + width: 50px; + margin-bottom: 0.5rem; + } + + :global(.actionButtons) { + gap: 1rem; + display: grid; + grid-template-columns: repeat(2, auto); + } +} diff --git a/microsite-next/src/components/content-block/content-block.tsx b/microsite-next/src/components/content-block/content-block.tsx new file mode 100644 index 0000000000..4c1cc6272e --- /dev/null +++ b/microsite-next/src/components/content-block/content-block.tsx @@ -0,0 +1,55 @@ +import Link from '@docusaurus/Link'; +import clsx from 'clsx'; +import React, { FC, PropsWithChildren, ReactNode } from 'react'; + +import contentBlockStyles from './content-block.module.scss'; + +export interface ContentBlockActionButtonProps { + label: string; + link: string; +} + +export type IContentBlockProps = PropsWithChildren<{ + title?: ReactNode; + className?: string; + topImgSrc?: string; + hasBulletLine?: boolean; + actionButtons?: ContentBlockActionButtonProps[]; +}>; + +export const ContentBlock = ({ + children, + title, + className, + topImgSrc, + hasBulletLine, + actionButtons, +}: IContentBlockProps) => { + return ( +
+ {topImgSrc && {topImgSrc}} + +
+ {hasBulletLine &&
} + + {title && React.isValidElement(title) ? title :

{title}

} +
+ + {children &&

{children}

} + + {actionButtons && ( +
+ {actionButtons.map(({ link, label }, index) => ( + + {label} + + ))} +
+ )} +
+ ); +}; diff --git a/microsite-next/src/pages/home/_home.tsx b/microsite-next/src/pages/home/_home.tsx index f7ad7f6bf9..da99da6f1a 100644 --- a/microsite-next/src/pages/home/_home.tsx +++ b/microsite-next/src/pages/home/_home.tsx @@ -4,17 +4,20 @@ import Layout from '@theme/Layout'; import { clsx } from 'clsx'; import React from 'react'; +import { BannerSection } from '../../components/banner-section/banner-section'; import homeStyles from './home.module.scss'; +import { BannerSectionColumns } from '../../components/banner-section/banner-section-columns'; +import { ContentBlock } from '@site/src/components/content-block/content-block'; export function Home() { const { siteConfig } = useDocusaurusContext(); return ( -
-
-
-
+
+ + X
-
-
+ } + > + An open platform for building developer portals} + actionButtons={[ + { + link: 'https://github.com/backstage/backstage#getting-started', + label: 'GITHUB', + }, + { + link: 'https://info.backstage.spotify.com/office-hours', + label: 'OFFICE HOURS', + }, + ]} + > + Powered by a centralized software catalog, Backstage restores + order to your infrastructure and enables your product teams to + ship high-quality code quickly — without compromising autonomy. + -
-
-

An open platform for building developer portals

- -

- Powered by a centralized software catalog, Backstage restores - order to your infrastructure and enables your product teams to - ship high-quality code quickly — without compromising autonomy. -

- -
- - GITHUB - - - OFFICE HOURS - -
-
- -
+
+ + + + + + + At Spotify, we've always believed in the speed and ingenuity that + comes from having autonomous development teams. But as we learned + firsthand, the faster you grow, the more fragmented and complex + your software ecosystem becomes. And then everything slows down + again. + + + + By centralizing services and standardizing your tooling, Backstage + streamlines your development environment from end to end. Instead + of restricting autonomy, standardization frees your engineers from + infrastructure complexity. So you can return to building and + scaling, quickly and safely. + + + + + +
+
+ Software Catalog Planet GIF + +

Backstage Software Catalog

+ +

Build an ecosystem, not a wilderness

+
+ + + + + + + + Backstage makes it easy for one team to manage 10 services — and + makes it possible for your company to manage thousands of them + + + + Every team can see all the services they own and related resources + (deployments, data pipelines, pull request status, etc.) + + + + All that information can be shared with plugins inside Backstage + to enable other management features, like resource monitoring and + testing + + + + Libraries, websites, ML models — you name it, Backstage knows all + about it, including who owns it, dependencies, and more + + + + No more orphan software hiding in the dark corners of your tech + stack +
-
-
+ +
); } diff --git a/microsite-next/src/pages/home/home.module.scss b/microsite-next/src/pages/home/home.module.scss index ae804e344d..aa442a0c7b 100644 --- a/microsite-next/src/pages/home/home.module.scss +++ b/microsite-next/src/pages/home/home.module.scss @@ -26,19 +26,41 @@ } } -.openPlatformBanner { - :global(.svgContainer) { - position: relative; +.svgContainer { + position: relative; - :global(img.laptopSvg) { - width: 100%; - } + :global(img.laptopSvg) { + width: 100%; + } - :global(img.laptopScreenGif) { - position: absolute; - top: 3%; - left: 17%; - width: 70%; + :global(img.laptopScreenGif) { + position: absolute; + top: 3%; + left: 17%; + width: 70%; + } +} + +.catalogContainer { + gap: 2rem; + display: grid; + align-items: center; + + grid-template-columns: repeat(4, 1fr); + + picture { + display: block; + + grid-row: 1/3; + grid-column: 3/-1; + } + + :global(.catalogTitle) { + grid-column: 1/3; + + img { + max-width: 190px; + max-height: 190px; } } }