Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
54 changes: 54 additions & 0 deletions components/common/AnnouncementBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { FC, ReactElement, useState } from 'react';

interface AnnouncementBannerProps {
message: string;
linkUrl: string;
linkText: string;
}

const AnnouncementBanner: FC<AnnouncementBannerProps> = ({
message,
linkUrl,
linkText
}): ReactElement | null => {
const [isVisible, setIsVisible] = useState(true);

if (!isVisible) {
return null;
}

return (
<div className="relative bg-gradient-to-r from-orange-600 to-orange-500 text-white py-3 px-4 text-center">
<div className="max-w-7xl mx-auto flex items-center justify-center gap-2 flex-wrap pr-8">
<span className="text-sm font-medium">{message}</span>
<a
href={linkUrl}
target="_blank"
rel="noopener noreferrer"
className="text-sm font-semibold underline hover:no-underline"
>
{linkText}
</a>
</div>
<button
onClick={() => setIsVisible(false)}
className="absolute right-4 top-1/2 transform -translate-y-1/2 text-white hover:text-gray-200 transition-colors"
aria-label="Close announcement"
>
<svg
className="w-5 h-5"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
);
};

export default AnnouncementBanner;
8 changes: 7 additions & 1 deletion components/common/layout/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Footer from '../../sections/Footer'
import Subscribe from '../../sections/Subscribe'
import OgData from './SEO/SEO'
import PHBadge from '../product-hunt/PHBadge'
import AnnouncementBanner from '../AnnouncementBanner'

interface BackgroundWrapperProps {
children: React.ReactNode
Expand Down Expand Up @@ -42,13 +43,18 @@ const PageLayout: FC<PageLayoutProps> = ({
noindex={false}
/>
)}
<AnnouncementBanner
message="OpenSauced has joined the Linux Foundation"
linkUrl="https://opensauced.pizza/blog/opensauced-is-joining-the-linux-foundation"
linkText="Read more"
/>
<BackgroundWrapper>
{Array.isArray(children) && !children[1]?.props.totalLaunchesCount && (
<PHBadge />
)}
{!pressPage && <Header navigationItems={navigationURLs} />}
<div>{children}</div>

<Footer pressPage={pressPage} />
</BackgroundWrapper>
</div>
Expand Down
25 changes: 25 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[build]
command = "npm run build"

[build.environment]
NODE_VERSION = "22"

[context.production.environment]
NODE_VERSION = "22"

[context.deploy-preview.environment]
NODE_VERSION = "22"

[context.branch-deploy.environment]
NODE_VERSION = "22"

# Explicitly define plugins to override UI configuration
# This prevents the @netlify/plugin-lighthouse from running
[[plugins]]
package = "@netlify/plugin-nextjs"

[[plugins]]
package = "netlify-plugin-cloudinary"

[[plugins]]
package = "@netlify/plugin-emails"
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
2 changes: 1 addition & 1 deletion public/_redirects
Original file line number Diff line number Diff line change
@@ -1 +1 @@
https://intro.opensauced.pizza/* https://opensauced.pizza/learn/:splat 308!
https://intro.opensauced.pizza/* https://learn.osscommunities.com/:splat 308!