Skip to content

Commit

Permalink
Merge pull request #7 from Team-INSERT/refactor/api
Browse files Browse the repository at this point in the history
Refactor/api
  • Loading branch information
Ubinquitous authored Apr 12, 2023
2 parents 6d5f123 + 1a03a39 commit a8b140c
Show file tree
Hide file tree
Showing 34 changed files with 338 additions and 252 deletions.
30 changes: 19 additions & 11 deletions components/Aside/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import * as S from './style'
import * as FC from '@/utils'
import * as utils from '@/utils'

import React from 'react'
import PrevLogo from 'assets/prev.svg'
import NextLogo from 'assets/next.svg'
import httpClient from '@/lib/httpClient'
import Docs from '@/types/docs.type'
import { useQuery } from 'react-query'
import { getAccessToken } from '@/lib/httpClient/getAccessToken'
import queryKey from '@/constants/queryKey.constants'

const Aside = () => {
const [page, setPage] = React.useState(0)
const [lastModifiedDocs, setLastModifiedDocs] = React.useState<Docs[]>([])

const onGetLastModifiedDocs = async () => {
return (await httpClient.lastModified.getInQuery('page', page)).data
}

const { refetch } = useQuery([queryKey.getLastModify], onGetLastModifiedDocs, {
onSuccess: (data) => {
setLastModifiedDocs(data)
},
onError: () => getAccessToken(),
})

React.useEffect(() => {
;(async () => {
try {
setLastModifiedDocs((await httpClient.lastModified.getInQuery('page', page)).data)
} catch (err) {
console.log(err)
}
})()
}, [page])
refetch()
}, [page, refetch])

