Skip to content

Commit

Permalink
feat(vth): add side-nav
Browse files Browse the repository at this point in the history
  • Loading branch information
bddjong committed Oct 11, 2023
1 parent cd003df commit 772d5fc
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { createStrapiURL } from '@frameless/vth-frontend/src/util/createStrapiURL';
import { fetchData } from '@frameless/vth-frontend/src/util/fetchData';
import {
Heading1,
Heading2,
Link,
Paragraph,
UnorderedList,
UnorderedListItem,
} from '@utrecht/component-library-react';
import { Heading1 } from '@utrecht/component-library-react';
import { Metadata } from 'next';
import React from 'react';
import { useTranslation } from '@/app/i18n';
import { Grid } from '@/components/Grid';
import { Markdown } from '@/components/Markdown';
import { LinkData, SideNavigation } from '@/components/SideNavigation';
import { GET_CONTENT_BY_SLUG } from '@/query';
import { SiblingData } from '@/types';

type Params = {
params: {
Expand All @@ -39,31 +34,39 @@ const Thema = async ({ params: { locale, contentSlug } }: Params) => {
});

const { title, content, parents } = data.findSlug.data.attributes;
const parentSlug = parents?.data[0]?.attributes?.slug;
const siblingThemas: SiblingData[] = parents?.data[0]?.attributes?.child_themas?.data || [];
const siblingContent: SiblingData[] = parents?.data[0]?.attributes?.child_contents?.data || [];

const themasLinks =
siblingThemas?.map(({ attributes: { slug, title } }: SiblingData) => ({
title,
slug,
href: `/themas/${slug}`,
isCurrent: slug === contentSlug,
})) || [];

const contentLinks =
siblingContent?.map(({ attributes: { slug, title } }: SiblingData) => ({
title,
slug,
href: `/themas/${parentSlug}/content/${slug}`,
isCurrent: slug === contentSlug,
})) || [];

const sideNavigationLinks: LinkData[] = [...themasLinks, ...contentLinks];

return (
<Grid className={'utrecht-grid--content-padding'}>
<div className={'utrecht-grid__two-third'}>
<Heading1>{title}</Heading1>
<Markdown strapiBackendURL={process.env.STRAPI_PUBLIC_URL}>{content}</Markdown>
<Heading2>Themas</Heading2>
{parents.data[0] ? (
<UnorderedList>
{parents.data &&
parents.data.map((content: any) => {
const { title, slug: parentSlug } = content.attributes;
return (
<UnorderedListItem key={`thema-${parentSlug}`}>
<Link href={`/themas/${parentSlug}`}>{title}</Link>
</UnorderedListItem>
);
})}
</UnorderedList>
) : (
<>
<Paragraph>Geen thema paginas verbonden.</Paragraph>
</>
)}
</div>
{sideNavigationLinks.length > 0 && (
<div className={'utrecht-grid-mobile-hidden utrecht-grid__one-third'}>
<SideNavigation links={sideNavigationLinks} />
</div>
)}
</Grid>
);
};
Expand Down
104 changes: 67 additions & 37 deletions apps/vth-frontend/src/app/[locale]/themas/[themaSlug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import { useTranslation } from '@/app/i18n';
import { Card } from '@/components/Card';
import { Grid } from '@/components/Grid';
import { Markdown } from '@/components/Markdown';
import { LinkData, SideNavigation } from '@/components/SideNavigation';
import { GET_THEMA_BY_SLUG } from '@/query';
import { buildImgURL } from '@/util/buildImgURL';
import { SiblingData } from '@/types';

type Params = {
params: {
Expand All @@ -33,47 +35,75 @@ const Thema = async ({ params: { locale, themaSlug } }: Params) => {
variables: { slug: themaSlug, locale: locale },
});

const { title, content, child_themas, child_contents } = data.findSlug.data.attributes;
const { title, content, parents, child_themas, child_contents } = data.findSlug.data.attributes;
const parentSlug = parents?.data[0]?.attributes?.slug;
const siblingThemas: SiblingData[] = parents?.data[0]?.attributes?.child_themas?.data || [];
const siblingContent: SiblingData[] = parents?.data[0]?.attributes?.child_contents?.data || [];

const themasLinks =
siblingThemas?.map(({ attributes: { slug, title } }: SiblingData) => ({
title,
slug,
href: `/themas/${slug}`,
isCurrent: slug === themaSlug,
})) || [];

const contentLinks =
siblingContent?.map(({ attributes: { slug, title } }: SiblingData) => ({
title,
slug,
href: `/themas/${parentSlug}/content/${slug}`,
isCurrent: slug === themaSlug,
})) || [];

const sideNavigationLinks: LinkData[] = [...themasLinks, ...contentLinks];

return (
<Grid className={'utrecht-grid--content-padding'}>
<div className={'utrecht-grid__two-third'}>
<Heading1>{title}</Heading1>
<Markdown strapiBackendURL={process.env.STRAPI_PUBLIC_URL}>{content}</Markdown>
</div>
<Grid className={'utrecht-grid__full-width'}>
{child_themas.data[0] &&
child_themas.data.map((thema: any) => {
const { title, description, slug: childSlug, previewImage: imageData } = thema.attributes;
const imageUrl = imageData?.data?.attributes?.url;
return (
<Card
className={'utrecht-grid__one-third'}
image={{ url: imageUrl && buildImgURL(imageUrl), alt: '' }}
title={title}
description={description}
key={`thema-${childSlug}`}
link={{ href: `/themas/${childSlug}` }}
/>
);
})}
{child_contents.data[0] &&
child_contents.data &&
child_contents.data.map((content: any) => {
const { title, description, slug: contentSlug, previewImage: imageData } = content.attributes;
const imageUrl = imageData?.data?.attributes?.url;
return (
<Card
className={'utrecht-grid__one-third'}
title={title}
description={description}
key={`thema-${contentSlug}`}
image={{ url: imageUrl && buildImgURL(imageUrl), alt: '' }}
link={{ href: `/themas/${themaSlug}/content/${contentSlug}` }}
/>
);
})}
<Grid className={'utrecht-grid__two-third'}>
<div className={'utrecht-grid__full-width'}>
<Heading1>{title}</Heading1>
<Markdown strapiBackendURL={process.env.STRAPI_PUBLIC_URL}>{content}</Markdown>
</div>
<Grid className={'utrecht-grid__full-width'}>
{child_themas.data[0] &&
child_themas.data.map((thema: any) => {
const { title, description, slug: childSlug, previewImage: imageData } = thema.attributes;
const imageUrl = imageData?.data?.attributes?.url;
return (
<Card
className={'utrecht-grid__half-width'}
image={{ url: imageUrl && buildImgURL(imageUrl), alt: '' }}
title={title}
description={description}
key={`thema-${childSlug}`}
link={{ href: `/themas/${childSlug}` }}
/>
);
})}
{child_contents.data[0] &&
child_contents.data &&
child_contents.data.map((content: any) => {
const { title, description, slug: contentSlug, previewImage: imageData } = content.attributes;
const imageUrl = imageData?.data?.attributes?.url;
return (
<Card
className={'utrecht-grid__half-width'}
title={title}
description={description}
key={`thema-${contentSlug}`}
image={{ url: imageUrl && buildImgURL(imageUrl), alt: '' }}
link={{ href: `/themas/${themaSlug}/content/${contentSlug}` }}
/>
);
})}
</Grid>
</Grid>
{sideNavigationLinks.length > 0 && (
<div className={'utrecht-grid-mobile-hidden utrecht-grid__one-third'}>
<SideNavigation links={sideNavigationLinks} />
</div>
)}
</Grid>
);
};
Expand Down
8 changes: 8 additions & 0 deletions apps/vth-frontend/src/components/Grid/index.style.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
padding-block-end: 0;
}

