import { Chip } from "components/Chip"; import { Img } from "components/Img"; import { InsetBox } from "components/Containers/InsetBox"; import { Markdawn } from "components/Markdown/Markdawn"; import { GetContentTextQuery, UploadImageFragment } from "graphql/generated"; import { prettyInlineTitle, prettySlug, slugify } from "helpers/formatters"; import { ImageQuality } from "helpers/img"; import { filterHasAttributes } from "helpers/asserts"; import { useAtomGetter } from "helpers/atoms"; import { atoms } from "contexts/atoms"; import { useFormat } from "hooks/useFormat"; /* * ╭─────────────╮ * ───────────────────────────────────────╯ COMPONENT ╰─────────────────────────────────────────── */ interface Props { pre_title?: string | null | undefined; title: string | null | undefined; subtitle?: string | null | undefined; description?: string | null | undefined; type?: NonNullable< NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"] >["type"]; categories?: NonNullable< NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"] >["categories"]; thumbnail?: UploadImageFragment | null | undefined; languageSwitcher?: JSX.Element; } // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ export const ThumbnailHeader = ({ pre_title, title, subtitle, thumbnail, type, categories, description, languageSwitcher, }: Props): JSX.Element => { const { format } = useFormat(); const { showLightBox } = useAtomGetter(atoms.lightBox); return ( <> <div className="mb-12 grid place-items-center gap-12"> <div className="drop-shadow-lg shadow-shade"> {thumbnail ? ( <Img className="cursor-pointer rounded-xl" src={thumbnail} quality={ImageQuality.Medium} onClick={() => showLightBox([thumbnail])} /> ) : ( <div className="aspect-[4/3] w-96 rounded-xl bg-light" /> )} </div> <div id={slugify(prettyInlineTitle(pre_title ?? "", title, subtitle ?? ""))} className="grid place-items-center text-center"> <p className="text-2xl">{pre_title}</p> <h1 className="text-3xl">{title}</h1> <h2 className="text-2xl">{subtitle}</h2> </div> </div> <div className="flew-wrap flex flex-row place-content-center gap-8"> {type?.data?.attributes && ( <div className="flex flex-col place-items-center gap-2"> <h3 className="text-xl">{format("type", { count: 1 })}</h3> <div className="flex flex-row flex-wrap"> <Chip text={ type.data.attributes.titles?.[0]?.title ?? prettySlug(type.data.attributes.slug) } /> </div> </div> )} {categories && categories.data.length > 0 && ( <div className="flex flex-col place-items-center gap-2"> <h3 className="text-xl">{format("category", { count: categories.data.length })}</h3> <div className="flex flex-row flex-wrap place-content-center gap-2"> {filterHasAttributes(categories.data, ["attributes", "id"] as const).map( (category) => ( <Chip key={category.id} text={category.attributes.name} /> ) )} </div> </div> )} {languageSwitcher} </div> {description && <InsetBox className="mt-8">{<Markdawn text={description} />}</InsetBox>} </> ); };