diff --git a/src/app/(frontend)/(pages)/posts/releases/[slug]/page.tsx b/src/app/(frontend)/(pages)/posts/releases/[slug]/page.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/(frontend)/(pages)/posts/releases/page.tsx b/src/app/(frontend)/(pages)/posts/releases/page.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/(frontend)/api/sync-releases/route.ts b/src/app/(frontend)/api/sync-releases/route.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/blocks/VersionSupportTable/index.ts b/src/blocks/VersionSupportTable/index.ts new file mode 100644 index 000000000..2c5f97884 --- /dev/null +++ b/src/blocks/VersionSupportTable/index.ts @@ -0,0 +1,78 @@ +import type { Block } from 'payload' + +import { blockFields } from '@root/fields/blockFields' + +export const VersionSupportTable: Block = { + slug: 'versionSupportTable', + fields: [ + blockFields({ + name: 'versionSupportTableFields', + fields: [ + { + name: 'heading', + type: 'text', + label: 'Heading', + }, + { + name: 'description', + type: 'textarea', + label: 'Description', + }, + { + name: 'rows', + type: 'array', + fields: [ + { + type: 'row', + fields: [ + { + name: 'payloadVersion', + type: 'text', + admin: { width: '20%' }, + label: 'Payload Version', + required: true, + }, + { + name: 'releaseDate', + type: 'text', + admin: { width: '20%' }, + label: 'Release Date', + }, + { + name: 'criticalFixesUntil', + type: 'text', + admin: { width: '20%' }, + label: 'Critical Fixes Until', + }, + { + name: 'securityFixesUntil', + type: 'text', + admin: { width: '20%' }, + label: 'Security Fixes Until', + }, + { + name: 'status', + type: 'select', + admin: { width: '20%' }, + label: 'Status', + options: [ + { label: 'Stable', value: 'stable' }, + { label: 'Beta', value: 'beta' }, + { label: 'EOL', value: 'eol' }, + ], + required: true, + }, + ], + }, + ], + label: 'Rows', + }, + ], + }), + ], + interfaceName: 'VersionSupportTableType', + labels: { + plural: 'Version Support Tables', + singular: 'Version Support Table', + }, +} diff --git a/src/collections/Pages.ts b/src/collections/Pages.ts index 90dad3f4e..ff763b5fd 100644 --- a/src/collections/Pages.ts +++ b/src/collections/Pages.ts @@ -84,6 +84,7 @@ export const Pages: CollectionConfig = { 'steps', 'stickyHighlights', 'exampleTabs', + 'versionSupportTable', ], blocks: [], required: true, diff --git a/src/collections/Releases.ts b/src/collections/Releases.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Release/ReleaseMarkdown/index.tsx b/src/components/Release/ReleaseMarkdown/index.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Release/index.module.scss b/src/components/Release/index.module.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Release/index.tsx b/src/components/Release/index.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/RenderBlocks/index.tsx b/src/components/RenderBlocks/index.tsx index ab25da826..6c4507311 100644 --- a/src/components/RenderBlocks/index.tsx +++ b/src/components/RenderBlocks/index.tsx @@ -34,6 +34,7 @@ import { Slider } from '@blocks/Slider/index' import { Statement } from '@blocks/Statement/index' import { Steps } from '@blocks/Steps/index' import { StickyHighlights } from '@blocks/StickyHighlights/index' +import { VersionSupportTable } from '@blocks/VersionSupportTable/index' import { getFieldsKeyFromBlock } from '@components/RenderBlocks/utilities' import { useThemePreference } from '@root/providers/Theme/index' import { toKebabCase } from '@utilities/to-kebab-case' @@ -71,6 +72,7 @@ const blockComponents = { statement: Statement, steps: Steps, stickyHighlights: StickyHighlights, + versionSupportTable: VersionSupportTable, } export type BlocksProp = RelatedPostsBlock | ReusableContent['layout'][0] | ReusableContentBlockType diff --git a/src/components/blocks/VersionSupportTable/index.module.scss b/src/components/blocks/VersionSupportTable/index.module.scss new file mode 100644 index 000000000..01dae0280 --- /dev/null +++ b/src/components/blocks/VersionSupportTable/index.module.scss @@ -0,0 +1,132 @@ +@use '@scss/common' as *; + +.heading { + margin-bottom: 0.5rem; +} + +.description { + @include body; + & { + color: var(--theme-elevation-500); + margin-bottom: 2rem; + } +} + +.tableWrap { + display: block; + overflow-x: scroll; + max-width: 100%; + margin-inline: 1px; +} + +.table { + border-block: 1px solid var(--theme-border-color); + border-collapse: collapse; + background-color: var(--theme-bg); + width: calc(var(--column) * 16 - 2px); + + * { + text-align: left; + padding: 0; + margin: 0; + } + + thead { + th { + @include small; + & { + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--theme-elevation-500); + font-weight: 500; + padding: 1.5rem; + white-space: nowrap; + } + } + } + + tbody { + tr { + border-top: 1px solid var(--theme-border-color); + } + + td { + padding: 1rem 1.5rem; + white-space: nowrap; + } + } +} + +.col { + width: calc(var(--column) * 3); + min-width: 140px; +} + +.colStatus { + width: calc(var(--column) * 2); + min-width: 100px; +} + +@include mid-break { + .table { + width: calc(var(--column) * 8 - 2px); + } + + .col { + width: auto; + min-width: 120px; + } + + .colStatus { + width: auto; + min-width: 80px; + } +} + +@include small-break { + .table { + width: auto; + } + + .col { + min-width: 110px; + } + + .colStatus { + min-width: 70px; + } + + .table thead th { + padding: 1rem; + } + + .table tbody td { + padding: 0.75rem 1rem; + } +} + +.badge { + display: inline-block; + padding: 0.2rem 0.75rem; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03em; + line-height: 1.4; +} + +.stable { + background-color: var(--theme-success-500); + color: var(--color-base-950); +} + +.beta { + background-color: var(--theme-elevation-200); + color: var(--theme-elevation-800); +} + +.eol { + background-color: var(--theme-error-500); + color: var(--color-base-0); +} diff --git a/src/components/blocks/VersionSupportTable/index.tsx b/src/components/blocks/VersionSupportTable/index.tsx new file mode 100644 index 000000000..7e8ce5b44 --- /dev/null +++ b/src/components/blocks/VersionSupportTable/index.tsx @@ -0,0 +1,82 @@ +import type { Page } from '@types' + +import { BackgroundGrid } from '@components/BackgroundGrid' +import { BlockWrapper, type PaddingProps } from '@components/BlockWrapper/index' +import { Gutter } from '@components/Gutter' +import React from 'react' + +import classes from './index.module.scss' + +type VersionSupportTableProps = { + hideBackground?: boolean + padding?: PaddingProps +} & Extract + +export const VersionSupportTable: React.FC = (props) => { + const { padding, versionSupportTableFields } = props + const { description, heading, rows, settings } = versionSupportTableFields || {} + + return ( + + + +
+ {heading ?

{heading}

: null} + {description ?

{description}

: null} +
+
+ + + + + + + + + + + + + + + + + + + {rows?.map( + ({ + id, + criticalFixesUntil, + payloadVersion, + releaseDate, + securityFixesUntil, + status, + }) => ( + + + + + + + + ), + )} + +
Payload VersionRelease DateCritical Fixes UntilSecurity Fixes UntilStatus
{payloadVersion}{releaseDate || '-'}{criticalFixesUntil || '-'}{securityFixesUntil || '-'} + + {status === 'eol' + ? 'EOL' + : status + ? status.charAt(0).toUpperCase() + status.slice(1) + : ''} + +
+
+
+
+ ) +} diff --git a/src/payload-types.ts b/src/payload-types.ts index a5cd35cec..279181f59 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -105,6 +105,7 @@ export interface Config { statement: Statement; steps: StepsBlock; stickyHighlights: StickyHighlights; + versionSupportTable: VersionSupportTableType; exampleTabs: ExampleTabsBlock; spotlight: SpotlightBlock; video: VideoBlock; @@ -749,6 +750,7 @@ export interface Page { | StepsBlock | StickyHighlights | ExampleTabsBlock + | VersionSupportTableType )[]; slug?: string | null; meta?: { @@ -2950,6 +2952,36 @@ export interface Command { blockName?: string | null; blockType: 'command'; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "VersionSupportTableType". + */ +export interface VersionSupportTableType { + versionSupportTableFields?: { + settings?: { + /** + * Leave blank for system default + */ + theme?: ('light' | 'dark') | null; + background?: ('solid' | 'transparent' | 'gradientUp' | 'gradientDown') | null; + }; + heading?: string | null; + description?: string | null; + rows?: + | { + payloadVersion: string; + releaseDate?: string | null; + criticalFixesUntil?: string | null; + securityFixesUntil?: string | null; + status: 'stable' | 'beta' | 'eol'; + id?: string | null; + }[] + | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'versionSupportTable'; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "DownloadBlockType". diff --git a/src/payload.config.ts b/src/payload.config.ts index 2e38a77a6..f3840dca1 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -52,6 +52,7 @@ import { Slider } from './blocks/Slider' import { Statement } from './blocks/Statement' import { Steps } from './blocks/Steps' import { StickyHighlights } from './blocks/StickyHighlights' +import { VersionSupportTable } from './blocks/VersionSupportTable' import { CaseStudies } from './collections/CaseStudies' import { Categories } from './collections/Categories' import { CommunityHelp } from './collections/CommunityHelp' @@ -152,6 +153,7 @@ export default buildConfig({ Statement, Steps, StickyHighlights, + VersionSupportTable, ExampleTabs, { slug: 'spotlight', diff --git a/src/scripts/fetchReleases.ts b/src/scripts/fetchReleases.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/scripts/seedReleases.ts b/src/scripts/seedReleases.ts new file mode 100644 index 000000000..e69de29bb