Skip to content

Commit

Permalink
feat: added renderer for badges (nodejs#6213)
Browse files Browse the repository at this point in the history
* feat: added renderer for badges

* refactor: refactored banner components and some optimizations

* fix: unit test

* fix: types
  • Loading branch information
ovflowd authored Jan 5, 2024
1 parent 132032b commit c2bb12f
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 53 deletions.
14 changes: 7 additions & 7 deletions components/Common/Banner/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,31 @@ type Meta = MetaObj<typeof Banner>;

export const Default: Story = {
args: {
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
children: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
type: 'default',
url: 'https://github.com/openjs-foundation/summit/issues/360',
link: 'https://github.com/openjs-foundation/summit/issues/360',
},
};

export const Error: Story = {
args: {
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
children: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
type: 'error',
url: 'https://github.com/nodejs/nodejs.org/issues/4495',
link: 'https://github.com/nodejs/nodejs.org/issues/4495',
},
};

export const Warning: Story = {
args: {
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
children: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
type: 'warning',
url: 'https://github.com/nodejs/nodejs.org/issues/4495',
link: 'https://github.com/nodejs/nodejs.org/issues/4495',
},
};

export const NoLink: Story = {
args: {
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
children: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
type: 'default',
},
};
Expand Down
17 changes: 10 additions & 7 deletions components/Common/Banner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { ArrowUpRightIcon } from '@heroicons/react/24/outline';
import type { FC } from 'react';
import type { FC, PropsWithChildren } from 'react';

import Link from '@/components/Link';

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

type BannerProps = {
type: 'default' | 'error' | 'warning';
text: string;
url?: string;
link?: string;
type?: 'default' | 'warning' | 'error';
};

const Banner: FC<BannerProps> = ({ type, text, url = '' }) => (
const Banner: FC<PropsWithChildren<BannerProps>> = ({
type = 'default',
link,
children,
}) => (
<div className={`${styles.banner} ${styles[type] || styles.default}`}>
{(url.length > 0 && <Link href={url}>{text}</Link>) || text}
{url.length > 0 && <ArrowUpRightIcon />}
{link ? <Link href={link}>{children}</Link> : children}
{link && <ArrowUpRightIcon />}
</div>
);

Expand Down
21 changes: 21 additions & 0 deletions components/withBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { FC } from 'react';

import Badge from '@/components/Common/Badge';
import { siteConfig } from '@/next.json.mjs';
import { dateIsBetween } from '@/util/dateIsBetween';

const WithBadge: FC<{ section: string }> = ({ section }) => {
const badge = siteConfig.websiteBadges[section];

if (badge && dateIsBetween(badge.startDate, badge.endDate)) {
return (
<Badge badgeText={badge.title} kind={badge.kind} href={badge.link}>
{badge.text}
</Badge>
);
}

return null;
};

export default WithBadge;
21 changes: 21 additions & 0 deletions components/withBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { FC } from 'react';

import Banner from '@/components/Common/Banner';
import { siteConfig } from '@/next.json.mjs';
import { dateIsBetween } from '@/util/dateIsBetween';

const WithBanner: FC<{ section: string }> = ({ section }) => {
const banner = siteConfig.websiteBanners[section];

if (banner && dateIsBetween(banner.startDate, banner.endDate)) {
return (
<Banner type={banner.type} link={banner.link}>
{banner.text}
</Banner>
);
}

return null;
};

export default WithBanner;
29 changes: 17 additions & 12 deletions components/withNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useTheme } from 'next-themes';
import type { FC } from 'react';

import NavBar from '@/components/Containers/NavBar';
import WithBanner from '@/components/withBanner';
import { useClientContext, useSiteNavigation } from '@/hooks';
import { useRouter } from '@/navigation.mjs';
import { availableLocales } from '@/next.locales.mjs';
Expand All @@ -21,18 +22,22 @@ const WithNavBar: FC = () => {
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark');

return (
<NavBar
onThemeTogglerClick={toggleCurrnetTheme}
languages={{
currentLanguage: locale,
availableLanguages: availableLocales,
onChange: locale => replace(pathname!, { locale: locale.code }),
}}
navItems={navigationItems.map(([, { label, link }]) => ({
link,
text: label,
}))}
/>
<>
<WithBanner section="index" />

<NavBar
onThemeTogglerClick={toggleCurrnetTheme}
languages={{
currentLanguage: locale,
availableLanguages: availableLocales,
onChange: locale => replace(pathname!, { locale: locale.code }),
}}
navItems={navigationItems.map(([, { label, link }]) => ({
link,
text: label,
}))}
/>
</>
);
};

Expand Down
10 changes: 2 additions & 8 deletions site.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,8 @@
"category": "vulnerability"
}
],
"websiteBanners": {
"index": {
"startDate": "2023-11-26T00:00:00.000Z",
"endDate": "2023-12-05T00:00:00.000Z",
"link": "https://training.linuxfoundation.org/cyber-monday-js-2023/?utm_source=openjsf&utm_medium=homepage-ticker&utm_campaign=cybermonday23",
"html": "<img src='https://i.imgur.com/8FgdVOy.png' alt='Node.js Training Banner' style='margin:0 auto;border-radius:4px;' />"
}
},
"websiteBanners": {},
"websiteBadges": {},
"footerLinks": [
{
"link": "https://openjsf.org/wp-content/uploads/sites/84/2021/01/OpenJS-Foundation-Trademark-Policy-2021-01-12.docx.pdf",
Expand Down
3 changes: 2 additions & 1 deletion types/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RSSFeed, WebsiteBanner } from './features';
import type { RSSFeed, WebsiteBadge, WebsiteBanner } from './features';

export interface TwitterConfig {
username: string;
Expand Down Expand Up @@ -34,6 +34,7 @@ export interface SiteConfig {
twitter: TwitterConfig;
rssFeeds: Array<RSSFeed>;
websiteBanners: Record<string, WebsiteBanner>;
websiteBadges: Record<string, WebsiteBadge>;
footerLinks: Array<FooterConfig>;
socialLinks: Array<SocialConfig>;
}
16 changes: 14 additions & 2 deletions types/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ export interface RSSFeed {
blogCategory?: string;
}

export interface WebsiteBanner {
interface WithRange {
startDate: string;
endDate: string;
text?: string;
}

export interface WebsiteBanner extends WithRange {
text: string;
link?: string;
/** @deprecated the html field is unsupported on the website redesign */
html?: string;
type?: 'default' | 'warning' | 'error';
}

export interface WebsiteBadge extends WithRange {
text: string;
link: string;
title?: string;
kind?: 'default' | 'warning' | 'error';
}
11 changes: 0 additions & 11 deletions types/releases.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
export interface UpcomingReleaseData {
releaseDate: string;
releaseType: 'Current' | 'LTS' | 'Maintenance' | 'End-of-life';
alreadyReleased: boolean;
}

export interface UpcomingRelease {
name: string;
releases: UpcomingReleaseData[];
}

export type NodeReleaseStatus =
| 'Maintenance LTS'
| 'Active LTS'
Expand Down
8 changes: 4 additions & 4 deletions util/__tests__/dateIsBetween.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ describe('dateIsBetween', () => {
expect(result).toBe(false);
});

it('returns false when either start or end date is invalid', () => {
it('throws when either start or end date is invalid', () => {
const invalidStartDate = 'Invalid Start Date';
const validEndDate = '2024-01-01T00:00:00.000Z';

const result = dateIsBetween(invalidStartDate, validEndDate);

expect(result).toBe(false);
expect(() => dateIsBetween(invalidStartDate, validEndDate)).toThrow(
'dateIsBetween got called with invalid dates'
);
});
});
2 changes: 1 addition & 1 deletion util/dateIsBetween.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const dateIsBetween = (startDate: string, endDate: string): boolean => {
const end = new Date(endDate);

if ([start.toString(), end.toString()].includes(invalidDateStr)) {
return false;
throw new Error('dateIsBetween got called with invalid dates');
}

const now = new Date();
Expand Down

0 comments on commit c2bb12f

Please sign in to comment.