[...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 }