Skip to content

Commit

Permalink
Merge pull request #135 from samvera/feature/119-partners-from-cms
Browse files Browse the repository at this point in the history
Wire up Samvera Partners UI to Contentful CMS data
  • Loading branch information
heathergreerklein authored Feb 21, 2024
2 parents 29ca92b + fce5330 commit 9218b9d
Show file tree
Hide file tree
Showing 21 changed files with 723 additions and 65 deletions.
55 changes: 36 additions & 19 deletions components/BannerPartners.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
import Link from "next/link";
import { SAMVERA_PARTNERS } from "app-config";
import PartnersMap from "./PartnersMap";
import React from "react";
import getContentful from "lib/get-contentful";
import { useRouter } from "next/router";
import useSamveraPartners from "hooks/use-samvera-partners";

export default function BannerPartners() {
const router = useRouter();
const isHomePage = router.pathname === "/";

const { partners } = useSamveraPartners();

return (
<section className="py-8 bg-samBlue">
<h3 className="pb-4 text-center title">Samvera Partners</h3>
<div className="container">
<ul className="grid grid-cols-2 gap-4 ml-0 list-none lg:gap-6 lg:px-10 md:grid-cols-3 xl:grid-cols-4 ">
{SAMVERA_PARTNERS.map((partner) => (
<li key={partner.label} className="text-left">
<Link
href={partner.href}
className="text-samGreyDark hover:text-samDarkRed"
>
{partner.label}
</Link>
</li>
))}
</ul>
</div>
</section>
<>
<section className="py-8 bg-samBlue">
<h3 className="pb-4 text-center title">Samvera Partners</h3>
<div className="container">
<ul className="grid grid-cols-2 gap-4 ml-0 list-none lg:gap-6 lg:px-10 md:grid-cols-3 xl:grid-cols-4 ">
{partners.map(({ id, name, url }) => (
<li key={id} className="text-left">
{!url && name}
{url && (
<a
href={url}
className="text-samGreyDark hover:text-samDarkRed"
target="_blank"
rel="noopener noreferrer"
>
{name}
</a>
)}
</li>
))}
</ul>
</div>
</section>

{isHomePage && <PartnersMap partners={partners} />}
</>
);
}
37 changes: 37 additions & 0 deletions components/PartnersMap.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Map from "./leaflet-map/Map";
import React from "react";

const DEFAULT_CENTER = [38.907132, -77.036546];

const PartnersMap = ({ partners }) => {
if (partners.length === 0) return null;

return (
<>
<Map width="800" height="400" center={DEFAULT_CENTER} zoom={3}>
{({ TileLayer, Marker, Popup }) => (
<>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{partners.map(({ id, location, name }) => {
const hasLocation = location && location.lat && location.lon;
if (!hasLocation) return;

return (
<Marker key={id} position={[location.lat, location.lon]}>
<Popup>
<strong>{name}</strong>
</Popup>
</Marker>
);
})}
</>
)}
</Map>
</>
);
};

export default PartnersMap;
2 changes: 1 addition & 1 deletion components/home/Hero.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function HomeHero() {
</div>
<div className="mt-3 rounded-md shadow sm:mt-0 sm:ml-3">
<a className="button-inverted" href="#applications">
Learn more
Learn More About Samvera
</a>
</div>
</div>
Expand Down
35 changes: 35 additions & 0 deletions components/leaflet-map/DynamicMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useEffect } from 'react';
import Leaflet from 'leaflet';
import * as ReactLeaflet from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

import styles from './Map.module.scss';

const { MapContainer } = ReactLeaflet;

const Map = ({ children, className, width, height, ...rest }) => {
let mapClassName = styles.map;

if ( className ) {
mapClassName = `${mapClassName} ${className}`;
}

useEffect(() => {
(async function init() {
delete Leaflet.Icon.Default.prototype._getIconUrl;
Leaflet.Icon.Default.mergeOptions({
iconRetinaUrl: 'leaflet/images/marker-icon-2x.png',
iconUrl: 'leaflet/images/marker-icon.png',
shadowUrl: 'leaflet/images/marker-shadow.png',
});
})();
}, []);

return (
<MapContainer className={mapClassName} {...rest}>
{children(ReactLeaflet, Leaflet)}
</MapContainer>
)
}

