diff --git a/microsite/package.json b/microsite/package.json index 98301ce2d0..f1732c1142 100644 --- a/microsite/package.json +++ b/microsite/package.json @@ -20,6 +20,7 @@ "@docusaurus/module-type-aliases": "0.0.0-5580", "@spotify/prettier-config": "^14.0.0", "@tsconfig/docusaurus": "^1.0.6", + "@types/luxon": "^3.0.0", "@types/webpack-env": "^1.18.0", "js-yaml": "^4.1.0", "prettier": "^2.6.2", @@ -34,6 +35,7 @@ "@swc/core": "^1.3.46", "clsx": "^1.1.1", "docusaurus-plugin-sass": "^0.2.3", + "luxon": "^3.0.0", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/microsite/src/pages/plugins/_pluginCard.tsx b/microsite/src/pages/plugins/_pluginCard.tsx index d6b4017db5..ba8e8069d2 100644 --- a/microsite/src/pages/plugins/_pluginCard.tsx +++ b/microsite/src/pages/plugins/_pluginCard.tsx @@ -1,5 +1,6 @@ import Link from '@docusaurus/Link'; import { SimpleCard } from '@site/src/components/simpleCard/simpleCard'; +import clsx from 'clsx'; import React from 'react'; export interface IPluginData { @@ -10,6 +11,8 @@ export interface IPluginData { documentation: string; iconUrl: string; title: string; + addedDate: string; + isNew: boolean; order?: number; } @@ -22,14 +25,17 @@ export const PluginCard = ({ description, documentation, iconUrl, + isNew = false, title, }: IPluginData) => ( + {isNew &&
NEW
} + {title} -

{title}

+

{title}

by {author} diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index b1c9601110..7cb917c01b 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -1,12 +1,14 @@ import Link from '@docusaurus/Link'; +import PluginsFilter from '@site/src/components/pluginsFilter/pluginsFilter'; +import { calcIsNewPlugin } from '@site/src/util/calcIsNewPlugin'; +import { truncateDescription } from '@site/src/util/truncateDescription'; +import { ChipCategory } from '@site/src/util/types'; import Layout from '@theme/Layout'; import clsx from 'clsx'; import React, { useState } from 'react'; + import { IPluginData, PluginCard } from './_pluginCard'; import pluginsStyles from './plugins.module.scss'; -import { ChipCategory } from '@site/src/util/types'; -import { truncateDescription } from '@site/src/util/truncateDescription'; -import PluginsFilter from '@site/src/components/pluginsFilter/pluginsFilter'; const pluginsContext = require.context( '../../../data/plugins', @@ -16,7 +18,9 @@ const pluginsContext = require.context( const plugins = pluginsContext.keys().reduce( (acum, id) => { - const pluginData: IPluginData = pluginsContext(id).default; + let pluginData: IPluginData = pluginsContext(id).default; + + pluginData = calcIsNewPlugin(pluginData); acum[ pluginData.category === 'Core Feature' ? 'corePlugins' : 'otherPlugins' diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index d5ea5de6e7..9db634c3ed 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -11,6 +11,7 @@ :global(.card .card__header) { display: grid; row-gap: 0.25rem; + position: relative; column-gap: 1rem; align-items: center; grid-template-columns: auto 1fr; @@ -19,6 +20,28 @@ margin: 0; } + :global(.newRibbon) { + --paddingX: 1.2lh; + --rotation: 45deg; + --translateX: 30%; + --translateY: -100%; + + top: 0; + right: 0; + padding: 0 var(--paddingX); + position: absolute; + text-align: center; + + transform: translateY(var(--translateY)) translateX(var(--translateX)) + rotate(var(--rotation)); + transform-origin: bottom left; + background-color: var(--ifm-color-primary); + } + + :global(.newRibbonPadding) { + padding-right: 1.2lh; + } + :global(img) { width: 80px; grid-row: 1/4; diff --git a/microsite/src/util/calcIsNewPlugin.tsx b/microsite/src/util/calcIsNewPlugin.tsx new file mode 100644 index 0000000000..4b23e1d47d --- /dev/null +++ b/microsite/src/util/calcIsNewPlugin.tsx @@ -0,0 +1,18 @@ +import { DateTime } from 'luxon'; + +export const newDaysLimit = 100; + +export const calcIsNewPlugin = < + T extends { addedDate: string; isNew: boolean }, +>( + itemData: T, +) => { + const addedDate = DateTime.fromISO(itemData.addedDate); + const daysOld = Math.abs(addedDate.diffNow('days').days); + const isNew = !isNaN(daysOld) && daysOld < newDaysLimit; + + return { + ...itemData, + isNew, + }; +}; diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 7097fb337e..1d116ad6da 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -2941,6 +2941,13 @@ __metadata: languageName: node linkType: hard +"@types/luxon@npm:^3.0.0": + version: 3.3.0 + resolution: "@types/luxon@npm:3.3.0" + checksum: f7e3a89fc3ca404fbc3ea538653ed6860bc28f570a8c4d6d24449b89b9b553b7d6ad6cc94a9e129c5b8c9a2b97f0c365b3017f811e59c4a859a9c219a1c918e0 + languageName: node + linkType: hard + "@types/mdast@npm:^3.0.0": version: 3.0.10 resolution: "@types/mdast@npm:3.0.10" @@ -3752,10 +3759,12 @@ __metadata: "@spotify/prettier-config": ^14.0.0 "@swc/core": ^1.3.46 "@tsconfig/docusaurus": ^1.0.6 + "@types/luxon": ^3.0.0 "@types/webpack-env": ^1.18.0 clsx: ^1.1.1 docusaurus-plugin-sass: ^0.2.3 js-yaml: ^4.1.0 + luxon: ^3.0.0 prettier: ^2.6.2 prism-react-renderer: ^1.3.5 react: ^17.0.2 @@ -7348,6 +7357,13 @@ __metadata: languageName: node linkType: hard +"luxon@npm:^3.0.0": + version: 3.3.0 + resolution: "luxon@npm:3.3.0" + checksum: 50cf17a0dc155c3dcacbeae8c0b7e80db425e0ba97b9cbdf12a7fc142d841ff1ab1560919f033af46240ed44e2f70c49f76e3422524c7fc8bb8d81ca47c66187 + languageName: node + linkType: hard + "make-dir@npm:^3.0.2": version: 3.1.0 resolution: "make-dir@npm:3.1.0"