Skip to content

Commit a8b140c

Browse files
authored
Merge pull request #7 from Team-INSERT/refactor/api
Refactor/api
2 parents 6d5f123 + 1a03a39 commit a8b140c

34 files changed

+338
-252
lines changed

components/Aside/index.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
11
import * as S from './style'
2-
import * as FC from '@/utils'
2+
import * as utils from '@/utils'
33

44
import React from 'react'
55
import PrevLogo from 'assets/prev.svg'
66
import NextLogo from 'assets/next.svg'
77
import httpClient from '@/lib/httpClient'
88
import Docs from '@/types/docs.type'
9+
import { useQuery } from 'react-query'
10+
import { getAccessToken } from '@/lib/httpClient/getAccessToken'
11+
import queryKey from '@/constants/queryKey.constants'
912

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

17+
const onGetLastModifiedDocs = async () => {
18+
return (await httpClient.lastModified.getInQuery('page', page)).data
19+
}
20+
21+
const { refetch } = useQuery([queryKey.getLastModify], onGetLastModifiedDocs, {
22+
onSuccess: (data) => {
23+
setLastModifiedDocs(data)
24+
},
25+
onError: () => getAccessToken(),
26+
})
27+
1428
React.useEffect(() => {
15-
;(async () => {
16-
try {
17-
setLastModifiedDocs((await httpClient.lastModified.getInQuery('page', page)).data)
18-
} catch (err) {
19-
console.log(err)
20-
}
21-
})()
22-
}, [page])
29+
refetch()
30+
}, [page, refetch])
2331

