Skip to content

Commit

Permalink
Merge pull request #114 from samvera/113-contentful-service-providers
Browse files Browse the repository at this point in the history
Wire up Service Providers data to Contentful CMS
  • Loading branch information
heathergreerklein authored Oct 5, 2023
2 parents 4651f5c + 7624af6 commit a7d3d8c
Show file tree
Hide file tree
Showing 16 changed files with 780 additions and 121 deletions.
Binary file added assets/partner-logos/bpl-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/partner-logos/emory-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/service-provider-logos/ubiquity-press.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions components/RichTextContent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { documentToReactComponents } from "@contentful/rich-text-react-renderer";

const RichTextContent = ({ content }) => {
if (!content) return null;
return <>{documentToReactComponents(content)}</>;
};

export default RichTextContent;
23 changes: 23 additions & 0 deletions components/RichTextFromMarkdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useEffect, useState } from "react";

import { documentToReactComponents } from "@contentful/rich-text-react-renderer";
import { richTextFromMarkdown } from "@contentful/rich-text-from-markdown";

const RichTextFromMarkdown = ({ content }) => {
const [richText, setRichText] = useState(null);

useEffect(() => {
if (!content) return;

async function fn() {
const response = await richTextFromMarkdown(content);

setRichText(response);
}
fn();
}, [content]);

return richText ? <>{documentToReactComponents(richText)}</> : null;
};

export default RichTextFromMarkdown;
97 changes: 97 additions & 0 deletions components/repository-solutions/ExamplesDemos.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import Breadcrumbs from "../Breadcrumbs";
import Layout from "../layout/Layout";
import Main from "../layout/Main";
import MarkdownContent from "../MarkdownContent";
import React from "react";
import RichTextContent from "components/RichTextContent";
import getContentful from "lib/get-contentful";

export default function ExamplesAndDemos({ config, content, frontmatter }) {
const contentful = getContentful();
const [entries, setEntries] = React.useState([]);

React.useEffect(() => {
async function fetchEntries() {
const entries = await contentful.getEntries({
content_type: "examplesAndDemos",
});

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

fetchEntries();
}, [contentful]);

function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}

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

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

<MarkdownContent content={content} />

<div className="mb-10 overflow-hidden bg-gray-200 divide-y divide-gray-200 rounded-lg shadow sm:grid sm:grid-cols-2 sm:gap-px sm:divide-y-0">
{entries.map((entry, actionIdx) => (
<div
key={entry.fields.title}
className={classNames(
actionIdx === 0
? "rounded-tl-lg rounded-tr-lg sm:rounded-tr-none"
: "",
actionIdx === 1 ? "sm:rounded-tr-lg" : "",
actionIdx === entries.length - 2 ? "sm:rounded-bl-lg" : "",
actionIdx === entries.length - 1
? "rounded-bl-lg rounded-br-lg sm:rounded-bl-none"
: "",
"group relative bg-white p-6 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-500"
)}
>
<div className="mt-8">
<h3 className="text-base font-semibold leading-6 text-gray-900">
<a href={entry.fields.url} className="focus:outline-none">
{/* Extend touch target to entire panel */}
<span className="absolute inset-0" aria-hidden="true" />
{entry.fields.title}
</a>
</h3>
<p className="mt-2 text-sm text-gray-500">
<RichTextContent content={entry.fields.description} />
</p>
</div>
<span
className="absolute text-gray-300 pointer-events-none right-6 top-6 group-hover:text-gray-400"
aria-hidden="true"
>
<svg
className="w-6 h-6"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M20 4h1a1 1 0 00-1-1v1zm-1 12a1 1 0 102 0h-2zM8 3a1 1 0 000 2V3zM3.293 19.293a1 1 0 101.414 1.414l-1.414-1.414zM19 4v12h2V4h-2zm1-1H8v2h12V3zm-.707.293l-16 16 1.414 1.414 16-16-1.414-1.414z" />
</svg>
</span>
</div>
))}
</div>
</Main>
</Layout>
);
}
35 changes: 34 additions & 1 deletion components/the-community/Faq.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { MinusSmallIcon, PlusSmallIcon } from "@heroicons/react/24/outline";
import Breadcrumbs from "../Breadcrumbs";
import { Disclosure } from "@headlessui/react";
import Layout from "../layout/Layout";
import Link from "next/link";
import Main from "../layout/Main";
import MarkdownContent from "../MarkdownContent";
import React from "react";
import RichTextContent from "components/RichTextContent";
import getContentful from "lib/get-contentful";

