Skip to content

Commit d22e42a

Browse files
authored
[WIP]
1 parent 77f675c commit d22e42a

File tree

22 files changed

+613
-0
lines changed

22 files changed

+613
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import partners from '#site/util/partners/constants.json' with { type: 'json' };
2+
3+
export const GET = async () => {
4+
const list = partners
5+
.sort(() => 0.5 - Math.random())
6+
.slice(0, 4)
7+
.sort((a, b) => b.threshold - a.threshold);
8+
9+
return Response.json(list);
10+
};
11+
12+
// Enforces that this route is used as static rendering
13+
// Except whenever on the Development mode as we want instant-refresh when making changes
14+
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
15+
export const dynamic = 'force-static';
16+
17+
// Ensures that this endpoint is invalidated and re-executed every X minutes
18+
// so that when new deployments happen, the data is refreshed
19+
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#revalidate
20+
export const revalidate = 5000;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { FC, ReactElement } from 'react';
2+
import { cloneElement } from 'react';
3+
4+
import type { Partners } from '#site/types';
5+
6+
import Button from '../../Button';
7+
8+
const PartnersIcon: FC<Partners> = ({ href, logo }) => {
9+
return (
10+
<Button href={href} kind="secondary">
11+
{cloneElement(logo as ReactElement)}
12+
</Button>
13+
);
14+
};
15+
16+
export default PartnersIcon;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use client';
2+
3+
import { use, type FC } from 'react';
4+
5+
import type { Partners } from '#site/types';
6+
import { partnersList } from '#site/util/partners';
7+
8+
import PartnerIcon from '../PartnerIcon';
9+
10+
type PartnersIconListProps = {
11+
partners: Promise<Array<Partners>>;
12+
maxLength?: number;
13+
};
14+
15+
const PartnersIconList: FC<PartnersIconListProps> = ({ partners }) => {
16+
const allPartners = use(partners);
17+
18+
return (
19+
<div>
20+
{partnersList(allPartners).map((supporter, index) => (
21+
<PartnerIcon {...supporter} key={index} />
22+
))}
23+
</div>
24+
);
25+
};
26+
27+
export default PartnersIconList;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Suspense, type FC } from 'react';
2+
3+
import getPartners from '#site/next-data/partners';
4+
5+
import PartnersIconList from './Common/Partners/PartnersIconList';
6+
7+
const withPartnerIconList: FC = () => {
8+
const partners = getPartners();
9+
return (
10+
<Suspense fallback={<div>Loading partners...</div>}>
11+
<PartnersIconList partners={partners} />
12+
</Suspense>
13+
);
14+
};
15+
16+
export default withPartnerIconList;

apps/site/next-data/partners.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { NEXT_DATA_URL } from '#site/next.constants.mjs';
2+
import type { Partners } from '#site/types';
3+
4+
const getPartners = async (): Promise<Array<Partners>> => {
5+
const fetchURL = `${NEXT_DATA_URL}partner-data`;
6+
const response = await fetch(fetchURL);
7+
const text = await response.text();
8+
return JSON.parse(text);
9+
};
10+
11+
export default getPartners;

apps/site/next.mdx.use.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import UpcomingMeetings from './components/MDX/Calendar/UpcomingMeetings';
77
import WithBadgeGroup from './components/withBadgeGroup';
88
import WithBanner from './components/withBanner';
99
import WithNodeRelease from './components/withNodeRelease';
10+
import WithPartnersIconList from './components/withPartnerIconList';
1011

1112
/**
1213
* A full list of React Components that we want to pass through to MDX
@@ -21,6 +22,7 @@ export const mdxComponents = {
2122
WithBanner,
2223
// HOC for providing Badge Data
2324
WithBadgeGroup,
25+
WithPartnersIconList,
2426
// Standalone Badge Group
2527
BadgeGroup,
2628
// Renders an container for Upcoming Node.js Meetings

apps/site/pages/en/about/partners.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: TODO
3+
layout: about
4+
---

apps/site/pages/en/index.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,6 @@ layout: home
137137
138138
</div>
139139
Learn more what Node.js is able to offer with our [Learning materials](/learn).
140+
141+
<WithPartnersIconList />
140142
</section>

apps/site/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export * from './redirects';
1010
export * from './server';
1111
export * from './github';
1212
export * from './calendar';
13+
export * from './partners';
1314
export * from './author';
1415
export * from './download';
1516
export * from './userAgent';

apps/site/types/partners.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// import type { ReactElement, SVGProps } from 'react';
2+
3+
import type { ReactElement, SVGProps } from 'react';
4+
5+
export interface Partners {
6+
id: string;
7+
// The name of the partner
8+
name: string;
9+
// A logo to render on the partners page
10+
logo: ReactElement<SVGProps<SVGSVGElement>>;
11+
// The promoted link to their website or social media
12+
href: string;
13+
// The categories this partner belongs to
14+
categories: Array<PartnerCategory>;
15+
// An optional description of the partner
16+
description?: string;
17+
threshold: number;
18+
}
19+
20+
export type PartnerCategory = 'infrastructure' | 'security' | 'esp partner';

0 commit comments

Comments
 (0)