Skip to content

Commit 0fec722

Browse files
authored
feat: redesign the previous releases page (#7630)
* feat(releaseData): add minorVersions prop * feat: create draft minor releases table modal * refactor: initials improvements * refactor: mv releasemodal component to correct dir * fix: release modal translation keys * feat: align button group * chore: rename badge component to badgegroup * refactor(BadgeGroup): use badge component * feat(DownloadReleasesTable): add status badge * feat(Modal): make subheader optional * refactor: create kind types * feat(ui-components): create separator component * feat(site): some improvements * refactor: nit * feat(site): add eol alerts * fix: remove incorrect anchor href * feat(ui-components): add smaller badge size * feat(site): add maintenance release status * feat(site): make codename prominent * chore: fix vertical separator story * refactor: some minor changes * fix: badgegroup references * refactor: small nit * feat: add minor versions release date * feat: smaller minor releases table * fix: oops wrong req * feat: create release overview component * fix: minor release links * feat(ui-components): add badge border on dark mode * chore: fix stylelint * chore: fix dep range * feat: format datetimes * refactor: small nits * fix: release announce links * refactor: remove comment * feat: use npm icon
1 parent e2828b8 commit 0fec722

File tree

40 files changed

+891
-243
lines changed

40 files changed

+891
-243
lines changed

apps/site/components/Downloads/DownloadReleasesTable.tsx

Lines changed: 0 additions & 61 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use client';
2+
3+
import { useTranslations } from 'next-intl';
4+
import type { FC } from 'react';
5+
import { use } from 'react';
6+
7+
import LinkWithArrow from '@/components/LinkWithArrow';
8+
import { ReleaseModalContext } from '@/providers/releaseModalProvider';
9+
import type { NodeRelease } from '@/types';
10+
11+
type DetailsButtonProps = {
12+
versionData: NodeRelease;
13+
};
14+
15+
const DetailsButton: FC<DetailsButtonProps> = ({ versionData }) => {
16+
const t = useTranslations('components.downloadReleasesTable');
17+
18+
const { openModal } = use(ReleaseModalContext);
19+
20+
return (
21+
<LinkWithArrow
22+
className="cursor-pointer"
23+
onClick={() => openModal(versionData)}
24+
>
25+
{t('details')}
26+
</LinkWithArrow>
27+
);
28+
};
29+
30+
export default DetailsButton;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import Badge from '@node-core/ui-components/Common/Badge';
2+
import { getTranslations } from 'next-intl/server';
3+
import type { FC } from 'react';
4+
5+
import FormattedTime from '@/components/Common/FormattedTime';
6+
import DetailsButton from '@/components/Downloads/DownloadReleasesTable/DetailsButton';
7+
import getReleaseData from '@/next-data/releaseData';
8+
9+
const DownloadReleasesTable: FC = async () => {
10+
const releaseData = await getReleaseData();
11+
12+
const t = await getTranslations();
13+
14+
return (
15+
<table id="tbVersions" className="download-table full-width">
16+
<thead>
17+
<tr>
18+
<th>{t('components.downloadReleasesTable.version')}</th>
19+
<th>{t('components.downloadReleasesTable.codename')}</th>
20+
<th>{t('components.downloadReleasesTable.firstReleased')}</th>
21+
<th>{t('components.downloadReleasesTable.lastUpdated')}</th>
22+
<th>{t('components.downloadReleasesTable.status')}</th>
23+
<th></th>
24+
</tr>
25+
</thead>
26+
<tbody>
27+
{releaseData.map(release => (
28+
<tr key={release.major}>
29+
<td data-label="Version">v{release.major}</td>
30+
<td data-label="LTS">{release.codename || '-'}</td>
31+
<td data-label="Date">
32+
<FormattedTime date={release.currentStart} />
33+
</td>
34+
<td data-label="Date">
35+
<FormattedTime date={release.releaseDate} />
36+
</td>
37+
<td data-label="Status">
38+
<Badge
39+
kind={release.status === 'End-of-life' ? 'warning' : 'default'}
40+
size="small"
41+
>
42+
{release.status}
43+
</Badge>
44+
</td>
45+
<td className="download-table-last">
46+
<DetailsButton versionData={release} />
47+
</td>
48+
</tr>
49+
))}
50+
</tbody>
51+
</table>
52+
);
53+
};
54+
55+
export default DownloadReleasesTable;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@reference "../../../styles/index.css";
2+
3+
.links {
4+
@apply flex
5+
h-4
6+
items-center
7+
gap-2;
8+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
'use client';
2+
3+
import Separator from '@node-core/ui-components/Common/Separator';
4+
import { useTranslations } from 'next-intl';
5+
import type { FC } from 'react';
6+
7+
import Link from '@/components/Link';
8+
import { BASE_CHANGELOG_URL } from '@/next.constants.mjs';
9+
import type { MinorVersion } from '@/types';
10+
import { getNodeApiLink } from '@/util/getNodeApiLink';
11+
12+
import styles from './index.module.css';
13+
14+
type MinorReleasesTableProps = {
15+
releases: Array<MinorVersion>;
16+
};
17+
18+
export const MinorReleasesTable: FC<MinorReleasesTableProps> = ({
19+
releases,
20+
}) => {
21+
const t = useTranslations('components.minorReleasesTable');
22+
23+
return (
24+
<table>
25+
<thead>
26+
<tr>
27+
<th>{t('version')}</th>
28+
<th>{t('links')}</th>
29+
</tr>
30+
</thead>
31+
<tbody>
32+
{releases.map(release => (
33+
<tr key={release.version}>
34+
<td>v{release.version}</td>
35+
<td>
36+
<div className={styles.links}>
37+
<Link
38+
kind="neutral"
39+
href={`https://nodejs.org/download/release/v${release.version}/`}
40+
>
41+
{t('actions.release')}
42+
</Link>
43+
<Separator orientation="vertical" />
44+
<Link
45+
kind="neutral"
46+
href={`${BASE_CHANGELOG_URL}${release.version}`}
47+
>
48+
{t('actions.changelog')}
49+
</Link>
50+
<Separator orientation="vertical" />
51+
<Link
52+
kind="neutral"
53+
href={getNodeApiLink(`v${release.version}`)}
54+
>
55+
{t('actions.docs')}
56+
</Link>
57+
</div>
58+
</td>
59+
</tr>
60+
))}
61+
</tbody>
62+
</table>
63+
);
64+
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import AlertBox from '@node-core/ui-components/Common/AlertBox';
2+
import Modal from '@node-core/ui-components/Common/Modal';
3+
import { useTranslations } from 'next-intl';
4+
import type { FC } from 'react';
5+
6+
import { MinorReleasesTable } from '@/components/Downloads/MinorReleasesTable';
7+
import { ReleaseOverview } from '@/components/Downloads/ReleaseOverview';
8+
import LinkWithArrow from '@/components/LinkWithArrow';
9+
import type { NodeRelease } from '@/types';
10+
11+
type ReleaseModalProps = {
12+
isOpen: boolean;
13+
closeModal: () => void;
14+
release: NodeRelease;
15+
};
16+
17+
const ReleaseModal: FC<ReleaseModalProps> = ({
18+
isOpen,
19+
closeModal,
20+
release,
21+
}) => {
22+
const t = useTranslations();
23+
24+
const modalHeadingKey = release.codename
25+
? 'components.releaseModal.title'
26+
: 'components.releaseModal.titleWithoutCodename';
27+
28+
const modalHeading = t(modalHeadingKey, {
29+
version: release.major,
30+
codename: release.codename ?? '',
31+
});
32+
33+
return (
34+
<Modal open={isOpen} onOpenChange={closeModal} heading={modalHeading}>
35+
{release.status === 'End-of-life' && (
36+
<AlertBox
37+
title={t('components.common.alertBox.warning')}
38+
level="warning"
39+
size="small"
40+
>
41+
{t('components.releaseModal.unsupportedVersionWarning')}
42+
</AlertBox>
43+
)}
44+
45+
{release.releaseAnnounceLink && (
46+
<LinkWithArrow href={release.releaseAnnounceLink}>
47+
{t('components.releaseModal.releaseAnnouncement')}
48+
</LinkWithArrow>
49+
)}
50+
51+
<h5>{t('components.releaseModal.overview')}</h5>
52+
53+
<ReleaseOverview release={release} />
54+
55+
<h5>{t('components.releaseModal.minorVersions')}</h5>
56+
57+
<MinorReleasesTable releases={release.minorVersions} />
58+
</Modal>
59+
);
60+
};
61+
62+
export default ReleaseModal;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
@reference "../../../styles/index.css";
2+
3+
.root {
4+
@apply rounded
5+
border
6+
border-neutral-200
7+
p-4
8+
text-neutral-900
9+
dark:border-neutral-800
10+
dark:text-white;
11+
12+
.container {
13+
@apply grid
14+
grid-cols-2
15+
gap-4
16+
lg:grid-cols-3;
17+
}
18+
19+
.item {
20+
@apply flex
21+
items-center
22+
gap-2;
23+
24+
h1 {
25+
@apply text-sm
26+
font-semibold;
27+
}
28+
29+
h2 {
30+
@apply text-xs
31+
font-normal;
32+
}
33+
34+
svg {
35+
@apply size-4;
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)