Skip to content

Commit

Permalink
Create featured app homepage banner slider
Browse files Browse the repository at this point in the history
  • Loading branch information
adamjarling committed Apr 9, 2024
1 parent 482ed0c commit ba0f6de
Show file tree
Hide file tree
Showing 25 changed files with 579 additions and 36 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn-error.log*

/assets/featured-repo-banners/
Binary file added assets/featured-app-banners.psd
Binary file not shown.
6 changes: 4 additions & 2 deletions components/BannerContact.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import FadeIn from "components/FadeIn";
import React from "react";
import { prefix } from "prefix";
import { useRouter } from "next/router";
Expand All @@ -6,8 +7,9 @@ export default function BannerContact() {
const router = useRouter();

return (
<section
<FadeIn
className="bg-samGrey flex flex-col justify-center items-center text-white p-10 pb-16 bg-fixed md:bg-[center_right] bg-center"
component="section"
style={{
backgroundImage: `url(${prefix}/images/hydra-transparency.png)`,
}}
Expand All @@ -21,6 +23,6 @@ export default function BannerContact() {
>
Contact Us
</button>
</section>
</FadeIn>
);
}
6 changes: 3 additions & 3 deletions components/BannerPartners.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import FadeIn from "components/FadeIn";
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";

Expand All @@ -12,7 +12,7 @@ export default function BannerPartners() {

return (
<>
<section className="py-8 bg-samBlue">
<FadeIn component="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 ">
Expand All @@ -33,7 +33,7 @@ export default function BannerPartners() {
))}
</ul>
</div>
</section>
</FadeIn>

{isHomePage && <PartnersMap partners={partners} />}
</>
Expand Down
15 changes: 15 additions & 0 deletions components/FadeIn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { motion } from "framer-motion";

export default function FadeIn({ children, component = "div", ...restProps }) {
const MotionEl = motion(component);
return (
<MotionEl
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ duration: 1.5 }}
{...restProps}
>
{children}
</MotionEl>
);
}
121 changes: 121 additions & 0 deletions components/home/AppBanner.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { LogoCloverIIIF, LogoServerlessIIIF } from "components/home/SVGLogos";

import { ChevronRightIcon } from "@heroicons/react/20/solid";
import Image from "next/image";

function LogoWrapper({ children }) {
return <div className="flex items-center justify-start h-16">{children}</div>;
}

