diff --git a/pages/applications/[repo].tsx b/pages/applications/[repo].tsx
deleted file mode 100644
index 085b1e42..00000000
--- a/pages/applications/[repo].tsx
+++ /dev/null
@@ -1,478 +0,0 @@
-import { type ComponentProps, useEffect } from 'react'
-
-import { AppIcon, Code, ColorModeProvider } from '@pluralsh/design-system'
-import {
- type GetStaticPaths,
- type GetStaticProps,
- type InferGetStaticPropsType,
-} from 'next'
-import { useRouter } from 'next/router'
-
-import { until } from '@open-draft/until'
-import { providerToProviderName } from '@pluralsh/design-system/dist/markdoc/utils/text'
-import { isEmpty } from 'lodash-es'
-import styled, { useTheme } from 'styled-components'
-import { type MergeDeep } from 'type-fest'
-
-// import { ProductValueSection } from '@pages/plural-stacks/ProductValueSection'
-import client, { directusClient } from '@src/apollo-client'
-import { mqs } from '@src/breakpoints'
-import { BasicMarkdoc } from '@src/components/BasicMarkdoc'
-import Embed from '@src/components/Embed'
-import { FooterVariant } from '@src/components/FooterFull'
-import { Columns, EqualColumn } from '@src/components/layout/Columns'
-import {
- StandardPageSection,
- StandardPageWidth,
-} from '@src/components/layout/LayoutHelpers'
-import { TextLimiter } from '@src/components/layout/TextLimiter'
-import { BackButton } from '@src/components/Nav'
-import BuildStackSection from '@src/components/page-sections/BuildStackSection'
-import {
- CaseStudySection,
- getCaseStudyApps,
-} from '@src/components/page-sections/CaseStudySection'
-import { HPWMiniSectionAppStacks } from '@src/components/page-sections/HowPluralWorksMiniSection'
-import { StandardFAQSection } from '@src/components/page-sections/StandardFAQSection'
-import { TestimonialsSection } from '@src/components/QuoteCards'
-import RepoReadmeMd from '@src/components/RepoReadme/RepoReadmeMd'
-import { SingleAccordion } from '@src/components/SingleAccordion'
-import { AppTitle, Cta } from '@src/components/Typography'
-import { QUICKSTART_VIDEO_URL, getAppMeta, getProviderIcon } from '@src/consts'
-import {
- type BasicRepo,
- type FullRepo,
- type TinyRepo,
- getFullRepo,
- getTinyRepos,
-} from '@src/data/getRepos'
-import { getStacks } from '@src/data/getStacks'
-import { getStackTabData } from '@src/data/getStackTabData'
-import {
- type AppDefaultsFragment,
- AppExtrasDocument,
- type AppExtrasFragment,
- type AppExtrasQuery,
- type AppExtrasQueryVariables,
- type FaqItemFragment,
- FaqListDocument,
- type FaqListQuery,
- type FaqListQueryVariables,
- type QuoteFragment,
-} from '@src/generated/graphqlDirectus'
-import {
- type Recipe,
- type RecipeFragment,
- RecipesDocument,
- type RecipesQuery,
- type RecipesQueryVariables,
-} from '@src/generated/graphqlPlural'
-import { cn as classNames } from '@src/utils/cn'
-import { combineErrors } from '@src/utils/combineErrors'
-import {
- type GlobalProps,
- propsWithGlobalSettings,
-} from '@src/utils/getGlobalProps'
-import { normalizeM2mItems, normalizeQuotes } from '@src/utils/normalizeQuotes'
-
-import { CompanyLogosSection } from '../../src/components/CompanyLogos'
-import { GradientBG } from '../../src/components/layout/GradientBG'
-import { HeaderPad } from '../../src/components/layout/HeaderPad'
-import { ProviderIcon } from '../../src/components/ProviderIcon'
-import { RepoSocials } from '../../src/components/RepoSocials'
-
-const DEFAULT_HERO_VIDEO = QUICKSTART_VIDEO_URL
-
-function isRecipe(
- recipe: RecipeFragment | null | undefined
-): recipe is RecipeFragment {
- return !!recipe
-}
-
-const AppPageTitle = styled(
- ({ app, ...props }: { app: BasicRepo } & ComponentProps<'div'>) => {
- const theme = useTheme()
- const iconProps = {
- url:
- (theme.mode === 'light'
- ? app.icon || app.darkIcon
- : app.darkIcon || app.icon) ?? '',
- }
-
- return (
-
- )
- }
-)(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- gap: theme.spacing.small,
- '.icon > .largeIcon': {
- display: 'none',
- },
- [mqs.md]: {
- '.icon': {
- '& > .smallIcon': {
- display: 'none',
- },
- '& > .largeIcon': {
- display: 'flex',
- },
- },
- },
-}))
-
-export type ProviderProps = {
- label?: string | null | undefined
- iconDark: string
- iconLight: string
-}
-
-export default function App({
- repo,
- heroVideo,
- heroText,
- secondaryTitle,
- secondaryText,
- caseStudy,
- quotes,
- recipes,
- buildStackTabs,
- caseStudyApps,
- faqs,
- globalProps,
-}: InferGetStaticPropsType) {
- const router = useRouter()
- const recipeTabs =
- recipes?.filter(isRecipe).map((recipe) => ({
- key: recipe.name,
- label:
- providerToProviderName[recipe?.provider?.toUpperCase() || ''] ||
- recipe.provider ||
- '',
- language: 'shell',
- content: `plural bundle install ${repo?.name} ${recipe.name}`,
- iconLight: getProviderIcon({ provider: recipe?.provider, mode: 'light' }),
- iconDark: getProviderIcon({ provider: recipe?.provider, mode: 'dark' }),
- })) || []
-
- useEffect(() => {
- if (!repo) {
- router.push('/marketplace')
- }
- }, [repo, router])
- if (!repo) {
- return null
- }
-
- return (
-
-
-
-
-
-
-
-
-
-
- {heroText ? (
-
- ) : (
-
{repo.description}
- )}
-
-
-
Available providers
- {!isEmpty(recipeTabs) ? (
-
- {recipeTabs.map((provider) => (
-
- ))}
-
- ) : (
-
Coming soon
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {!isEmpty(recipeTabs) && (
- <>
-
-
- Deploying {repo.displayName} is a matter of executing
- these 3 commands:
-
-
-
plural build
-
- {`plural deploy --commit "deploying ${repo.name}"`}
-
-
-
- Read the install documentation
-
- >
- )}
-
-
- {repo?.readme && (
-
-
-
-
-
- )}
-
-
-
- {buildStackTabs && }
-
-
-
-
-
-
- )
-}
-
-export function CaseStudyFAQSection({
- caseStudyProps,
- faqProps,
-}: {
- caseStudyProps?: ComponentProps
- faqProps: ComponentProps
-}) {
- return (
-
-
- {caseStudyProps?.featuredArticle && (
-
-
-
- )}
-
-
-
- )
-}
-
-export const getStaticPaths: GetStaticPaths = async () => {
- if (process.env.NODE_ENV === 'development') {
- return {
- paths: [],
- fallback: 'blocking',
- }
- }
-
- const repos = (await getTinyRepos()) || []
-
- return {
- paths: repos.map((repo) => ({ params: { repo: repo?.name } })),
- fallback: true,
- }
-}
-
-export type AppPageProps = {
- repo?: FullRepo | null
- quotes: QuoteFragment[] | null
- heroVideo: Exclude<
- ReturnType['heroVideo'],
- undefined
- >
- heroText: Exclude<
- ReturnType['hero_text'],
- undefined
- >
- secondaryTitle: Exclude<
- ReturnType['secondary_title'],
- undefined
- >
- secondaryText: Exclude<
- ReturnType['secondary_text'],
- undefined
- >
- caseStudy: Exclude<
- ReturnType['case_study'],
- undefined
- >
- recipes?: Recipe[]
- buildStackTabs?: ReturnType
- caseStudyApps: TinyRepo[]
- faqs: (FaqItemFragment | null)[]
- globalProps: GlobalProps
-}
-
-const normalizeAppExtras = (extras: AppExtrasQuery) =>
- ({
- ...(extras.app_defaults || {}),
- ...Object.fromEntries(
- Object.entries(extras.apps?.[0] || {}).filter(([_, val]) => !!val)
- ),
- }) as MergeDeep
-
-export const getStaticProps: GetStaticProps = async (context) => {
- const repoName = context?.params?.repo
-
- const { data: repos, error: reposError } = await until(() => getTinyRepos())
-
- const { data: repo, error: repoError } = await until(() =>
- getFullRepo(`${repoName}`)
- )
-
- const { data: stacks, error: stacksError } = await until(() => getStacks())
-
- const thisRepo = repo
-
- if (!thisRepo || !repoName || typeof repoName !== 'string') {
- return { notFound: true }
- }
-
- const { data: appData, error: appError } = await directusClient.query<
- AppExtrasQuery,
- AppExtrasQueryVariables
- >({
- query: AppExtrasDocument,
- variables: { name: repoName },
- })
-
- const { data: recipesData, error: recipesError } = await client.query<
- RecipesQuery,
- RecipesQueryVariables
- >({
- query: RecipesDocument,
- variables: {
- repoName,
- },
- })
-
- const buildStackTabs = getStackTabData({ repos, stacks })
-
- if (recipesError) {
- throw new Error(`${recipesError.name}: ${recipesError.message}`)
- }
-
- const recipes =
- recipesData?.recipes?.edges
- ?.map((edge) => edge?.node)
- .filter((r): r is Recipe => !!r && !r?.private) || []
-
- const appExtras = normalizeAppExtras(appData) || {}
-
- const { data: faqData, error: faqError } = await directusClient.query<
- FaqListQuery,
- FaqListQueryVariables
- >({
- query: FaqListDocument,
- variables: { slug: 'generic' },
- })
-
- return propsWithGlobalSettings({
- repo: thisRepo
- ? {
- ...thisRepo,
- }
- : null,
- caseStudy: appExtras.case_study || null,
- heroVideo: appExtras.heroVideo || null,
- heroText: appExtras.hero_text || null,
- secondaryText: appExtras.secondary_text || null,
- secondaryTitle: appExtras.secondary_title || null,
- quotes: normalizeQuotes(appExtras.quotes),
- recipes,
- ...getAppMeta(thisRepo),
- faqs: normalizeM2mItems(faqData.collapsible_lists?.[0]) || [],
- buildStackTabs,
- caseStudyApps: getCaseStudyApps(
- repos,
- (appExtras.case_study?.stack_apps as string[]) || []
- ),
- footerVariant: FooterVariant.kitchenSink,
- errors: combineErrors([
- reposError,
- stacksError,
- repoError,
- appError,
- faqError,
- ]),
- })
-}
diff --git a/pages/index.tsx b/pages/index.tsx
index 5b826154..12ed8ae5 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -176,6 +176,7 @@ function HeroImages({ ...props }: ComponentProps) {
export default function Index({
articleCards,
+ quotes,
}: InferGetStaticPropsType) {
const [showVideo, setShowVideo] = useState(false)
@@ -307,10 +308,7 @@ export default function Index({
diff --git a/pages/kubernetes-fleet-management.tsx b/pages/kubernetes-fleet-management.tsx
deleted file mode 100644
index 08738636..00000000
--- a/pages/kubernetes-fleet-management.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import { Button } from 'honorable'
-import { type InferGetStaticPropsType } from 'next'
-import Link from 'next/link'
-
-import { directusClient } from '@src/apollo-client'
-import { FooterVariant } from '@src/components/FooterFull'
-import { GradientBG } from '@src/components/layout/GradientBG'
-import {
- StandardPageSection,
- StandardPageWidth,
-} from '@src/components/layout/LayoutHelpers'
-import { TextLimiter } from '@src/components/layout/TextLimiter'
-import ArticleSection from '@src/components/page-sections/articleSection'
-import { ProductFeaturesSection } from '@src/components/page-sections/ProductFeatureSection'
-import { QuoteSection } from '@src/components/page-sections/QuoteSection'
-import { CenteredSectionHead } from '@src/components/SectionHeads'
-import { ResponsiveText } from '@src/components/Typography'
-import {
- PageHomepageDocument,
- type PageHomepageQuery,
- type PageHomepageQueryVariables,
-} from '@src/generated/graphqlDirectus'
-import { propsWithGlobalSettings } from '@src/utils/getGlobalProps'
-
-import { HeaderPad } from '../src/components/layout/HeaderPad'
-
-export default function Legal(
- _props: InferGetStaticPropsType
-) {
- return (
- <>
-
-
-
-
- Automating Kubernetes management and enhancing security for
- enterprises
-
-
-
- Book now
-
-
-
-
-
-
-
-
- Import manifests and helm charts from Git repositories and
- deploy services to clusters in a couple of clicks.
-
- }
- />
-
-
-
-
-
-
-
-
-
-
- >
- )
-}
-
-export const getStaticProps = async () => {
- const { data } = await directusClient.query<
- PageHomepageQuery,
- PageHomepageQueryVariables
- >({
- query: PageHomepageDocument,
- })
-
- return propsWithGlobalSettings({
- metaTitle: 'Kubernetes fleet management',
- metaDescription:
- 'An end-to-end solution for managing Kubernetes clusters and application deployment.',
- footerVariant: FooterVariant.kitchenSink,
- articleCards: data.page_homepage?.article_cards || null,
- })
-}
diff --git a/pages/plural-stacks/[stack].tsx b/pages/plural-stacks/[stack].tsx
deleted file mode 100644
index 7ccd0355..00000000
--- a/pages/plural-stacks/[stack].tsx
+++ /dev/null
@@ -1,383 +0,0 @@
-import { useEffect, useRef, useState } from 'react'
-
-import { Button, TabList, TabPanel } from '@pluralsh/design-system'
-import {
- type GetStaticPaths,
- type GetStaticProps,
- type InferGetStaticPropsType,
-} from 'next'
-import Link from 'next/link'
-import { useRouter } from 'next/router'
-
-import { until } from '@open-draft/until'
-import { providerToProviderName } from '@pluralsh/design-system/dist/markdoc/utils/text'
-import { isEmpty } from 'lodash-es'
-import styled from 'styled-components'
-import { type MergeDeep } from 'type-fest'
-
-import { CaseStudyFAQSection } from '@pages/applications/[repo]'
-import { directusClient } from '@src/apollo-client'
-import { AppCard } from '@src/components/AppOrStackCard'
-import Embed from '@src/components/Embed'
-import { FooterVariant } from '@src/components/FooterFull'
-import { GradientBG } from '@src/components/layout/GradientBG'
-import {
- StandardPageSection,
- StandardPageWidth,
-} from '@src/components/layout/LayoutHelpers'
-import { BackButton } from '@src/components/Nav'
-import BuildStackSection from '@src/components/page-sections/BuildStackSection'
-import { getCaseStudyApps } from '@src/components/page-sections/CaseStudySection'
-import { HPWMiniSectionAppStacks } from '@src/components/page-sections/HowPluralWorksMiniSection'
-import { ProviderIcon } from '@src/components/ProviderIcon'
-import { TestimonialsSection } from '@src/components/QuoteCards'
-import { RepoSocials } from '@src/components/RepoSocials'
-import { AppTitle } from '@src/components/Typography'
-import { getProviderIcon, getStackMeta } from '@src/consts'
-import { appUrl } from '@src/consts/routes'
-import { type TinyRepo, getTinyRepos, normalizeRepo } from '@src/data/getRepos'
-import { type FullStack, getFullStack, getStacks } from '@src/data/getStacks'
-import { getStackTabData } from '@src/data/getStackTabData'
-import {
- type FaqItemFragment,
- FaqListDocument,
- type FaqListQuery,
- type FaqListQueryVariables,
- type QuoteFragment,
- type StackDefaultsFragment,
- StackExtrasDocument,
- type StackExtrasFragment,
- type StackExtrasQuery,
- type StackExtrasQueryVariables,
-} from '@src/generated/graphqlDirectus'
-import {
- type BasicRepoFragment,
- type StackCollectionFragment,
-} from '@src/generated/graphqlPlural'
-import { cn as classNames } from '@src/utils/cn'
-import { combineErrors } from '@src/utils/combineErrors'
-import {
- type GlobalProps,
- propsWithGlobalSettings,
-} from '@src/utils/getGlobalProps'
-import { normalizeM2mItems, normalizeQuotes } from '@src/utils/normalizeQuotes'
-import { startsWithVowel } from '@src/utils/text'
-
-import { CompanyLogosSection } from '../../src/components/CompanyLogos'
-import { Columns, EqualColumn } from '../../src/components/layout/Columns'
-import { HeaderPad } from '../../src/components/layout/HeaderPad'
-import { TextLimiter } from '../../src/components/layout/TextLimiter'
-
-// import { ProductValueSection } from './ProductValueSection'
-
-const DEFAULT_HERO_VIDEO = 'https://www.youtube.com/watch?v=LOUshNTgPV0'
-
-function isCollection(
- collection: StackCollectionFragment | null | undefined
-): collection is StackCollectionFragment {
- return !!collection
-}
-
-const StackAppsTabList = styled(TabList)(({ theme }) => ({
- flexDirection: 'column',
- border: theme.borders['fill-two'],
- padding: theme.spacing.xsmall,
- rowGap: theme.spacing.xsmall,
- borderRadius: theme.borderRadiuses.medium,
-}))
-
-const StackAppsTabPanel = styled(TabPanel)((_) => ({}))
-
-export default function Stack({
- stack,
- quotes,
- heroVideo,
- caseStudy,
- faqs,
- buildStackTabs,
- caseStudyApps,
- globalProps,
-}: InferGetStaticPropsType) {
- const router = useRouter()
- const providers =
- stack?.collections?.filter(isCollection).map((collection) => ({
- key: collection.id,
- label:
- providerToProviderName[collection?.provider?.toUpperCase() || ''] ||
- collection.provider,
- // language: 'shell',
- // content: `plural stack install ${stack?.name}`,
- iconLight: getProviderIcon({
- provider: collection?.provider,
- mode: 'light',
- }),
- iconDark: getProviderIcon({
- provider: collection?.provider,
- mode: 'dark',
- }),
- })) || []
-
- const apps = stack?.collections?.[0]?.bundles
- ?.map((bundle) => bundle?.recipe.repository)
- .filter((repo): repo is BasicRepoFragment => !!repo)
- .map((repo) => normalizeRepo(repo))
-
- const appsTabStateRef = useRef()
- const [curAppTabKey, setCurTabKey] = useState(apps?.[0].name ?? '')
- const curApp = apps?.find((app) => app.name === curAppTabKey)
-
- useEffect(() => {
- if (!stack) {
- // router.push('/marketplace')
- }
- }, [stack, router])
- if (!stack) {
- return null
- }
-
- return (
-
-
-
-
-
-
-
-
-
- Build {startsWithVowel(stack.displayName) ? 'an' : 'a'}{' '}
- {stack.displayName} Stack with Plural
-
- {stack.description}
-
-
- Available providers
-
- {!isEmpty(providers) && (
-
- {providers.map((provider) => (
-
- ))}
-
- )}
-
-
-
- Install with Plural
-
-
-
-
-
-
-
-
-
-
-
- The stack
-
-
-
-
-
- {/* @ts-no-check */}
- setCurTabKey(key as string),
- }}
- >
- {apps?.map((repo) => {
- if (!repo || !repo.name) {
- return null
- }
-
- return (
-
- {repo.name}
-
- )
- })}
-
-
-
-
-
- About {curApp?.displayName}
-
-
- {curApp?.description}
-
-
-
-
-
-
- Learn more about {curApp?.displayName}
-
-
-
-
-
-
-
-
-
- {/* */}
- {buildStackTabs && }
-
-
-
-
-
-
- )
-}
-
-export const getStaticPaths: GetStaticPaths = async () => {
- if (process.env.NODE_ENV === 'development') {
- return {
- paths: [],
- fallback: 'blocking',
- }
- }
-
- const stacks = (await getStacks()) || []
-
- return {
- paths: stacks.map((stack) => ({ params: { stack: stack?.name } })),
- fallback: true,
- }
-}
-
-export type StackPageProps = {
- stack: FullStack | null
- quotes: QuoteFragment[] | null
- heroVideo: Exclude<
- ReturnType['heroVideo'],
- undefined
- >
- caseStudy: Exclude<
- ReturnType['case_study'],
- undefined
- >
- buildStackTabs?: ReturnType
- caseStudyApps: TinyRepo[]
- faqs: (FaqItemFragment | null)[]
- globalProps: GlobalProps
-}
-
-const normalizeStackExtras = (extras: StackExtrasQuery) =>
- ({
- ...(extras.stack_defaults || {}),
- ...(extras.stacks?.[0] || {}),
- }) as MergeDeep
-
-export const getStaticProps: GetStaticProps = async (
- context
-) => {
- const stackName = context?.params?.stack
-
- if (!stackName || typeof stackName !== 'string') {
- return { notFound: true }
- }
- const { data: repos, error: reposError } = await until(() => getTinyRepos())
-
- const { data: stacks, error: stacksError } = await until(() => getStacks())
- const { data: stack, error: stackError } = await until(() =>
- getFullStack(stackName)
- )
-
- const thisStack = stack // stacks?.find((r) => r.name === stackName)
-
- if (!thisStack || !stackName || typeof stackName !== 'string') {
- return { notFound: true }
- }
-
- const { data: stackData, error: appError } = await directusClient.query<
- StackExtrasQuery,
- StackExtrasQueryVariables
- >({
- query: StackExtrasDocument,
- variables: { name: stackName },
- })
-
- const buildStackTabs = getStackTabData({ repos, stacks })
-
- const { data: faqData, error: faqError } = await directusClient.query<
- FaqListQuery,
- FaqListQueryVariables
- >({
- query: FaqListDocument,
- variables: { slug: 'generic' },
- })
-
- const stackExtras = normalizeStackExtras(stackData) || {}
-
- return propsWithGlobalSettings({
- stack: thisStack
- ? {
- ...thisStack,
- }
- : null,
- heroVideo: stackExtras.heroVideo || null,
- caseStudy: stackExtras.case_study || null,
- quotes: normalizeQuotes(stackExtras.quotes),
- ...getStackMeta(thisStack),
- faqs: normalizeM2mItems(faqData.collapsible_lists?.[0]) || [],
- buildStackTabs,
- caseStudyApps: getCaseStudyApps(
- repos,
- (stackExtras.case_study?.stack_apps as string[]) || []
- ),
- footerVariant: FooterVariant.kitchenSink,
- errors: combineErrors([
- reposError,
- stacksError,
- stackError,
- appError,
- faqError,
- ]),
- })
-}
diff --git a/pages/product.tsx b/pages/product.tsx
deleted file mode 100644
index 9279ef33..00000000
--- a/pages/product.tsx
+++ /dev/null
@@ -1,260 +0,0 @@
-import { Button, ColorModeProvider } from '@pluralsh/design-system'
-import { type InferGetStaticPropsType } from 'next'
-import Head from 'next/head'
-import Link from 'next/link'
-import Script from 'next/script'
-
-import styled from 'styled-components'
-
-import { mqs } from '@src/breakpoints'
-import { QuickstartDemoCard } from '@src/components/ArticleCard'
-import { FeaturedQuote } from '@src/components/FeaturedQuote'
-import { FooterVariant } from '@src/components/FooterFull'
-import { Columns, EqualColumn } from '@src/components/layout/Columns'
-import { GradientBG } from '@src/components/layout/GradientBG'
-import { HeaderPad } from '@src/components/layout/HeaderPad'
-import {
- StandardPageSection,
- StandardPageWidth,
-} from '@src/components/layout/LayoutHelpers'
-import { TextLimiter } from '@src/components/layout/TextLimiter'
-import { HowPluralWorksSection } from '@src/components/page-sections/HowPluralWorksSection'
-import { StandardFAQSection } from '@src/components/page-sections/StandardFAQSection'
-import { WhatIsPluralSection } from '@src/components/page-sections/WhatIsPluralSection'
-import { CenteredSectionHead } from '@src/components/SectionHeads'
-import { getProductPageData } from '@src/data/getProductPageData'
-import { useAnimationPauser } from '@src/hooks/useAnimationPauser'
-import { cn as classNames } from '@src/utils/cn'
-import { combineErrors } from '@src/utils/combineErrors'
-import { propsWithGlobalSettings } from '@src/utils/getGlobalProps'
-import { normalizeM2mItems } from '@src/utils/normalizeQuotes'
-
-import { TryPluralForFreeSection } from '../src/components/page-sections/TryPluralForFreeSection'
-import { HeroMainText } from '../src/components/PageHeros'
-
-export const ArchitectureContentSC = styled(TextLimiter)(({ theme }) => ({
- color: theme.colors['text-light'],
- 'h1, h2, h3, h4, h5, h6': {
- ...theme.partials.text.body1Bold,
- marginBottom: theme.spacing.small,
- },
- 'p, li': {
- ...theme.partials.text.body2,
- },
- '& :is(p, ul) + :is(p, ul)': {
- marginTop: theme.spacing.medium,
- },
-}))
-
-const AnimationWrapSC = styled.div((_) => ({
- flex: 1,
- '& > div': {
- width: '100%',
- position: 'relative',
- height: 0,
- },
- iframe: {
- position: 'absolute',
- top: 0,
- left: 0,
- width: '100%',
- height: '100%;',
- },
-}))
-
-const HeroAnimationWrapSC = styled(AnimationWrapSC)((_) => ({
- display: 'none',
- height: 0,
-
- '& > div': {
- paddingBottom: 'calc((455/700) * 100%)',
- },
- [mqs.columns]: {
- display: 'block',
- marginTop: '-32%',
- marginLeft: '-12%',
- marginRight: '-8%',
- },
- [mqs.xl]: {
- marginTop: '-35%',
- marginLeft: '-24%',
- marginRight: '-0%',
- },
- [mqs.max]: {
- marginTop: '-41%',
- marginLeft: '-25%',
- marginRight: '-5%',
- },
-}))
-
-export default function Index({
- featuredQuote,
- faqs,
-}: InferGetStaticPropsType) {
- useAnimationPauser()
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
- Start deploying
-
-
- Book a demo
-
-
- }
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {featuredQuote && }
-
-
-
-
-
-
-
-
- {faqs &&
}
-
-
-
-
-
-
- >
- )
-}
-
-export const getStaticProps = async () => {
- const { data: pageData, error: pageDataError } = await getProductPageData()
-
- return propsWithGlobalSettings({
- metaTitle: 'How Plural works',
- metaDescription:
- 'Plural is an open-source, unified, application deployment platform that stands up a Kubernetes cluster and selected applications in the cloud provider of your choice.',
- featuredQuote: pageData?.featured_quote,
- faqs: normalizeM2mItems(pageData?.faq),
- footerVariant: FooterVariant.kitchenSink,
- errors: combineErrors([pageDataError]),
- })
-}
diff --git a/src/components/CarouselDots.tsx b/src/components/CarouselDots.tsx
index e5e2c8e5..81eaae19 100644
--- a/src/components/CarouselDots.tsx
+++ b/src/components/CarouselDots.tsx
@@ -1,6 +1,16 @@
+import { ArrowLeftIcon } from '@pluralsh/design-system'
+
import styled from 'styled-components'
-export const CarouselDots = styled.div((_) => ({
+export const CarouselDots = styled.div(({ theme }) => ({
+ position: 'relative',
+ display: 'flex',
+ width: '100%',
+ marginTop: theme.spacing.large,
+ justifyContent: 'center',
+}))
+
+export const CarouselDotsWrapperSC = styled.div((_) => ({
display: 'flex',
gap: 5,
}))
@@ -24,14 +34,27 @@ export const CarouselDot = styled.div<{ $selected: boolean }>(
overflow: 'hidden',
},
'&::before': {
- border: `1px solid ${theme.colors['icon-xlight']}`,
+ backgroundColor: theme.colors['action-link-inline-visited-hover'],
},
'&::after': {
backgroundColor: theme.colors['action-link-active'],
- opacity: 0.2,
transform: 'scale(0)',
transition: 'all 0.3s ease',
...($selected ? { transform: 'scale(1)', opacity: '100%' } : {}),
},
})
)
+
+export const CarouselArrow = styled(ArrowLeftIcon)<{
+ $direction: 'left' | 'right'
+}>(({ $direction }) => ({
+ cursor: 'pointer',
+ position: 'absolute',
+ top: '-40%',
+ transform: $direction === 'left' ? 'none' : 'rotate(180deg)',
+ left: $direction === 'left' ? 0 : 'auto',
+ right: $direction === 'right' ? 0 : 'auto',
+ '&:hover': {
+ filter: 'brightness(1.2)',
+ },
+}))
diff --git a/src/components/FeaturedQuote.tsx b/src/components/FeaturedQuote.tsx
deleted file mode 100644
index 7ee85840..00000000
--- a/src/components/FeaturedQuote.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import { type ComponentProps } from 'react'
-
-import styled from 'styled-components'
-
-import { type QuoteFragment } from '@src/generated/graphqlDirectus'
-
-import { StandardPageWidth } from './layout/LayoutHelpers'
-import { ResponsiveText } from './Typography'
-
-const FeaturedQuoteSC = styled.div(({ theme }) => ({
- paddingTop: theme.spacing.xxxxxxlarge,
- paddingBottom: theme.spacing.xxxxxxlarge,
- // Used fill-two in Product page comp, but think that's a mistake
- // backgroundColor: theme.colors['fill-two'],
- backgroundColor: theme.colors['fill-zero'],
- position: 'relative',
- '.contentArea': {
- display: 'flex',
- flexDirection: 'column',
- rowGap: theme.spacing.xlarge,
- textWrap: 'balance',
- },
-}))
-
-export function FeaturedQuote({
- quote,
- ...props
-}: ComponentProps & { quote?: QuoteFragment | null }) {
- if (!quote) {
- return null
- }
-
- return (
-
-
-
-
-
-
- "{quote.quote}"
-
-
- {[quote.name, quote.title].filter((q) => !!q).join(' | ')}
-
-
-
-
- )
-}
diff --git a/src/components/LearnAboutPluralSection.tsx b/src/components/LearnAboutPluralSection.tsx
deleted file mode 100644
index 5c6b0a2d..00000000
--- a/src/components/LearnAboutPluralSection.tsx
+++ /dev/null
@@ -1,243 +0,0 @@
-import { type ComponentProps, type ReactNode, useEffect, useState } from 'react'
-
-import Link from 'next/link'
-
-import styled, { useTheme } from 'styled-components'
-import { Swiper, SwiperSlide } from 'swiper/react'
-import { type Swiper as SwiperT } from 'swiper/types'
-import { type Merge } from 'type-fest'
-import 'swiper/css'
-
-import { mqs } from '@src/breakpoints'
-
-import { CarouselDot, CarouselDots } from './CarouselDots'
-import useIndex from './hooks/useIndex'
-import { StandardPageWidth } from './layout/LayoutHelpers'
-import { Heading1 } from './Typography'
-
-type ContentType = {
- title?: ReactNode
- body?: ReactNode
- image?: string
- href: string
-}
-
-const LearnAboutCardSC = styled(Link)<{ $variant: 'default' | 'active' }>(
- ({ theme }) => ({
- boxSizing: 'border-box',
- borderRadius: theme.borderRadiuses.large,
- transition: 'all 0.5s ease',
- flexGrow: 1,
- display: 'flex',
- flexDirection: 'column',
- overflow: 'hidden',
- cursor: 'pointer',
- '.title': {
- ...theme.partials.marketingText.body1Bold,
- color: theme.colors.text,
- [mqs.md]: {
- ...theme.partials.marketingText.title2,
- },
- },
- '.content': {
- display: 'flex',
- flexDirection: 'column',
- gap: theme.spacing.medium,
- paddingTop: theme.spacing.xlarge,
- paddingBottom: theme.spacing.xlarge,
- paddingLeft: theme.spacing.large,
- paddingRight: theme.spacing.large,
- },
- '.body': {
- ...theme.partials.marketingText.body1,
- color: theme.colors.text,
- [mqs.md]: {
- ...theme.partials.marketingText.body1,
- },
- },
- '.image': {
- flexGrow: 1,
- ...theme.partials.marketingText.title2,
- img: {
- width: '100%',
- },
- },
- '&:hover': {
- background: theme.colors['action-primary'],
- '.title': {
- textDecoration: 'underline',
- },
- },
-
- background: theme.colors['fill-three'],
- })
-)
-
-export function LearnAboutCard({
- image,
- title,
- body,
- href,
- variant = 'default',
- ...props
-}: {
- variant?: 'active' | 'default'
-} & ContentType &
- ComponentProps) {
- return (
-
-
-
-
-
-
- {title &&
{title} }
- {body &&
{body}
}
-
-
- )
-}
-
-const CarouselFC = styled.div(({ theme }) => ({
- display: 'flex',
- flexDirection: 'column',
- paddingLeft: theme.spacing.medium,
- paddingRight: theme.spacing.medium,
- paddingBottom: theme.spacing.xlarge,
- paddingTop: theme.spacing.xlarge,
- '.swiper': {
- overflow: 'visible',
- maxWidth: 'none',
- },
- '.swiper-wrapper': {
- alignItems: 'stretch',
- overflow: 'visible',
- },
- '.dotList': {
- marginTop: theme.spacing.medium,
- justifyContent: 'center',
- },
- '.swiper-slide': {
- maxWidth: 400,
- [mqs.xxl]: {
- maxWidth: 456,
- },
- overfow: 'visible',
- flexDirection: 'column',
- flexGrow: 1,
- height: 'unset',
- },
-}))
-
-export function Carousel({
- contentList,
- ...props
-}: Merge<
- ComponentProps,
- {
- contentList?: (ContentType | null | undefined)[] | null
- }
->) {
- const theme = useTheme()
- const [swiper, setSwiper] = useState(null)
- const { activeIndex: activeI, setIndex } = useIndex(
- contentList?.length || 0,
- 0,
- true
- )
-
- const activeIndex = activeI ?? 0
-
- useEffect(() => {
- if (activeIndex !== swiper?.realIndex) {
- swiper?.slideToLoop(activeIndex)
- }
- }, [activeIndex, swiper])
-
- if (!contentList) return null
-
- return (
-
-
- {
- setIndex(s.realIndex)
- }}
- onSwiper={setSwiper}
- >
- {contentList.map(
- (content, i) =>
- content && (
-
- {
- setIndex(i)
- }}
- variant={i === activeIndex ? 'active' : undefined}
- />
-
- )
- )}
-
-
-
- {contentList.map((_, i) => (
- {
- setIndex(i)
- }}
- />
- ))}
-
-
- )
-}
-
-const contentList: ContentType[] = [
- {
- title: 'Product documentation',
- image: '/images/homepage/learn-more/product-documentation.png',
- body: 'Learn how to provision infrastructure and automate delivery with Plural CD.',
- href: 'https://docs.plural.sh/',
- },
- {
- title: 'Product roadmap',
- image: '/images/homepage/learn-more/product-roadmap.png',
- body: 'See our latest feature releases, bug fixes, and improvements.',
- href: 'https://github.com/orgs/pluralsh/projects/2/views/2',
- },
- {
- title: 'Blog articles',
- image: '/images/homepage/learn-more/blog-articles.png',
- body: 'See our latest feature releases, bug fixes, and improvements.',
- href: 'https://plural.sh/blog',
- },
-]
-
-export function LearnAboutPluralSection({
- ...props
-}: Omit, 'children'>) {
- return (
-
-
- Learn more about Plural
-
-
-
- )
-}
diff --git a/src/components/ProviderIcon.tsx b/src/components/ProviderIcon.tsx
index 09943ad8..9f73c904 100644
--- a/src/components/ProviderIcon.tsx
+++ b/src/components/ProviderIcon.tsx
@@ -4,7 +4,11 @@ import { Tooltip } from '@pluralsh/design-system'
import styled from 'styled-components'
-import { type ProviderProps } from '../../pages/applications/[repo]'
+export type ProviderProps = {
+ label?: string | null | undefined
+ iconDark: string
+ iconLight: string
+}
export const ProviderIcon = styled(
({
diff --git a/src/components/QuoteCards.tsx b/src/components/QuoteCards.tsx
index 76188b3d..f0d96458 100644
--- a/src/components/QuoteCards.tsx
+++ b/src/components/QuoteCards.tsx
@@ -1,170 +1,58 @@
-import { type ComponentProps, useEffect, useState } from 'react'
+import {
+ type ComponentProps,
+ type ReactElement,
+ cloneElement,
+ useEffect,
+ useState,
+} from 'react'
-import styled, { useTheme } from 'styled-components'
+import styled from 'styled-components'
import { Swiper, SwiperSlide } from 'swiper/react'
import { type Swiper as SwiperT } from 'swiper/types'
-import { type Merge } from 'type-fest'
-import 'swiper/css'
-import { mqs } from '@src/breakpoints'
-import { getImageUrl } from '@src/consts/routes'
import { type QuoteFragment } from '@src/generated/graphqlDirectus'
-import BasicMarkdown from './BasicMarkdown'
-import { CarouselDot, CarouselDots } from './CarouselDots'
+import {
+ CarouselArrow,
+ CarouselDot,
+ CarouselDots,
+ CarouselDotsWrapperSC,
+} from './CarouselDots'
import useIndex from './hooks/useIndex'
-import { StandardPageWidth } from './layout/LayoutHelpers'
-import { Heading1 } from './Typography'
-export const QuoteCard = styled(
- ({
- quote,
- variant: _variant,
- ...props
- }: {
- quote: QuoteFragment
- variant?: 'default' | 'active'
- } & ComponentProps<'div'>) => {
- const imgUrl = getImageUrl(quote.logo)
-
- return (
-
-
-
-
- {imgUrl && (
-
-
-
- )}
-
- {quote.portrait && (
-
- )}
-
- {quote.name &&
{quote.name}
}
- {quote.title &&
{quote.title}
}
-
-
-
- )
- }
-)(({ theme, variant }) => ({
- boxSizing: 'border-box',
- paddingTop: theme.spacing.xlarge,
- paddingBottom: theme.spacing.xlarge,
- paddingLeft: theme.spacing.large,
- paddingRight: theme.spacing.large,
- borderRadius: theme.borderRadiuses.large,
- transition: 'all 0.5s ease',
- flexGrow: 1,
- display: 'flex',
- flexDirection: 'column',
- gap: theme.spacing.large,
- ...(variant === 'active'
- ? {
- transform: 'translateY(-15px)',
- }
- : {}),
- '.attribution': {
- display: 'flex',
- gap: theme.spacing.medium,
- alignItem: 'center',
- },
- '.quote': {
- ...theme.partials.marketingText.body1Bold,
- color: theme.colors.text,
- [mqs.md]: {
- ...theme.partials.marketingText.title2,
- },
- },
- '.logo': {
- flexGrow: 1,
- ...theme.partials.marketingText.title2,
- img: {
- height: 28,
- },
- },
- '.nameTitle': {
- display: 'flex',
- flexDirection: 'column',
- justifyContent: 'center',
- },
- '.name': {
- ...theme.partials.text.subtitle1,
- color: theme.colors['text-light'],
- },
- '.title': {
- ...theme.partials.text.body1,
- color: theme.colors['text-xlight'],
- },
- '.portrait': {
- flexShrink: 0,
- width: 46,
- height: 46,
- borderRadius: '50%',
- overflow: 'hidden',
- backgroundSize: 'cover',
- },
- backgroundColor:
- variant === 'active'
- ? theme.colors['action-primary']
- : theme.colors['fill-three'],
-}))
+export type QuoteElementProps = {
+ quote?: QuoteFragment
+ variant?: 'default' | 'active'
+ onClick?: () => void
+}
-const QuotesCarouselFC = styled.div(({ theme }) => ({
+const QuotesCarouselSC = styled.div((_) => ({
display: 'flex',
flexDirection: 'column',
'.swiper': {
- overflow: 'visible',
- maxWidth: 'none',
- // maxWidth: 400,
- // [mqs.xxl]: {
- // maxWidth: 456,
- // },
- },
- '.swiper-wrapper': {
- alignItems: 'stretch',
- overflow: 'visible',
- },
- '.dotList': {
- marginTop: theme.spacing.medium,
- justifyContent: 'center',
- },
- '.swiper-slide': {
- maxWidth: 400,
- [mqs.xxl]: {
- maxWidth: 456,
- },
- overfow: 'visible',
- flexDirection: 'column',
- flexGrow: 1,
- height: 'unset',
+ height: '100%',
+ width: '100%',
},
}))
export function QuotesCarousel({
quotes,
+ quoteElement,
+ showArrows = true,
...props
-}: Merge<
- ComponentProps,
- {
- quotes?: (QuoteFragment | null | undefined)[] | null
- }
->) {
- const theme = useTheme()
+}: ComponentProps & {
+ quotes?: Nullable[]
+ quoteElement: ReactElement>
+ showArrows?: boolean
+}) {
const [swiper, setSwiper] = useState(null)
const {
activeIndex: activeI,
setIndex,
goForward,
+ goBack,
+ atEnd,
+ atStart,
} = useIndex(quotes?.length || 0, 0, true)
const activeIndex = activeI ?? 0
@@ -190,65 +78,56 @@ export function QuotesCarousel({
const quotesInner = quotes
return (
-
-
- {
- setIndex(s.realIndex)
- }}
- onSwiper={setSwiper}
- >
- {quotesInner.map(
- (quote, i) =>
- quote && (
-
- {
- setIndex(i)
- }}
- variant={i === activeIndex ? 'active' : undefined}
- />
-
- )
- )}
-
-
-
- {quotesInner.map((_, i) => (
- {
- setIndex(i)
- }}
+
+ {
+ setIndex(s.realIndex)
+ }}
+ onSwiper={setSwiper}
+ >
+ {quotesInner.map(
+ (quote, i) =>
+ quote && (
+
+ {cloneElement(quoteElement, {
+ quote,
+ onClick: () => {
+ setIndex(i)
+ },
+ variant: i === activeIndex ? 'active' : undefined,
+ })}
+
+ )
+ )}
+
+
+ {showArrows && !atStart && (
+
+ )}
+
+ {quotesInner.map((_, i) => (
+ {
+ setIndex(i)
+ }}
+ />
+ ))}
+
+ {showArrows && !atEnd && (
+
- ))}
+ )}
-
- )
-}
-
-export function TestimonialsSection({
- quotes,
- ...props
-}: Merge<
- Omit, 'children'>,
- { quotes?: QuoteFragment[] | null }
->) {
- return (
-
-
- What companies are saying about us
-
-
-
+
)
}
diff --git a/src/components/hooks/useIndex.tsx b/src/components/hooks/useIndex.tsx
index b158ea98..8bf31237 100644
--- a/src/components/hooks/useIndex.tsx
+++ b/src/components/hooks/useIndex.tsx
@@ -23,13 +23,10 @@ export type IndexState = {
goBack: (options?: { loop?: boolean; increment?: number }) => void
}
-const getBoundedIndex = (index, length) => {
- if (index > length - 1) {
- return length - 1
- }
- if (index < 0) {
- return 0
- }
+const getBoundedIndex = (index: number | null, length: number) => {
+ if (index === null) return null
+ if (index > length - 1) return length - 1
+ if (index < 0) return 0
return index
}
@@ -77,15 +74,13 @@ const useIndex = (
goForward: useCallback(
({ increment = 1, loop: loopThis = undefined } = {}) => {
if (activeIndex !== null) {
+ const isLooping = loopThis !== undefined ? loopThis : loop
let newIndex = activeIndex + increment
- if (
- (loopThis !== undefined ? loopThis : loop) &&
- newIndex > length - 1
- ) {
- newIndex -= length
- } else if (newIndex > length - increment) {
- newIndex = length - increment
+ if (isLooping && length > 0) {
+ newIndex %= length
+ } else {
+ newIndex = length > 0 ? Math.min(newIndex, length - 1) : 0
}
setUnsafeActiveIndex(newIndex)
}
@@ -95,13 +90,15 @@ const useIndex = (
goBack: useCallback(
({ increment = 1, loop: loopThis = undefined } = {}) => {
if (activeIndex !== null) {
+ const isLooping = loopThis !== undefined ? loopThis : loop
let newIndex = activeIndex - increment
- if (loopThis !== undefined ? loopThis : loop) {
- newIndex = length + newIndex - 1
- } else if (newIndex < 0) {
- newIndex = 0
+ if (isLooping && length > 0) {
+ newIndex = (newIndex + length) % length
+ } else {
+ newIndex = Math.max(newIndex, 0)
}
+
setUnsafeActiveIndex(newIndex)
}
},
diff --git a/src/components/page-sections/MarketplaceCarousel.tsx b/src/components/page-sections/MarketplaceCarousel.tsx
index 120b810f..c0a30ad8 100644
--- a/src/components/page-sections/MarketplaceCarousel.tsx
+++ b/src/components/page-sections/MarketplaceCarousel.tsx
@@ -11,7 +11,7 @@ import { type Swiper as SwiperT } from 'swiper/types'
import { mqs } from '@src/breakpoints'
-import { CarouselDot, CarouselDots } from '../CarouselDots'
+import { CarouselDot, CarouselDotsWrapperSC } from '../CarouselDots'
const switchPointMQ = mqs.sm
@@ -71,7 +71,7 @@ const Buttons = styled.div(({ theme }) => ({
},
}))
-const Dots = styled(CarouselDots)((_) => ({
+const Dots = styled(CarouselDotsWrapperSC)((_) => ({
display: 'flex',
width: '100%',
height: '100%',
diff --git a/src/components/page-sections/QuoteSection.tsx b/src/components/page-sections/QuoteSection.tsx
index 9c5bb3f5..7dfaff68 100644
--- a/src/components/page-sections/QuoteSection.tsx
+++ b/src/components/page-sections/QuoteSection.tsx
@@ -1,16 +1,17 @@
-import { useTheme } from 'styled-components'
+import styled, { useTheme } from 'styled-components'
+
+import { type QuoteFragment } from '@src/generated/graphqlDirectus'
import { StandardPageWidth } from '../layout/LayoutHelpers'
+import { QuotesCarousel } from '../QuoteCards'
import { ResponsiveText } from '../Typography'
export function QuoteSection({
title,
- quote,
- attribution,
+ quotes,
}: {
title: string
- quote: string
- attribution: string
+ quotes: Nullable[]
}) {
const theme = useTheme()
@@ -21,7 +22,7 @@ export function QuoteSection({
'linear-gradient(to bottom, #0E1015, rgba(14, 16, 21, 0)), linear-gradient(to bottom, #0A0F8F, #747AF6)',
}}
>
-
+
-
- {quote}
-
- {attribution}
+ }
+ />
@@ -50,6 +46,15 @@ export function QuoteSection({
)
}
+function QuoteText({ quote }: { quote?: QuoteFragment }) {
+ return (
+ <>
+
{quote?.quote}
+
{quote?.author_text?.repeat(1)}
+ >
+ )
+}
+
function DoubleQuote(props) {
const theme = useTheme()
@@ -70,3 +75,13 @@ function DoubleQuote(props) {
)
}
+
+const QuoteTextSC = styled.p(({ theme }) => ({
+ fontFamily: 'Monument',
+ fontSize: '28px',
+ fontStyle: 'normal',
+ fontWeight: 400,
+ letterSpacing: '1.058px',
+ color: theme.colors.text,
+ marginBottom: theme.spacing.xlarge,
+}))
diff --git a/src/components/page-sections/WhatIsPluralSection.tsx b/src/components/page-sections/WhatIsPluralSection.tsx
deleted file mode 100644
index 9a3f6b4b..00000000
--- a/src/components/page-sections/WhatIsPluralSection.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-import { InlineCode } from '@pluralsh/design-system'
-
-import { ArchitectureContentSC } from '@pages/product'
-import { cn as classNames } from '@src/utils/cn'
-
-import { Columns, EqualColumn } from '../layout/Columns'
-import { CenteredSectionHead, SubsectionHead } from '../SectionHeads'
-import { BasicUl, Cta } from '../Typography'
-
-export function WhatIsPluralSection() {
- return (
- <>
-
- Plural is an open-source, unified, application deployment platform
- that stands up a Kubernetes cluster and selected applications in the
- cloud provider of your choice. Plural writes all the Helm,
- Terraform, and YAML needed for your desired infrastructure and
- deploys it all into production. Plural stores your infrastructure
- code and configuration in a fresh Git repository of your choosing.
-
- }
- className={classNames('pb-xxxxxxlarge')}
- />
-
-
-
-
-
-
-
-
-
- Plural API
-
- The primary responsibility of the Plural API is to store the
- packages needed for application installation – terraform, helm –
- and ingesting high-level dependency information about them. This
- allows us to properly sequence installations and deliver updates
- that avoid mismatched dependencies.
-
-
- It also can serve as an identity provider for any Plural
- application, delegating authentication via OpenID Connect, giving
- seamless login security for all applications.
-
-
-
- Plural CLI
-
- The Plural CLI uses the Plural API as a package manager to
- generate a fully functional git repository with all the
- infrastructure-as-code needed to deploy any of your applications
- with Plural. This allows you to stand up any open-source stack
- {/* @ts-ignore */}
- with just plural build and{' '}
- {/* @ts-ignore */}
- plural deploy , and never even have to
- give us cloud credentials, since the infrastructure as code lives
- in your local workstation.
-
-
- It also streamlines things like git secret encryption,
- dependency-ordering deploys and provides an operational toolkit
- for accessing databases and logs, watching the status of
- applications and providing login info.{' '}
-
-
-
- Plural Console
-
- The Plural Console is the operational hub for all applications
- managed by Plural. It is deployed in-cluster alongside
- applications and provides a few key features:
-
-
-
- Automated upgrades – by subscribing to the API's upgrade
- websocket
-
-
- Observability – leverages prometheus and loki to provide fully
- featured dashboards, runbooks and log aggregation.
-
-
- Documentation/Self-serviceability – application docs for
- advanced configuration settings and usage patterns are available
- in console, alongside tooling to easily bind users to
- applications, reconfigure them, and other information needed to
- get started quickly.
-
-
-
- Explore the docs
-
-
-
-
-
-
-
-
-
-
- >
- )
-}
diff --git a/src/generated/graphqlDirectus.ts b/src/generated/graphqlDirectus.ts
index 076b3415..dc8b63f0 100644
--- a/src/generated/graphqlDirectus.ts
+++ b/src/generated/graphqlDirectus.ts
@@ -5272,6 +5272,7 @@ export type Create_Quote_Lists_Items_Input = {
};
export type Create_Quotes_Input = {
+ author_text?: InputMaybe;
company?: InputMaybe;
date_created?: InputMaybe;
date_updated?: InputMaybe;
@@ -7229,6 +7230,7 @@ export type Quote_Lists_Items_Item_Union = Quotes;
export type Quotes = {
__typename?: 'quotes';
+ author_text?: Maybe;
company?: Maybe;
date_created?: Maybe;
date_created_func?: Maybe;
@@ -7312,6 +7314,7 @@ export type Quotes_Aggregated = {
export type Quotes_Aggregated_Count = {
__typename?: 'quotes_aggregated_count';
+ author_text?: Maybe;
company?: Maybe;
date_created?: Maybe;
date_updated?: Maybe;
@@ -7335,6 +7338,7 @@ export type Quotes_Aggregated_Fields = {
export type Quotes_Filter = {
_and?: InputMaybe>>;
_or?: InputMaybe>>;
+ author_text?: InputMaybe;
company?: InputMaybe;
date_created?: InputMaybe;
date_created_func?: InputMaybe;
@@ -8895,6 +8899,7 @@ export type Update_Quote_Lists_Items_Input = {
};
export type Update_Quotes_Input = {
+ author_text?: InputMaybe;
company?: InputMaybe;
date_created?: InputMaybe;
date_updated?: InputMaybe;
@@ -9072,25 +9077,25 @@ export type CaseStudyFragment = { __typename?: 'case_studies', id: string, slug?
export type AppExtrasFragment = { __typename?: 'apps', name?: string | null, heroVideo?: string | null, hero_text?: string | null, secondary_title?: string | null, secondary_text?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null };
-export type AppDefaultsFragment = { __typename?: 'app_defaults', secondary_title?: string | null, secondary_text?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null> | null } | null };
+export type AppDefaultsFragment = { __typename?: 'app_defaults', secondary_title?: string | null, secondary_text?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null> | null } | null };
export type AppExtrasQueryVariables = Exact<{
name?: InputMaybe;
}>;
-export type AppExtrasQuery = { __typename?: 'Query', apps: Array<{ __typename?: 'apps', name?: string | null, heroVideo?: string | null, hero_text?: string | null, secondary_title?: string | null, secondary_text?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null }>, app_defaults?: { __typename?: 'app_defaults', secondary_title?: string | null, secondary_text?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null> | null } | null } | null };
+export type AppExtrasQuery = { __typename?: 'Query', apps: Array<{ __typename?: 'apps', name?: string | null, heroVideo?: string | null, hero_text?: string | null, secondary_title?: string | null, secondary_text?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null }>, app_defaults?: { __typename?: 'app_defaults', secondary_title?: string | null, secondary_text?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null> | null } | null } | null };
export type StackExtrasFragment = { __typename?: 'stacks', name?: string | null, heroVideo?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null };
-export type StackDefaultsFragment = { __typename?: 'stack_defaults', case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null> | null } | null };
+export type StackDefaultsFragment = { __typename?: 'stack_defaults', case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null> | null } | null };
export type StackExtrasQueryVariables = Exact<{
name?: InputMaybe;
}>;
-export type StackExtrasQuery = { __typename?: 'Query', stacks: Array<{ __typename?: 'stacks', name?: string | null, heroVideo?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null }>, stack_defaults?: { __typename?: 'stack_defaults', case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null> | null } | null } | null };
+export type StackExtrasQuery = { __typename?: 'Query', stacks: Array<{ __typename?: 'stacks', name?: string | null, heroVideo?: string | null, case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null }>, stack_defaults?: { __typename?: 'stack_defaults', case_study?: { __typename?: 'case_studies', id: string, slug?: string | null, label?: string | null, title?: string | null, content?: string | null, ctas?: any | null, stack_label?: string | null, stack_apps?: any | null, hero_image?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null> | null } | null } | null };
export type ImageFileFragment = { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null };
@@ -9123,7 +9128,7 @@ export type SolutionFeatureFragment = { __typename?: 'solution_features', id: st
export type SolutionProblemFragment = { __typename?: 'solution_problems', id: string, title?: string | null, subtitle?: string | null, problem?: string | null, solution?: string | null };
-export type SolutionFragment = { __typename?: 'solutions_pages', id: string, slug: string, title?: string | null, description?: string | null, upper_features_title?: string | null, lower_features_title?: string | null, download_section_title?: string | null, download_section_description?: string | null, upper_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, lower_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, problems?: Array<{ __typename?: 'solution_problems', id: string, title?: string | null, subtitle?: string | null, problem?: string | null, solution?: string | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null };
+export type SolutionFragment = { __typename?: 'solutions_pages', id: string, slug: string, title?: string | null, description?: string | null, upper_features_title?: string | null, lower_features_title?: string | null, download_section_title?: string | null, download_section_description?: string | null, upper_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, lower_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, problems?: Array<{ __typename?: 'solution_problems', id: string, title?: string | null, subtitle?: string | null, problem?: string | null, solution?: string | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null };
export type SolutionsSlugsQueryVariables = Exact<{ [key: string]: never; }>;
@@ -9135,7 +9140,7 @@ export type SolutionsQueryVariables = Exact<{
}>;
-export type SolutionsQuery = { __typename?: 'Query', solutions_pages: Array<{ __typename?: 'solutions_pages', id: string, slug: string, title?: string | null, description?: string | null, upper_features_title?: string | null, lower_features_title?: string | null, download_section_title?: string | null, download_section_description?: string | null, upper_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, lower_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, problems?: Array<{ __typename?: 'solution_problems', id: string, title?: string | null, subtitle?: string | null, problem?: string | null, solution?: string | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null }> };
+export type SolutionsQuery = { __typename?: 'Query', solutions_pages: Array<{ __typename?: 'solutions_pages', id: string, slug: string, title?: string | null, description?: string | null, upper_features_title?: string | null, lower_features_title?: string | null, download_section_title?: string | null, download_section_description?: string | null, upper_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, lower_features?: Array<{ __typename?: 'solution_features', id: string, title?: string | null, description?: string | null, icon?: string | null, link_title?: string | null, link_url?: string | null } | null> | null, problems?: Array<{ __typename?: 'solution_problems', id: string, title?: string | null, subtitle?: string | null, problem?: string | null, solution?: string | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null }> };
export type MinJobListingFragment = { __typename?: 'job_listings', id: string, slug: string, job_title?: string | null, department?: string | null, tags?: any | null, location?: string | null, status?: string | null };
@@ -9185,12 +9190,12 @@ export type PageCommunityQueryVariables = Exact<{ [key: string]: never; }>;
export type PageCommunityQuery = { __typename?: 'Query', page_community?: { __typename?: 'page_community', callouts?: Array<{ __typename?: 'callouts', id: string, sort?: number | null, category?: string | null, title?: string | null, content?: string | null, ctas?: any | null } | null> | null } | null };
-export type PageProductFragment = { __typename?: 'page_product', featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, faq?: { __typename?: 'collapsible_lists', items?: Array<{ __typename?: 'collapsible_lists_items', item?: { __typename?: 'collapsibles', id: string, label?: string | null, content?: string | null } | null } | null> | null } | null };
+export type PageProductFragment = { __typename?: 'page_product', featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null, faq?: { __typename?: 'collapsible_lists', items?: Array<{ __typename?: 'collapsible_lists_items', item?: { __typename?: 'collapsibles', id: string, label?: string | null, content?: string | null } | null } | null> | null } | null };
export type PageProductQueryVariables = Exact<{ [key: string]: never; }>;
-export type PageProductQuery = { __typename?: 'Query', page_product?: { __typename?: 'page_product', featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null, faq?: { __typename?: 'collapsible_lists', items?: Array<{ __typename?: 'collapsible_lists_items', item?: { __typename?: 'collapsibles', id: string, label?: string | null, content?: string | null } | null } | null> | null } | null } | null };
+export type PageProductQuery = { __typename?: 'Query', page_product?: { __typename?: 'page_product', featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null, faq?: { __typename?: 'collapsible_lists', items?: Array<{ __typename?: 'collapsible_lists_items', item?: { __typename?: 'collapsibles', id: string, label?: string | null, content?: string | null } | null } | null> | null } | null } | null };
export type MarkdownPageFragment = { __typename?: 'markdown_pages', id: string, slug?: string | null, title?: string | null, subtitle?: string | null, content?: string | null };
@@ -9208,16 +9213,16 @@ export type LegalPageSlugsQuery = { __typename?: 'Query', page_legal?: { __typen
export type ArticleCardFragment = { __typename?: 'article_cards', id: string, heading?: string | null, description?: string | null, videoUrl?: string | null, date?: any | null, author?: string | null, ctas?: any | null, url?: string | null, thumbnail?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null };
-export type PageHomepageFragment = { __typename?: 'page_homepage', quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null> | null } | null, article_cards?: Array<{ __typename?: 'article_cards', id: string, heading?: string | null, description?: string | null, videoUrl?: string | null, date?: any | null, author?: string | null, ctas?: any | null, url?: string | null, thumbnail?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null };
+export type PageHomepageFragment = { __typename?: 'page_homepage', quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null> | null } | null, article_cards?: Array<{ __typename?: 'article_cards', id: string, heading?: string | null, description?: string | null, videoUrl?: string | null, date?: any | null, author?: string | null, ctas?: any | null, url?: string | null, thumbnail?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null };
export type PageHomepageQueryVariables = Exact<{ [key: string]: never; }>;
-export type PageHomepageQuery = { __typename?: 'Query', page_homepage?: { __typename?: 'page_homepage', quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null> | null } | null, article_cards?: Array<{ __typename?: 'article_cards', id: string, heading?: string | null, description?: string | null, videoUrl?: string | null, date?: any | null, author?: string | null, ctas?: any | null, url?: string | null, thumbnail?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null };
+export type PageHomepageQuery = { __typename?: 'Query', page_homepage?: { __typename?: 'page_homepage', quotes?: { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null> | null } | null, article_cards?: Array<{ __typename?: 'article_cards', id: string, heading?: string | null, description?: string | null, videoUrl?: string | null, date?: any | null, author?: string | null, ctas?: any | null, url?: string | null, thumbnail?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null> | null, featured_quote?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null };
-export type QuoteFragment = { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null };
+export type QuoteFragment = { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null };
-export type QuoteListFragment = { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, name?: string | null, title?: string | null, company?: string | null, portrait?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null, logo?: { __typename?: 'directus_files', id: string, title?: string | null, description?: string | null, tags?: any | null, filename_disk?: string | null, filename_download: string, metadata?: any | null, type?: string | null, filesize?: any | null } | null } | null } | null> | null };
+export type QuoteListFragment = { __typename?: 'quote_lists', slug: string, items?: Array<{ __typename?: 'quote_lists_items', item?: { __typename?: 'quotes', id: string, quote?: string | null, author_text?: string | null } | null } | null> | null };
export const EventFragmentDoc = gql`
fragment Event on events {
@@ -9313,17 +9318,9 @@ export const QuoteFragmentDoc = gql`
fragment Quote on quotes {
id
quote
- name
- title
- company
- portrait {
- ...ImageFile
- }
- logo {
- ...ImageFile
- }
+ author_text
}
- ${ImageFileFragmentDoc}`;
+ `;
export const QuoteListFragmentDoc = gql`
fragment QuoteList on quote_lists {
slug
diff --git a/src/generated/pages.json b/src/generated/pages.json
index 21b34fba..8111bc5f 100644
--- a/src/generated/pages.json
+++ b/src/generated/pages.json
@@ -17,16 +17,10 @@
{
"path": "/"
},
- {
- "path": "/kubernetes-fleet-management"
- },
{
"path": "/marketplace"
},
{
"path": "/pricing"
- },
- {
- "path": "/product"
}
]
\ No newline at end of file
diff --git a/src/graph/directus/quotes.graphql b/src/graph/directus/quotes.graphql
index ca13a685..1a4a9ced 100644
--- a/src/graph/directus/quotes.graphql
+++ b/src/graph/directus/quotes.graphql
@@ -1,15 +1,7 @@
fragment Quote on quotes {
id
quote
- name
- title
- company
- portrait {
- ...ImageFile
- }
- logo {
- ...ImageFile
- }
+ author_text
}
fragment QuoteList on quote_lists {
diff --git a/src/types/global.d.ts b/src/types/global.d.ts
new file mode 100644
index 00000000..54b8185d
--- /dev/null
+++ b/src/types/global.d.ts
@@ -0,0 +1 @@
+type Nullable = T | null | undefined