diff --git a/src/app.tsx b/src/app.tsx index fb63c87..fe873f4 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -10,6 +10,7 @@ import { MetaProvider } from '@solidjs/meta' import { loadHomePage } from './data/home.data' import { loadPost } from './data/post.data' import { loadSearchPage } from './data/search.data' +import { loadPagesPage } from './data/pages.data' const ROUTES: RouteDefinition[] = [ { @@ -21,8 +22,9 @@ const ROUTES: RouteDefinition[] = [ load: loadPost, }, { - path: '/_debug', - component: lazy(() => import('~/pages/Debug')), + path: '/pages/:slug', + component: lazy(() => import('~/pages/Pages')), + load: loadPagesPage, }, { path: '/search', @@ -39,6 +41,10 @@ const ROUTES: RouteDefinition[] = [ }, ], }, + { + path: '/_debug', + component: lazy(() => import('~/pages/Debug')), + }, { path: '/', component: lazy(() => import('~/pages/Home')), diff --git a/src/data/pages.data.ts b/src/data/pages.data.ts new file mode 100644 index 0000000..5da9fb7 --- /dev/null +++ b/src/data/pages.data.ts @@ -0,0 +1,39 @@ +import { gql, request } from '@solid-primitives/graphql' +import { cache, redirect, RouteLoadFunc } from '@solidjs/router' +import { GRAPHQL_BACKEND_URL } from '~/constants' +import { Page } from '~/models/page' + +const QUERY = gql` + query Page($slug: String!) { + page(slug: $slug) { + id + template + name + title + content + extras + } + } +` + +export const queryPageByID = cache(async (slug: string): Promise => { + type Response = { + page: Page + } + + const response = await request(GRAPHQL_BACKEND_URL, QUERY, { + variables: { + slug, + }, + }) + + if (response.page === null) { + throw redirect('/404') + } + + return response.page +}, 'Pages.queryPageByID') + +export const loadPagesPage: RouteLoadFunc = ({ params }) => { + void queryPageByID(params.slug) +} diff --git a/src/models/page.ts b/src/models/page.ts new file mode 100644 index 0000000..d63f07e --- /dev/null +++ b/src/models/page.ts @@ -0,0 +1,14 @@ +export enum PageTemplate { + SERVICES = 'services', +} + +export type Page = { + id: number + template: PageTemplate + name: string + title: string + content: string + extras: { + [attr: string]: any + } +} diff --git a/src/pages/Pages.module.scss b/src/pages/Pages.module.scss new file mode 100644 index 0000000..6678cf6 --- /dev/null +++ b/src/pages/Pages.module.scss @@ -0,0 +1,5 @@ +.container { + max-width: var(--content-page-width-wide); + padding-inline: var(--page-padding); + margin-inline: auto; +} diff --git a/src/pages/Pages.tsx b/src/pages/Pages.tsx new file mode 100644 index 0000000..1febe6e --- /dev/null +++ b/src/pages/Pages.tsx @@ -0,0 +1,25 @@ +import { Meta, Title } from '@solidjs/meta' +import { createAsync, RouteSectionProps } from '@solidjs/router' +import { Component, Show } from 'solid-js' +import PageRenderer from '~/components/PageRenderer' +import { queryPageByID } from '~/data/pages.data' +import styles from './Pages.module.scss' + +const PagesPage: Component = ({ params }) => { + const data = createAsync(() => queryPageByID(params.slug), { + deferStream: true, + }) + + return ( + + + <Meta property="og:title" content={data()!.title} /> + + <div class={styles.container}> + <PageRenderer title={data()!.title} content={data()!.content} /> + </div> + </Show> + ) +} + +export default PagesPage