Skip to content

feat: Introduce Downloads Archive page #7794

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

Draft
wants to merge 42 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3937420
feat: simplified download page
canerakdas May 20, 2025
fa51777
chore: resolve conflict
canerakdas May 20, 2025
3e9cbeb
chore: fix type errors
canerakdas May 20, 2025
8abad4e
chore: remove unused css file
canerakdas May 20, 2025
924c640
refactor: release check and version without minor
canerakdas May 20, 2025
9c375d5
refactor: better localization
canerakdas May 25, 2025
e586292
refactor: separate layout, markdown and sidebar logic
canerakdas May 25, 2025
644882f
refactor: simple download utils
canerakdas May 25, 2025
4a0fd1c
refactor: getNodeDownloadUrl args destructuring
canerakdas May 25, 2025
426f4ed
refactor: localize and improve sidebar getter
canerakdas May 25, 2025
1f6e3db
refactor: better naming, docs and alias import
canerakdas May 25, 2025
dfd47a0
chore: sidebargroup naming
canerakdas May 25, 2025
fd09988
fix: active simplified sidebar and more docs
canerakdas May 25, 2025
0f1ae0a
feat: simple download meta bar added
canerakdas May 28, 2025
9c96639
chore: details styles moved into the site app
canerakdas May 29, 2025
bb5c03c
chore: details styles moved into the site app
canerakdas May 29, 2025
7f9c14b
fix: win x64, mac arm64 semver compat
canerakdas May 29, 2025
107b9f7
refactor: self review
canerakdas May 29, 2025
b07ba56
docs: downloads table
canerakdas May 29, 2025
5b30781
docs: fileoverview removed
canerakdas May 31, 2025
17cc8a0
fix: layout import
canerakdas May 31, 2025
a92ad35
Update apps/site/next.mdx.use.mjs
canerakdas May 31, 2025
c7264ea
refactor: layout changes
canerakdas Jun 2, 2025
199c3e6
refactor: renamed to download archive
canerakdas Jun 2, 2025
8a43b85
refactor: enhance buildReleaseArtifacts
canerakdas Jun 3, 2025
968517f
chore: resolve conflict
canerakdas Jun 3, 2025
1e6e0f4
docs: updating according to layout/naming
canerakdas Jun 4, 2025
52b6cdc
Update apps/site/util/downloadUtils/archive.tsx
canerakdas Jun 4, 2025
2759b68
chore: review updates
canerakdas Jun 4, 2025
7186a9b
Merge branch 'feat/simplified-download' of https://github.com/canerak…
canerakdas Jun 4, 2025
2eaa893
fix: scroll and archive artifacts
canerakdas Jun 4, 2025
31400af
refactor: minor versions table
canerakdas Jun 5, 2025
e516c0b
chore: lint
canerakdas Jun 5, 2025
1417339
feat: release alert box
canerakdas Jun 5, 2025
7358d16
chore: previous releases links
canerakdas Jun 5, 2025
b832299
refactor: version navigation and content
canerakdas Jun 5, 2025
0fa1f1d
fix: separator, modal border color
canerakdas Jun 6, 2025
2b17e6b
feat: DownloadReleasesTable download archive redirects
canerakdas Jun 6, 2025
f533ebc
refactor: markdown content editing and Node.js logo added
canerakdas Jun 6, 2025
1c8abdd
feat: home page button redirects
canerakdas Jun 6, 2025
d241894
refactor: minor text and styling updates
canerakdas Jun 8, 2025
edaf4e1
Merge branch 'main' into feat/simplified-download
canerakdas Jun 8, 2025
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
6 changes: 5 additions & 1 deletion apps/site/components/Downloads/DownloadButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ const DownloadButton: FC<PropsWithChildren<DownloadButtonProps>> = ({
const { os, bitness, architecture } = useClientContext();

const platform = getUserPlatform(architecture, bitness);
const downloadLink = getNodeDownloadUrl(versionWithPrefix, os, platform);
const downloadLink = getNodeDownloadUrl({
version: versionWithPrefix,
os: os,
platform: platform,
});

return (
<>
Expand Down
12 changes: 6 additions & 6 deletions apps/site/components/Downloads/DownloadLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ const DownloadLink: FC<PropsWithChildren<DownloadLinkProps>> = ({

const platform = getUserPlatform(architecture, bitness);

const downloadLink = getNodeDownloadUrl(
versionWithPrefix,
os,
platform,
kind
);
const downloadLink = getNodeDownloadUrl({
version: versionWithPrefix,
os: os,
platform: platform,
kind: kind,
});

return <LinkWithArrow href={downloadLink}>{children}</LinkWithArrow>;
};
Expand Down
49 changes: 49 additions & 0 deletions apps/site/components/Downloads/DownloadsTable/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use client';

import { useTranslations } from 'next-intl';
import type { FC } from 'react';

import Link from '#site/components/Link';
import { OperatingSystemLabel } from '#site/util/downloadUtils';
import type { NodeDownloadArtifact } from '#site/util/downloadUtils/simple';

type DownloadsTableProps = {
source: Array<NodeDownloadArtifact>;
};

const DownloadsTable: FC<DownloadsTableProps> = ({ source }) => {
const t = useTranslations();

return (
<table>
<thead>
<tr>
<th>{t('components.downloadsTable.fileName')}</th>
<th className="md:w-24">
{t('components.downloadsTable.operatingSystem')}
</th>
<th className="md:w-24">
{t('components.downloadsTable.architecture')}
</th>
</tr>
</thead>
<tbody>
{source.map(release => (
<tr key={`${release.file}-${release.architecture}`}>
<td data-label={t('components.downloadsTable.fileName')}>
<Link href={release.url}>{release.file}</Link>
</td>
<td data-label={t('components.downloadsTable.operatingSystem')}>
{OperatingSystemLabel[release.os]}
</td>
<td data-label={t('components.downloadsTable.architecture')}>
{release.architecture}
</td>
</tr>
))}
</tbody>
</table>
);
};

export default DownloadsTable;
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,21 @@ const PrebuiltDownloadButtons: FC = () => {
const { release, os, platform } = useContext(ReleaseContext);

const installerUrl = platform
? getNodeDownloadUrl(release.versionWithPrefix, os, platform, 'installer')
? getNodeDownloadUrl({
version: release.versionWithPrefix,
os: os,
platform: platform,
kind: 'installer',
})
: '';

const binaryUrl = platform
? getNodeDownloadUrl(release.versionWithPrefix, os, platform, 'binary')
? getNodeDownloadUrl({
version: release.versionWithPrefix,
os: os,
platform: platform,
kind: 'binary',
})
: '';

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const ReleaseCodeBox: FC = () => {
>
{t.rich('layouts.download.codeBox.noScriptDetected', {
link: text => (
<Link href="/about/previous-releases#looking-for-latest-release-of-a-version-branch">
<Link href="/download/simplified">
<b>{text}</b>
</Link>
),
Expand Down
41 changes: 41 additions & 0 deletions apps/site/components/MDX/Details/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@reference "../../../styles/index.css";

.root {
@apply border-b
border-neutral-200
px-0
pb-4
text-neutral-900
dark:border-neutral-800
dark:text-white;

summary {
@apply cursor-default
select-none
list-none
after:float-right
after:pr-4
after:text-2xl
after:text-neutral-400
after:content-['›']
dark:after:text-neutral-600;

h3 {
@apply inline;
}
}

&[open] summary {
@apply pb-4
after:rotate-90
after:transform
after:pt-4;
}

.detail {
@apply flex
select-none
flex-col
gap-4;
}
}
21 changes: 21 additions & 0 deletions apps/site/components/MDX/Details/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { FC, PropsWithChildren } from 'react';

import styles from './index.module.css';

type DetailsProps = {
summary: React.ReactNode;
};

const Details: FC<PropsWithChildren<DetailsProps>> = ({
children,
summary,
}) => (
<details className={styles.root}>
<summary>
<h3>{summary}</h3>
</summary>
<div className={styles.detail}>{children}</div>
</details>
);

export default Details;
2 changes: 2 additions & 0 deletions apps/site/components/withLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ArticlePageLayout from '#site/layouts/ArticlePage';
import BlogLayout from '#site/layouts/Blog';
import DefaultLayout from '#site/layouts/Default';
import DownloadLayout from '#site/layouts/Download';
import DownloadSimpleLayout from '#site/layouts/DownloadSimple';
import GlowingBackdropLayout from '#site/layouts/GlowingBackdrop';
import LearnLayout from '#site/layouts/Learn';
import PostLayout from '#site/layouts/Post';
Expand All @@ -18,6 +19,7 @@ const layouts = {
'blog-post': PostLayout,
'blog-category': BlogLayout,
download: DownloadLayout,
'download-simple': DownloadSimpleLayout,
article: ArticlePageLayout,
} satisfies Record<Layouts, FC>;

Expand Down
35 changes: 35 additions & 0 deletions apps/site/components/withMarkdownContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getLocale } from 'next-intl/server';
import type { FC } from 'react';

import { dynamicRouter } from '#site/next.dynamic';

const getMarkdownContent = async (locale: string, file: Array<string>) => {
const filePathname = dynamicRouter.getPathname(file);

// Retrieves the Markdown file source content based on the file path and locale
// Uses dynamic routing to locate and load the appropriate markdown file
// for the given locale and file path segments
const { source, filename } = await dynamicRouter.getMarkdownFile(
locale,
filePathname
);

// Parses the Markdown/MDX source content and transforms it into a React component
// Handles both standard Markdown and MDX files
const { content } = await dynamicRouter.getMDXContent(source, filename);

return content;
};

type WithMarkdownContentProps = {
file: Array<string>;
};

const WithMarkdownContent: FC<WithMarkdownContentProps> = async ({ file }) => {
const locale = await getLocale();
const content = await getMarkdownContent(locale, file);

return content || null;
};

export default WithMarkdownContent;
13 changes: 10 additions & 3 deletions apps/site/components/withMetaBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import MetaBar from '@node-core/ui-components/Containers/MetaBar';
import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub';
import { useFormatter, useLocale, useTranslations } from 'next-intl';
import type { FC } from 'react';
import type { ComponentProps, FC } from 'react';

import Link from '#site/components/Link';
import WithAvatarGroup from '#site/components/withAvatarGroup';
Expand All @@ -14,7 +14,11 @@ import { TRANSLATION_URL } from '#site/next.constants.mjs';
import { defaultLocale } from '#site/next.locales.mjs';
import { getGitHubBlobUrl } from '#site/util/gitHubUtils';

const WithMetaBar: FC = () => {
type WithMetaBarProps = {
items?: ComponentProps<typeof MetaBar>['items'];
};

const WithMetaBar: FC<WithMetaBarProps> = ({ items }) => {
const { headings, readingTime, frontmatter, filename } = useClientContext();
const formatter = useFormatter();
const lastUpdated = frontmatter.date
Expand Down Expand Up @@ -45,8 +49,11 @@ const WithMetaBar: FC = () => {
heading={t('components.metabar.tableOfContents')}
as={Link}
items={{
...items,
[t('components.metabar.lastUpdated')]: lastUpdated,
[t('components.metabar.readingTime')]: readingTimeText,
...(readingTime.minutes >= 1 && {
[t('components.metabar.readingTime')]: readingTimeText,
}),
...(usernames.length && {
[t(
`components.metabar.${usernames.length > 1 ? 'authors' : 'author'}`
Expand Down
44 changes: 29 additions & 15 deletions apps/site/components/withProgressionSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,53 @@ import ProgressionSidebar from '@node-core/ui-components/Common/ProgressionSideb
import { usePathname } from 'next/navigation';
import { useLocale, useTranslations } from 'next-intl';
import type { RichTranslationValues } from 'next-intl';
import type { FC } from 'react';
import type { ComponentProps, FC } from 'react';

import Link from '#site/components/Link';
import { useSiteNavigation } from '#site/hooks/server';
import { useRouter } from '#site/navigation.mjs';
import type { NavigationKeys } from '#site/types';

type WithProgressionSidebarProps = {
navKey: NavigationKeys;
context?: Record<string, RichTranslationValues>;
};
type Group = ComponentProps<typeof ProgressionSidebar>['groups'][number];

type WithProgressionSidebarProps =
| {
navKey: NavigationKeys;
context?: Record<string, RichTranslationValues>;
groups?: never;
}
| {
groups: Array<Group>;
navKey?: never;
context?: never;
};

const WithProgressionSidebar: FC<WithProgressionSidebarProps> = ({
navKey,
context,
}) => {
const WithProgressionSidebar: FC<WithProgressionSidebarProps> = props => {
const { getSideNavigation } = useSiteNavigation();
const pathname = usePathname();
const locale = useLocale();
const t = useTranslations();
const { push } = useRouter();
const [[, sidebarNavigation]] = getSideNavigation([navKey], context);

const mappedProgressionSidebarItems = sidebarNavigation.items.map(
([, { label, items }]) => ({
let groups: Array<Group> = [];

if ('navKey' in props && props.navKey) {
const [[, sidebarNavigation]] = getSideNavigation(
[props.navKey],
props.context
);

groups = sidebarNavigation.items.map(([, { label, items }]) => ({
groupName: label,
items: items.map(([, item]) => item),
})
);
}));
} else if ('groups' in props) {
groups = props.groups;
}

return (
<ProgressionSidebar
groups={mappedProgressionSidebarItems}
groups={groups}
pathname={pathname?.replace(`/${locale}`, '')}
title={t('components.common.sidebar.title')}
onSelect={push}
Expand Down
Loading