export default function AppBanner({ banner }) {
const {
bannerImage,
description,
githubUrl,
headline,
logo,
name,
url,
version,
} = banner;

const isSvgLogo = ["Clover IIIF", "Serverless IIIF"].includes(name);

return (
<div className="bg-white">
<div className="relative overflow-hidden isolate bg-gradient-to-b from-samBlue-100/20">
<div className="pt-10 pb-24 mx-auto max-w-7xl sm:pb-32 lg:grid lg:grid-cols-2 lg:gap-x-8 lg:px-8 lg:py-10">
<div className="px-6 lg:px-0 lg:pt-4">
<div className="max-w-2xl mx-auto">
<div className="max-w-lg">
{/* Logo */}
{isSvgLogo ? (
<LogoWrapper>
{name === "Clover IIIF" ? (
<LogoCloverIIIF />
) : (
<LogoServerlessIIIF />
)}
</LogoWrapper>
) : (
<Image
className={`w-auto h-16`}
src={logo}
alt={`${name} logo`}
/>
)}

<div className="mt-12 sm:mt-16 lg:mt-12">
<a
href={githubUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex space-x-6"
>
<span className="px-3 py-1 text-sm font-semibold leading-6 rounded-full text-samGrey bg-samGrey/10 ring-1 ring-inset ring-samGrey/10">
Whats new
</span>
<span className="inline-flex items-center space-x-2 text-sm font-medium leading-6 text-gray-600">
<span>Just shipped {version}</span>
<ChevronRightIcon
className="w-5 h-5 text-gray-400"
aria-hidden="true"
/>
</span>
</a>
</div>
<h1 className="mt-8 text-3xl font-bold tracking-tight text-samGreyDark sm:text-5xl swiper-no-swiping">
{headline}
</h1>
<p className="mt-6 text-lg leading-8 text-samGrey swiper-no-swiping">
{description}
</p>
<div className="flex items-center mt-8 gap-x-6">
<a href={url} className="button">
Documentation
</a>
<a
href={githubUrl}
className="text-sm font-semibold leading-6 text-gray-900"
>
View on GitHub <span aria-hidden="true"></span>
</a>
</div>
</div>
</div>
</div>
<div className="mt-20 sm:mt-24 md:mx-auto md:max-w-2xl lg:mx-0 lg:mt-0 lg:w-screen">
<div
className="absolute inset-y-0 right-1/2 -z-10 -mr-10 w-[200%] skew-x-[-30deg] bg-white shadow-xl shadow-indigo-600/10 ring-1 ring-indigo-50 md:-mr-20 lg:-mr-36"
aria-hidden="true"
/>
<div className="shadow-lg md:rounded-3xl">
<div className="bg-samBlue [clip-path:inset(0)] md:[clip-path:inset(0_round_theme(borderRadius.3xl))]">
<div
className="absolute -inset-y-px left-1/2 -z-10 ml-10 w-[200%] skew-x-[-30deg] bg-indigo-100 opacity-20 ring-1 ring-inset ring-white md:ml-20 lg:ml-36"
aria-hidden="true"
/>
<div className="relative px-6 pt-8 sm:pt-16 md:pl-16 md:pr-0">
<div className="max-w-2xl mx-auto md:mx-0 md:max-w-none">
<div className="w-screen overflow-hidden rounded-tl-xl">
<Image
src={bannerImage}
alt={`${name} application screenshot`}
height={500}
/>
</div>
</div>
<div
className="absolute inset-0 pointer-events-none ring-1 ring-inset ring-black/10 md:rounded-3xl"
aria-hidden="true"
/>
</div>
</div>
</div>
</div>
</div>
<div className="absolute inset-x-0 bottom-0 h-24 -z-10 bg-gradient-to-t from-white sm:h-32" />
</div>
</div>
);
}
19 changes: 6 additions & 13 deletions components/home/ApplicationTypes.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { AtIcon } from "pages/types-of-applications";
import FadeIn from "components/FadeIn";
import Link from "next/link";
import RichTextContent from "components/RichTextContent";
import { motion } from "framer-motion";

export default function ApplicationTypes({ applicationTypes = [] }) {
return (
<div className="py-24 bg-samGreyDark sm:py-32">
<div className="px-6 mx-auto max-w-7xl lg:px-8">
<div className="max-w-2xl mx-auto lg:text-center">
<FadeIn className="max-w-2xl mx-auto lg:text-center">
<h2
id="applications"
className="text-base font-semibold leading-7 text-samBlue"
Expand All @@ -17,29 +19,20 @@ export default function ApplicationTypes({ applicationTypes = [] }) {
Types of Applications powered by Samvera Community technology
solutions
</p>
{/* <p className="mt-6 text-lg leading-8 text-gray-300">
Quis tellus eget adipiscing convallis sit sit eget aliquet quis.
Suspendisse eget egestas a elementum pulvinar et feugiat blandit at.
In mi viverra elit nunc.
</p> */}
</div>
</FadeIn>
<div className="max-w-2xl mx-auto mt-16 sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{applicationTypes.map((at) => {
const { title, description } = at.fields;

return (
<div key={at.sys.id} className="flex flex-col">
<FadeIn key={at.sys.id} className="flex flex-col">
<dt className="flex items-center text-base font-semibold leading-7 text-white gap-x-3">
<AtIcon
atId={at.sys.id}
className="flex-none w-5 h-5 text-samBlue"
aria-hidden="true"
/>
{/* <CheckCircleIcon
className="flex-none w-5 h-5 text-samBlue"
aria-hidden="true"
/> */}
{title}
</dt>
<dd className="flex flex-col flex-auto mt-4 text-base leading-7 text-gray-300">
Expand All @@ -55,7 +48,7 @@ export default function ApplicationTypes({ applicationTypes = [] }) {
</Link>
</p>
</dd>
</div>
</FadeIn>
);
})}
</dl>
Expand Down
5 changes: 3 additions & 2 deletions components/home/BenefitHow.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import FadeIn from "components/FadeIn";
import React from "react";

export default function BenefitHow() {
return (
<section className="bg-none md:bg-benefit-how">
<FadeIn component="section" className="bg-none md:bg-benefit-how">
<div className="container max-w-full px-0 md:px-4">
<div className="grid grid-cols-1 gap-12 md:grid-cols-2">
<div className="p-10">
Expand Down Expand Up @@ -65,6 +66,6 @@ export default function BenefitHow() {
</div>
</div>
</div>
</section>
</FadeIn>
);
}
7 changes: 4 additions & 3 deletions components/home/Community.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import FadeIn from "components/FadeIn";
import Link from "next/link";

export default function Community() {
return (
<div className="bg-white">
<FadeIn className="bg-white">
<div className="px-6 py-24 sm:px-6 sm:py-32 lg:px-8">
<div className="max-w-3xl mx-auto text-center">
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl">
The Samvera Community
</h2>
<div className="mt-6 text-lg leading-8 text-gray-600">
<div className="mt-6 leading-8 text-gray-600 lg:text-lg">
<p>
Samvera is not (and has never been) grant funded. It is
distributed, robust and open. The Samvera Community&nbsp;was
Expand Down Expand Up @@ -36,6 +37,6 @@ export default function Community() {
</div>
</div>
</div>
</div>
</FadeIn>
);
}
95 changes: 95 additions & 0 deletions components/home/FeaturedAppsSlider.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useEffect, useRef } from "react";

import AppBanner from "./AppBanner";
import { registerSwiper } from "lib/swiper";
import useFeaturedApps from "hooks/use-featured-apps";

registerSwiper();

const FeaturedAppsSlider = () => {
const swiperRef = useRef(null);
const featuredApps = useFeaturedApps();

useEffect(() => {
// Set up the Swiper instance
const refCurrent = swiperRef.current;
const params = {
autoplay: {
delay: 6000,
},
injectStyles: [
`
@media (max-width: 640px) {
.swiper-button-next svg,
.swiper-button-prev svg {
display: none;
}
}
.swiper-button-next svg,
.swiper-button-prev svg {
color: #383d3b
}
.swiper-pagination-bullet-active {
background-color: #383d3b;
}
swiper-slide {
user-select: auto !important;
-webkit-user-select: auto !important;
-moz-user-select: auto !important;
-ms-user-select: auto !important;
}
`,
],
};

Object.assign(refCurrent, params);
refCurrent.initialize();
refCurrent.addEventListener("click", handleSlideClick);

// Clean up, avoid memory leaks
return () => {
refCurrent.removeEventListener("click", handleSlideClick);
};
}, []);

function handleSlideClick(pointerEvent) {
const clickedOnSelectableText =
pointerEvent.target.className.includes("swiper-no-swiping");

if (clickedOnSelectableText) return;

const swiper = swiperRef.current.swiper;
const clickedOnLeftHalf = pointerEvent.x < swiper.width / 2;

if (clickedOnLeftHalf) {
swiper.slidePrev();
} else {
swiper.slideNext();
}
}

return (
<section className="mb-5 min-h-[80vh]">
<swiper-container
init="false"
ref={swiperRef}
loop="true"
pagination="true"
slides-per-view="1"
speed="1500"
>
{featuredApps.length > 0 &&
featuredApps.map((slide) => (
<swiper-slide key={slide.name}>
<AppBanner banner={slide} />
</swiper-slide>
))}
</swiper-container>
</section>
);
};

export default FeaturedAppsSlider;
Loading

0 comments on commit ba0f6de

Please sign in to comment.