export default Map;
22 changes: 22 additions & 0 deletions components/leaflet-map/Map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import dynamic from 'next/dynamic';

const DynamicMap = dynamic(() => import('./DynamicMap'), {
ssr: false
});

// Set default sizing to control aspect ratio which will scale responsively
// but also help avoid layout shift

const DEFAULT_WIDTH = 600;
const DEFAULT_HEIGHT = 600;

const Map = (props) => {
const { width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT } = props;
return (
<div style={{ aspectRatio: width / height }}>
<DynamicMap {...props} />
</div>
)
}

export default Map;
4 changes: 4 additions & 0 deletions components/leaflet-map/Map.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.map {
width: 100%;
height: 100%;
}
1 change: 1 addition & 0 deletions components/leaflet-map/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Map';
52 changes: 52 additions & 0 deletions components/the-community/Partners.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useEffect, useState } from "react";

import Breadcrumbs from "components/Breadcrumbs";
import Layout from "../layout/Layout";
import Main from "components/layout/Main";
import MarkdownContent from "components/MarkdownContent";
import useSamveraPartners from "hooks/use-samvera-partners";

export default function SamveraPartners({ config, content, frontmatter }) {
const { partners } = useSamveraPartners();

return (
<Layout title={`${frontmatter.title} - ${config.parentDirLabel} - Samvera`}>
<Breadcrumbs
items={[
{
href: "/",
label: config.parentDirLabel,
},
{
label: frontmatter.title,
},
]}
/>

<h1>{frontmatter.title}</h1>

<Main>
<ul className="grid grid-cols-2 gap-4 ml-0 list-none lg:gap-6 lg:px-10 md:grid-cols-3 xl:grid-cols-4">
{partners.map(({ id, name, url }) => (
<li key={id} className="text-left">
{!url && name}
{url && (
<a
href={url}
className="text-samGreyDark hover:text-samDarkRed"
target="_blank"
rel="noopener noreferrer"
>
{name}
</a>
)}
</li>
))}
</ul>
<hr />

<MarkdownContent content={content} />
</Main>
</Layout>
);
}
32 changes: 32 additions & 0 deletions hooks/use-samvera-partners.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useEffect, useState } from "react";

import getContentful from "lib/get-contentful";

export default function useSamveraPartners() {
const contentful = getContentful();

const [partners, setPartners] = useState([]);

useEffect(() => {
(async function init() {
const partners = await contentful.getEntries({
content_type: "samveraPartner",
});

if (!partners.items) {
return console.error("Error getting partners.");
}

const sorted = partners.items.sort((a, b) =>
a.fields.name.localeCompare(b.fields.name)
);
const groomedData = sorted.map((record) => ({
...record.fields,
id: record.sys.id,
}));
setPartners(groomedData);
})();
}, [contentful]);

return { partners };
}
1 change: 0 additions & 1 deletion lib/open-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@ export function buildWorkOpenGraphData(page, title, urlPath, imageUrl = image) {
"og:url": `https://samvera.org/${urlPath}`,
};

console.log("openGraphData", openGraphData);
return openGraphData;
}
36 changes: 3 additions & 33 deletions markdown/the-community/samvera-partners.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ date: "2016-12-06"

