Skip to content

Commit f47fcdd

Browse files
committed
Add new partner pack page
1 parent 49d802b commit f47fcdd

34 files changed

+646
-2
lines changed

common/routes.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ export const Y2023 = makePath('/2023')
2828

2929
export const Y2024 = makePath('/2024')
3030

31-
export const NEWS = makePath("/news")
31+
export const NEWS = makePath("/news")
32+
33+
export const PARTNER_PACK = makePath('/partner-pack')

components/header/Header.jsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import GitHubLogo from '../../public/icons/github-logo'
1111
import IconCalendar from '../../public/icons/calendar'
1212
import IconBooks from '../../public/icons/books'
1313
import IconBell from '../../public/icons/bell'
14+
import BoxGift from '../../public/icons/box-gift'
1415
import { BREAKPOINTS } from '../../common/constants'
1516

1617
const Header = () => {
@@ -70,7 +71,7 @@ const Header = () => {
7071
href={ROUTES.NEWS.getPath(year)}
7172
aria-label={getLiteral('navigation:news')}
7273
className={clsx('header__link', {
73-
['is-active']: pathname === ROUTES.SCHEDULE.getPath(year),
74+
['is-active']: pathname === ROUTES.NEWS.getPath(year),
7475
})}
7576
>
7677
<IconBell />
@@ -79,6 +80,20 @@ const Header = () => {
7980
</span>
8081
</Link>
8182
</li>
83+
<li>
84+
<Link
85+
href={ROUTES.PARTNER_PACK.getPath(year)}
86+
aria-label={getLiteral('navigation:partner-pack')}
87+
className={clsx('header__link', {
88+
['is-active']: pathname === ROUTES.PARTNER_PACK.getPath(year),
89+
})}
90+
>
91+
<BoxGift />
92+
<span className="header__link-text">
93+
{getLiteral('navigation:partner-pack')}
94+
</span>
95+
</Link>
96+
</li>
8297
<li>
8398
<Link
8499
href={ROUTES.SCHEDULE.getPath(year)}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React from 'react'
2+
3+
const OfferCard = ({ offer }) => {
4+
const {
5+
name,
6+
logo,
7+
headline,
8+
description,
9+
secondaryCta,
10+
ctaText,
11+
ctaLink,
12+
multipleCtas,
13+
ctaText1,
14+
ctaLink1,
15+
ctaText2,
16+
ctaLink2
17+
} = offer;
18+
19+
return (
20+
<div className="offer-card">
21+
<div className="offer-card__logo">
22+
<img src={`/images/partners/${logo}`} alt={`${name} Logo`} />
23+
</div>
24+
<div className="offer-card__description">
25+
<h3>{name}</h3>
26+
<p><strong>{headline}</strong></p>
27+
<p>{description}</p>
28+
{secondaryCta && <p><strong>{secondaryCta}</strong></p>}
29+
</div>
30+
31+
{multipleCtas ? (
32+
<div className="offer-card__cta-container">
33+
<a href={ctaLink1} className="offer-card__cta" target="_blank" rel="noopener noreferrer">{ctaText1}</a>
34+
<a href={ctaLink2} className="offer-card__cta" target="_blank" rel="noopener noreferrer">{ctaText2}</a>
35+
</div>
36+
) : (
37+
<div className="offer-card__cta-container">
38+
<a href={ctaLink} className="offer-card__cta" target="_blank" rel="noopener noreferrer">{ctaText}</a>
39+
</div>
40+
)}
41+
</div>
42+
)
43+
}
44+
45+
const Offers = ({ partnerOffers, additionalSections }) => {
46+
const {
47+
wantMoreTitle,
48+
wantMoreContent,
49+
wantMoreLinkText,
50+
wantMoreLinkUrl,
51+
partnersTitle,
52+
partnersContent,
53+
joinAsPartnerContent
54+
} = additionalSections;
55+
56+
// Sort the partner offers alphabetically by name
57+
const sortedPartnerOffers = [...partnerOffers].sort((a, b) =>
58+
a.name.localeCompare(b.name)
59+
);
60+
61+
// Filter out private offers for the public offer cards
62+
const publicOffers = sortedPartnerOffers.filter(offer => !offer.private);
63+
64+
return (
65+
<div>
66+
<h2>Offers</h2>
67+
<div className="offers-grid-container">
68+
<div className="offers-grid">
69+
{publicOffers.map((offer, index) => (
70+
<OfferCard key={index} offer={offer} />
71+
))}
72+
</div>
73+
</div>
74+
75+
<h2>{wantMoreTitle}</h2>
76+
<p dangerouslySetInnerHTML={{ __html: wantMoreContent }}></p>
77+
78+
<h2>{partnersTitle}</h2>
79+
<p>{partnersContent}</p>
80+
81+
<div className="partner-logos">
82+
{sortedPartnerOffers.map((offer, index) => (
83+
<img
84+
key={index}
85+
src={`/images/partners/${offer.logo}`}
86+
alt={offer.name}
87+
/>
88+
))}
89+
</div>
90+
91+
<div className="become-partner-note">
92+
<p dangerouslySetInnerHTML={{ __html: joinAsPartnerContent }}></p>
93+
</div>
94+
</div>
95+
)
96+
}
97+
98+
export default Offers
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// Override the section-divider styling for the partner pack page
2+
.partner-pack {
3+
.section-divider {
4+
&__content {
5+
@media (min-width: $md) {
6+
grid-column: 1 / 9;
7+
}
8+
9+
@media (min-width: $lg) {
10+
grid-column: 1 / 13;
11+
}
12+
}
13+
}
14+
}
15+
16+
.offers-grid {
17+
display: grid;
18+
gap: spacing(3);
19+
grid-template-columns: 1fr;
20+
margin: 2rem 0 4rem 0;
21+
22+
@media (min-width: $sm) {
23+
grid-template-columns: repeat(2, 1fr);
24+
}
25+
26+
@media (min-width: $lg) {
27+
grid-template-columns: repeat(3, 1fr);
28+
}
29+
}
30+
31+
.offer-card {
32+
position: relative;
33+
display: flex;
34+
flex-direction: column;
35+
width: 100%;
36+
background: rgba(255, 255, 255, 0.05);
37+
border-radius: 12px;
38+
overflow: hidden;
39+
transition: transform 0.2s ease, background 0.2s ease;
40+
height: 100%;
41+
border: none;
42+
43+
&:hover {
44+
background: rgba(255, 255, 255, 0.1);
45+
transform: translateY(-2px);
46+
box-shadow: none;
47+
}
48+
49+
&__logo {
50+
padding: spacing(2) spacing(3);
51+
height: 90px;
52+
display: flex;
53+
align-items: center;
54+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
55+
56+
img {
57+
max-height: 60px;
58+
max-width: 180px;
59+
}
60+
}
61+
62+
&__description {
63+
padding: spacing(3);
64+
flex: 1;
65+
display: flex;
66+
flex-direction: column;
67+
gap: spacing(2);
68+
69+
h3 {
70+
font-family: 'JetBrains Mono', monospace;
71+
margin: 0;
72+
}
73+
74+
p {
75+
font-size: 1rem; // Back to normal size
76+
line-height: 1.5;
77+
color: rgba(255, 255, 255, 0.75);
78+
79+
strong {
80+
color: rgba(255, 255, 255, 0.9);
81+
}
82+
}
83+
}
84+
85+
a, a:hover, a:focus, a:visited {
86+
text-decoration: none !important;
87+
}
88+
89+
&__cta-container {
90+
margin-top: auto;
91+
padding: spacing(3);
92+
padding-top: spacing(2);
93+
border-top: 1px solid rgba(255, 255, 255, 0.1);
94+
text-align: left;
95+
}
96+
97+
&__cta {
98+
display: inline-block;
99+
background-color: transparent;
100+
color: white;
101+
padding: 0;
102+
border-radius: 0;
103+
text-align: left;
104+
font-weight: 500;
105+
transition: color 0.2s ease;
106+
font-family: 'Inter', sans-serif;
107+
box-shadow: none;
108+
text-decoration: none !important;
109+
font-size: 1.125rem;
110+
111+
&:hover, &:focus, &:visited {
112+
background-color: transparent;
113+
color: rgba(255, 255, 255, 0.8);
114+
text-decoration: none !important;
115+
transform: none;
116+
box-shadow: none;
117+
}
118+
}
119+
}
120+
121+
.partner-logos {
122+
display: flex;
123+
flex-wrap: wrap;
124+
justify-content: center;
125+
align-items: center;
126+
gap: 2rem;
127+
margin: 2rem 0;
128+
width: 100%;
129+
130+
img {
131+
max-width: 120px;
132+
max-height: 60px;
133+
filter: grayscale(100%);
134+
opacity: 0.7;
135+
transition: filter 0.3s, opacity 0.3s;
136+
137+
&:hover {
138+
filter: grayscale(0%);
139+
opacity: 1;
140+
}
141+
}
142+
}
143+
144+
.become-partner-note {
145+
margin-top: 2.5rem;
146+
text-align: center;
147+
148+
p {
149+
font-size: 0.9rem;
150+
color: var(--color-text-primary);
151+
opacity: 0.8;
152+
}
153+
154+
a {
155+
color: inherit;
156+
text-decoration: underline;
157+
158+
&:hover {
159+
opacity: 1;
160+
}
161+
}
162+
}
163+
164+
@media (max-width: 768px) {
165+
.offers-grid {
166+
grid-template-columns: 1fr;
167+
}
168+
}

content/commons.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"navigation:news": "News",
6363
"navigation:schedule": "Schedule",
6464
"navigation:library": "Library",
65+
"navigation:partner-pack": "Partner Pack",
6566

6667
"news:title": "News",
6768
"news:description": "This is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.",
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
wantMoreTitle: "Want More?"
3+
wantMoreContent: "<a href='https://maintainers.github.com'>Request to join</a> the Maintainer Community to unlock additional perks and early access."
4+
5+
partnersTitle: "Our Partners"
6+
partnersContent: "A big thank you to every partner supporting the people who make open source possible."
7+
8+
joinAsPartnerContent: "Interested in joining as a partner? <a href='mailto:[email protected]'>Email us</a>—we're accepting new offers throughout May!"
9+
---

content/partner-pack/index.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
title: "Maintainer Month 2025 Partner Pack"
3+
subtitle: "Real support for the people behind open source"
4+
metaTitle: "Maintainer Month 2025 Partner Pack | Resources for Open Source Maintainers"
5+
metaDesc: "Exclusive perks, tools, and resources for open source maintainers during Maintainer Month 2025."
6+
---
7+
8+
To celebrate Maintainer Month, we’re spotlighting the people who power open source — and giving back. We’ve teamed up with partners across the ecosystem to offer perks, tools, and resources especially for maintainers.
9+
10+
Check back throughout May as we add even more!
11+
12+
## How It Works
13+
14+
All offers below are available to any open source maintainer—just follow the links to claim your perk.
15+
16+
Some partners are offering premium perks exclusively for our private Maintainer Community. <a href="https://maintainers.github.com" target="_blank" rel="noopener noreferrer">Learn more & request access</a>.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
name: "boot.dev"
3+
logo: "bootdev.png"
4+
headline: "Level up your backend development skills."
5+
description: "Get 1 month of free premium access to boot.dev's interactive courses in Python, Go, JavaScript, and TypeScript."
6+
ctaText: "Redeem here"
7+
ctaLink: "https://www.boot.dev/github-maintainer-month/2025"
8+
---
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
name: "CNCF"
3+
logo: "cncf.png"
4+
headline: "Deepen your cloud native expertise."
5+
description: "Access discounts on select CNCF training courses, including Kubernetes-related offerings."
6+
secondaryCta: "(Details and redemption info coming soon)"
7+
ctaText: "Learn more"
8+
ctaLink: "#"
9+
---
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
name: "DevCycle"
3+
logo: "devcycle.png"
4+
headline: "Feature management built for open source."
5+
description: "Enjoy 1 year of free access to DevCycle's Developer plan — empowering maintainers to ship features faster and with more control."
6+
ctaText: "Claim here"
7+
ctaLink: "https://www.devcycle.com/github-maintainer-month"
8+
---

0 commit comments

Comments
 (0)