diff --git a/pages/[...slug].tsx b/pages/[...slug].tsx index 8a59c1ad..38a64cf1 100644 --- a/pages/[...slug].tsx +++ b/pages/[...slug].tsx @@ -6,7 +6,7 @@ import { Meta } from 'src/components/Meta' import { meta } from 'src/lib/meta' import { createApiUrl, requestGet, wrapInitialProps, IResponseItems } from 'src/next-lib' import { NextPage } from 'next' -import { IBreadcumbsPart, IMeta } from 'src/types' +import { IBreadcumbsPart, IMeta, IPage } from 'src/types' function array(value: T | T[]) { return Array.isArray(value) @@ -15,9 +15,10 @@ function array(value: T | T[]) { } type Props = { + page: any title: string content: string - breadcrumbs: IBreadcumbsPart[] + breadcrumb: IBreadcumbsPart[] meta: IMeta } @@ -27,7 +28,7 @@ const Index: NextPage = props => ( contentStyle={{ marginTop: 'var(--size-l)' }} - breadcrumbs={props.breadcrumbs} + breadcrumbs={props.breadcrumb} > {props.title} @@ -49,14 +50,17 @@ export const unstable_getStaticProps = async (ctx: any) => { } else { slug = '/' + array(ctx.params.slug).join('/') } - const page = await requestGet(createApiUrl(`/api/page?page=${slug}`), null) + const page = await requestGet(createApiUrl(`/api/page?page=${slug}`), null) if (!page) { throw new Error(`Not found: ${slug}`) } const image = page.preview ? page.preview.artifacts.fb : {} + const breadcrumbSize = page.breadcrumb?.length ?? 0 + const breadcrumb = breadcrumbSize < 2 ? null : page.breadcrumb return { props: { + page, content: page.data, title: page.title, meta: meta({ @@ -65,6 +69,7 @@ export const unstable_getStaticProps = async (ctx: any) => { imageWidth: image.width, imageHeight: image.height, }), + breadcrumb, } } } diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 77d26707..2ca49e69 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -8,6 +8,8 @@ import { Content } from '../Content' import { Block } from '../Block' import { Breadcrumbs } from '../Breadcrumbs' import { IBreadcumbsPart } from 'src/types' +import { useRouter } from 'next/router' +import { route } from 'next/dist/next-server/server/router' const Navigation = dynamic(() => import('../Navigation').then(mod => mod.Navigation), { ssr: false, @@ -21,6 +23,7 @@ export interface IAppProps { } export const App: React.FC = props => { + const router = useRouter() const wide = props.wide ?? false const blockStyle = { alignItems: 'center' @@ -36,7 +39,8 @@ export const App: React.FC = props => { diff --git a/src/components/Breadcrumbs/index.tsx b/src/components/Breadcrumbs/index.tsx index b701fb2e..ee5ba6a7 100644 --- a/src/components/Breadcrumbs/index.tsx +++ b/src/components/Breadcrumbs/index.tsx @@ -2,30 +2,41 @@ import './styles.css' import { IBreadcumbsPart } from 'src/types' import { Button } from '../Button' +import { insertBetween } from 'src/lib/array' export type BreadcrumbsProps = { style?: React.CSSProperties - path: IBreadcumbsPart[] + items: IBreadcumbsPart[] + path: string } export const Breadcrumbs: React.FC = props => { + const items = insertBetween(props.items, () => '/') + return ( + return ( +
  • + +
  • + ) + })} + ) } diff --git a/src/components/Breadcrumbs/styles.css b/src/components/Breadcrumbs/styles.css index 7b2c7130..054bd4d5 100644 --- a/src/components/Breadcrumbs/styles.css +++ b/src/components/Breadcrumbs/styles.css @@ -5,3 +5,9 @@ position: relative; right: var(--size-s); } + +.breadcrumbCurrent { + color: var(--color-text-second); + font-size: var(--font-size-second); + text-overflow: ellipsis; +} \ No newline at end of file diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 59b268cb..01b37473 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -8,13 +8,18 @@ export type ButtonProps = { href?: string theme?: 'default' | 'ghost' size?: 'default' | 'small' + disabled?: boolean } -export const Button: React.FC = ({ size='default', theme = 'default', ...props }) => { +export const Button: React.FC = ({ size = 'default', theme = 'default', disabled = false, ...props }) => { + const className = cx('button', theme, size, { + disabled + }) + if (props.href) { return ( - + {props.children} @@ -22,7 +27,7 @@ export const Button: React.FC = ({ size='default', theme = 'default } return ( - ) diff --git a/src/components/Button/styles.css b/src/components/Button/styles.css index 889be855..b6d3cb89 100644 --- a/src/components/Button/styles.css +++ b/src/components/Button/styles.css @@ -24,6 +24,13 @@ box-shadow: var(--shadow-active); } +/* MODIFICATORS */ + +.button.disabled { + pointer-events: none; + color: var(--color-text-second); +} + /* THEME */ .button.ghost { diff --git a/src/lib/array.js b/src/lib/array.js deleted file mode 100644 index fd794f61..00000000 --- a/src/lib/array.js +++ /dev/null @@ -1,26 +0,0 @@ -export function splitBy(fn) { - return items => { - return items.reduce((acc, item) => { - const key = fn(item) - const items = acc.get(key) || [] - - return acc.set(key, [...items, item]) - }, new Map()) - } -} - -export function head(list) { - return Array.isArray(list) && list.length - ? list[0] - : null -} - -export function last(list) { - return Array.isArray(list) && list.length - ? list[list.length - 1] - : null -} - -// exports.splitBy = splitBy -// exports.head = head -// exports.last = last diff --git a/src/lib/array.ts b/src/lib/array.ts new file mode 100644 index 00000000..e2b31612 --- /dev/null +++ b/src/lib/array.ts @@ -0,0 +1,22 @@ +export function splitBy(fn) { + return items => { + return items.reduce((acc, item) => { + const key = fn(item) + const items = acc.get(key) || [] + + return acc.set(key, [...items, item]) + }, new Map()) + } +} + +export function insertBetween(items: T[], fn: (i: number) => I): Array { + return items.reduce((acc, x, i) => { + acc.push(x) + + if (i < items.length - 1) { + acc.push(fn(i)) + } + + return acc + }, []) +} diff --git a/src/types.ts b/src/types.ts index 8a71138b..c64d9bcd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,6 +8,16 @@ export interface IBreadcumbsPart { href: string } +export interface IPage { + id: string + title: string + url: string + data: string + preview: any //IImage + tokens: any[] + breadcrumb?: IBreadcumbsPart[] +} + export interface IDocument { category: string fileName: string