From 5dcaedb8e39e78251dde41eb3972c94bf396ff8e Mon Sep 17 00:00:00 2001 From: Claudio Wunder Date: Fri, 7 Mar 2025 11:29:59 -0300 Subject: [PATCH 1/2] draft: add supporters mechanism and new home page --- .../components/Common/NodejsLogo/index.tsx | 8 +- .../Common/Supporters/SupporterIcon/index.tsx | 24 +++ .../Supporters/SupporterIconList/index.tsx | 65 ++++++++ .../Common/Supporters/SupporterLogo/index.tsx | 9 ++ .../Supporters/SupporterLogoList/index.tsx | 14 ++ .../components/Common/Supporters/utils.ts | 10 ++ .../components/Containers/Footer/index.tsx | 15 +- .../Downloads/DownloadButton/index.module.css | 17 --- .../DownloadButton/index.stories.tsx | 30 ---- .../Downloads/DownloadButton/index.tsx | 51 ------- apps/site/components/withFooter.tsx | 8 +- .../site/components/withSupporterIconList.tsx | 10 ++ apps/site/navigation.json | 4 + apps/site/next.mdx.use.client.mjs | 17 +-- apps/site/next.supporters.constants.tsx | 19 +++ apps/site/pages/en/about/supporters.mdx | 6 + apps/site/pages/en/index.mdx | 40 +++-- apps/site/pages/es/index.mdx | 139 ----------------- apps/site/pages/fa/index.mdx | 134 ----------------- apps/site/pages/fr/index.mdx | 137 ----------------- apps/site/pages/id/index.mdx | 139 ----------------- apps/site/pages/ja/index.mdx | 137 ----------------- apps/site/pages/ko/index.mdx | 137 ----------------- apps/site/pages/pt/index.mdx | 134 ----------------- apps/site/pages/tr/index.mdx | 140 ------------------ apps/site/pages/uk/index.mdx | 138 ----------------- apps/site/pages/zh-cn/index.mdx | 133 ----------------- apps/site/pages/zh-tw/index.mdx | 137 ----------------- apps/site/types/index.ts | 11 +- apps/site/types/supporters.ts | 14 ++ packages/i18n/locales/en.json | 3 +- 31 files changed, 228 insertions(+), 1652 deletions(-) create mode 100644 apps/site/components/Common/Supporters/SupporterIcon/index.tsx create mode 100644 apps/site/components/Common/Supporters/SupporterIconList/index.tsx create mode 100644 apps/site/components/Common/Supporters/SupporterLogo/index.tsx create mode 100644 apps/site/components/Common/Supporters/SupporterLogoList/index.tsx create mode 100644 apps/site/components/Common/Supporters/utils.ts delete mode 100644 apps/site/components/Downloads/DownloadButton/index.module.css delete mode 100644 apps/site/components/Downloads/DownloadButton/index.stories.tsx delete mode 100644 apps/site/components/Downloads/DownloadButton/index.tsx create mode 100644 apps/site/components/withSupporterIconList.tsx create mode 100644 apps/site/next.supporters.constants.tsx create mode 100644 apps/site/pages/en/about/supporters.mdx delete mode 100644 apps/site/pages/es/index.mdx delete mode 100644 apps/site/pages/fa/index.mdx delete mode 100644 apps/site/pages/fr/index.mdx delete mode 100644 apps/site/pages/id/index.mdx delete mode 100644 apps/site/pages/ja/index.mdx delete mode 100644 apps/site/pages/ko/index.mdx delete mode 100644 apps/site/pages/pt/index.mdx delete mode 100644 apps/site/pages/tr/index.mdx delete mode 100644 apps/site/pages/uk/index.mdx delete mode 100644 apps/site/pages/zh-cn/index.mdx delete mode 100644 apps/site/pages/zh-tw/index.mdx create mode 100644 apps/site/types/supporters.ts diff --git a/apps/site/components/Common/NodejsLogo/index.tsx b/apps/site/components/Common/NodejsLogo/index.tsx index 7ca383e10c505..b6b43f48d505a 100644 --- a/apps/site/components/Common/NodejsLogo/index.tsx +++ b/apps/site/components/Common/NodejsLogo/index.tsx @@ -1,16 +1,16 @@ -import type { FC } from 'react'; +import type { ComponentProps, FC } from 'react'; import Nodejs from '@/components/Icons/Logos/Nodejs'; import type { LogoVariant } from '@/types'; import style from './index.module.css'; -type NodejsLogoProps = { +type NodejsLogoProps = ComponentProps & { variant?: LogoVariant; }; -const NodejsLogo: FC = ({ variant = 'default' }) => ( - +const NodejsLogo: FC = ({ variant = 'default', ...props }) => ( + ); export default NodejsLogo; diff --git a/apps/site/components/Common/Supporters/SupporterIcon/index.tsx b/apps/site/components/Common/Supporters/SupporterIcon/index.tsx new file mode 100644 index 0000000000000..86455ae2bf6fc --- /dev/null +++ b/apps/site/components/Common/Supporters/SupporterIcon/index.tsx @@ -0,0 +1,24 @@ +import Link from 'next/link'; +import { cloneElement, type ComponentProps, type FC } from 'react'; + +import Skeleton from '@/components/Common/Skeleton'; +import type { Supporter } from '@/types'; + +type SupporterIconProps = Supporter & ComponentProps; + +const SupporterIcon: FC = ({ + name, + href, + icon, + loading = false, +}) => ( + + + {cloneElement(icon, { + className: 'h-12 w-12 rounded-lg bg-neutral-100 p-1', + })} + + +); + +export default SupporterIcon; diff --git a/apps/site/components/Common/Supporters/SupporterIconList/index.tsx b/apps/site/components/Common/Supporters/SupporterIconList/index.tsx new file mode 100644 index 0000000000000..a1bb038bcca52 --- /dev/null +++ b/apps/site/components/Common/Supporters/SupporterIconList/index.tsx @@ -0,0 +1,65 @@ +'use client'; + +import { useEffect, useRef, useState, type FC } from 'react'; + +import SupporterIcon from '@/components/Common/Supporters/SupporterIcon'; +import { randomSupporterList } from '@/components/Common/Supporters/utils'; +import { DEFAULT_SUPPORTERS_LIST } from '@/next.supporters.constants'; +import type { Supporter } from '@/types'; + +type SupporterIconListProps = { + supporters: Array; + maxLength?: number; +}; + +const SupporterIconList: FC = ({ + supporters, + maxLength = 4, +}) => { + const initialRenderer = useRef(true); + + const [seedList, setSeedList] = useState>( + DEFAULT_SUPPORTERS_LIST + ); + + useEffect(() => { + // We intentionally render the initial default "mock" list of sponsors + // to have the Skeletons loading, and then we render the actual list + // after an enough amount of time has passed to give a proper sense of Animation + // We do this client-side effect, to ensure that a random-amount of sponsors is renderered + // on every page load. Since our page is natively static, we need to ensure that + // on the client-side we have a random amount of sponsors rendered. + // Although whilst we are deployed on Vercel or other environment that supports ISR + // (Incremental Static Generation) whose would invalidate the cache every 5 minutes + // We want to ensure that this feature is compatible on a full-static environment + const renderSponsorsAnimation = setTimeout(() => { + initialRenderer.current = false; + + setSeedList( + randomSupporterList( + supporters, + Math.max(supporters.length, maxLength * 2) + ) + ); + }, 1000); + + return () => clearTimeout(renderSponsorsAnimation); + // We only want this to run once on initial render + // We don't really care if the props change as realistically they shouldn't ever + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( +
+ {seedList.slice(0, maxLength).map((supporter, index) => ( + + ))} +
+ ); +}; + +export default SupporterIconList; diff --git a/apps/site/components/Common/Supporters/SupporterLogo/index.tsx b/apps/site/components/Common/Supporters/SupporterLogo/index.tsx new file mode 100644 index 0000000000000..bd6de5a35043d --- /dev/null +++ b/apps/site/components/Common/Supporters/SupporterLogo/index.tsx @@ -0,0 +1,9 @@ +import type { FC } from 'react'; + +import type { Supporter } from '@/types'; + +// @TODO: This will be used within the MDX page for Supporters +// to render the Logos of Supporters in the page +const SupporterLogo: FC = () => null; + +export default SupporterLogo; diff --git a/apps/site/components/Common/Supporters/SupporterLogoList/index.tsx b/apps/site/components/Common/Supporters/SupporterLogoList/index.tsx new file mode 100644 index 0000000000000..0fc31d2acbae5 --- /dev/null +++ b/apps/site/components/Common/Supporters/SupporterLogoList/index.tsx @@ -0,0 +1,14 @@ +import type { FC } from 'react'; + +import type { Supporter } from '@/types'; + +type SupporterLogoListProps = { + supporters: Array; +}; + +// @TODO: This will be used within the MDX page for Supporters +// to render the Logos of Supporters in the page +// in a grid format that renders logo biggers based on thresholds +const SupporterLogoList: FC = () => null; + +export default SupporterLogoList; diff --git a/apps/site/components/Common/Supporters/utils.ts b/apps/site/components/Common/Supporters/utils.ts new file mode 100644 index 0000000000000..0e0fee9c89340 --- /dev/null +++ b/apps/site/components/Common/Supporters/utils.ts @@ -0,0 +1,10 @@ +import type { Supporter } from '@/types'; + +export const randomSupporterList = ( + supporters: Array, + pick: number +) => + supporters + .sort(() => 0.5 - Math.random()) + .slice(0, pick) + .sort((a, b) => b.threshold - a.threshold); diff --git a/apps/site/components/Containers/Footer/index.tsx b/apps/site/components/Containers/Footer/index.tsx index e2d2411db1098..f0ec9c5eba6c6 100644 --- a/apps/site/components/Containers/Footer/index.tsx +++ b/apps/site/components/Containers/Footer/index.tsx @@ -8,7 +8,7 @@ import LinkedIn from '@/components/Icons/Social/LinkedIn'; import Mastodon from '@/components/Icons/Social/Mastodon'; import Slack from '@/components/Icons/Social/Slack'; import Twitter from '@/components/Icons/Social/Twitter'; -import { siteNavigation } from '@/next.json.mjs'; +import type { FooterConfig, SocialConfig } from '@/types'; import styles from './index.module.css'; @@ -21,15 +21,20 @@ const footerSocialIcons: Record>> = { bluesky: Bluesky, }; -const Footer: FC = () => { +type FooterProps = { + socialLinks: Array; + footerLinks: Array; +}; + +const Footer: FC = ({ socialLinks, footerLinks }) => { const t = useTranslations(); - const openJSlink = siteNavigation.footerLinks.at(-1)!; + const openJSlink = footerLinks.at(-1)!; return (