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

Community page #95

Merged
merged 8 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@markdoc/markdoc": "0.4.0",
"@markdoc/next.js": "0.2.2",
"@open-draft/until": "2.1.0",
"@pluralsh/design-system": "3.49.0",
"@pluralsh/design-system": "3.53.0",
"@react-types/shared": "3.22.0",
"@tanstack/react-table": "8.10.7",
"@tanstack/react-virtual": "3.0.1",
Expand Down
242 changes: 242 additions & 0 deletions pages/community.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
import {
ArrowRightIcon,
Button,
Card,
Chip,
ColorModeProvider,
DocumentIcon,
GitHubLogoIcon,
IconFrame,
YouTubeIcon,
} from '@pluralsh/design-system'
import { type GetStaticProps, type InferGetStaticPropsType } from 'next'
import { useRouter } from 'next/router'

import { useTheme } from 'styled-components'

import { FooterVariant } from '@src/components/FooterFull'
import { GradientBG } from '@src/components/layout/GradientBG'
import { HeaderPad } from '@src/components/layout/HeaderPad'
import { StandardPageWidth } from '@src/components/layout/LayoutHelpers'
import { formatDateTime } from '@src/components/page-sections/EventsSection'
import { BasicPageHero } from '@src/components/PageHeros'
import { ResponsiveText } from '@src/components/Typography'
import { type PluralEvent, getEvents } from '@src/data/getEvents'
import { cn as classNames } from '@src/utils/cn'
import { combineErrors } from '@src/utils/combineErrors'
import { propsWithGlobalSettings } from '@src/utils/getGlobalProps'

export default function Community({
events,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<>
<HeaderPad
as={GradientBG}
size="cover"
// position="top middle"
image="/images/gradients/gradient-bg-13.png"
>
<BasicPageHero
heading="Plural community"
description="The Plural community is built to support all Plural users through discussions, educational resources, and events."
/>
</HeaderPad>
{/* resources */}
<StandardPageWidth
className={classNames(
'flex flex-col gap-xlarge [text-wrap:balance]',
'p-xxlarge lg:p-xxxxxxlarge'
)}
>
<ResponsiveText
className=" mb-xxlarge text-center"
as="h2"
textStyles={{
'': 'mTitle2',
sm: 'mHero2',
}}
>
Community Resources
</ResponsiveText>
<div className="flex flex-col items-stretch justify-between gap-medium md:flex-row md:items-center">
{kinds.map((key) => (
<ResourceLink
key={key}
kind={key}
/>
))}
</div>
</StandardPageWidth>
{/* events */}
<ColorModeProvider mode="light">
<div
className={classNames(
'bg-fill-zero',
'p-large py-xxxlarge md:p-xxxxxlarge md:pt-xxxxxlarge'
)}
>
<StandardPageWidth>
<ResponsiveText
className=" mb-xxlarge text-center"
as="h2"
textStyles={{
'': 'mTitle2',
sm: 'mHero2',
}}
>
Plural Events
</ResponsiveText>
{events.length ? (
<EventsGrid events={events} />
) : (
<Card
fillLevel={1}
className={classNames(
'flex',
'justify-center p-large md:p-xxxxlarge'
)}
>
<ResponsiveText
as="span"
textStyles={{ md: 'mSubtitle1', '': 'mBody2Bold' }}
className="m-large md:m-xxxxlarge"
>
No planned events at this time
</ResponsiveText>
</Card>
)}
</StandardPageWidth>
</div>
</ColorModeProvider>
</>
)
}

const resources = {
gitHub: {
url: 'https://github.com/pluralsh/plural',
title: 'GitHub',
icon: <GitHubLogoIcon />,
},
youtube: {
url: 'https://www.youtube.com/channel/UCt8xwvJH4f4c6g8J1Y6ZmJQ',
renemennab marked this conversation as resolved.
Show resolved Hide resolved
title: 'YouTube',
icon: <YouTubeIcon />,
},
docs: {
url: 'https://docs.plural.sh',
title: 'Docs',
icon: <DocumentIcon />,
},
} as const

const kinds = Object.keys(resources) as Array<keyof typeof resources>

function ResourceLink({ kind }: { kind: keyof typeof resources }) {
const theme = useTheme()

return (
<Button
secondary
as="a"
className="flex grow items-center justify-start gap-medium"
href={resources[kind].url}
target="_blank"
rel="noopener noreferrer"
style={{ justifyContent: 'flex-start', padding: theme.spacing.large }}
>
<IconFrame
type="floating"
style={{
display: 'inline-flex',
marginRight: theme.spacing.xsmall,
}}
icon={resources[kind].icon}
size="medium"
/>
<span>{resources[kind].title}</span>
</Button>
)
}

