Skip to content

Commit

Permalink
Static sites routing and markdown (#35)
Browse files Browse the repository at this point in the history
* Upgrade next to v12, fix node-sass by replacing with sass (#34)

* `yarn remove node-sass`

* `yarn add -D sass`

* `yarn add next`

* add autogenerated types

* add NEXT_PUBLIC_BE_URL build-time env var

* `yarn add react-markdown`

* added Markdown and Text components

* remove old static sites (gdpr, minisustredenia) - content of these will be fetched from BE

* "static" sites handling - flatpage info (title and content) fetched server-side from BE and then rendered

* fix `getSeminarName` in `SitesArrayField`
  • Loading branch information
rtrembecky authored Mar 14, 2022
1 parent e114ad6 commit 6cb66c9
Show file tree
Hide file tree
Showing 18 changed files with 655 additions and 68 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NEXT_PUBLIC_BE_URL=http://localhost:8000
10 changes: 5 additions & 5 deletions next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = {
// rewrite API requestov na django BE (podstatne aj koncove lomitko)
{
source: '/api/:path*',
destination: 'http://localhost:8000/:path*/',
destination: `${process.env.NEXT_PUBLIC_BE_URL}/:path*/`,
},
]
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"react-dom": "^17.0.2",
"react-hook-form": "^6.12.1",
"react-icons": "^3.11.0",
"react-markdown": "^8.0.0",
"typescript": "^4.3.4"
},
"scripts": {
Expand Down
4 changes: 3 additions & 1 deletion src/components/Admin/custom/SitesArrayField.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {FC} from 'react'
import {FieldProps} from 'react-admin'

import {getSeminarName} from '@/components/PageLayout/MenuMain/MenuMain'
import {seminarIdToName} from '@/utils/useSeminarInfo'

import {MyArrayField} from './MyArrayField'

const getSeminarName = (seminarId: number) => seminarIdToName[seminarId]

export const SitesArrayField: FC<FieldProps> = (props) => <MyArrayField {...props} formatNumber={getSeminarName} />
23 changes: 23 additions & 0 deletions src/components/StaticSites/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {FC} from 'react'
import ReactMarkdown from 'react-markdown'

import {H1, H2, H3, H4, H5, H6} from './Texts'

type MarkdownProps = {
content: string
}

export const Markdown: FC<MarkdownProps> = ({content}) => (
<ReactMarkdown
components={{
h1: H1,
h2: H2,
h3: H3,
h4: H4,
h5: H5,
h6: H6,
}}
>
{content}
</ReactMarkdown>
)
3 changes: 3 additions & 0 deletions src/components/StaticSites/Texts.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.h1 {
color: brown;
}
10 changes: 10 additions & 0 deletions src/components/StaticSites/Texts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {FC} from 'react'

import styles from './Texts.module.css'

export const H1: FC = ({children}) => <h1 className={styles.h1}>{children}</h1>
export const H2: FC = ({children}) => <h2 className={styles.h2}>{children}</h2>
export const H3: FC = ({children}) => <h3 className={styles.h3}>{children}</h3>
export const H4: FC = ({children}) => <h4 className={styles.h4}>{children}</h4>
export const H5: FC = ({children}) => <h5 className={styles.h5}>{children}</h5>
export const H6: FC = ({children}) => <h6 className={styles.h6}>{children}</h6>
5 changes: 5 additions & 0 deletions src/pages/malynar/[page].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import StromStaticPage, {seminarBasedGetServerSideProps} from '../strom/[page]'

export default StromStaticPage

export const getServerSideProps = seminarBasedGetServerSideProps('malynar')
12 changes: 0 additions & 12 deletions src/pages/malynar/gdpr.tsx

This file was deleted.

12 changes: 0 additions & 12 deletions src/pages/malynar/minisustredenia.tsx

This file was deleted.

5 changes: 5 additions & 0 deletions src/pages/matik/[page].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import StromStaticPage, {seminarBasedGetServerSideProps} from '../strom/[page]'

export default StromStaticPage

export const getServerSideProps = seminarBasedGetServerSideProps('matik')
12 changes: 0 additions & 12 deletions src/pages/matik/gdpr.tsx

This file was deleted.

12 changes: 0 additions & 12 deletions src/pages/matik/minisustredenia.tsx

This file was deleted.

46 changes: 46 additions & 0 deletions src/pages/strom/[page].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import axios from 'axios'
import {GetServerSideProps, NextPage} from 'next'

import {PageLayout} from '@/components/PageLayout/PageLayout'
import {Markdown} from '@/components/StaticSites/Markdown'
import {FlatPage} from '@/types/api/generated/base'
import {Seminar} from '@/utils/useSeminarInfo'

type StaticPageProps = {
title: string
content: string
}

const StaticPage: NextPage<StaticPageProps> = ({title, content}) => (
<PageLayout title={title}>
<Markdown content={content} />
</PageLayout>
)

export default StaticPage

// wrapper aby sme to lahko vyuzili pre ostatne seminare a neduplikovali kod
export const seminarBasedGetServerSideProps = (seminar: Seminar): GetServerSideProps<StaticPageProps> => async ({
query,
}) => {
// `page` vychadza z nazvu suboru `[page]`
// tento check je hlavne pre typescript - parameter `page` by vzdy mal existovat a vzdy ako string
if (query?.page && typeof query.page === 'string') {
const requestedUrl = query.page
const {data} = await axios.get<FlatPage | undefined>(
`${process.env.NEXT_PUBLIC_BE_URL}/base/flat-page/by-url/${requestedUrl}/`,
)
// ked stranka neexistuje, vrati sa `content: ""`. teraz renderujeme stranku len ked je content neprazdny a server rovno vrati redirect.
// druha moznost by bola nechat prazdny content handlovat clienta - napriklad zobrazit custom error, ale nechat usera na neplatnej stranke.
// tretia moznost je miesto redirectu vratit nextovsku 404
if (data?.content) {
return {
props: {content: data.content, title: data.title},
}
}
}

return {redirect: {destination: `/${seminar}`, permanent: false}}
}

export const getServerSideProps = seminarBasedGetServerSideProps('strom')
12 changes: 0 additions & 12 deletions src/pages/strom/gdpr.tsx

This file was deleted.

9 changes: 8 additions & 1 deletion src/utils/useSeminarInfo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useRouter} from 'next/router'

type Seminar = 'strom' | 'matik' | 'malynar'
export type Seminar = 'strom' | 'matik' | 'malynar'
type SeminarId = 0 | 1 | 2

const seminarToId: Record<Seminar, SeminarId> = {
Expand All @@ -18,3 +18,10 @@ export const useSeminarInfo = () => {

return {seminar, seminarId}
}

// for admin purposes we need backwards mapping from seminar ID to seminar name
// need to use `number` signature instead of `SeminarId`
export const seminarIdToName = Object.entries(seminarToId).reduce<Record<number, Seminar>>(
(acc, [seminar, seminarId]) => ((acc[seminarId] = seminar as Seminar), acc),
{},
)
Loading

0 comments on commit 6cb66c9

Please sign in to comment.