Added previous/next content recommendation
This commit is contained in:
parent
2fe1ffb273
commit
1c2653ad07
|
@ -0,0 +1,68 @@
|
|||
import { UploadImageFragment } from "graphql/generated";
|
||||
import Link from "next/link";
|
||||
import Chip from "./Chip";
|
||||
import Img, { ImageQuality } from "./Img";
|
||||
|
||||
interface Props {
|
||||
thumbnail?: UploadImageFragment | string | null | undefined;
|
||||
thumbnailAspectRatio?: string;
|
||||
href: string;
|
||||
pre_title?: string | null | undefined;
|
||||
title: string | null | undefined;
|
||||
subtitle?: string | null | undefined;
|
||||
topChips?: string[];
|
||||
bottomChips?: string[];
|
||||
}
|
||||
|
||||
export default function PreviewLine(props: Props): JSX.Element {
|
||||
const {
|
||||
href,
|
||||
thumbnail,
|
||||
pre_title,
|
||||
title,
|
||||
subtitle,
|
||||
topChips,
|
||||
bottomChips,
|
||||
thumbnailAspectRatio,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Link href={href} passHref>
|
||||
<div
|
||||
className="drop-shadow-shade-xl rounded-md bg-light cursor-pointer hover:scale-[1.02]
|
||||
transition-transform flex flex-row gap-4 overflow-hidden place-items-center pr-4 w-full h-36"
|
||||
>
|
||||
{thumbnail ? (
|
||||
<div className="h-full aspect-[3/2]">
|
||||
<Img image={thumbnail} quality={ImageQuality.Medium} />
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ aspectRatio: thumbnailAspectRatio }}></div>
|
||||
)}
|
||||
<div className="grid gap-2">
|
||||
{topChips && topChips.length > 0 && (
|
||||
<div className="grid grid-flow-col gap-1 overflow-hidden place-content-start">
|
||||
{topChips.map((text, index) => (
|
||||
<Chip key={index}>{text}</Chip>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col">
|
||||
{pre_title && <p>{pre_title}</p>}
|
||||
{title && <h1 className="text-lg">{title}</h1>}
|
||||
{subtitle && <h2>{subtitle}</h2>}
|
||||
</div>
|
||||
{bottomChips && bottomChips.length > 0 && (
|
||||
<div className="grid grid-flow-col gap-1 overflow-hidden place-content-start">
|
||||
{bottomChips.map((text, index) => (
|
||||
<Chip key={index} className="text-sm">
|
||||
{text}
|
||||
</Chip>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
|
@ -106,6 +106,84 @@ query getContentText($slug: String, $language_code: String) {
|
|||
}
|
||||
}
|
||||
}
|
||||
previous_recommended {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
pre_title
|
||||
title
|
||||
subtitle
|
||||
}
|
||||
categories {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
}
|
||||
}
|
||||
}
|
||||
type {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
thumbnail {
|
||||
data {
|
||||
attributes {
|
||||
...uploadImage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
next_recommended {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||
pre_title
|
||||
title
|
||||
subtitle
|
||||
}
|
||||
categories {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
short
|
||||
}
|
||||
}
|
||||
}
|
||||
type {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
thumbnail {
|
||||
data {
|
||||
attributes {
|
||||
...uploadImage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,14 @@ import ReturnButton, {
|
|||
} from "components/PanelComponents/ReturnButton";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import SubPanel from "components/Panels/SubPanel";
|
||||
import PreviewLine from "components/PreviewLine";
|
||||
import RecorderChip from "components/RecorderChip";
|
||||
import ThumbnailHeader from "components/ThumbnailHeader";
|
||||
import ToolTip from "components/ToolTip";
|
||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||
import { GetContentTextQuery } from "graphql/generated";
|
||||
import { getReadySdk } from "graphql/sdk";
|
||||
import { useMediaMobile } from "hooks/useMediaQuery";
|
||||
import {
|
||||
GetStaticPathsContext,
|
||||
GetStaticPathsResult,
|
||||
|
@ -47,6 +49,8 @@ export default function Content(props: Props): JSX.Element {
|
|||
const router = useRouter();
|
||||
const appLayout = useAppLayout();
|
||||
|
||||
const isMobile = useMediaMobile();
|
||||
|
||||
const [selectedTextSet, setSelectedTextSet] = useState<
|
||||
| Exclude<
|
||||
Exclude<Props["content"], null | undefined>["text_set"],
|
||||
|
@ -261,9 +265,111 @@ export default function Content(props: Props): JSX.Element {
|
|||
}
|
||||
/>
|
||||
|
||||
{content.previous_recommended?.data?.attributes && (
|
||||
<div className="mt-12 mb-8 w-full">
|
||||
<h2 className="text-center text-2xl mb-4">Previous content</h2>
|
||||
<PreviewLine
|
||||
href={`/contents/${content.previous_recommended.data.attributes.slug}`}
|
||||
pre_title={
|
||||
content.previous_recommended.data.attributes.titles?.[0]
|
||||
?.pre_title
|
||||
}
|
||||
title={
|
||||
content.previous_recommended.data.attributes.titles?.[0]
|
||||
?.title ??
|
||||
prettySlug(content.previous_recommended.data.attributes.slug)
|
||||
}
|
||||
subtitle={
|
||||
content.previous_recommended.data.attributes.titles?.[0]
|
||||
?.subtitle
|
||||
}
|
||||
thumbnail={
|
||||
content.previous_recommended.data.attributes.thumbnail?.data
|
||||
?.attributes
|
||||
}
|
||||
thumbnailAspectRatio="3/2"
|
||||
topChips={
|
||||
isMobile
|
||||
? undefined
|
||||
: content.previous_recommended.data.attributes.type?.data
|
||||
?.attributes
|
||||
? [
|
||||
content.previous_recommended.data.attributes.type.data
|
||||
.attributes.titles?.[0]
|
||||
? content.previous_recommended.data.attributes.type
|
||||
.data.attributes.titles[0]?.title
|
||||
: prettySlug(
|
||||
content.previous_recommended.data.attributes.type
|
||||
.data.attributes.slug
|
||||
),
|
||||
]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={
|
||||
isMobile
|
||||
? undefined
|
||||
: content.previous_recommended.data.attributes.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<HorizontalLine />
|
||||
|
||||
<Markdawn text={selectedTextSet?.text ?? ""} />
|
||||
|
||||
<HorizontalLine />
|
||||
|
||||
{content.next_recommended?.data?.attributes && (
|
||||
<>
|
||||
<h2 className="text-center text-2xl mb-4">Follow-up content</h2>
|
||||
<PreviewLine
|
||||
href={`/contents/${content.next_recommended.data.attributes.slug}`}
|
||||
pre_title={
|
||||
content.next_recommended.data.attributes.titles?.[0]
|
||||
?.pre_title
|
||||
}
|
||||
title={
|
||||
content.next_recommended.data.attributes.titles?.[0]?.title ??
|
||||
prettySlug(content.next_recommended.data.attributes.slug)
|
||||
}
|
||||
subtitle={
|
||||
content.next_recommended.data.attributes.titles?.[0]?.subtitle
|
||||
}
|
||||
thumbnail={
|
||||
content.next_recommended.data.attributes.thumbnail?.data
|
||||
?.attributes
|
||||
}
|
||||
thumbnailAspectRatio="3/2"
|
||||
topChips={
|
||||
isMobile
|
||||
? undefined
|
||||
: content.next_recommended.data.attributes.type?.data
|
||||
?.attributes
|
||||
? [
|
||||
content.next_recommended.data.attributes.type.data
|
||||
.attributes.titles?.[0]
|
||||
? content.next_recommended.data.attributes.type.data
|
||||
.attributes.titles[0]?.title
|
||||
: prettySlug(
|
||||
content.next_recommended.data.attributes.type.data
|
||||
.attributes.slug
|
||||
),
|
||||
]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={
|
||||
isMobile
|
||||
? undefined
|
||||
: content.next_recommended.data.attributes.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</ContentPanel>
|
||||
|
@ -338,7 +444,10 @@ export async function getStaticPaths(
|
|||
contents.contents?.data.map((item) => {
|
||||
context.locales?.map((local) => {
|
||||
if (item.attributes)
|
||||
paths.push({ params: { slug: item.attributes.slug }, locale: local });
|
||||
paths.push({
|
||||
params: { slug: item.attributes.slug },
|
||||
locale: local,
|
||||
});
|
||||
});
|
||||
});
|
||||
return {
|
||||
|
|
Loading…
Reference in New Issue