Added videos page and all
This commit is contained in:
parent
762df56aea
commit
1db24083cb
|
@ -22,7 +22,7 @@ export default function PostPreview(props: Props): JSX.Element {
|
|||
const { video } = props;
|
||||
|
||||
return (
|
||||
<Link href={`/archives/videos/${video.uid}`} passHref>
|
||||
<Link href={`/archives/videos/v/${video.uid}`} passHref>
|
||||
<div className="drop-shadow-shade-xl cursor-pointer grid items-end hover:scale-[1.02] [--bg-opacity:0] hover:[--bg-opacity:0.5] [--play-opacity:0] hover:[--play-opacity:100] transition-transform">
|
||||
<div className="relative">
|
||||
<img
|
||||
|
|
|
@ -6,6 +6,7 @@ query getVideo($uid: String) {
|
|||
uid
|
||||
title
|
||||
description
|
||||
gone
|
||||
published_date {
|
||||
year
|
||||
month
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
query getVideoChannel($channel: String) {
|
||||
videoChannels(filters: { uid: { eq: $channel } } ) {
|
||||
data {
|
||||
attributes {
|
||||
uid
|
||||
title
|
||||
subscribers
|
||||
videos (pagination:{limit: -1}) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
uid
|
||||
title
|
||||
views
|
||||
duration
|
||||
gone
|
||||
categories {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
}
|
||||
}
|
||||
}
|
||||
published_date {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
query getVideoChannelsSlugs {
|
||||
videoChannels(pagination: {limit: -1}) {
|
||||
data {
|
||||
attributes {
|
||||
uid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ query getVideosPreview {
|
|||
title
|
||||
views
|
||||
duration
|
||||
gone
|
||||
categories {
|
||||
data {
|
||||
id
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
import AppLayout from "components/AppLayout";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import ReturnButton, {
|
||||
ReturnButtonType,
|
||||
} from "components/PanelComponents/ReturnButton";
|
||||
import ContentPanel, {
|
||||
ContentPanelWidthSizes,
|
||||
} from "components/Panels/ContentPanel";
|
||||
import SubPanel from "components/Panels/SubPanel";
|
||||
import VideoPreview from "components/Videos/VideoPreview";
|
||||
import { GetVideoChannelQuery } from "graphql/generated";
|
||||
import { getReadySdk } from "graphql/sdk";
|
||||
import {
|
||||
GetStaticPathsContext,
|
||||
GetStaticPathsResult,
|
||||
GetStaticPropsContext,
|
||||
} from "next";
|
||||
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
||||
|
||||
interface Props extends AppStaticProps {
|
||||
channel: Exclude<
|
||||
GetVideoChannelQuery["videoChannels"],
|
||||
null | undefined
|
||||
>["data"][number]["attributes"];
|
||||
}
|
||||
|
||||
export default function Channel(props: Props): JSX.Element {
|
||||
const { langui, channel } = props;
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<ReturnButton
|
||||
href="/archives/videos/"
|
||||
title={"Videos"}
|
||||
langui={langui}
|
||||
displayOn={ReturnButtonType.desktop}
|
||||
className="mb-10"
|
||||
/>
|
||||
|
||||
<PanelHeader
|
||||
icon="movie"
|
||||
title="Videos"
|
||||
description={langui.archives_description}
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
|
||||
const contentPanel = (
|
||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||
<div className="mb-8">
|
||||
<h1 className="text-3xl">{channel?.title}</h1>
|
||||
<p>{channel?.subscribers.toLocaleString()} subscribers</p>
|
||||
</div>
|
||||
<div className="grid gap-8 items-start mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0">
|
||||
{channel?.videos?.data.map((video) => (
|
||||
<>{video.attributes && <VideoPreview video={video.attributes} />}</>
|
||||
))}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
);
|
||||
return (
|
||||
<AppLayout
|
||||
navTitle={langui.archives}
|
||||
subPanel={subPanel}
|
||||
contentPanel={contentPanel}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export async function getStaticProps(
|
||||
context: GetStaticPropsContext
|
||||
): Promise<{ notFound: boolean } | { props: Props }> {
|
||||
const sdk = getReadySdk();
|
||||
const channel = await sdk.getVideoChannel({
|
||||
channel: context.params?.uid?.toString() ?? "",
|
||||
});
|
||||
if (!channel.videoChannels?.data[0].attributes) return { notFound: true };
|
||||
const props: Props = {
|
||||
...(await getAppStaticProps(context)),
|
||||
channel: channel.videoChannels?.data[0].attributes,
|
||||
};
|
||||
return {
|
||||
props: props,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getStaticPaths(
|
||||
context: GetStaticPathsContext
|
||||
): Promise<GetStaticPathsResult> {
|
||||
const sdk = getReadySdk();
|
||||
const channels = await sdk.getVideoChannelsSlugs();
|
||||
const paths: GetStaticPathsResult["paths"] = [];
|
||||
if (channels.videoChannels?.data)
|
||||
channels.videoChannels.data.map((channel) => {
|
||||
context.locales?.map((local) => {
|
||||
if (channel.attributes)
|
||||
paths.push({
|
||||
params: { uid: channel.attributes.uid },
|
||||
locale: local,
|
||||
});
|
||||
});
|
||||
});
|
||||
return {
|
||||
paths,
|
||||
fallback: "blocking",
|
||||
};
|
||||
}
|
|
@ -39,7 +39,7 @@ export default function Videos(props: Props): JSX.Element {
|
|||
|
||||
const contentPanel = (
|
||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||
<div className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0">
|
||||
<div className="grid gap-8 items-start mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0">
|
||||
{videos.map((video) => (
|
||||
<>{video.attributes && <VideoPreview video={video.attributes} />}</>
|
||||
))}
|
||||
|
|
|
@ -86,11 +86,23 @@ export default function Video(props: Props): JSX.Element {
|
|||
id="video"
|
||||
className="w-full rounded-xl shadow-shade shadow-lg overflow-hidden"
|
||||
>
|
||||
<video
|
||||
className="w-full"
|
||||
src={getVideoFile(video.uid)}
|
||||
controls
|
||||
></video>
|
||||
{video.gone ? (
|
||||
<video
|
||||
className="w-full"
|
||||
src={getVideoFile(video.uid)}
|
||||
controls
|
||||
></video>
|
||||
) : (
|
||||
<iframe
|
||||
src={`https://www.youtube-nocookie.com/embed/${video.uid}`}
|
||||
className="w-full aspect-video"
|
||||
title="YouTube video player"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
)}
|
||||
|
||||
<div className="p-6 mt-2">
|
||||
<h1 className="text-2xl">{video.title}</h1>
|
||||
<div className="flex flex-row flex-wrap gap-x-6 w-full">
|
||||
|
@ -118,10 +130,13 @@ export default function Video(props: Props): JSX.Element {
|
|||
: video.likes.toLocaleString()}
|
||||
</p>
|
||||
)}
|
||||
<Button
|
||||
href=""
|
||||
className="!py-0 !px-3"
|
||||
>{`View on ${video.source}`}</Button>
|
||||
<a
|
||||
href={`https://youtu.be/${video.uid}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button className="!py-0 !px-3">{`View on ${video.source}`}</Button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -131,7 +146,7 @@ export default function Video(props: Props): JSX.Element {
|
|||
<div className="w-[clamp(0px,100%,42rem)] grid place-items-center gap-4 text-center">
|
||||
<h2 className="text-2xl">{"Channel"}</h2>
|
||||
<div>
|
||||
<Button href="#">
|
||||
<Button href={`/archives/videos/c/${video.channel.data.attributes.uid}`}>
|
||||
<h3>{video.channel.data.attributes.title}</h3>
|
||||
</Button>
|
||||
|
||||
|
@ -184,7 +199,7 @@ export async function getStaticPaths(
|
|||
context: GetStaticPathsContext
|
||||
): Promise<GetStaticPathsResult> {
|
||||
const sdk = getReadySdk();
|
||||
const videos = await sdk.getVideo();
|
||||
const videos = await sdk.getVideosSlugs();
|
||||
const paths: GetStaticPathsResult["paths"] = [];
|
||||
if (videos.videos?.data)
|
||||
videos.videos.data.map((video) => {
|
Loading…
Reference in New Issue