The Samvera Community is built around a core group of Partners committed to the success of the project and more importantly to the success of each other.  There are also many institutions and individuals that have formally committed to the sustainability of the Community through code contributions, participation in working or interest groups, helping with documentation, design, or planning.  No contribution is too small.  If you are interested in contributing to the Samvera Community or just interested in Samvera in general read more about the Community [here](https://samvera.org/hydra-partners/community-framework/). The number of Samvera Partners has grown steadily worldwide.

<iframe src="https://www.google.com/maps/d/u/1/embed?mid=1kLOr2tK3nZyuc49AInv_CtjwF30CzSGT" width="640" height="480"></iframe>
<iframe src="https://www.google.com/maps/d/u/1/embed?mid=1kLOr2tK3nZyuc49AInv_CtjwF30CzSGT" width="100%" height="600"></iframe>

<br />
The Hydra Project, Samvera's original name, was founded in 2008 by:

- Stanford University
Expand All @@ -20,35 +21,4 @@ quickly augmented by:

The three founding universities are still very active and, together with Data Curation Experts, continue to contribute to the work of the Samvera Community.  DuraSpace withdrew from formal Partnership in 2020 following their merger with Lyrasis but is still active in supporting the Community.

Additional Partners have formally committed themselves to support and further Samvera’s work.  In order of Partnership:

- Northwestern University
- Columbia University
- Penn State University
- Indiana University
- GBH Archives
- Boston Public Library
- Duke University
- Yale University
- University of Cincinnati
- Princeton University Library
- Cornell University
- University of Oregon
- Oregon State University
- Tufts University
- University of Michigan
- University of California, San Diego
- Lafayette College
- Washington University in St Louis
- Digital Repository of Ireland
- University of California, Santa Barbara
- University of Houston Libraries
- Emory University
- CoSector, University of London
- Ubiquity Press
- University of Utah
- Software Services by Scientist.com
- Hyku for Consortia (PALNI & PALCI)
- El Colegio de Mexico

…and further institutions are working with Samvera and its components.  Many of them are listed on our '[Samvera adopters](https://samvera.org/samvera-adopters/)' page.
Additional Partners have formally committed themselves to support and further Samvera’s work. Further institutions are working with Samvera and its components.  Many of them are listed on our '[Samvera adopters](https://samvera.org/samvera-adopters/)' page.
16 changes: 16 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");

/**
* @type {import('next').NextConfig}
*/
Expand All @@ -13,6 +16,19 @@ const nextConfig = {
},
output: "export",
reactStrictMode: true,
webpack: (config) => {
config.plugins.push(
new CopyPlugin({
patterns: [
{
from: "node_modules/leaflet/dist/images",
to: path.resolve(__dirname, "public", "leaflet", "images"),
},
],
})
);
return config;
},
};

module.exports = nextConfig;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@
"@tanstack/react-query": "^5.17.19",
"autoprefixer": "^10.4.17",
"contentful": "^10.6.16",
"copy-webpack-plugin": "^12.0.2",
"date-fns": "^3.3.1",
"deepmerge": "^4.3.1",
"gray-matter": "^4.0.3",
"jest": "^29.7.0",
"leaflet": "^1.9.4",
"markdown-it": "^14.0.0",
"next": "^14.1.0",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.2.1",
"rehype-raw": "^7.0.0",
"rehype-sanitize": "^6.0.0",
"rehype-stringify": "^10.0.0",
Expand Down
12 changes: 12 additions & 0 deletions pages/the-community/[slug].jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getMarkdownPageContent, getPaths } from "lib/markdown-helpers";
import CommunityLeadership from "components/the-community/CommunityLeadership";
import DynamicPage from "components/layout/DynamicPage";
import Faq from "components/the-community/Faq";
import SamveraPartners from "components/the-community/Partners";
import ServiceProviders from "components/the-community/ServiceProviders";
import UserProfilesPage from "components/the-community/UserProfiles";
import { buildWorkOpenGraphData } from "lib/open-graph";
Expand Down Expand Up @@ -35,6 +36,17 @@ export default function TheCommunityPage({ content, frontmatter, slug }) {
return <Faq config={CONFIG} content={content} frontmatter={frontmatter} />;
}

// Samvera Partners
if (slug === "samvera-partners") {
return (
<SamveraPartners
config={CONFIG}
content={content}
frontmatter={frontmatter}
/>
);
}

// Service Providers
if (slug === "service-providers") {
return (
Expand Down
Loading

0 comments on commit 9218b9d

Please sign in to comment.