const FAQItem = ({ children }) => {
return (
Expand Down Expand Up @@ -44,6 +46,24 @@ const Answer = ({ children }) => {
};

export default function Faq({ config, content, frontmatter }) {
const contentful = getContentful();
const [faqs, setFaqs] = React.useState([]);

React.useEffect(() => {
async function fetchEntries() {
const entries = await contentful.getEntries({
content_type: "faq",
});

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

fetchEntries();
}, [contentful]);

return (
<Layout title={`${frontmatter.title} - ${config.parentDirLabel} - Samvera`}>
<Main>
Expand All @@ -60,9 +80,22 @@ export default function Faq({ config, content, frontmatter }) {
/>

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

<MarkdownContent content={content} />

<dl className="mt-10 space-y-6 divide-y divide-gray-900/10">
{/* {faqs.map((faq, idx) => (
<FAQItem key={idx}>
{({ open }) => (
<>
<Question open={open}>{faq.fields.question}</Question>
<Answer>
<RichTextContent content={faq.fields.answer} />
</Answer>
</>
)}
</FAQItem>
))} */}
<FAQItem>
{({ open }) => (
<>
Expand Down
114 changes: 114 additions & 0 deletions components/the-community/ServiceProviders.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
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 RichTextContent from "components/RichTextContent";
import getContentful from "lib/get-contentful";

function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}

export default function ServiceProviders({ config, content, frontmatter }) {
const contentful = getContentful();
const [entries, setEntries] = useState([]);

useEffect(() => {
async function fetchEntries() {
const entries = await contentful.getEntries({
content_type: "serviceProviderProfile",
});
console.log("entries", entries);

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

fetchEntries();
}, [contentful]);

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

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

<MarkdownContent content={content} />
<Main>
<div className="my-10 overflow-hidden bg-gray-200 divide-y divide-gray-200 rounded-lg shadow sm:grid sm:grid-cols-2 sm:gap-px sm:divide-y-0">
{entries.map(
(
{ fields: { descriptionRich, email, logo, name, url } },
actionIdx
) => (
<div
key={name}
className={classNames(
actionIdx === 0
? "rounded-tl-lg rounded-tr-lg sm:rounded-tr-none"
: "",
actionIdx === 1 ? "sm:rounded-tr-lg" : "",
actionIdx === entries?.length - 2 ? "sm:rounded-bl-lg" : "",
actionIdx === entries?.length - 1
? "rounded-bl-lg rounded-br-lg sm:rounded-bl-none"
: "",
"group relative bg-white p-6 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-500"
)}
>
<div>
<img
src={logo?.fields?.file?.url}
alt={logo?.fields?.title || ""}
/>
</div>
<div className="mt-8 space-y-4">
<h3 className="text-base font-semibold leading-6 ">
<a
href={url}
className="inline-block text-gray-900 focus:outline-none hover:text-gray-900"
>
<span className="" aria-hidden="true" />
{name}
</a>
</h3>
<a href={`mailto:${email}`} className="text-base leading-6 ">
{email}
</a>
<p className="text-gray-500 ">
<RichTextContent content={descriptionRich} />
</p>
</div>
<a
href={url}
className="absolute text-gray-300 right-6 top-6 group-hover:text-gray-400"
>
<svg
className="w-6 h-6"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M20 4h1a1 1 0 00-1-1v1zm-1 12a1 1 0 102 0h-2zM8 3a1 1 0 000 2V3zM3.293 19.293a1 1 0 101.414 1.414l-1.414-1.414zM19 4v12h2V4h-2zm1-1H8v2h12V3zm-.707.293l-16 16 1.414 1.414 16-16-1.414-1.414z" />
</svg>
</a>
</div>
)
)}
</div>
</Main>
</Layout>
);
}
16 changes: 16 additions & 0 deletions lib/get-contentful.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createClient } from "contentful";

let client;

function getContentful() {
if (!client) {
client = createClient({
space: process.env.NEXT_PUBLIC_CONTENTFUL_SPACE_ID,
accessToken: process.env.NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN,
});
}

return client;
}

export default getContentful;
25 changes: 12 additions & 13 deletions markdown/repository-solutions/examples-and-demos.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,28 @@ date: "2023-08-04"
---

There are many ways to see what Samvera Community repositories can do:

* Try out Avalon Media System on the [Avalon Demo site](https://www.avalonmediasystem.org/try-out-avalon)

* See Hyrax in action on the [Hyrax development site](https://dev.nurax.samvera.org/)
- Try out Avalon Media System on the [Avalon Demo site](https://www.avalonmediasystem.org/try-out-avalon)

* See the [Samvera Community Repository](https://repo.samvera.org/) for an example of a Hyku tenant

* Watch the [latest Samvera technology and repository demo videos on YouTube](https://youtube.com/playlist?list=PLvnoImgmm7Cf6K3ZdMiXDSwxhmfN6sQJq)

* Check out the repository examples below or [view the full list of known repositories using Samvera Community-supported technologies](https://samvera.atlassian.net/wiki/spaces/samvera/pages/422319621/Samvera+Implementations+in+production) on the Samvera wiki to learn more about the specific repository solutions they use and other implementation details.
- See Hyrax in action on the [Hyrax development site](https://dev.nurax.samvera.org/)

- See the [Samvera Community Repository](https://repo.samvera.org/) for an example of a Hyku tenant

* * *
- Watch the [latest Samvera technology and repository demo videos on YouTube](https://youtube.com/playlist?list=PLvnoImgmm7Cf6K3ZdMiXDSwxhmfN6sQJq)

- Check out the repository examples below or [view the full list of known repositories using Samvera Community-supported technologies](https://samvera.atlassian.net/wiki/spaces/samvera/pages/422319621/Samvera+Implementations+in+production) on the Samvera wiki to learn more about the specific repository solutions they use and other implementation details.

---

#### Examples of Samvera Community repository solutions in action

American Theological Library Association (ATLA) - [Atla Digital Library](https://dl.atla.com/) provides [Atla](https://www.atla.com/) members and other organizations with access to aggregated theological library collections from across the US.

[British Library Shared Research Repository](https://iro.bl.uk/) - Institutional repositories for UK cultural heritage organisations, currently all Independent Research Organisations (IROs). Content includes a variety of outputs including published works, datasets, 3D models and exhibition material. Six individual repositories with a unified search layer over the top.
[British Library Shared Research Repository](https://iro.bl.uk/) - Institutional repositories for UK cultural heritage organisations, currently all Independent Research Organisations (IROs). Content includes a variety of outputs including published works, datasets, 3D models and exhibition material. Six individual repositories with a unified search layer over the top.

[Carolina Digital Repository (CDR)](https://cdr.lib.unc.edu/) - Institutional Repository for OA articles, journals, student papers, research data, posters, 3d objects, OER and more.

Cincinnati University - [Scholar@UC](https://scholar.uc.edu/) - Self-submission institutional repository.
Cincinnati University - [Scholar@UC](https://scholar.uc.edu/) - Self-submission institutional repository.

Cornell University - [Southeast Asia Visions](http://seasiavisions.library.cornell.edu/) - A collection of more than 350 European travel accounts of pre-modern Southeast Asia.

Expand All @@ -52,7 +51,7 @@ Indiana University - [Pages Online](https://pages.dlib.indiana.edu/catalog) - Pa

[King's Fund Digital Archive](https://archive.kingsfund.org.uk/) - Digitized publications from the King's Fund from 1898 onwards.

[Linn-Benton Community College Community Archive](http://libarchive.linnbenton.edu/) - CommunityArchive@LBCC is a tool for showcasing and preserving important content created at Linn-Benton Community College. Our collection focuses on teaching and learning materials (particularly Open Educational Resources) and institutional history.
[Linn-Benton Community College Community Archive](http://libarchive.linnbenton.edu/) - CommunityArchive@LBCC is a tool for showcasing and preserving important content created at Linn-Benton Community College. Our collection focuses on teaching and learning materials (particularly Open Educational Resources) and institutional history.

[MAE, Theater Institute of Barcelona](http://colleccions.cdmae.cat/)

Expand All @@ -68,7 +67,7 @@ Oregon State University - [ScholarsArchive@OSU](https://ir.library.oregonstate.e

Oregon State University - [Oregon Digital](https://oregondigital.org/) - Collaborative digital collections system for unique digitized and born-digital materials including photographs, articles, sheet music, manuscripts, ephemera, and more.

Princeton University Library - [Figgy](https://figgy.princeton.edu/) - Staff tool for building digital objects, which are served using IIIF, and embedded in our user-facing applications. This is a secured site. [A screencast is available here](https://vimeo.com/334453271).
Princeton University Library - [Figgy](https://figgy.princeton.edu/) - Staff tool for building digital objects, which are served using IIIF, and embedded in our user-facing applications. This is a secured site. [A screencast is available here](https://vimeo.com/334453271).

[Tufts University Digital Library](http://dl.tufts.edu/)

Expand Down
Loading

0 comments on commit a7d3d8c

Please sign in to comment.