diff options
Diffstat (limited to 'components/notice/notice-client.tsx')
| -rw-r--r-- | components/notice/notice-client.tsx | 116 |
1 files changed, 53 insertions, 63 deletions
diff --git a/components/notice/notice-client.tsx b/components/notice/notice-client.tsx index e5c05d84..1eb6d75f 100644 --- a/components/notice/notice-client.tsx +++ b/components/notice/notice-client.tsx @@ -1,6 +1,6 @@ "use client"
-import { useState, useEffect, useTransition } from "react"
+import React, { useState, useEffect, useTransition } from "react"
import { useParams } from "next/navigation"
import { useTranslation } from "@/i18n/client"
import { Button } from "@/components/ui/button"
@@ -91,28 +91,12 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr const fetchNotices = async () => {
try {
setLoading(true)
- const search = searchQuery || undefined
startTransition(async () => {
- const result = await getNoticeLists({
- page: 1,
- perPage: 50,
- search: search,
- sort: [{ id: sortField, desc: sortDirection === "desc" }],
- flags: [],
- filters: [],
- joinOperator: "and",
- pagePath: "",
- title: "",
- content: "",
- authorId: null,
- isActive: null,
- from: "",
- to: "",
- })
+ const result = await getNoticeLists()
if (result?.data) {
- setNotices(result.data)
+ setNotices(result.data as NoticeWithAuthor[])
} else {
toast.error("공지사항 목록을 가져오는데 실패했습니다.")
}
@@ -125,37 +109,12 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr }
}
- // 검색 핸들러
+ // 검색 핸들러 (클라이언트 사이드에서 필터링하므로 별도 동작 불필요)
const handleSearch = () => {
- fetchNotices()
+ // 클라이언트 사이드 필터링이므로 별도 서버 요청 불필요
}
- // 정렬 함수
- const sortNotices = (notices: NoticeWithAuthor[]) => {
- return [...notices].sort((a, b) => {
- let aValue: string | Date
- let bValue: string | Date
- if (sortField === "title") {
- aValue = a.title
- bValue = b.title
- } else if (sortField === "pagePath") {
- aValue = a.pagePath
- bValue = b.pagePath
- } else {
- aValue = new Date(a.createdAt)
- bValue = new Date(b.createdAt)
- }
-
- if (aValue < bValue) {
- return sortDirection === "asc" ? -1 : 1
- }
- if (aValue > bValue) {
- return sortDirection === "asc" ? 1 : -1
- }
- return 0
- })
- }
// 정렬 핸들러
const handleSort = (field: SortField) => {
@@ -184,8 +143,49 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr }
}
- // 정렬된 공지사항 목록
- const sortedNotices = sortNotices(notices)
+ // 클라이언트 사이드 필터링 및 정렬
+ const filteredAndSortedNotices = React.useMemo(() => {
+ let filtered = notices
+
+ // 검색 필터
+ if (searchQuery.trim()) {
+ const query = searchQuery.toLowerCase()
+ filtered = filtered.filter(notice =>
+ notice.title.toLowerCase().includes(query) ||
+ notice.pagePath.toLowerCase().includes(query) ||
+ notice.content.toLowerCase().includes(query)
+ )
+ }
+
+ // 정렬
+ filtered = filtered.sort((a, b) => {
+ let aValue: string | Date
+ let bValue: string | Date
+
+ switch (sortField) {
+ case "title":
+ aValue = a.title
+ bValue = b.title
+ break
+ case "pagePath":
+ aValue = a.pagePath
+ bValue = b.pagePath
+ break
+ case "createdAt":
+ aValue = new Date(a.createdAt)
+ bValue = new Date(b.createdAt)
+ break
+ default:
+ return 0
+ }
+
+ if (aValue < bValue) return sortDirection === "asc" ? -1 : 1
+ if (aValue > bValue) return sortDirection === "asc" ? 1 : -1
+ return 0
+ })
+
+ return filtered
+ }, [notices, searchQuery, sortField, sortDirection])
// 페이지 경로 옵션 로딩
const loadPagePathOptions = async () => {
@@ -227,13 +227,7 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr loadPagePathOptions()
}, [])
- useEffect(() => {
- if (searchQuery !== "") {
- fetchNotices()
- } else if (initialData.length > 0) {
- setNotices(initialData)
- }
- }, [searchQuery])
+ // 검색은 클라이언트 사이드에서 실시간으로 처리됨
return (
<div className="space-y-6">
@@ -243,16 +237,12 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr <div className="relative flex-1 max-w-md">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
<Input
- placeholder="제목이나 페이지 경로로 검색..."
+ placeholder="제목, 페이지 경로, 내용으로 검색..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-10"
- onKeyPress={(e) => e.key === "Enter" && handleSearch()}
/>
</div>
- <Button onClick={handleSearch} variant="outline">
- 검색
- </Button>
<Button
variant="outline"
onClick={() => window.location.reload()}
@@ -328,14 +318,14 @@ export function NoticeClient({ initialData = [], currentUserId }: NoticeClientPr 로딩 중...
</TableCell>
</TableRow>
- ) : notices.length === 0 ? (
+ ) : filteredAndSortedNotices.length === 0 ? (
<TableRow>
<TableCell colSpan={6} className="text-center py-8 text-gray-500">
- 공지사항이 없습니다.
+ {searchQuery.trim() ? "검색 결과가 없습니다." : "공지사항이 없습니다."}
</TableCell>
</TableRow>
) : (
- sortedNotices.map((notice) => (
+ filteredAndSortedNotices.map((notice) => (
<TableRow key={notice.id}>
<TableCell className="font-medium">
<div className="flex items-center gap-2">
|