2432
return (
2533
<S.AsideWrap>
@@ -28,8 +36,8 @@ const Aside = () => {
2836
</S.AsideTitleWrap>
2937
{lastModifiedDocs.map((docs: Docs) => (
3038
<S.AsideDocWrap key={docs.id}>
31-
<S.AsideList href={`/docs/${docs.title}`}>{FC.asideFormat(docs.title, docs.docsType)}</S.AsideList>
32-
<S.AsideLastModified>&nbsp; {FC.getLastDate(docs.lastModifiedAt)}</S.AsideLastModified>
39+
<S.AsideList href={`/docs/${docs.title}`}>{utils.asideFormat(docs.title, docs.docsType)}</S.AsideList>
40+
<S.AsideLastModified>&nbsp; {utils.getLastDate(docs.lastModifiedAt)}</S.AsideLastModified>
3341
</S.AsideDocWrap>
3442
))}
3543
<S.AsidePageWrap>

components/Button/Authority/index.tsx

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,15 @@
11
import * as S from './style'
22

33
import React from 'react'
4-
import { useMutation } from 'react-query'
5-
import httpClient from '@/lib/httpClient'
6-
import Swal from 'sweetalert2'
74
import authority from '@/constants/authority.constants'
5+
import useAuthorityMutation from '@/features/AuthorityFeature'
86

9-
interface AuthorityProps {
7+
interface AuthorityPropsType {
108
email: string
119
}
1210

13-
interface AuthorityApiProps extends AuthorityProps {
14-
authority: string
15-
}
16-
17-
const Authority = ({ email }: AuthorityProps) => {
18-
const { mutate } = useMutation(({ email, authority }: AuthorityApiProps) => httpClient.authority.put({ email, authority }), {
19-
onSuccess: () =>
20-
Swal.fire({
21-
icon: 'success',
22-
title: '유저 권한이 변경되었습니다!',
23-
}),
24-
})
11+
const Authority = ({ email }: AuthorityPropsType) => {
12+
const { mutate } = useAuthorityMutation()
2513

2614
const onClickAuthorityUser = (authority: string) => {
2715
if (window.confirm(`유저 권한을 ${authority}(으)로 변경하시겠습니까?`)) return mutate({ email, authority })

components/Button/Detail/index.tsx

Lines changed: 33 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,55 @@
11
import * as S from './style'
22

33
import React from 'react'
4-
import userState from '@/context/userState'
5-
import { useMutation, useQueryClient } from 'react-query'
6-
import { useRecoilValue } from 'recoil'
74
import { useRouter } from 'next/router'
8-
import httpClient from '@/lib/httpClient'
9-
import { Storage } from '@/lib/storage'
105
import { CustomToastContainer } from '@/layout/HomeLayout.style'
116
import { toast } from 'react-toastify'
12-
import Swal from 'sweetalert2'
137
import authority from '@/constants/authority.constants'
8+
import useUpdateTitleMutation from '@/features/UpdateTitleFeature'
9+
import useUpdateTypeMutation from '@/features/UpdateTypeFeature'
10+
import useUser from '@/hooks/useUser'
11+
import useDeleteDocsMutation from '@/features/DeleteDocsFeature'
12+
import Swal from 'sweetalert2'
1413

1514
interface DetailBtnProps {
1615
docsId: number
1716
}
1817

1918
const DetailBtn = ({ docsId }: DetailBtnProps) => {
2019
const router = useRouter()
21-
const user = useRecoilValue(userState)
20+
const { user, isLogined } = useUser()
2221
const [docsName, setDocsName] = React.useState('')
2322
const [docsType, setDocsType] = React.useState('')
24-
const queryClient = useQueryClient()
25-
26-
const updateDocsTitleMutation = useMutation(() => httpClient.updateTitle.putByTitle(router.pathname, docsName), {
27-
onSuccess: (res) => {
28-
Swal.fire({
29-
icon: 'success',
30-
title: '문서 이름 변경 완료!',
31-
})
32-
queryClient.invalidateQueries('lastModifiedDocs')
33-
router.push(`/docs/${res.data.title}`)
34-
},
35-
})
36-
37-
const onUpdateType = async () => {
38-
return (
39-
await httpClient.updateType.put(
40-
{ id: docsId, docsType },
41-
{
42-
headers: {
43-
Authorization: Storage.getItem('access_token'),
44-
},
45-
}
46-
)
47-
).data
48-
}
49-
50-
const updateDocsTypeMutation = useMutation(onUpdateType, {
51-
onSuccess: (res) => {
52-
Swal.fire({
53-
icon: 'success',
54-
title: '문서 타입 변경 완료!',
55-
})
56-
queryClient.invalidateQueries('lastModifiedDocs')
57-
router.push(`/docs/${res.data.title}`)
58-
},
59-
})
6023

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

67-
const onDeleteDocsTitle = async () => {
68-
return (
69-
await httpClient.deleteDocs.deleteById(docsId, {
70-
headers: {
71-
Authorization: Storage.getItem('access_token'),
72-
},
73-
})
74-
).data
28+
const onChangeTitle = async () => {
29+
if (!docsName) return toast.error('내용이 없습니다.')
30+
updateTitle.mutate()
7531
}
7632

77-
const deleteDocsTitleMutation = useMutation(onDeleteDocsTitle, {
78-
onSuccess: () => {
79-
Swal.fire({
80-
icon: 'success',
81-
title: '문서 삭제 완료!',
82-
})
83-
router.push('/')
84-
},
85-
})
86-
87-
const onClickChangeDocsName = async () => {
88-
if (!docsName.length) return toast.error('내용이 없습니다.')
89-
updateDocsTitleMutation.mutate()
33+
const onChangeType = async () => {
34+
if (!docsType) return toast.error('내용이 없습니다.')
35+
updateType.mutate()
9036
}
9137

92-
const onClickChangeDocsType = async () => {
93-
if (!docsType.length) return toast.error('내용이 없습니다.')
94-
updateDocsTypeMutation.mutate()
38+
const onDeleteDocs = () => {
39+
Swal.fire({
40+
title: '문서를 정말 삭제하시겠습니까?',
41+
showDenyButton: true,
42+
confirmButtonText: '네',
43+
denyButtonText: '아니오',
44+
}).then((result) => {
45+
if (result.isConfirmed) deleteDocs.mutate()
46+
})
9547
}
9648

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

10155
return (
@@ -104,18 +58,18 @@ const DetailBtn = ({ docsId }: DetailBtnProps) => {
10458
{user.authority === authority.ADMIN ? (
10559
<>
10660
<S.DetailInput value={docsType} onChange={(e) => setDocsType(e.target.value)} />
107-
<S.DetailWrap onClick={onClickChangeDocsType}>
61+
<S.DetailWrap onClick={onChangeType}>
10862
<S.DetailButton>
10963
<S.DetailText>타입변경</S.DetailText>
11064
</S.DetailButton>
11165
</S.DetailWrap>
112-
<S.DetailWrap onClick={onClickDeleteDocs}>
66+
<S.DetailWrap onClick={onDeleteDocs}>
11367
<S.DetailButton>
11468
<S.DetailText>삭제</S.DetailText>
11569
</S.DetailButton>
11670
</S.DetailWrap>
11771
<S.DetailInput value={docsName} onChange={(e) => setDocsName(e.target.value)} />
118-
<S.DetailWrap onClick={onClickChangeDocsName}>
72+
<S.DetailWrap onClick={onChangeTitle}>
11973
<S.DetailButton>
12074
<S.DetailText>변경</S.DetailText>
12175
</S.DetailButton>
@@ -124,12 +78,12 @@ const DetailBtn = ({ docsId }: DetailBtnProps) => {
12478
) : (
12579
''
12680
)}
127-
<S.DetailLinkWrap onClick={() => onClickNavigatePage('UPDATE')}>
81+
<S.DetailLinkWrap onClick={() => onNavigatePage('UPDATE')}>
12882
<S.DetailButton>
12983
<S.DetailText>편집</S.DetailText>
13084
</S.DetailButton>
13185
</S.DetailLinkWrap>
132-
<S.DetailLinkWrap onClick={() => onClickNavigatePage('VERSION')}>
86+
<S.DetailLinkWrap onClick={() => onNavigatePage('VERSION')}>
13387
<S.DetailButton>
13488
<S.DetailText>기록</S.DetailText>
13589
</S.DetailButton>

constants/queryKey.constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const queryKey = {
2+
getLastModify: 'getLastModify',
3+
}
4+
5+
export default queryKey

features/AuthorityFeature.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import httpClient from '@/lib/httpClient'
2+
import { useMutation } from 'react-query'
3+
import Swal from 'sweetalert2'
4+
5+
interface AuthorityApiProps {
6+
email: string
7+
authority: string
8+
}
9+
10+
const onAuthority = async ({ email, authority }: AuthorityApiProps) => {
11+
return (await httpClient.authority.put({ email, authority })).data
12+
}
13+
14+
const useAuthorityMutation = () => {
15+
return useMutation(onAuthority, {
16+
onSuccess: () =>
17+
Swal.fire({
18+
icon: 'success',
19+
title: '유저 권한이 변경되었습니다!',
20+
}),
21+
})
22+
}
23+
24+
export default useAuthorityMutation

features/CreateDocsFeature.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { IFileTypes } from '@/components/DragDrop'
2+
import httpClient from '@/lib/httpClient'
3+
import { encodeContents } from '@/utils/document/requestContents'
4+
import { useRouter } from 'next/router'
5+
import { useMutation } from 'react-query'
6+
import Swal from 'sweetalert2'
7+
8+
interface CreateDocsFormType {
9+
title: string
10+
enroll: number
11+
contents: string
12+
docsType: string
13+
files: IFileTypes[]
14+
}
15+
16+
const createDocsForm = ({ title, enroll, contents, docsType, files }: CreateDocsFormType) => {
17+
const data = new FormData()
18+
data.append(
19+
'request',
20+
new Blob([`{ "title": "${title}", "enroll":"${enroll}", "contents":"${encodeContents(contents)}", "docsType":"${docsType}"}`], {
21+
type: 'application/json',
22+
})
23+
)
24+
files.reverse().forEach((file) => data.append('files', file.object, file.object.name))
25+
return data
26+
}
27+
28+
const onCreateDocs = async (data: CreateDocsFormType) => {
29+
const formData = createDocsForm(data)
30+
return (await httpClient.create.post(formData)).data
31+
}
32+
33+
const useCreateDocsMutation = () => {
34+
const router = useRouter()
35+
36+
return useMutation(onCreateDocs, {
37+
onSuccess: (data) => {
38+
Swal.fire({
39+
icon: 'success',
40+
title: '문서 생성 완료!',
41+
})
42+
router.push(`/docs/${data.title}`)
43+
},
44+
})
45+
}
46+
47+
export default useCreateDocsMutation

features/DeleteDocsFeature.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import httpClient from '@/lib/httpClient'
2+
import { useRouter } from 'next/router'
3+
import { useMutation } from 'react-query'
4+
import Swal from 'sweetalert2'
5+
6+
const useDeleteDocsMutation = (docsId: number) => {
7+
const router = useRouter()
8+
9+
return useMutation(async () => (await httpClient.deleteDocs.deleteById(docsId, {})).data, {
10+
onSuccess: () => {
11+
Swal.fire({
12+
icon: 'success',
13+
title: '문서 삭제 완료!',
14+
})
15+
router.push('/')
16+
},
17+
})
18+
}
19+
20+
export default useDeleteDocsMutation

features/LoginFeature.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import httpClient from '@/lib/httpClient'
2+
import { Storage } from '@/lib/storage'
3+
import { useRouter } from 'next/router'
4+
import { useMutation, useQueryClient } from 'react-query'
5+
6+
const onLogin = async (authCode: string | string[] | undefined) => {
7+
return (
8+
await httpClient.oauth.post(null, {
9+
headers: { authCode },
10+
})
11+
).data
12+
}
13+
14+
const useLoginMutation = () => {
15+
const router = useRouter()
16+
const queryClient = useQueryClient()
17+
18+
return useMutation(() => onLogin(router.query.code), {
19+
onSuccess: (data) => {
20+
Storage.setItem('access_token', data.accessToken)
21+
Storage.setItem('refresh_token', data.refreshToken)
22+
queryClient.invalidateQueries('getUser')
23+
router.back()
24+
router.back()
25+
// window.history.go(-2)
26+
},
27+
onError: () => window.history.go(-2),
28+
})
29+
}
30+
31+
export default useLoginMutation

0 commit comments

Comments
 (0)