diff --git a/apps/web/src/app/(afterLogin)/vocabulary/[id]/_component/term/Term.tsx b/apps/web/src/app/(afterLogin)/vocabulary/[id]/_component/term/Term.tsx
index 847290b..d4d89e3 100644
--- a/apps/web/src/app/(afterLogin)/vocabulary/[id]/_component/term/Term.tsx
+++ b/apps/web/src/app/(afterLogin)/vocabulary/[id]/_component/term/Term.tsx
@@ -1,6 +1,6 @@
'use client'
-import React, { useEffect, useState } from 'react'
+import React, { useEffect, useState, useCallback, useMemo } from 'react'
import { Checkbox, Dropbox, Icon, List, Text } from '@vook-client/design-system'
import {
TermSort,
@@ -12,11 +12,15 @@ import {
import { useQueryClient } from '@tanstack/react-query'
import { usePathname, useSearchParams } from 'next/navigation'
import clsx from 'clsx'
+import {
+ GetTermResponse,
+ TermSortValues,
+} from 'node_modules/@vook-client/api/src/services/term/model'
-import { useModal } from '@/hooks/useModal'
-import { ModalTypes } from '@/hooks/useModal/useModal'
import { useToast } from '@/hooks/useToast'
import { useVocabularyStore } from '@/store/term'
+import { useModal } from '@/hooks/useModal'
+import { ModalTypes } from '@/hooks/useModal/useModal'
import {
LoadingComponent,
@@ -35,40 +39,181 @@ import {
import { dropboxItem } from 'src/app/(afterLogin)/workspace/VocabularyItem.css'
-const TextContainer = ({ length }: { length?: number }) => {
+const TextContainer = ({ length }: { length?: number }) => (
+
+ π μ©μ΄λͺ©λ‘
+
+ {length}
+
+
+)
+
+const SortableListHeader = ({
+ handleSort,
+ response,
+}: {
+ response: GetTermResponse
+ handleSort: (sort: TermSort) => void
+}) => {
+ const { checkList, handleCheckList } = useVocabularyStore()
+
return (
-
- π μ©μ΄λͺ©λ‘
-
+ handleCheckList('all', response)}
+ >
+ {}}
+ checked={checkList.length === response.result.length}
+ />
+
+ handleSort(termSort.Term)}
>
- {length}
-
+ μ©μ΄
+
+ handleSort(termSort.Synonym)}
+ >
+ λμμ΄
+
+ handleSort(termSort.Meaning)}
+ >
+ λ»
+
+ handleSort(termSort.CreatedAt)}
+ >
+ μμ±μΌμ
+
+
)
}
-interface Term {
- sort: 'term' | 'meaning' | 'synonym' | 'createdAt'
+const TermItem = ({
+ response,
+ termData,
+ termUid,
+ deleteTerm,
+}: {
+ response: GetTermResponse
+ termData: Terms
+ termUid: string | null
+ deleteTerm: (termUid: string) => void
+}) => {
+ const synonymsList = termData.synonyms.join('\n')
+ const { checkList, handleCheckList } = useVocabularyStore()
+
+ const { setModalData } = useVocabularyStore()
+ const { toggleModal, setModal } = useModal()
+
+ const handleEdit = (data: Terms) => {
+ setModalData({
+ termUid: data.termUid,
+ meaning: data.meaning,
+ name: data.term,
+ synonym: data.synonyms,
+ })
+ setModal(ModalTypes.EDIT)
+ toggleModal()
+ }
+
+ const formatter = useMemo(
+ () =>
+ new Intl.DateTimeFormat('ko-KR', {
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric',
+ }),
+ [],
+ )
+
+ return (
+
+
handleCheckList(termData.termUid, response)}
+ >
+ {}}
+ checked={checkList.includes(termData.termUid)}
+ />
+
+
+
+
',
+ ``,
+ )}
+ />
+ ',
+ ``,
+ )}
+ />
+
+
+
+
+
+
+
+ handleEdit(termData)}>
+
+
+ μμ
+
+
+ deleteTerm(termData.termUid)}>
+
+
+ μμ
+
+
+
+
+
+
+ )
}
export const Term = () => {
const path = usePathname()
const id = path.split('/').pop() ?? ''
- const { checkList, setModalData, handleCheckList } = useVocabularyStore()
const searchParams = useSearchParams()
const termUid = searchParams.get('term-uid')
- const { toggleModal, setModal } = useModal()
- const [sorts, setSorts] = useState([
- termSort.TermAsc,
- termSort.SynonymAsc,
- termSort.MeaningAsc,
- termSort.CreatedAtAsc,
- ])
+ const [sorts, setSorts] = useState([])
const [selectedTermUid, setSelectedTermUid] = useState('')
const [updated, setUpdated] = useState(false)
@@ -79,13 +224,8 @@ export const Term = () => {
const deleteTermMutation = useDeleteTermMutation(selectedTermUid, {
onSuccess: () => {
- queryClient.invalidateQueries({
- queryKey: ['term', id],
- })
- addToast({
- message: 'μ©μ΄κ° μμ λμμ΅λλ€.',
- type: 'success',
- })
+ queryClient.invalidateQueries({ queryKey: ['term', id] })
+ addToast({ message: 'μ©μ΄κ° μμ λμμ΅λλ€.', type: 'success' })
},
})
@@ -96,7 +236,6 @@ export const Term = () => {
if (termUid) {
const offset = document.getElementById(termUid)?.offsetTop
-
if (offset) {
window.scrollTo({ top: offset, behavior: 'smooth' })
}
@@ -110,59 +249,42 @@ export const Term = () => {
}
}, [updated, queryClient, id, sorts])
- if (isLoading || response == null) {
- return
- }
+ const handleSort = useCallback(
+ (sort: TermSort) => {
+ const checkSort = (sortAsc: TermSortValues, sortDesc: TermSortValues) => {
+ if (sorts.includes(sortAsc)) {
+ setSorts([sortDesc])
+ } else {
+ setSorts([sortAsc])
+ }
+ }
+ switch (sort) {
+ case termSort.Term:
+ checkSort(termSort.Term.Asc, termSort.Term.Desc)
+ break
+ case termSort.CreatedAt:
+ checkSort(termSort.CreatedAt.Asc, termSort.CreatedAt.Desc)
+ break
+ case termSort.Synonym:
+ checkSort(termSort.Synonym.Asc, termSort.Synonym.Desc)
+ break
+ case termSort.Meaning:
+ checkSort(termSort.Meaning.Asc, termSort.Meaning.Desc)
+ break
+ }
- const formatter = new Intl.DateTimeFormat('ko-KR', {
- year: 'numeric',
- month: 'long',
- day: 'numeric',
- })
+ setUpdated(true)
+ },
+ [sorts],
+ )
- const updateSort = (sorts: TermSort[], asc: TermSort, desc: TermSort) => {
- const ascIndex = sorts.indexOf(asc)
- const descIndex = sorts.indexOf(desc)
- if (ascIndex !== -1) {
- sorts.splice(ascIndex, 1)
- sorts.unshift(desc)
- } else if (descIndex !== -1) {
- sorts.splice(descIndex, 1)
- sorts.unshift(asc)
- }
+ const deleteTerm = (termUid: string) => {
+ setSelectedTermUid(termUid)
+ deleteTermMutation.mutate()
}
- const handleSort = ({ sort }: Term) => {
- const newSorts = [...sorts]
- switch (sort) {
- case 'term':
- updateSort(newSorts, termSort.TermAsc, termSort.TermDesc)
- break
- case 'meaning':
- updateSort(newSorts, termSort.MeaningAsc, termSort.MeaningDesc)
- break
- case 'synonym':
- updateSort(newSorts, termSort.SynonymAsc, termSort.SynonymDesc)
- break
- case 'createdAt':
- updateSort(newSorts, termSort.CreatedAtAsc, termSort.CreatedAtDesc)
- break
- default:
- return
- }
- setSorts(newSorts)
- setUpdated(true)
- }
-
- const handleEdit = (data: Terms) => {
- setModalData({
- termUid: data.termUid,
- meaning: data.meaning,
- name: data.term,
- synonym: data.synonyms,
- })
- setModal(ModalTypes.EDIT)
- toggleModal()
+ if (isLoading || response == null) {
+ return
}
return (
@@ -171,157 +293,16 @@ export const Term = () => {
{response?.result.length ? (
<>
-
- {
- handleCheckList('all', response)
- }}
- >
- {}}
- checked={checkList.length === response.result.length}
- />
-
-
- {
- handleSort({ sort: 'term' })
- }}
- icon={
- sorts.includes(termSort.TermAsc)
- ? 'arrow-down-small'
- : 'arrow-up-small'
- }
- >
- μ©μ΄
-
- {
- handleSort({ sort: 'synonym' })
- }}
- icon={
- sorts.includes(termSort.SynonymAsc)
- ? 'arrow-down-small'
- : 'arrow-up-small'
- }
- >
- λμμ΄
-
- {
- handleSort({ sort: 'meaning' })
- }}
- icon={
- sorts.includes(termSort.MeaningAsc)
- ? 'arrow-down-small'
- : 'arrow-up-small'
- }
- >
- λ»
-
- {
- handleSort({ sort: 'createdAt' })
- }}
- icon={
- sorts.includes(termSort.CreatedAtAsc)
- ? 'arrow-down-small'
- : 'arrow-up-small'
- }
- >
- μμ±μΌμ
-
-
-
- {response?.result.map((termData, index) => {
- const synonymsList = termData.synonyms.join('\n')
-
- return (
-
-
{
- handleCheckList(termData.termUid, response)
- }}
- >
- {}}
- checked={checkList.includes(termData.termUid)}
- />
-
-
-
-
',
- ``,
- )}
- />
- ',
- ``,
- )}
- />
-
-
-
-
-
-
-
- {
- handleEdit(termData)
- }}
- >
-
-
- μμ
-
-
- {
- setSelectedTermUid(termData.termUid)
- deleteTermMutation.mutate()
- }}
- >
-
-
- μμ
-
-
-
-
-
-
- )
- })}
+
+ {response?.result.map((termData) => (
+
+ ))}
>
) : (
diff --git a/apps/web/src/components/common/index.ts b/apps/web/src/components/common/index.ts
index 58eed37..65acd40 100644
--- a/apps/web/src/components/common/index.ts
+++ b/apps/web/src/components/common/index.ts
@@ -1 +1 @@
-export { Hyperlink, Logo } from './Common'
+export { Hyperlink, LoadingComponent, Logo, NoneDataComponent } from './Common'
diff --git a/packages/api/src/services/term/model.ts b/packages/api/src/services/term/model.ts
index b860643..33fc996 100644
--- a/packages/api/src/services/term/model.ts
+++ b/packages/api/src/services/term/model.ts
@@ -1,16 +1,27 @@
export const termSort = {
- TermAsc: 'term%2Casc',
- TermDesc: 'term%2Cdesc',
- SynonymAsc: 'synonym%2Casc',
- SynonymDesc: 'synonym%2Cdesc',
- MeaningAsc: 'meaning%2Casc',
- MeaningDesc: 'meaning%2Cdesc',
- CreatedAtAsc: 'createdAt%2Casc',
- CreatedAtDesc: 'createdAt%2Cdesc',
+ Term: {
+ Asc: 'term%2Casc',
+ Desc: 'term%2Cdesc',
+ },
+ Synonym: {
+ Asc: 'synonym%2Casc',
+ Desc: 'synonym%2Cdesc',
+ },
+ Meaning: {
+ Asc: 'meaning%2Casc',
+ Desc: 'meaning%2Cdesc',
+ },
+ CreatedAt: {
+ Asc: 'createdAt%2Casc',
+ Desc: 'createdAt%2Cdesc',
+ },
} as const
export type TermSort = (typeof termSort)[keyof typeof termSort]
+export type TermSortValues =
+ (typeof termSort)[keyof typeof termSort][keyof typeof termSort.Term]
+
export interface Terms extends TermType {
termUid: string
createdAt: string
diff --git a/packages/api/src/services/term/quries.ts b/packages/api/src/services/term/quries.ts
index eb69661..b9eb0c1 100644
--- a/packages/api/src/services/term/quries.ts
+++ b/packages/api/src/services/term/quries.ts
@@ -14,11 +14,15 @@ import {
DeleteAllDTO as DeleteBatchDTO,
EditTermDTO,
GetTermResponse,
- TermSort,
+ TermSortValues,
} from './model'
export const termOptions = {
- termInfo: (client: QueryClient, vocabularyUid: string, sort: TermSort[]) => ({
+ termInfo: (
+ client: QueryClient,
+ vocabularyUid: string,
+ sort: TermSortValues[],
+ ) => ({
queryKey: ['term', vocabularyUid, sort],
queryFn: () => termService.getTerm(client, vocabularyUid, sort),
}),
@@ -38,7 +42,7 @@ export const termOptions = {
export const useGetTermQuery = (
vocabularyUid: string,
- sort: TermSort[],
+ sort: TermSortValues[],
options: QueryOptions = {},
) => {
const queryClient = useQueryClient()
diff --git a/packages/api/src/services/term/service.ts b/packages/api/src/services/term/service.ts
index 9459350..bfe2daa 100644
--- a/packages/api/src/services/term/service.ts
+++ b/packages/api/src/services/term/service.ts
@@ -8,11 +8,15 @@ import {
DeleteAllDTO as DeleteBatchDTO,
EditTermDTO,
GetTermResponse,
- TermSort,
+ TermSortValues,
} from './model'
export const termService = {
- async getTerm(client: QueryClient, vocabularyUid: string, sort?: TermSort[]) {
+ async getTerm(
+ client: QueryClient,
+ vocabularyUid: string,
+ sort?: TermSortValues[],
+ ) {
let url = `/terms?vocabularyUid=${vocabularyUid}`
if (sort) {
url = url + '&sort=' + sort.join('&sort=')