dh_demo

DreamHanks demo project
git clone git://git.lair.cx/dh_demo
Log | Files | Refs | README

[...path].tsx (4424B)


      1 import { SubmitButton } from '@/components/elements/Button'
      2 import Field from '@/components/form/Field'
      3 import Fields from '@/components/form/Fields'
      4 import Form from '@/components/form/Form'
      5 import Section from '@/components/layout/Section'
      6 import WikiArticle from '@/components/wiki/WikiArticle'
      7 import WikiBase from '@/components/wiki/WikiBase'
      8 import { useForm } from '@/lib/hooks/use_form'
      9 import { withConnection } from '@/lib/model_helpers'
     10 import { getWikiViaSlug, WikiInfo } from '@/lib/models/wiki_info'
     11 import { getWikiPage, WikiPage } from '@/lib/models/wiki_page'
     12 import { resolveACL } from '@/lib/security/acl'
     13 import { authenticationFromCookies } from '@/lib/security/token'
     14 import { getSlugAndPath } from '@/lib/utils/wiki'
     15 import { GetServerSideProps } from 'next'
     16 
     17 export interface WikiManagePageProps {
     18   wiki?: WikiInfo
     19   page?: WikiPage
     20 }
     21 
     22 export const getServerSideProps: GetServerSideProps<WikiManagePageProps> = async (context) => {
     23   const [slug, path] = getSlugAndPath(context)
     24   if (slug == null || path == null) {
     25     return { notFound: true }
     26   }
     27 
     28   const token = await authenticationFromCookies(context.req.cookies)
     29 
     30   return await withConnection(async (conn) => {
     31     const wiki = await getWikiViaSlug(conn, [slug])
     32     if (wiki == null) {
     33       return { notFound: true }
     34     }
     35 
     36     if (token == null || !resolveACL(token, wiki.acl, 'manage')) {
     37       return {
     38         redirect: {
     39           destination: `/users/login?redirect_to=${context.resolvedUrl}`,
     40         },
     41         props: {},
     42       }
     43     }
     44 
     45     const page = await getWikiPage(conn, [wiki.id, path])
     46     if (page == null) {
     47       return {
     48         notFound: true,
     49       }
     50     }
     51 
     52     return {
     53       props: {
     54         wiki: wiki,
     55         page: page,
     56       },
     57     }
     58   })
     59 }
     60 
     61 export default function WikiManagePage (props: WikiManagePageProps) {
     62   const [wikiFields, updateWikiFields, submitWiki, isWikiLoading, wikiResult, wikiError] = useForm(
     63     { method: 'PATCH', url: `/api/wiki/${props.wiki?.slug}` },
     64     {
     65       title: props.wiki?.title,
     66       description: props.wiki?.description,
     67       acl: props.wiki?.acl == null ? '{}' : JSON.stringify(props.wiki.acl, null, 2),
     68     },
     69   )
     70 
     71   const [pageFields, updatePageFields, submitPage, isPageLoading, pageResult, pageError] = useForm(
     72     { method: 'PUT', url: `/api/wiki/${props.wiki?.slug}/${props.page?.path}` },
     73     {
     74       acl: props.page?.acl == null ? '{}' : JSON.stringify(props.page.acl, null, 2),
     75     },
     76   )
     77 
     78   return (
     79     <WikiBase
     80       pageKind={'manage'}
     81       title={(
     82         <>관리: {props.wiki?.title}/{props.page?.path}</>
     83       )}
     84     >
     85       <Section>
     86         <WikiArticle>
     87           <h2>{props.wiki?.title}</h2>
     88 
     89           <Form onSubmit={submitWiki}>
     90             <Fields>
     91               <Field
     92                 type="text"
     93                 placeholder="제목"
     94                 value={wikiFields.title}
     95                 onValueChange={updateWikiFields.bind(null, 'title')}
     96                 disabled={isWikiLoading}
     97               />
     98               <Field
     99                 type="text"
    100                 placeholder="짧은 설명"
    101                 value={wikiFields.description}
    102                 onValueChange={updateWikiFields.bind(null, 'description')}
    103                 disabled={isWikiLoading}
    104               />
    105               <Field
    106                 type="textarea"
    107                 placeholder="ACL"
    108                 value={wikiFields.acl}
    109                 onValueChange={updateWikiFields.bind(null, 'acl')}
    110                 disabled={isWikiLoading}
    111               />
    112               <SubmitButton
    113                 value="저장"
    114                 disabled={isWikiLoading}
    115               />
    116             </Fields>
    117           </Form>
    118         </WikiArticle>
    119       </Section>
    120 
    121       <Section>
    122         <WikiArticle>
    123           <h2>{props.page?.path}</h2>
    124           <Form onSubmit={submitPage}>
    125             <Fields>
    126               <Field
    127                 type="textarea"
    128                 placeholder="ACL"
    129                 value={pageFields.acl}
    130                 onValueChange={updatePageFields.bind(null, 'acl')}
    131                 disabled={isPageLoading}
    132                 color={pageError != null ? 'error' : undefined}
    133                 message={pageError?.message}
    134               />
    135               <SubmitButton
    136                 value="저장"
    137                 disabled={isPageLoading}
    138               />
    139             </Fields>
    140           </Form>
    141         </WikiArticle>
    142       </Section>
    143     </WikiBase>
    144   )
    145 }