function EventsGrid({ events }: { events: PluralEvent[] }) {
const locale = useRouter().locale || 'en-us'

return (
<div
className="grid grid-cols-1 gap-xxlarge md:grid-cols-2 xl:grid-cols-3"
style={{ gridAutoRows: '1fr' }}
>
{events.map((event) => (
<a
key={event.id}
href="#"
jsladerman marked this conversation as resolved.
Show resolved Hide resolved
className=""
>
<Card
fillLevel={1}
padding="xlarge"
className={classNames(
'flex h-full flex-col',
' items-start justify-center p-large md:p-xxxxlarge'
)}
>
<Chip
padding="small"
severity="neutral"
className="mb-medium w-fit"
>
Event
</Chip>
<ResponsiveText
as="span"
textStyles={{ md: 'mSubtitle1', '': 'mBody2Bold' }}
className="mb-large overflow-hidden text-ellipsis"
>
{event.name}
</ResponsiveText>
<ResponsiveText
as="span"
textStyles={{ md: 'mBody2', '': 'mBody2' }}
className="mb-xxlarge"
>
{formatDateTime(new Date(event.start_date), {
timeZone: event.timezone,
locale,
timeZoneShort: event.timezone_short,
showTime: true,
})}
</ResponsiveText>
<IconFrame
type="floating"
icon={<ArrowRightIcon />}
size="large"
color="text"
className="mt-auto"
// style={{ display: 'inline-flex' }}
/>
</Card>
</a>
))}
</div>
)
}

export type CommunityPageProps = {
events: PluralEvent[]
}

export const getStaticProps: GetStaticProps<CommunityPageProps> = async (
_context
) => {
const { data: events, error: eventsError } = await getEvents()

return propsWithGlobalSettings({
metaTitle: 'Community',
metaDescription: 'Flexible plans for every stage of your business',
footerVariant: FooterVariant.kitchenSink,
errors: combineErrors([eventsError]),
events,
})
}
16 changes: 10 additions & 6 deletions src/components/page-sections/EventsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import { TextLimiter } from '../layout/TextLimiter'
import { ResponsiveText } from '../Typography'

const DATE_FORMAT = {
month: 'short',
month: 'long',
day: 'numeric',
year: 'numeric',
weekday: 'short',
} as const

const TIME_FORMAT = {
Expand All @@ -32,8 +31,8 @@ function formatTime(
showTimeZone = true,
}: {
locale: string
timeZone?: string
timeZoneShort?: string
timeZone?: string | null
timeZoneShort?: string | null
showTimeZone?: boolean
}
) {
Expand All @@ -45,14 +44,19 @@ function formatTime(
}${showTimeZone && timeZoneShort ? ` ${timeZoneShort}` : ''}`
}

function formatDateTime(
export function formatDateTime(
date: Date | null | undefined,
{
locale,
showTime,
timeZone,
timeZoneShort,
}: { locale: string; showTime; timeZone?: string; timeZoneShort?: string }
}: {
locale: string
showTime
timeZone?: string | null
timeZoneShort?: string | null
}
) {
if (!date) {
return ''
Expand Down
16 changes: 8 additions & 8 deletions src/data/getSiteSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,14 @@ export const getSiteSettings = (solutions?: Solution[]) => ({
url: '/contact',
},
},
// {
// id: '6-5',
// link: {
// id: '6-5',
// title: 'Community',
// url: '/community',
// },
// },
{
id: '6-5',
link: {
id: '6-5',
title: 'Community',
url: '/community',
},
},
],
},
],
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4276,9 +4276,9 @@ __metadata:
languageName: node
linkType: hard

"@pluralsh/design-system@npm:3.49.0":
version: 3.49.0
resolution: "@pluralsh/design-system@npm:3.49.0"
"@pluralsh/design-system@npm:3.53.0":
version: 3.53.0
resolution: "@pluralsh/design-system@npm:3.53.0"
dependencies:
"@floating-ui/react-dom-interactions": 0.13.3
"@loomhq/loom-embed": 1.5.0
Expand Down Expand Up @@ -4326,7 +4326,7 @@ __metadata:
react-dom: ">=18.3.1"
react-transition-group: ">=4.4.5"
styled-components: ">=5.3.11"
checksum: 17b233f9eb16f2a94c2b5197d3ac12ee529fa65c298b092d43f4aec21bc3749cdf03953d9421bfb737fe728cb1993e5d1467b12f4d0373f0382be29a8770d123
checksum: b0ee7c5e2ae382be6c62e724c9b9aba1655e16a3aa5b88450d1442808b8e33c9f6d2578e2ecae0f9eab5aca61f8bb679ad1cdfca42b22f64c75ecc903255e41f
languageName: node
linkType: hard

Expand Down Expand Up @@ -13743,7 +13743,7 @@ __metadata:
"@markdoc/next.js": 0.2.2
"@next/bundle-analyzer": 13.4.12
"@open-draft/until": 2.1.0
"@pluralsh/design-system": 3.49.0
"@pluralsh/design-system": 3.53.0
"@pluralsh/eslint-config-typescript": 2.5.183
"@pluralsh/stylelint-config": 2.0.10
"@radix-ui/react-slot": 1.0.2
Expand Down
Loading