Skip to content

Commit

Permalink
Add related videos
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvarner committed Jun 17, 2024
1 parent 3fa16e8 commit 4d4121b
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 7 deletions.
20 changes: 20 additions & 0 deletions app/components/FeaturedMedium.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import VideoEmbed from "./VideoEmbed";
import type { TRelatedCoreDataRecords } from "~/types";

interface Props {
record: TRelatedCoreDataRecords;
}

const FeaturedMedium = ({ record }: Props) => {
if (record.items?.videos) {
return <VideoEmbed video={record.items.videos[0]} />;
}
if (record.media_contents?.photographs) {
return (
<img src={record.media_contents.photographs[0].content_url} alt="" />
);
}
return <></>;
};

export default FeaturedMedium;
28 changes: 28 additions & 0 deletions app/components/RelatedVideos.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { TVideoItem } from "~/types";
import RelatedSection from "./RelatedSection";
import VideoThumbnail from "./VideoThumbnail";

interface Props {
videos: TVideoItem[];
}

const RelatedVideos = ({ videos }: Props) => {
return (
<RelatedSection title="Videos">
<div className="flex flex-wrap justify-around">
{videos.map((video) => {
return (
<VideoThumbnail
key={video.uuid}
video={video}
figClassName="md:m-8 max-w-xs"
imgClassName="drop-shadow-md border rounded-lg"
/>
);
})}
</div>
</RelatedSection>
);
};

export default RelatedVideos;
37 changes: 37 additions & 0 deletions app/components/VideoEmbed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useMemo, useState } from "react";
import type { TVideoItem } from "../types";

interface Props {
video: TVideoItem;
}

const VideoEmbed = ({ video }: Props) => {
const [embedSrc, setEmbedSrc] = useState<string | undefined>(undefined);

useMemo(() => {
console.log("🚀 ~ useMemo ~ video.provider:", video.provider);
switch (video.provider) {
case "Vimeo":
setEmbedSrc(`https://player.vimeo.com/video/${video.embed_id}`);
break;
case "YouTube":
setEmbedSrc(`https://www.youtube.com/embed/${video.embed_id}`);
default:
break;
}
return;
}, [video]);

return (
<div className="relative pb-[56.25%] h-0 overflow-hidden max-w-full">
<iframe
className="absolute t-0 l-0 h-full w-full"
src={embedSrc}
title={video.source_titles.find((t) => t.primary)?.name.name}
allowFullScreen
/>
</div>
);
};

export default VideoEmbed;
50 changes: 50 additions & 0 deletions app/components/VideoThumbnail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useMemo, useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlayCircle } from "@fortawesome/free-solid-svg-icons";
import type { TVideoItem } from "../types";

interface Props {
video: TVideoItem;
imgClassName?: string;
figClassName?: string;
}

const VideoThumbnail = ({ video, imgClassName, figClassName }: Props) => {
const [thumbnailSrc, setThumbnailSrc] = useState<string | undefined>(
undefined,
);

useMemo(() => {
switch (video.provider) {
case "Vimeo":
setThumbnailSrc(`https://vumbnail.com/${video.embed_id}.jpg`);
break;
case "YouTube":
setThumbnailSrc(
`https://img.youtube.com/vi/${video.embed_id}/hqdefault.jpg`,
);
default:
break;
}
return;
}, [video]);

return (
<figure className={`${figClassName ?? ""}`}>
<div className="relative">
<span className="text-white absolute w-full z-10 text-8xl h-full flex items-center justify-center">
<FontAwesomeIcon
icon={faPlayCircle}
className="drop-shadow-2xl opacity-80"
/>
</span>
<img className={`${imgClassName ?? ""}`} src={thumbnailSrc} alt="" />
</div>
<figcaption>
{video.source_titles.find((t) => t.primary)?.name.name}
</figcaption>
</figure>
);
};

export default VideoThumbnail;
18 changes: 11 additions & 7 deletions app/components/layout/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NavLink, useNavigate } from "@remix-run/react";
import gcaLogo from 'app/images/gca-logo.png';
import gcaLogo from "app/images/gca-logo.png";
import { islands } from "~/config.ts";
import { useState } from "react";
import islandsButtonImage from 'app/images/islandsButton.png';
import islandsButtonImage from "app/images/islandsButton.png";

const Navbar = () => {
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
Expand Down Expand Up @@ -37,24 +37,28 @@ const Navbar = () => {
className="flex justify-center"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter') {
if (e.key === "Enter") {
toggleDropdown();
}
}}
>
<img src={islandsButtonImage} alt="Islands Button" />
</button>
{isDropdownOpen && (
<div className="absolute right-1 transform translate-x-1/3 top-full mt-2 bg-white rounded-md shadow-lg">
<div className="absolute right-1 transform translate-x-1/3 top-full mt-2 bg-white rounded-md shadow-lg w-64">
<ul className="font-serif text-lg text-center">
{islands.map((island) => (
<li key={island.slug}>
<button
className="px-6 py-3 hover:bg-gray-200 w-full text-left"
onClick={() => navigate(`/${island.slug}-island`)}
onClick={() => {
navigate(`/${island.slug}-island`);
setIsDropdownOpen(false);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
if (e.key === "Enter") {
navigate(`/${island.slug}-island`);
setIsDropdownOpen(false);
}
}}
>
Expand All @@ -70,4 +74,4 @@ const Navbar = () => {
);
};

export default Navbar;
export default Navbar;

0 comments on commit 4d4121b

Please sign in to comment.