return (
<S.AsideWrap>
Expand All @@ -28,8 +36,8 @@ const Aside = () => {
</S.AsideTitleWrap>
{lastModifiedDocs.map((docs: Docs) => (
<S.AsideDocWrap key={docs.id}>
<S.AsideList href={`/docs/${docs.title}`}>{FC.asideFormat(docs.title, docs.docsType)}</S.AsideList>
<S.AsideLastModified>&nbsp; {FC.getLastDate(docs.lastModifiedAt)}</S.AsideLastModified>
<S.AsideList href={`/docs/${docs.title}`}>{utils.asideFormat(docs.title, docs.docsType)}</S.AsideList>
<S.AsideLastModified>&nbsp; {utils.getLastDate(docs.lastModifiedAt)}</S.AsideLastModified>
</S.AsideDocWrap>
))}
<S.AsidePageWrap>
Expand Down
20 changes: 4 additions & 16 deletions components/Button/Authority/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import * as S from './style'

import React from 'react'
import { useMutation } from 'react-query'
import httpClient from '@/lib/httpClient'
import Swal from 'sweetalert2'
import authority from '@/constants/authority.constants'
import useAuthorityMutation from '@/features/AuthorityFeature'

interface AuthorityProps {
interface AuthorityPropsType {
email: string
}

interface AuthorityApiProps extends AuthorityProps {
authority: string
}

const Authority = ({ email }: AuthorityProps) => {
const { mutate } = useMutation(({ email, authority }: AuthorityApiProps) => httpClient.authority.put({ email, authority }), {
onSuccess: () =>
Swal.fire({
icon: 'success',
title: '유저 권한이 변경되었습니다!',
}),
})
const Authority = ({ email }: AuthorityPropsType) => {
const { mutate } = useAuthorityMutation()

const onClickAuthorityUser = (authority: string) => {
if (window.confirm(`유저 권한을 ${authority}(으)로 변경하시겠습니까?`)) return mutate({ email, authority })
Expand Down
112 changes: 33 additions & 79 deletions components/Button/Detail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,101 +1,55 @@
import * as S from './style'

import React from 'react'
import userState from '@/context/userState'
import { useMutation, useQueryClient } from 'react-query'
import { useRecoilValue } from 'recoil'
import { useRouter } from 'next/router'
import httpClient from '@/lib/httpClient'
import { Storage } from '@/lib/storage'
import { CustomToastContainer } from '@/layout/HomeLayout.style'
import { toast } from 'react-toastify'
import Swal from 'sweetalert2'
import authority from '@/constants/authority.constants'
import useUpdateTitleMutation from '@/features/UpdateTitleFeature'
import useUpdateTypeMutation from '@/features/UpdateTypeFeature'
import useUser from '@/hooks/useUser'
import useDeleteDocsMutation from '@/features/DeleteDocsFeature'
import Swal from 'sweetalert2'

interface DetailBtnProps {
docsId: number
}

const DetailBtn = ({ docsId }: DetailBtnProps) => {
const router = useRouter()
const user = useRecoilValue(userState)
const { user, isLogined } = useUser()
const [docsName, setDocsName] = React.useState('')
const [docsType, setDocsType] = React.useState('')
const queryClient = useQueryClient()

const updateDocsTitleMutation = useMutation(() => httpClient.updateTitle.putByTitle(router.pathname, docsName), {
onSuccess: (res) => {
Swal.fire({
icon: 'success',
title: '문서 이름 변경 완료!',
})
queryClient.invalidateQueries('lastModifiedDocs')
router.push(`/docs/${res.data.title}`)
},
})

const onUpdateType = async () => {
return (
await httpClient.updateType.put(
{ id: docsId, docsType },
{
headers: {
Authorization: Storage.getItem('access_token'),
},
}
)
).data
}

const updateDocsTypeMutation = useMutation(onUpdateType, {
onSuccess: (res) => {
Swal.fire({
icon: 'success',
title: '문서 타입 변경 완료!',
})
queryClient.invalidateQueries('lastModifiedDocs')
router.push(`/docs/${res.data.title}`)
},
})

const onClickNavigatePage = (type: string) => {
if (type === 'VERSION') return router.push(`/version/${router.query.title}`)
if (type === 'UPDATE' && !user.id) return alert('로그인 후 편집하실 수 있습니다!')
router.push(`/update/${router.query.title}`)
}
const updateTitle = useUpdateTitleMutation(docsName)
const updateType = useUpdateTypeMutation(docsId, docsType)
const deleteDocs = useDeleteDocsMutation(docsId)

const onDeleteDocsTitle = async () => {
return (
await httpClient.deleteDocs.deleteById(docsId, {
headers: {
Authorization: Storage.getItem('access_token'),
},
})
).data
const onChangeTitle = async () => {
if (!docsName) return toast.error('내용이 없습니다.')
updateTitle.mutate()
}

const deleteDocsTitleMutation = useMutation(onDeleteDocsTitle, {
onSuccess: () => {
Swal.fire({
icon: 'success',
title: '문서 삭제 완료!',
})
router.push('/')
},
})

const onClickChangeDocsName = async () => {
if (!docsName.length) return toast.error('내용이 없습니다.')
updateDocsTitleMutation.mutate()
const onChangeType = async () => {
if (!docsType) return toast.error('내용이 없습니다.')
updateType.mutate()
}

const onClickChangeDocsType = async () => {
if (!docsType.length) return toast.error('내용이 없습니다.')
updateDocsTypeMutation.mutate()
const onDeleteDocs = () => {
Swal.fire({
title: '문서를 정말 삭제하시겠습니까?',
showDenyButton: true,
confirmButtonText: '네',
denyButtonText: '아니오',
}).then((result) => {
if (result.isConfirmed) deleteDocs.mutate()
})
}

const onClickDeleteDocs = () => {
if (window.confirm('정말 삭제하시겠습니까?')) deleteDocsTitleMutation.mutate()
const onNavigatePage = (type: string) => {
if (type === 'VERSION') return router.push(`/version/${router.query.title}`)
if (type === 'UPDATE' && !isLogined) return alert('로그인 후 편집하실 수 있습니다!')
router.push(`/update/${router.query.title}`)
}

return (
Expand All @@ -104,18 +58,18 @@ const DetailBtn = ({ docsId }: DetailBtnProps) => {
{user.authority === authority.ADMIN ? (
<>
<S.DetailInput value={docsType} onChange={(e) => setDocsType(e.target.value)} />
<S.DetailWrap onClick={onClickChangeDocsType}>
<S.DetailWrap onClick={onChangeType}>
<S.DetailButton>
<S.DetailText>타입변경</S.DetailText>
</S.DetailButton>
</S.DetailWrap>
<S.DetailWrap onClick={onClickDeleteDocs}>
<S.DetailWrap onClick={onDeleteDocs}>
<S.DetailButton>
<S.DetailText>삭제</S.DetailText>
</S.DetailButton>
</S.DetailWrap>
<S.DetailInput value={docsName} onChange={(e) => setDocsName(e.target.value)} />
<S.DetailWrap onClick={onClickChangeDocsName}>
<S.DetailWrap onClick={onChangeTitle}>
<S.DetailButton>
<S.DetailText>변경</S.DetailText>
</S.DetailButton>
Expand All @@ -124,12 +78,12 @@ const DetailBtn = ({ docsId }: DetailBtnProps) => {
) : (
''
)}
<S.DetailLinkWrap onClick={() => onClickNavigatePage('UPDATE')}>
<S.DetailLinkWrap onClick={() => onNavigatePage('UPDATE')}>
<S.DetailButton>
<S.DetailText>편집</S.DetailText>
</S.DetailButton>
</S.DetailLinkWrap>
<S.DetailLinkWrap onClick={() => onClickNavigatePage('VERSION')}>
<S.DetailLinkWrap onClick={() => onNavigatePage('VERSION')}>
<S.DetailButton>
<S.DetailText>기록</S.DetailText>
</S.DetailButton>
Expand Down
5 changes: 5 additions & 0 deletions constants/queryKey.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const queryKey = {
getLastModify: 'getLastModify',
}

export default queryKey
24 changes: 24 additions & 0 deletions features/AuthorityFeature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import httpClient from '@/lib/httpClient'
import { useMutation } from 'react-query'
import Swal from 'sweetalert2'

interface AuthorityApiProps {
email: string
authority: string
}

const onAuthority = async ({ email, authority }: AuthorityApiProps) => {
return (await httpClient.authority.put({ email, authority })).data
}

const useAuthorityMutation = () => {
return useMutation(onAuthority, {
onSuccess: () =>
Swal.fire({
icon: 'success',
title: '유저 권한이 변경되었습니다!',
}),
})
}

export default useAuthorityMutation
47 changes: 47 additions & 0 deletions features/CreateDocsFeature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { IFileTypes } from '@/components/DragDrop'
import httpClient from '@/lib/httpClient'
import { encodeContents } from '@/utils/document/requestContents'
import { useRouter } from 'next/router'
import { useMutation } from 'react-query'
import Swal from 'sweetalert2'

interface CreateDocsFormType {
title: string
enroll: number
contents: string
docsType: string
files: IFileTypes[]
}

const createDocsForm = ({ title, enroll, contents, docsType, files }: CreateDocsFormType) => {
const data = new FormData()
data.append(
'request',
new Blob([`{ "title": "${title}", "enroll":"${enroll}", "contents":"${encodeContents(contents)}", "docsType":"${docsType}"}`], {
type: 'application/json',
})
)
files.reverse().forEach((file) => data.append('files', file.object, file.object.name))
return data
}

const onCreateDocs = async (data: CreateDocsFormType) => {
const formData = createDocsForm(data)
return (await httpClient.create.post(formData)).data
}

const useCreateDocsMutation = () => {
const router = useRouter()

return useMutation(onCreateDocs, {
onSuccess: (data) => {
Swal.fire({
icon: 'success',
title: '문서 생성 완료!',
})
router.push(`/docs/${data.title}`)
},
})
}

export default useCreateDocsMutation
20 changes: 20 additions & 0 deletions features/DeleteDocsFeature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import httpClient from '@/lib/httpClient'
import { useRouter } from 'next/router'
import { useMutation } from 'react-query'
import Swal from 'sweetalert2'

const useDeleteDocsMutation = (docsId: number) => {
const router = useRouter()

return useMutation(async () => (await httpClient.deleteDocs.deleteById(docsId, {})).data, {
onSuccess: () => {
Swal.fire({
icon: 'success',
title: '문서 삭제 완료!',
})
router.push('/')
},
})
}

export default useDeleteDocsMutation
31 changes: 31 additions & 0 deletions features/LoginFeature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import httpClient from '@/lib/httpClient'
import { Storage } from '@/lib/storage'
import { useRouter } from 'next/router'
import { useMutation, useQueryClient } from 'react-query'

const onLogin = async (authCode: string | string[] | undefined) => {
return (
await httpClient.oauth.post(null, {
headers: { authCode },
})
).data
}

const useLoginMutation = () => {
const router = useRouter()
const queryClient = useQueryClient()

return useMutation(() => onLogin(router.query.code), {
onSuccess: (data) => {
Storage.setItem('access_token', data.accessToken)
Storage.setItem('refresh_token', data.refreshToken)
queryClient.invalidateQueries('getUser')
router.back()
router.back()
// window.history.go(-2)
},
onError: () => window.history.go(-2),
})
}

export default useLoginMutation
Loading

0 comments on commit a8b140c

Please sign in to comment.