Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): Organization page with "standalone" theme - Level 2 sitemap #17085

Merged
31 changes: 31 additions & 0 deletions apps/web/pages/s/[...slugs]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ import StandaloneHome, {
import StandaloneLevel1Sitemap, {
type StandaloneLevel1SitemapProps,
} from '@island.is/web/screens/Organization/Standalone/Level1Sitemap'
import StandaloneLevel2Sitemap, {
type StandaloneLevel2SitemapProps,
} from '@island.is/web/screens/Organization/Standalone/Level2Sitemap'
import StandaloneParentSubpage, {
StandaloneParentSubpageProps,
} from '@island.is/web/screens/Organization/Standalone/ParentSubpage'
Expand All @@ -50,6 +53,7 @@ enum PageType {
STANDALONE_FRONTPAGE = 'standalone-frontpage',
STANDALONE_PARENT_SUBPAGE = 'standalone-parent-subpage',
STANDALONE_LEVEL1_SITEMAP = 'standalone-level1-sitemap',
STANDALONE_LEVEL2_SITEMAP = 'standalone-level2-sitemap',
SUBPAGE = 'subpage',
ALL_NEWS = 'news',
PUBLISHED_MATERIAL = 'published-material',
Expand All @@ -69,6 +73,9 @@ const pageMap: Record<PageType, FC<any>> = {
[PageType.STANDALONE_LEVEL1_SITEMAP]: (props) => (
<StandaloneLevel1Sitemap {...props} />
),
[PageType.STANDALONE_LEVEL2_SITEMAP]: (props) => (
<StandaloneLevel2Sitemap {...props} />
),
[PageType.SUBPAGE]: (props) => <SubPage {...props} />,
[PageType.ALL_NEWS]: (props) => <OrganizationNewsList {...props} />,
[PageType.PUBLISHED_MATERIAL]: (props) => <PublishedMaterial {...props} />,
Expand Down Expand Up @@ -101,6 +108,10 @@ interface Props {
type: PageType.STANDALONE_LEVEL1_SITEMAP
props: StandaloneLevel1SitemapProps
}
| {
type: PageType.STANDALONE_LEVEL2_SITEMAP
props: StandaloneLevel2SitemapProps
}
| {
type: PageType.SUBPAGE
props: {
Expand Down Expand Up @@ -316,6 +327,26 @@ Component.getProps = async (context) => {
}
}

if (
isStandaloneTheme &&
organizationPage.topLevelNavigation?.links.some(
(link) => slugs[1] === link.href.split('/').pop(),
)
) {
try {
return {
page: {
type: PageType.STANDALONE_LEVEL2_SITEMAP,
props: await StandaloneLevel2Sitemap.getProps(modifiedContext),
},
}
} catch (error) {
if (!(error instanceof CustomNextError)) {
throw error
}
}
}

if (isStandaloneTheme) {
return {
page: {
Expand Down
177 changes: 177 additions & 0 deletions apps/web/screens/Organization/Standalone/Level2Sitemap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import { useMemo } from 'react'

import {
BreadCrumbItem,
Breadcrumbs,
GridColumn,
GridContainer,
GridRow,
LinkV2,
Stack,
} from '@island.is/island-ui/core'
import { Text } from '@island.is/island-ui/core'
import {
ContentLanguage,
OrganizationPage,
OrganizationPageStandaloneSitemapLevel2,
OrganizationPageTopLevelNavigationLink,
Query,
QueryGetOrganizationPageArgs,
QueryGetOrganizationPageStandaloneSitemapLevel2Args,
} from '@island.is/web/graphql/schema'
import useContentfulId from '@island.is/web/hooks/useContentfulId'
import { StandaloneLayout } from '@island.is/web/layouts/organization/standalone'
import type { Screen, ScreenContext } from '@island.is/web/types'
import { CustomNextError } from '@island.is/web/units/errors'

import {
GET_ORGANIZATION_PAGE_QUERY,
GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL2_QUERY,
} from '../../queries'

const LanguageToggleSetup = (props: { ids: string[] }) => {
useContentfulId(...props.ids)
return null
}

type StandaloneLevel2SitemapScreenContext = ScreenContext & {
organizationPage?: Query['getOrganizationPage']
}

export interface StandaloneLevel2SitemapProps {
organizationPage: OrganizationPage
category?: OrganizationPageTopLevelNavigationLink
sitemap: OrganizationPageStandaloneSitemapLevel2
}

const StandaloneLevel2Sitemap: Screen<
StandaloneLevel2SitemapProps,
StandaloneLevel2SitemapScreenContext
> = ({ organizationPage, category, sitemap }) => {
const breadcrumbItems: BreadCrumbItem[] = useMemo(() => {
const items: BreadCrumbItem[] = []

if (category) {
items.push({
title: category.label,
href: category.href,
})
}
return items
}, [category])

return (
<StandaloneLayout
organizationPage={organizationPage}
seo={{
title: `${sitemap.label} | ${organizationPage.title}`,
}}
>
<LanguageToggleSetup ids={[organizationPage.id]} />
<GridContainer>
<GridRow>
<GridColumn span={['9/9', '9/9', '7/9']} offset={['0', '0', '1/9']}>
<Stack space={1}>
<Breadcrumbs items={breadcrumbItems} />
<Stack space={3}>
<Text variant="h1" as="h1">
{sitemap.label}
</Text>
<Stack space={3}>
{sitemap.childCategories.map(({ label, childLinks }) => (
<Stack space={1} key={label}>
<Text variant="h3" as="h2">
{label}
</Text>
<Stack space={1}>
{childLinks.map((link) => (
<LinkV2
key={link.label}
href={link.href}
color="blue400"
>
{link.label}
</LinkV2>
))}
</Stack>
RunarVestmann marked this conversation as resolved.
Show resolved Hide resolved
</Stack>
))}
</Stack>
</Stack>
</Stack>
</GridColumn>
</GridRow>
</GridContainer>
</StandaloneLayout>
)
}

StandaloneLevel2Sitemap.getProps = async ({
apolloClient,
locale,
query,
organizationPage,
}) => {
const [organizationPageSlug, categorySlug, subcategorySlug] = (query.slugs ??
[]) as string[]

const [
{
data: { getOrganizationPage },
},
{
data: { getOrganizationPageStandaloneSitemapLevel2 },
},
] = await Promise.all([
!organizationPage
? apolloClient.query<Query, QueryGetOrganizationPageArgs>({
query: GET_ORGANIZATION_PAGE_QUERY,
variables: {
input: {
slug: organizationPageSlug,
lang: locale as ContentLanguage,
},
},
})
: {
data: { getOrganizationPage: organizationPage },
},
apolloClient.query<
Query,
QueryGetOrganizationPageStandaloneSitemapLevel2Args
>({
query: GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL2_QUERY,
variables: {
input: {
organizationPageSlug,
categorySlug,
subcategorySlug,
lang: locale as ContentLanguage,
},
},
}),
])

if (!getOrganizationPage) {
throw new CustomNextError(404, 'Organization page was not found')
}

if (!getOrganizationPageStandaloneSitemapLevel2) {
throw new CustomNextError(
404,
'Organization page standalone level 2 sitemap was not found',
)
}

const category = organizationPage?.topLevelNavigation?.links.find(
(link) => categorySlug === link.href.split('/').pop(),
)

return {
organizationPage: getOrganizationPage,
category,
sitemap: getOrganizationPageStandaloneSitemapLevel2,
}
}

export default StandaloneLevel2Sitemap
18 changes: 18 additions & 0 deletions apps/web/screens/queries/Organization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -445,3 +445,21 @@ export const GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL1_QUERY = gql`
}
}
`

export const GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL2_QUERY = gql`
query GetOrganizationPageStandaloneSitemapLevel2Query(
$input: GetOrganizationPageStandaloneSitemapLevel2Input!
) {
getOrganizationPageStandaloneSitemapLevel2(input: $input) {
label
childCategories {
label
href
childLinks {
label
href
}
}
}
}
`
Loading