Adding podcast episodes (#27462)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
01985c11db
commit
f7eab14f6b
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: 'Nx Enterprise Podcast Episode 1: Hicham El Hammouchi'
|
||||||
|
slug: 'hicham-el-hammouchi-podcast-1'
|
||||||
|
authors: ['Zack DeRose']
|
||||||
|
tags: [podcast]
|
||||||
|
cover_image: /blog/images/2024-06-18/ep-1-hicham.png
|
||||||
|
podcastYoutubeId: 8iiLB_2djZ8
|
||||||
|
podcastSpotifyId: 24yagCNpu9EGj0fCwSDQkj
|
||||||
|
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/899a2e4c-2e56-4dfa-a3e3-e69eb216f2b0/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-1-hicham-el-hamouchi
|
||||||
|
podcastAppleUrl: https://podcasters.spotify.com/pod/show/enterprise-software/episodes/The-Enterprise-Software-Podcast-By-Nx-1--Hicham-El-Hamouchi-e2l0302
|
||||||
|
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-186891511/
|
||||||
|
---
|
||||||
|
|
||||||
|
In this episode, Zack DeRose from Nx chats with Hicham El Hammouchi, a veteran in enterprise software. Hicham dives into his background, sharing his career journey and the wealth of experience he's gathered along the way.
|
||||||
|
|
||||||
|
They tackle the tough challenges that companies face in software development. Hicham offers practical insights and real-life examples from his own career, making complex issues easier to understand. He also shares some tried-and-true strategies for overcoming these hurdles, emphasizing the importance of teamwork and effective project management.
|
||||||
|
|
||||||
|
As the chat continues, Zack and Hicham explore the latest tech trends and innovations that are shaking up the industry. Hicham's forward-thinking views provide a sneak peek into the future of enterprise software. They also discuss detailed case studies of successful projects, highlighting the importance of staying focused on customer needs and feedback.
|
||||||
18
docs/blog/2024-07-19-podcast-episode-2-tine-kondo.md
Normal file
18
docs/blog/2024-07-19-podcast-episode-2-tine-kondo.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: 'Nx Enterprise Podcast Episode 2: Tine Kondo'
|
||||||
|
slug: 'tine-kondo-podcast-2'
|
||||||
|
authors: ['Zack DeRose']
|
||||||
|
tags: [podcast]
|
||||||
|
cover_image: /blog/images/2024-07-19/ep-2-tine.png
|
||||||
|
podcastYoutubeId: Nzf3BmymfEo
|
||||||
|
podcastSpotifyId: 0CCQaWCln7rvwkkVvsyxsk
|
||||||
|
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/53934cd9-c521-441e-8523-8b947ed207ca/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-2-tine-kondo
|
||||||
|
podcastAppleUrl: https://podcasts.apple.com/us/podcast/the-enterprise-software-podcast-by-nx-2-tine-kondo/id1752704996?i=1000662764990
|
||||||
|
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-197335640/
|
||||||
|
---
|
||||||
|
|
||||||
|
In this episode, welcome Nx Champion and Nx Expert, Tine Kondo. Our discussion highlights how Nx is poised to make an impact in the Java space.
|
||||||
|
|
||||||
|
We touch on the difficulties larger organizations face when merging PRs in a timely manner, emphasizing how a monorepo alleviates the headache of coordinating multiple PRs across various repositories, and share firsthand experiences and frustrations with traditional multi-repo setups, underscoring the benefits of a unified approach.
|
||||||
|
|
||||||
|
In particular, Nx's new plugin: [@nx/gradle](/nx-api/gradle) is of interest, and Tine provides some valuable insight on the impact this plugin can make, as well as the importance for Maven support.
|
||||||
16
docs/blog/2024-08-14-podcast-episode-3-ahmed-elsakaan.md
Normal file
16
docs/blog/2024-08-14-podcast-episode-3-ahmed-elsakaan.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
title: 'Nx Enterprise Podcast Episode 3: Ahmed Elsakaan'
|
||||||
|
slug: 'ahmed-elsakaan-podcast-3'
|
||||||
|
authors: ['Zack DeRose']
|
||||||
|
tags: [podcast]
|
||||||
|
cover_image: /blog/images/2024-08-14/ep-3-ahmed.png
|
||||||
|
podcastYoutubeId: l_b6EOXqYRg
|
||||||
|
podcastSpotifyId: 4d4oE8B3y9BmECZ3P4uvDP
|
||||||
|
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/28209cf9-1b88-48b5-a798-7b24c843e9b1/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-3-ahmed-elsakaan
|
||||||
|
podcastAppleUrl: https://podcasts.apple.com/us/podcast/the-enterprise-software-podcast-by-nx-3-ahmed-elsakaan/id1752704996?i=1000665363260
|
||||||
|
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-205664230/
|
||||||
|
---
|
||||||
|
|
||||||
|
In this episode we welcome Nx Champion and creator of [noodle](https://noodle.run) and [OrbitKit](https://orbitkit.dev/): Ahmed Elsakaan.
|
||||||
|
|
||||||
|
As a monorepo enthusiast, we explore Ahmed's thoughts on monorepos and how these tools can add value to developers - both in the space of setting up your monorepo (like Nx does) and in the space of creating reusable customizable modules (like OrbitKit is attempting).
|
||||||
BIN
docs/blog/images/2024-06-18/ep-1-hicham.png
Normal file
BIN
docs/blog/images/2024-06-18/ep-1-hicham.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 159 KiB |
BIN
docs/blog/images/2024-07-19/ep-2-tine.png
Normal file
BIN
docs/blog/images/2024-07-19/ep-2-tine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
BIN
docs/blog/images/2024-08-14/ep-3-ahmed.png
Normal file
BIN
docs/blog/images/2024-08-14/ep-3-ahmed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 754 KiB |
@ -68,6 +68,11 @@ export class BlogApi {
|
|||||||
ogImageType: type,
|
ogImageType: type,
|
||||||
filePath,
|
filePath,
|
||||||
slug,
|
slug,
|
||||||
|
podcastYoutubeId: frontmatter.podcastYoutubeId,
|
||||||
|
podcastSpotifyId: frontmatter.podcastSpotifyId,
|
||||||
|
podcastIHeartUrl: frontmatter.podcastIHeartUrl,
|
||||||
|
podcastAppleUrl: frontmatter.podcastAppleUrl,
|
||||||
|
podcastAmazonUrl: frontmatter.podcastAmazonUrl,
|
||||||
};
|
};
|
||||||
const isDevelopment = process.env.NODE_ENV === 'development';
|
const isDevelopment = process.env.NODE_ENV === 'development';
|
||||||
const shouldIncludePost = !frontmatter.draft || isDevelopment;
|
const shouldIncludePost = !frontmatter.draft || isDevelopment;
|
||||||
|
|||||||
@ -11,8 +11,11 @@ export type BlogPostDataEntry = {
|
|||||||
pinned?: boolean;
|
pinned?: boolean;
|
||||||
filePath: string;
|
filePath: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
ogImage: string;
|
podcastYoutubeId?: string;
|
||||||
ogImageType: string;
|
podcastSpotifyId?: string;
|
||||||
|
podcastAmazonUrl?: string;
|
||||||
|
podcastAppleUrl?: string;
|
||||||
|
podcastIHeartUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BlogAuthor = {
|
export type BlogAuthor = {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import Image from 'next/image';
|
|||||||
import { BlogAuthors } from './authors';
|
import { BlogAuthors } from './authors';
|
||||||
import { ChevronLeftIcon } from '@heroicons/react/24/outline';
|
import { ChevronLeftIcon } from '@heroicons/react/24/outline';
|
||||||
import { renderMarkdown } from '@nx/nx-dev/ui-markdoc';
|
import { renderMarkdown } from '@nx/nx-dev/ui-markdoc';
|
||||||
|
import { EpisodePlayer } from './episode-player';
|
||||||
|
|
||||||
export interface BlogDetailsProps {
|
export interface BlogDetailsProps {
|
||||||
post: BlogPostDataEntry;
|
post: BlogPostDataEntry;
|
||||||
@ -65,7 +66,18 @@ export function BlogDetails({ post }: BlogDetailsProps) {
|
|||||||
{post.title}
|
{post.title}
|
||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
{post.cover_image && (
|
{post.podcastYoutubeId && post.podcastSpotifyId ? (
|
||||||
|
<div className="mx-auto mb-16 w-full max-w-screen-md">
|
||||||
|
<EpisodePlayer
|
||||||
|
podcastYoutubeId={post.podcastYoutubeId}
|
||||||
|
podcastSpotifyId={post.podcastSpotifyId}
|
||||||
|
amazonUrl={post.podcastAmazonUrl}
|
||||||
|
appleUrl={post.podcastAppleUrl}
|
||||||
|
iHeartUrl={post.podcastIHeartUrl}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
post.cover_image && (
|
||||||
<div className="mx-auto mb-16 aspect-[1.7] w-full max-w-screen-md">
|
<div className="mx-auto mb-16 aspect-[1.7] w-full max-w-screen-md">
|
||||||
<Image
|
<Image
|
||||||
className="h-full w-full object-cover md:rounded-md"
|
className="h-full w-full object-cover md:rounded-md"
|
||||||
@ -75,6 +87,7 @@ export function BlogDetails({ post }: BlogDetailsProps) {
|
|||||||
height={735}
|
height={735}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
<div className="mx-auto min-w-0 max-w-3xl flex-auto px-4 pb-24 lg:px-0 lg:pb-16">
|
<div className="mx-auto min-w-0 max-w-3xl flex-auto px-4 pb-24 lg:px-0 lg:pb-16">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
|||||||
149
nx-dev/ui-blog/src/lib/episode-player.tsx
Normal file
149
nx-dev/ui-blog/src/lib/episode-player.tsx
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
import {
|
||||||
|
AmazonMusicIcon,
|
||||||
|
ApplePodcastsIcon,
|
||||||
|
IHeartRadioIcon,
|
||||||
|
SpotifyIcon,
|
||||||
|
} from '@nx/nx-dev/ui-icons';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
export function EpisodePlayer({
|
||||||
|
podcastYoutubeId,
|
||||||
|
podcastSpotifyId,
|
||||||
|
amazonUrl,
|
||||||
|
appleUrl,
|
||||||
|
iHeartUrl,
|
||||||
|
}: {
|
||||||
|
podcastYoutubeId: string;
|
||||||
|
podcastSpotifyId: string;
|
||||||
|
amazonUrl?: string;
|
||||||
|
appleUrl?: string;
|
||||||
|
iHeartUrl?: string;
|
||||||
|
}) {
|
||||||
|
const [viewType, setViewType] = useState<ViewMode>('audio');
|
||||||
|
return (
|
||||||
|
<div className="flex basis-2/3 flex-col items-center justify-center gap-2">
|
||||||
|
{viewType === 'audio' ? (
|
||||||
|
<>
|
||||||
|
<iframe
|
||||||
|
style={{ borderRadius: '12px' }}
|
||||||
|
src={`https://open.spotify.com/embed/episode/${podcastSpotifyId}?utm_source=generator&theme=0`}
|
||||||
|
width="100%"
|
||||||
|
height="152"
|
||||||
|
frameBorder="0"
|
||||||
|
allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
|
||||||
|
loading="lazy"
|
||||||
|
key="audio"
|
||||||
|
></iframe>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<iframe
|
||||||
|
style={{ borderRadius: '12px' }}
|
||||||
|
width="100%"
|
||||||
|
height="400"
|
||||||
|
src={`https://www.youtube.com/embed/${podcastYoutubeId}?si=8rkgAzJfLfd-hxAA`}
|
||||||
|
title="YouTube video player"
|
||||||
|
frameBorder="0"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
referrerPolicy="strict-origin-when-cross-origin"
|
||||||
|
allowFullScreen
|
||||||
|
key="video"
|
||||||
|
></iframe>
|
||||||
|
)}
|
||||||
|
<div className="container my-1 flex">
|
||||||
|
<div className="basis-1/2">
|
||||||
|
{viewType === 'audio' && (
|
||||||
|
<PlatformLinks
|
||||||
|
amazonUrl={amazonUrl}
|
||||||
|
appleUrl={appleUrl}
|
||||||
|
iHeartUrl={iHeartUrl}
|
||||||
|
podcastSpotifyId={podcastSpotifyId}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex basis-1/2 flex-wrap justify-end gap-6 sm:gap-4">
|
||||||
|
<button
|
||||||
|
className="flex shrink-0 items-center gap-2 text-slate-400 hover:text-slate-800 dark:text-slate-600 dark:hover:text-slate-200"
|
||||||
|
onClick={() => setViewType(getOpposite(viewType))}
|
||||||
|
>
|
||||||
|
Switch to {getOpposite(viewType) === 'audio' ? 'Audio' : 'Video'}
|
||||||
|
</button>
|
||||||
|
<Link
|
||||||
|
className="flex shrink-0 items-center gap-2 text-slate-400 hover:text-slate-800 dark:text-slate-600 dark:hover:text-slate-200"
|
||||||
|
href="/podcast"
|
||||||
|
>
|
||||||
|
More Podcasts
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PlatformLinks({
|
||||||
|
amazonUrl,
|
||||||
|
appleUrl,
|
||||||
|
iHeartUrl,
|
||||||
|
podcastSpotifyId,
|
||||||
|
}: {
|
||||||
|
amazonUrl?: string;
|
||||||
|
appleUrl?: string;
|
||||||
|
iHeartUrl?: string;
|
||||||
|
podcastSpotifyId: string;
|
||||||
|
}): JSX.Element {
|
||||||
|
const platforms = [
|
||||||
|
{
|
||||||
|
name: 'Amazon Music',
|
||||||
|
url: amazonUrl,
|
||||||
|
icon: AmazonMusicIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Apple Podcasts',
|
||||||
|
url: appleUrl,
|
||||||
|
icon: ApplePodcastsIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'iHeartRadio',
|
||||||
|
url: iHeartUrl,
|
||||||
|
icon: IHeartRadioIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Spotify',
|
||||||
|
url: `https://open.spotify.com/episode/${podcastSpotifyId}?si=Nqd7F40hQXugagH8oDxxpA`,
|
||||||
|
icon: SpotifyIcon,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className="flex flex-wrap gap-6 sm:gap-4">
|
||||||
|
{platforms
|
||||||
|
.filter((platform) => !!platform.url)
|
||||||
|
.map((platform) => {
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
key={platform.name}
|
||||||
|
className="inline-block cursor-pointer place-items-center rounded-2xl border border-slate-100 bg-white p-4 text-slate-600 transition-all hover:scale-[1.02] hover:text-slate-950 dark:border-slate-800/60 dark:bg-slate-950 dark:text-slate-400 dark:hover:text-white"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href={platform.url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="flex h-full w-full items-center justify-center"
|
||||||
|
>
|
||||||
|
<platform.icon className="h-6 w-6 shrink-0" />
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type ViewMode = 'audio' | 'video';
|
||||||
|
|
||||||
|
function getOpposite(viewMode: ViewMode): ViewMode {
|
||||||
|
if (viewMode === 'audio') return 'video';
|
||||||
|
return 'audio';
|
||||||
|
}
|
||||||
@ -20,7 +20,7 @@ export function PodcastListItem({ podcast, episode }: PodcastListItemProps) {
|
|||||||
prefetch={false}
|
prefetch={false}
|
||||||
>
|
>
|
||||||
<span className="w-1/2 flex-none text-balance text-slate-500 sm:w-8/12 dark:text-white">
|
<span className="w-1/2 flex-none text-balance text-slate-500 sm:w-8/12 dark:text-white">
|
||||||
Episode {episode}: {podcast.title}
|
{podcast.title}
|
||||||
</span>
|
</span>
|
||||||
<span className="hidden w-2/12 flex-none sm:inline-block">
|
<span className="hidden w-2/12 flex-none sm:inline-block">
|
||||||
<time dateTime={podcast.date}>{formattedDate}</time>
|
<time dateTime={podcast.date}>{formattedDate}</time>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user