.utrecht-grid-mobile-hidden {
display: none;
}

.utrecht-grid--content-padding {
padding-block-start: 1rem;
padding-inline-end: 1rem;
Expand Down Expand Up @@ -63,6 +67,10 @@
grid-template-columns: repeat(12, 1fr);
}

.utrecht-grid-mobile-hidden {
display: unset;
}

.utrecht-grid__half-width {
grid-column: span 6;
}
Expand Down
42 changes: 42 additions & 0 deletions apps/vth-frontend/src/components/SideNavigation/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import clsx from 'clsx';
import Link from 'next/link';
import React, { FC } from 'react';

export type LinkData = {
title: string;
slug: string;
href: string;
isCurrent: boolean;
};

export type SideNavigationProps = {
links: LinkData[];
};

export const SideNavigation: FC<SideNavigationProps> = (props) => {
const buildNavItem = (slug: string, title: string, href: string, isCurrent: boolean) => {
return (
<li
key={`sidenav-thema-${slug}`}
className={clsx('utrecht-sidenav__item', { 'utrecht-sidenav__item--current': isCurrent })}
>
<Link
aria-current={isCurrent ? 'page' : 'false'}
className={clsx('utrecht-sidenav__link', { 'utrecht-sidenav__link--current': isCurrent })}
href={href}
>
<div className={clsx('utrecht-sidenav__marker', { 'utrecht-sidenav__marker--current': isCurrent })}></div>
{title}
</Link>
</li>
);
};

return (
<nav className={'utrecht-sidenav'}>
<ul className={'utrecht-sidenav__list'}>
{props.links.map(({ slug, title, href, isCurrent }: LinkData) => buildNavItem(slug, title, href, isCurrent))}
</ul>
</nav>
);
};
33 changes: 25 additions & 8 deletions apps/vth-frontend/src/query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,21 @@ query GET_THEMA_BY_SLUG($slug: String) {
parents {
data {
attributes {
title,
slug,
description,
previewImage {
title
slug
child_themas {
data {
attributes {
url
title
slug
}
}
}
child_contents {
data {
attributes {
title
slug
}
}
}
Expand Down Expand Up @@ -125,12 +133,21 @@ query GET_CONTENT_BY_SLUG($slug: String) {
parents {
data {
attributes {
title,
title
slug
previewImage {
child_themas {
data {
attributes {
url
title
slug
}
}
}
child_contents {
data {
attributes {
title
slug
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions apps/vth-frontend/src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,16 @@ a {
object-fit: cover;
}

.utrecht-navigation__toggle-button {
float: right;
position: absolute;
}

.utrecht-navigation {
border-block-end-color: var(--utrecht-navigation-border-block-start-color);
border-block-end-style: solid;
border-block-end-width: var(--utrecht-navigation-border-block-start-width);
}

.utrecht-sidenav {
border-block-end: none;
}

.utrecht-sidenav__item {
border-block-end: 1px solid var(--utrecht-color-grey-80);
}
25 changes: 5 additions & 20 deletions apps/vth-frontend/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,9 @@ export interface Timing {
request: number;
}

export interface SearchResult {
total: number;
hits: Hit[];
request: Request;
received: Received;
pagination: Pagination;
timing: Timing;
}

export interface SuggestedResult {
suggestedHits: SuggestedHits;
suggestions: Suggestions;
}

export type SuggestedHits = {
titleRaw: string;
url: string;
};
export type Suggestions = {
text: string;
export type SiblingData = {
attributes: {
slug: string;
title: string;
};
};

0 comments on commit 772d5fc

Please sign in to comment.