_includes/layouts/ListingLayout.11ty.tsx (106 lines of code) (raw):

import { EleventyCollectionItem, LayoutContext, LayoutProps, } from "../../src/models"; import ResourceCard from "../resourcecard/ResourceCard.11ty"; import { ResourceFrontmatter } from "../../src/ResourceModels"; import { BaseLayout } from "./BaseLayout.11ty"; import Pagination from "../pagination/Pagination.11ty"; import { sortByFrontmatter } from "../queries"; type FullData = { pagination: { resourceType?: string; sortBy?: string; }; } & ResourceFrontmatter; type ListingLayoutProps = { content?: string; figure?: string[]; listing: string[]; } & LayoutProps & ResourceFrontmatter; export default class ListingLayout { data() { return { eleventyExcludeFromCollections: true, pagination: { data: "collections.all", size: 12, reverse: true, before: function ( paginationData: EleventyCollectionItem[], fullData: FullData, ): EleventyCollectionItem[] { // Get pagination.resourceType and pagination.channel, if present const { resourceType } = fullData.pagination; const { sortBy }: { sortBy?: string } = fullData.pagination; const channel = fullData.channel; const result = paginationData .filter((item) => { return !(resourceType && resourceType != item.data.resourceType); }) .filter((item) => { return !(channel && channel != item.data.channel); }); sortByFrontmatter(result, sortBy); return result; }, }, }; } render(this: LayoutContext, data: ListingLayoutProps): JSX.Element { const { content, figure, pagination } = data; const paginationItems = pagination ? pagination.items : []; const resources = paginationItems.map((r: any) => { return this.getResource(r.url); }); const pages = ( <section class="section" aria-label="Pagination"> <div class="container"> {pagination && <Pagination pagination={pagination} />} <div class="columns is-multiline"> {resources.map((resource) => { return ( <ResourceCard resource={resource} includeContentType={false} includeCardFooter={resource.resourceType != "channel"} /> ); })} </div> {pagination && <Pagination pagination={pagination} />} </div> </section> ); return ( <BaseLayout {...data}> <section class="section"> <div class="container"> <div class="is-flex"> {figure && ( <span class="mr-4"> <figure class="image is-128x128">{figure}</figure> </span> )} <div> <h1 class="mt-2 mb-4 title is-size-2 is-size-3-mobile has-text-weight-bold"> {data.title} </h1> {data.subtitle && ( <p class="subtitle is-size-4 has-text-grey mb-5"> {data.subtitle} </p> )} </div> </div> {content && content != data.subtitle && ( <div class="content pt-2">{content}</div> )} </div> </section> {pages} </BaseLayout> ); } }