diff --git a/.gitignore b/.gitignore index aed3eb67..4c605104 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ public/ static/admin/*.bundle.* .idea/ .env.* +# Production configuration reference: never commit or use for local CMS writes. +.env.prod.secret .env src/content/events.json src/content/summit.json diff --git a/src/cms/cms.js b/src/cms/cms.js index d54821ce..3f42baea 100644 --- a/src/cms/cms.js +++ b/src/cms/cms.js @@ -26,6 +26,7 @@ import ContributorsPagePreview from './preview-templates/ContributorsPagePreview import AnnualReportPagePreview from './preview-templates/AnnualReportPagePreview' import SummitLandingPagePreview from './preview-templates/SummitLandingPagePreview' import OpenInfraDaysPagePreview from './preview-templates/OpenInfraDaysPagePreview' +import CommunityEventsPagePreview from './preview-templates/CommunityEventsPagePreview' CMS.registerPreviewStyle('style/styles.scss'); CMS.registerPreviewStyle('style/previews.css'); @@ -57,4 +58,5 @@ CMS.registerPreviewTemplate('electionPage', ElectionPagePreview) CMS.registerPreviewTemplate('contributors-pages', ContributorsPagePreview) CMS.registerPreviewTemplate('annual-report-pages', AnnualReportPagePreview) CMS.registerPreviewTemplate('summit-landing-page', SummitLandingPagePreview) -CMS.registerPreviewTemplate('openinfra-days', OpenInfraDaysPagePreview) \ No newline at end of file +CMS.registerPreviewTemplate('openinfra-days', OpenInfraDaysPagePreview) +CMS.registerPreviewTemplate('community-events', CommunityEventsPagePreview) diff --git a/src/cms/preview-templates/CommunityEventsPagePreview.js b/src/cms/preview-templates/CommunityEventsPagePreview.js new file mode 100644 index 00000000..579d33fc --- /dev/null +++ b/src/cms/preview-templates/CommunityEventsPagePreview.js @@ -0,0 +1,25 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { CommunityEventsPageTemplate } from '../../templates/community-events-page' + +const CommunityEventsPagePreview = ({ entry, widgetFor }) => { + const data = entry.getIn(['data']).toJS() + + return ( + + ) +} + +CommunityEventsPagePreview.propTypes = { + entry: PropTypes.shape({ getIn: PropTypes.func }).isRequired, + widgetFor: PropTypes.func.isRequired, +} + +export default CommunityEventsPagePreview diff --git a/src/components/MoreEventsSection/index.jsx b/src/components/MoreEventsSection/index.jsx index de27e2d6..97c7ce27 100644 --- a/src/components/MoreEventsSection/index.jsx +++ b/src/components/MoreEventsSection/index.jsx @@ -9,14 +9,14 @@ const COLORS = [ "#28a4db" ]; -const MoreEventsSection = ({ title, events }) => { +const MoreEventsSection = ({ title, events, headingTag: Heading = 'h1' }) => { return (
-

-
+ +
{events.map((event, idx) => ( -
+
{event.link ? <> @@ -42,4 +42,4 @@ const MoreEventsSection = ({ title, events }) => { ) } -export default MoreEventsSection \ No newline at end of file +export default MoreEventsSection diff --git a/src/pages/events/community-events/index.md b/src/pages/events/community-events/index.md index d951bfd8..abe8fa13 100644 --- a/src/pages/events/community-events/index.md +++ b/src/pages/events/community-events/index.md @@ -14,23 +14,57 @@ footer: display: false title: OPENINFRA COMMUNITY EVENTS subTitle: "" +eventsSchedule: + title: OpenInfra Events Schedule 2026 + events: + - name: "OpenInfra Day DRC" + date: "February 4, 2026" + location: "Kinshasa, DRC" + - name: "Project Teams Gathering (PTG)" + date: "April 20–24, 2026" + location: "Virtual" + link: "https://openinfra.org/ptg/" + - name: "OpenInfra Forum Sweden" + date: "May 21, 2026" + location: "Sweden" + link: "https://www.meetup.com/openinfra-user-group-sweden/events/313615139/" + - name: "KCD x OpenInfra Day Vietnam" + date: "July 25, 2026" + location: "Hanoi, Vietnam" + link: "https://2026.vietopeninfra.org/en/" + - name: "OpenInfra Day Nigeria" + date: "August 29, 2026" + location: "Jalingo, Nigeria" + link: "https://www.meetup.com/openstack-nigeria-user-group/events/313525373/" + - name: "KCD x Ceph x OpenInfra Day Korea" + date: "September 1, 2026" + location: "Seoul, South Korea" + link: "https://community2.cncf.io/events/details/cncf-kcd-south-korea-presents-kcd-x-ceph-x-openinfra-day-korea-2026/" + - name: "KubeCon + CloudNativeCon + OpenInfra Summit Asia + PyTorch Conference" + date: "September 8–9, 2026" + location: "Shanghai, China" + link: "https://www.lfasiallc.com/kubecon-cloudnativecon-openinfra-summit-china/" + - name: "OpenInfra Community at CODT" + date: "September 11, 2026" + location: "Tokyo, Japan" + link: "https://cloudopsdays.com/" + - name: "OpenInfra track at Sovereign Cloud Days Germany" + date: "October 22–25, 2026" + location: "Saarbrücken, Germany" + link: "https://www.sovereign-cloud-days.eu/en" + - name: "OpenInfra Track at ALASCA Summit" + date: "November 3–4, 2026" + location: "Dresden, Germany" + link: "https://alasca.cloud/en/alasca-summit-2026/alasca-summit-2026-programme/alasca-summit-2026-call-for-contributions/" + - name: "OpenInfra Day Kenya" + date: "November 6–7, 2026" + location: "Nairobi, Kenya" + link: "https://www.meetup.com/openinfra-user-group-kenya/events/315616588/" + - name: "OpenInfra Day North America" + date: "November 17, 2026" + location: "Chicago, IL" + link: "https://linuxfoundation.regfox.com/openinfra-day-north-america" --- -### **OpenInfra Events Schedule 2026** - -| **Date** | **Event Name** | -| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -| **February 4, 2026** | OpenInfra Day DRC | -| **April 20–24, 2026** | [Project Teams Gathering (PTG)](https://openinfra.org/ptg/) | -| **May 21, 2026** | [OpenInfra Forum Sweden](https://www.meetup.com/openinfra-user-group-sweden/events/313615139/) | -| **July 25, 2026** | [KCD x OpenInfra Day Vietnam](https://2026.vietopeninfra.org/en/) | -| **August 29, 2026** | [OpenInfra Day Nigeria](https://www.meetup.com/openstack-nigeria-user-group/events/313525373/) | -| **September 1, 2026** | [KCD x Ceph x OpenInfra Day Korea](https://community2.cncf.io/events/details/cncf-kcd-south-korea-presents-kcd-x-ceph-x-openinfra-day-korea-2026/) | -| **September 8–9, 2026** | [KubeCon + CloudNativeCon + OpenInfra Summit Asia + PyTorch Conference](https://www.lfasiallc.com/kubecon-cloudnativecon-openinfra-summit-china/) | -| **September 11, 2026** | OpenInfra Community at [CODT](https://cloudopsdays.com/) | -| **October 22-25, 2026** | OpenInfra track at [Sovereign Cloud Days Germany](https://www.sovereign-cloud-days.eu/en) | -| **November 3-4, 2026** | OpenInfra Track at [ALASCA Summit](https://alasca.cloud/en/alasca-summit-2026/alasca-summit-2026-programme/alasca-summit-2026-call-for-contributions/) | -| **November 6-7, 2026** | [OpenInfra Day Kenya](https://www.meetup.com/openinfra-user-group-kenya/events/315616588/) | -| **November 17, 2026** | [OpenInfra Day North America](https://linuxfoundation.regfox.com/openinfra-day-north-america) | ## [OpenInfra Summit ](/summit) @@ -50,4 +84,4 @@ OpenInfra User Groups are organized and hosted throughout the year by volunteer ## [Project Teams Gatherings](/ptg) -The Project Teams Gathering (PTG) provides meeting facilities allowing the various technical community groups working on open infrastructure projects to meet virtually, exchange and get work done in a productive, low-key setting. It lets those various groups discuss their priorities for the upcoming months, assign work items, iterate quickly on solutions for complex problems, and make fast progress on critical issues. The co-location of those various meetings, combined with the dynamic scheduling of the event, make it easy to get specific people in the same room to discuss a specific topic, or participate in multiple team meetings. \ No newline at end of file +The Project Teams Gathering (PTG) provides meeting facilities allowing the various technical community groups working on open infrastructure projects to meet virtually, exchange and get work done in a productive, low-key setting. It lets those various groups discuss their priorities for the upcoming months, assign work items, iterate quickly on solutions for complex problems, and make fast progress on critical issues. The co-location of those various meetings, combined with the dynamic scheduling of the event, make it easy to get specific people in the same room to discuss a specific topic, or participate in multiple team meetings. diff --git a/src/style/modules/_community-events.scss b/src/style/modules/_community-events.scss index da0c265e..1f7694d9 100644 --- a/src/style/modules/_community-events.scss +++ b/src/style/modules/_community-events.scss @@ -7,6 +7,75 @@ padding-bottom: 80px; } +// Reuse the OpenInfra Days event list, with spacing and wrapping for this page. +.community-events-schedule .more-events-section-wrapper .container { + margin: 0 auto 64px; + width: 100%; + max-width: 1100px; + + .title { + margin: 20px 0 40px !important; + font-size: clamp(28px, 4vw, 44px); + line-height: 1.2; + } + + .more-agenda-list { + margin-top: 0; + max-width: none; + + .agenda-row { + display: grid; + grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr) minmax(0, 1fr); + gap: 24px; + height: auto; + min-height: 88px; + padding: 22px 24px; + + .agenda-name, .agenda-date, .agenda-location { + width: auto; + min-width: 0; + margin: 0; + font-size: 16px; + line-height: 1.5; + overflow-wrap: anywhere; + } + + .agenda-name { + padding-left: 0; + + a:hover { + color: #b71920; + } + + a:focus-visible { + outline: 2px solid #b71920; + outline-offset: 4px; + } + } + + .agenda-date, .agenda-location { + padding-left: 34px; + + img { + width: 22px; + height: 24px; + } + } + } + } + + @media screen and (max-width: 767px) { + margin-bottom: 40px; + + .more-agenda-list .agenda-row { + grid-template-columns: minmax(0, 1fr); + gap: 12px; + padding: 20px; + border-left-width: 8px; + } + } +} + .community-events-wrapper { p { color: #161616; @@ -49,4 +118,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/templates/community-events-page.js b/src/templates/community-events-page.js index d6d656db..4848a28c 100644 --- a/src/templates/community-events-page.js +++ b/src/templates/community-events-page.js @@ -9,6 +9,7 @@ import NavbarV2 from '../components/NavbarV2'; import Hero from '../components/Hero' import SEO from '../components/SEO' import CommunityEventsSubNav from '../components/CommunityEventsSubNav' +import MoreEventsSection from '../components/MoreEventsSection' import { connect } from "react-redux"; @@ -17,6 +18,7 @@ export const CommunityEventsPageTemplate = ({ title, subTitle, footer, + eventsSchedule, content, contentComponent }) => { @@ -37,6 +39,15 @@ export const CommunityEventsPageTemplate = ({
+ {eventsSchedule && eventsSchedule.events && eventsSchedule.events.length > 0 && ( +
+ +
+ )}
@@ -73,6 +84,15 @@ CommunityEventsPageTemplate.propTypes = { title: PropTypes.string, subTitle: PropTypes.string, footer: PropTypes.object, + eventsSchedule: PropTypes.shape({ + title: PropTypes.string, + events: PropTypes.arrayOf(PropTypes.shape({ + name: PropTypes.string.isRequired, + date: PropTypes.string.isRequired, + location: PropTypes.string, + link: PropTypes.string, + })), + }), } const CommunityEventsPage = ({ isLoggedUser, data }) => { @@ -87,6 +107,7 @@ const CommunityEventsPage = ({ isLoggedUser, data }) => { title={post.frontmatter.title} subTitle={post.frontmatter.subTitle} footer={post.frontmatter.footer} + eventsSchedule={post.frontmatter.eventsSchedule} content={post.html} /> @@ -122,6 +143,15 @@ export const communityEventsPageQuery = graphql` } title subTitle + eventsSchedule { + title + events { + name + date + location + link + } + } footer { title subTitle @@ -132,4 +162,4 @@ export const communityEventsPageQuery = graphql` } } } -` \ No newline at end of file +` diff --git a/static/admin/config.yml b/static/admin/config.yml index 1f72261b..a62404c4 100644 --- a/static/admin/config.yml +++ b/static/admin/config.yml @@ -617,7 +617,7 @@ collections: files: - file: "src/pages/events/community-events/index.md" label: "Community Events" - name: "" + name: "community-events" fields: - { label: "Template Key", name: "templateKey", widget: "hidden", default: "community-events-page" } - { label: SEO, name: seo, widget: object, fields: [ @@ -629,6 +629,20 @@ collections: ] } - { label: "Title", name: title, widget: string } - { label: "Sub Title", name: subTitle, widget: string } + - label: "Events Schedule" + name: eventsSchedule + widget: object + fields: + - { label: "Heading", name: title, widget: string } + - label: "Events" + name: events + widget: list + summary: "{{fields.name}} — {{fields.date}}" + fields: + - { label: "Event Name", name: name, widget: string } + - { label: "Date", name: date, widget: string } + - { label: "Location", name: location, widget: string } + - { label: "Link", name: link, widget: string, required: false } - { label: "Body", name: body, widget: markdown } - { label: "Footer", name: footer, widget: object, required: false, fields: [ { label: "Title", name: title, widget: string, required: false }, @@ -1357,4 +1371,4 @@ collections: { label: "Link", name: link, widget: string }, { label: "Text", name: text, widget: string } ]} - ]} \ No newline at end of file + ]}