-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
259 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"web": minor | ||
--- | ||
|
||
Added `publicaties` page |
15 changes: 15 additions & 0 deletions
15
apps/web/src/app/publicaties/[slug]/copy-cite-to-clipboard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
'use client'; | ||
|
||
import { Button } from '@/components/button'; | ||
import { IconClipboard } from '@tabler/icons-react'; | ||
import { CopyToClipboard } from 'react-copy-to-clipboard'; | ||
|
||
interface Props { | ||
text: string; | ||
} | ||
|
||
export const CopyCiteToClipboard: React.FC<Props> = ({ text }) => ( | ||
<CopyToClipboard text={text}> | ||
<Button startIcon={<IconClipboard />}>Kopiëren naar klembord</Button> | ||
</CopyToClipboard> | ||
); |
19 changes: 19 additions & 0 deletions
19
apps/web/src/app/publicaties/[slug]/download/get-publication-file-by-slug.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { db } from '@/drizzle/db'; | ||
import { files, filesRelatedMorphs, publications } from '@/drizzle/schema'; | ||
import { and, eq } from 'drizzle-orm'; | ||
|
||
interface Args { | ||
slug: string; | ||
} | ||
|
||
export async function getPublicationFileBySlug({ slug }: Args) { | ||
const [result] = await db | ||
.select({ file: files }) | ||
.from(publications) | ||
.leftJoin(filesRelatedMorphs, eq(publications.id, filesRelatedMorphs.relatedId)) | ||
.leftJoin(files, eq(files.id, filesRelatedMorphs.fileId)) | ||
.where(and(eq(publications.slug, slug), eq(filesRelatedMorphs.relatedType, 'api::publication.publication'))) | ||
.limit(1); | ||
|
||
return result.file; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { resolveCmsImage } from '@/common/resolve-cms-image'; | ||
import slugify from '@sindresorhus/slugify'; | ||
import { NextRequest } from 'next/server'; | ||
import { getPublicationFileBySlug } from './get-publication-file-by-slug'; | ||
|
||
export async function GET(req: NextRequest, { params }: { params: { slug: string } }) { | ||
const file = await getPublicationFileBySlug({ slug: params.slug }); | ||
|
||
const fetchResponse = await fetch(resolveCmsImage(file as any), { | ||
method: 'GET', | ||
}); | ||
|
||
const headers = new Headers(); | ||
|
||
headers.set('Content-Disposition', `attachment; filename="${slugify(params.slug)}${file?.ext}"`); | ||
headers.set('Content-Type', file?.mime || ''); | ||
|
||
return new Response(fetchResponse.body, { | ||
headers, | ||
status: fetchResponse.status, | ||
}); | ||
} |
13 changes: 13 additions & 0 deletions
13
apps/web/src/app/publicaties/[slug]/get-publication-by-slug.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { db } from '@/drizzle/db'; | ||
import { publications } from '@/drizzle/schema'; | ||
import { eq } from 'drizzle-orm'; | ||
|
||
interface Args { | ||
slug: string; | ||
} | ||
|
||
export async function getPublicationBySlug({ slug }: Args) { | ||
const [publication] = await db.select().from(publications).where(eq(publications.slug, slug)).limit(1); | ||
|
||
return publication; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import { EnhanceMenuBreadcrumbs } from '@/app/menu-breadcrumbs'; | ||
import { Button } from '@/components/button'; | ||
import { Container } from '@/components/container'; | ||
import * as Dialog from '@/components/dialog'; | ||
import { Pill } from '@/components/pill'; | ||
import { RemoteMdx } from '@/components/remote-mdx'; | ||
import { Typography } from '@/components/typography'; | ||
import { IconArrowLeft, IconBlockquote, IconDownload, IconExternalLink, IconFileTypePdf } from '@tabler/icons-react'; | ||
import { format } from 'date-fns'; | ||
import Link from 'next/link'; | ||
import { CopyCiteToClipboard } from './copy-cite-to-clipboard'; | ||
import { getPublicationBySlug } from './get-publication-by-slug'; | ||
|
||
type Args = { params: { slug: string } }; | ||
|
||
export default async function PublicatiesSlugPage({ params }: Args) { | ||
const publication = await getPublicationBySlug({ slug: params.slug }); | ||
|
||
return ( | ||
<> | ||
<EnhanceMenuBreadcrumbs append={publication.title!} /> | ||
<Container component="header" className="-mt-14 bg-[#F7FBFD] py-12"> | ||
<Typography variant="h1">{publication.title}</Typography> | ||
<section className="flex flex-col gap-y-1 pb-2 pt-12"> | ||
<Typography className="!mt-0 text-lg text-primary-dark"> | ||
Gepubliceerd op: {format(publication.updatedAt!, 'dd MMMM yyyy')} | ||
</Typography> | ||
<Typography className="!mt-0 text-lg text-primary-dark">Auteurs: {publication.authors}</Typography> | ||
<Typography className="!mt-0 text-lg text-primary-dark">Locatie: {publication.location}</Typography> | ||
</section> | ||
<section> | ||
<ul className="-ml-4 flex"> | ||
<li> | ||
<Dialog.Root> | ||
<Dialog.Trigger asChild> | ||
<Button startIcon={<IconBlockquote />} variant="text"> | ||
Citeer dit artikel | ||
</Button> | ||
</Dialog.Trigger> | ||
<Dialog.Portal> | ||
<Dialog.Content> | ||
<Dialog.Title>Citeer deze publicatie</Dialog.Title> | ||
<Dialog.Description> | ||
{publication.cite} | ||
<div className="mt-4 flex justify-center"> | ||
<CopyCiteToClipboard text={publication.cite!} /> | ||
</div> | ||
</Dialog.Description> | ||
</Dialog.Content> | ||
</Dialog.Portal> | ||
</Dialog.Root> | ||
</li> | ||
<li> | ||
<Button | ||
component={Link} | ||
href={`/publicaties/${params.slug}/download`} | ||
startIcon={<IconFileTypePdf />} | ||
variant="text" | ||
> | ||
Download dit artikel | ||
</Button> | ||
</li> | ||
<li> | ||
<Button | ||
component="a" | ||
variant="text" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
startIcon={<IconExternalLink />} | ||
href={publication.originalSource!} | ||
> | ||
Originele bron | ||
</Button> | ||
</li> | ||
</ul> | ||
</section> | ||
</Container> | ||
<Container component="main" className="pt-12"> | ||
<section> | ||
<Typography variant="h2">Samenvatting</Typography> | ||
<RemoteMdx content={publication.content!} /> | ||
</section> | ||
<section> | ||
<Typography variant="h3">Trefwoorden</Typography> | ||
<ul className="mt-4 flex gap-x-6"> | ||
{publication.tags?.split(',').map((tag) => ( | ||
<Pill key={tag} component="li" label={tag} /> | ||
))} | ||
</ul> | ||
</section> | ||
</Container> | ||
<Container component="footer" className="pb-12"> | ||
<div className="mt-16 flex justify-between"> | ||
<Button component={Link} href="/publicaties" startIcon={<IconArrowLeft />}> | ||
Overzicht | ||
</Button> | ||
<Button | ||
component={Link} | ||
color="primary-light" | ||
href={`/publicaties/${params.slug}/download`} | ||
startIcon={<IconDownload />} | ||
> | ||
Download | ||
</Button> | ||
</div> | ||
</Container> | ||
</> | ||
); | ||
} | ||
|
||
export async function generateMetadata({ params }: Args) { | ||
const publication = await getPublicationBySlug({ slug: params.slug }); | ||
|
||
return { | ||
title: publication.title + ' - Regelregister van de Nederlandse Overheid', | ||
keywords: publication.tags, | ||
authors: publication.authors?.split(',').map((author) => ({ name: author.trim() })), | ||
description: publication.summary, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Pill } from '@/components/pill'; | ||
import { Typography } from '@/components/typography'; | ||
import { getPublications } from './get-publications'; | ||
import Link from 'next/link'; | ||
|
||
interface Props { | ||
publication: Awaited<ReturnType<typeof getPublications>>[number]; | ||
} | ||
|
||
export const CardPublication: React.FC<Props> = ({ publication }) => { | ||
if (!publication.slug || !publication.title || !publication.summary) return null; | ||
|
||
return ( | ||
<Link href={'/publicaties/' + publication.slug} className="rounded-md border border-grey-lighter p-6"> | ||
<Typography variant="h3" className="mt-0 text-xl text-grey-dark"> | ||
{publication.title} | ||
</Typography> | ||
<Typography className="mb-4 mt-2 text-grey-dark">{publication.summary}</Typography> | ||
<div className="flex items-start gap-x-4"> | ||
{publication.tags?.split(',').map((tag) => ( | ||
<Pill key={tag} label={tag.trim()} /> | ||
))} | ||
</div> | ||
</Link> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { db } from '@/drizzle/db'; | ||
import { publications } from '@/drizzle/schema'; | ||
import { and, desc, lte } from 'drizzle-orm'; | ||
|
||
export function getPublications() { | ||
return db | ||
.select() | ||
.from(publications) | ||
.orderBy(desc(publications.publicationDate)) | ||
.where(and(lte(publications.publishedAt, new Date().toISOString()))); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Container } from '@/components/container'; | ||
import { RemotePage } from '@/components/remote-page'; | ||
import { Typography } from '@/components/typography'; | ||
import { Metadata } from 'next'; | ||
import { CardPublication } from './card-publication'; | ||
import { getPublications } from './get-publications'; | ||
|
||
export default async function PublicatiesPage() { | ||
const publications = await getPublications(); | ||
|
||
return ( | ||
<> | ||
<Container className="mb-16"> | ||
<Typography variant="h1">Publicaties</Typography> | ||
<RemotePage page="publicaties" /> | ||
<div className="mt-28 flex flex-col gap-y-4"> | ||
{publications.map((publication) => ( | ||
<CardPublication key={publication.id} publication={publication} /> | ||
))} | ||
</div> | ||
</Container> | ||
</> | ||
); | ||
} | ||
|
||
export const metadata: Metadata = { | ||
title: 'Regelregister van de Nederlandse Overheid - Publicaties', | ||
}; |