feat(microsite-next): Add on demand page with basic styles

Signed-off-by: Carlos Esteban Lopez <lcarlosesteb@vmware.com>
This commit is contained in:
Carlos Esteban Lopez
2023-03-08 21:34:30 -05:00
parent 673292e273
commit 907eabb6ae
7 changed files with 236 additions and 30 deletions
@@ -0,0 +1,17 @@
import React from 'react';
export interface ICardData {
header: React.ReactNode;
body: React.ReactNode;
footer: React.ReactNode;
}
export const SimpleCard = ({ header, body, footer }: ICardData) => (
<div className="card">
<div className="card__header">{header}</div>
<div className="card__body">{body}</div>
<div className="card__footer">{footer}</div>
</div>
);
@@ -0,0 +1,66 @@
import Link from '@docusaurus/Link';
import { SimpleCard } from '@site/src/components/simpleCard/simpleCard';
import React from 'react';
export interface IOnDemandData {
title: string;
category: string;
description: string;
date: string;
youtubeUrl: string;
youtubeImgUrl: string;
rsvpUrl: string;
eventUrl: string;
}
export const OnDemandCard = ({
title,
category,
description,
date,
youtubeUrl,
youtubeImgUrl,
rsvpUrl,
eventUrl,
}: IOnDemandData) => (
<SimpleCard
header={
<>
<h3>{title}</h3>
<p className="PluginCardAuthor">on {date}</p>
<span className="badge badge--primary">{category}</span>
<img src={youtubeImgUrl} alt={title} />
</>
}
body={<p>{description}</p>}
footer={
category.toLowerCase() === 'upcoming' ? (
<>
<Link
to={eventUrl}
className="button button--outline button--sm button--primary"
>
Event page
</Link>
<Link
to={rsvpUrl}
className="button button--outline button--sm button--primary"
>
Remind me
</Link>
</>
) : (
<Link
to={youtubeUrl}
className="button button--outline button--primary button--block"
>
Watch on YouTube
</Link>
)
}
/>
);
@@ -0,0 +1,78 @@
import Layout from '@theme/Layout';
import clsx from 'clsx';
import React from 'react';
import { IOnDemandData, OnDemandCard } from './_onDemandCard';
import pluginsStyles from './onDemand.module.scss';
import { truncateDescription } from '@site/src/util/truncateDescription';
import Link from '@docusaurus/Link';
//#region Plugin data import
const onDemandContext = require.context(
'../../../../microsite/data/on-demand',
false,
/\.ya?ml/,
);
const onDemandData = onDemandContext.keys().reduce(
(acum, id) => {
const pluginData: IOnDemandData = onDemandContext(id).default;
acum[
pluginData.category === 'Upcoming' ? 'upcomingEvents' : 'onDemandEvents'
].push(truncateDescription(pluginData));
return acum;
},
{
upcomingEvents: [] as IOnDemandData[],
onDemandEvents: [] as IOnDemandData[],
},
);
//#endregion
const Plugins = () => (
<Layout>
<div
className={clsx('container', 'padding--lg', pluginsStyles.onDemandPage)}
>
<div className="marketplaceBanner">
<div className="marketplaceContent">
<h2>Community sessions</h2>
<p>
Upcoming events and recorded sessions about updates, demos and
discussions.
</p>
</div>
<Link
to="/docs/overview/support"
className="button button--outline button--primary"
>
Add an event or recording
</Link>
</div>
<div className="bulletLine margin-bottom--lg"></div>
<h2>Upcoming live events</h2>
<div className="cardsContainer margin-bottom--lg">
{onDemandData.upcomingEvents.map(eventData => (
<OnDemandCard key={eventData.title} {...eventData}></OnDemandCard>
))}
</div>
<h2>Community on demand</h2>
<div className="cardsContainer margin-bottom--lg">
{onDemandData.onDemandEvents.map(eventData => (
<OnDemandCard key={eventData.title} {...eventData}></OnDemandCard>
))}
</div>
</div>
</Layout>
);
export default Plugins;
@@ -0,0 +1,44 @@
.onDemandPage {
:global(.marketplaceBanner) {
display: flex;
align-items: center;
}
:global(.marketplaceContent) {
flex: 1;
}
:global(.card) {
max-width: 100%;
}
:global(.card .card__header) {
display: grid;
row-gap: 0.25rem;
column-gap: 1rem;
justify-items: start;
> * {
margin: 0;
}
:global(img) {
width: 250px;
max-width: 100%;
justify-self: center;
}
}
:global(.card .card__footer) {
gap: 1rem;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
:global(.cardsContainer) {
gap: 1rem;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
justify-items: start;
}
}
@@ -1,4 +1,5 @@
import Link from '@docusaurus/Link';
import { SimpleCard } from '@site/src/components/simpleCard/simpleCard';
import React from 'react';
export interface IPluginData {
@@ -23,32 +24,30 @@ export const PluginCard = ({
iconUrl,
title,
}: IPluginData) => (
<div className="card">
<div className="card__header">
<img src={iconUrl || defaultIconUrl} alt={title} />
<SimpleCard
header={
<>
<img src={iconUrl || defaultIconUrl} alt={title} />
<h3>{title}</h3>
<h3>{title}</h3>
<p className="PluginCardAuthor">
by <a href={authorUrl}>{author}</a>
</p>
<p className="PluginCardAuthor">
by <a href={authorUrl}>{author}</a>
</p>
<span className="button button--sm button--outline button--primary">
{category}
</span>
</div>
<div className="card__body">
<p>{description}</p>
</div>
<div className="card__footer">
<span className="button button--sm button--outline button--primary">
{category}
</span>
</>
}
body={<p>{description}</p>}
footer={
<Link
to={documentation}
className="button button--outline button--primary button--block"
>
Explore
</Link>
</div>
</div>
}
/>
);
+2 -11
View File
@@ -5,18 +5,9 @@ import React from 'react';
import { IPluginData, PluginCard } from './_pluginCard';
import pluginsStyles from './plugins.module.scss';
import { truncateDescription } from '@site/src/util/truncateDescription';
//#region Plugin data import
const maxDescLength = 160;
const truncatePluginDescription = (pluginData: IPluginData) =>
pluginData.description.length > maxDescLength
? {
...pluginData,
description: pluginData.description.slice(0, maxDescLength) + '...',
}
: pluginData;
const pluginsContext = require.context(
'../../../../microsite/data/plugins',
false,
@@ -29,7 +20,7 @@ const plugins = pluginsContext.keys().reduce(
acum[
pluginData.category === 'Core Feature' ? 'corePlugins' : 'otherPlugins'
].push(truncatePluginDescription(pluginData));
].push(truncateDescription(pluginData));
return acum;
},
@@ -0,0 +1,11 @@
export const maxDescLength = 160;
export const truncateDescription = <T extends { description: string }>(
itemData: T,
) =>
itemData.description.length > maxDescLength
? {
...itemData,
description: itemData.description.slice(0, maxDescLength) + '...',
}
: itemData;