summaryrefslogtreecommitdiff
path: root/components/information
diff options
context:
space:
mode:
Diffstat (limited to 'components/information')
-rw-r--r--components/information/information-button.tsx189
1 files changed, 106 insertions, 83 deletions
diff --git a/components/information/information-button.tsx b/components/information/information-button.tsx
index 38e8cb12..f8707439 100644
--- a/components/information/information-button.tsx
+++ b/components/information/information-button.tsx
@@ -11,7 +11,7 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
-import { Info, Download, Edit } from "lucide-react"
+import { Info, Download, Edit, Loader2 } from "lucide-react"
import { getCachedPageInformation, getCachedEditPermission } from "@/lib/information/service"
import { getCachedPageNotices } from "@/lib/notice/service"
import { UpdateInformationDialog } from "@/lib/information/table/update-information-dialog"
@@ -48,11 +48,13 @@ export function InformationButton({
const [selectedNotice, setSelectedNotice] = useState<NoticeWithAuthor | null>(null)
const [isNoticeViewDialogOpen, setIsNoticeViewDialogOpen] = useState(false)
const [dataLoaded, setDataLoaded] = useState(false)
+ const [isLoading, setIsLoading] = useState(false)
// 데이터 로드 함수 (단순화)
const loadData = React.useCallback(async () => {
if (dataLoaded) return // 이미 로드되었으면 중복 방지
+ setIsLoading(true)
try {
// pagePath 정규화 (앞의 / 제거)
const normalizedPath = pagePath.startsWith('/') ? pagePath.slice(1) : pagePath
@@ -74,6 +76,8 @@ export function InformationButton({
}
} catch (error) {
console.error("데이터 로딩 중 오류:", error)
+ } finally {
+ setIsLoading(false)
}
}, [pagePath, session?.user?.id, dataLoaded])
@@ -140,100 +144,119 @@ export function InformationButton({
</div>
</DialogHeader>
- <div className="mt-4 space-y-6">
- {/* 공지사항 섹션 */}
- {notices.length > 0 && (
- <div className="space-y-3">
- <div className="flex items-center justify-between">
- <h4 className="font-semibold">공지사항</h4>
- <span className="text-xs text-gray-500">{notices.length}개</span>
- </div>
- <div className="max-h-60 overflow-y-auto border rounded-lg bg-gray-50 p-2">
- <div className="space-y-2">
- {notices.map((notice) => (
- <div
- key={notice.id}
- className="p-3 bg-white border rounded-lg hover:bg-gray-50 cursor-pointer transition-colors"
- onClick={() => handleNoticeClick(notice)}
- >
- <div className="space-y-1">
- <h5 className="font-medium text-sm line-clamp-2">
- {notice.title}
- </h5>
- <div className="flex items-center gap-3 text-xs text-gray-500">
- <span>{formatDate(notice.createdAt)}</span>
- {notice.authorName && (
- <span>{notice.authorName}</span>
- )}
+ <div className="mt-4">
+ {isLoading ? (
+ <div className="flex items-center justify-center py-12">
+ <Loader2 className="h-6 w-6 animate-spin text-gray-500" />
+ <span className="ml-2 text-gray-500">정보를 불러오는 중...</span>
+ </div>
+ ) : (
+ <div className="space-y-6">
+ {/* 공지사항 섹션 */}
+ <div className="space-y-3">
+ <div className="flex items-center justify-between">
+ <h4 className="font-semibold">공지사항</h4>
+ {notices.length > 0 && (
+ <span className="text-xs text-gray-500">{notices.length}개</span>
+ )}
+ </div>
+ {notices.length > 0 ? (
+ <div className="max-h-60 overflow-y-auto border rounded-lg bg-gray-50 p-2">
+ <div className="space-y-2">
+ {notices.map((notice) => (
+ <div
+ key={notice.id}
+ className="p-3 bg-white border rounded-lg hover:bg-gray-50 cursor-pointer transition-colors"
+ onClick={() => handleNoticeClick(notice)}
+ >
+ <div className="space-y-1">
+ <h5 className="font-medium text-sm line-clamp-2">
+ {notice.title}
+ </h5>
+ <div className="flex items-center gap-3 text-xs text-gray-500">
+ <span>{formatDate(notice.createdAt)}</span>
+ {notice.authorName && (
+ <span>{notice.authorName}</span>
+ )}
+ </div>
+ </div>
</div>
- </div>
+ ))}
</div>
- ))}
- </div>
+ </div>
+ ) : (
+ <div className="bg-gray-50 border rounded-lg p-4">
+ <div className="text-center text-gray-500">
+ 공지사항이 없습니다
+ </div>
+ </div>
+ )}
</div>
- </div>
- )}
- {/* 인포메이션 컨텐츠 */}
- {information?.informationContent && (
- <div className="space-y-3">
- <div className="flex items-center justify-between">
- <h4 className="font-semibold">안내사항</h4>
- {hasEditPermission && information && (
- <Button
- variant="outline"
- size="sm"
- onClick={handleEditClick}
- className="flex items-center gap-2 mr-2"
- >
- <Edit className="h-4 w-4" />
- 편집
- </Button>
- )}
- </div>
- <div className="bg-gray-50 border rounded-lg p-4">
- <div className="text-sm text-gray-600 whitespace-pre-wrap max-h-40 overflow-y-auto">
- {information.informationContent}
+ {/* 인포메이션 컨텐츠 */}
+ <div className="space-y-3">
+ <div className="flex items-center justify-between">
+ <h4 className="font-semibold">안내사항</h4>
+ {hasEditPermission && information && (
+ <Button
+ variant="outline"
+ size="sm"
+ onClick={handleEditClick}
+ className="flex items-center gap-2 mr-2"
+ >
+ <Edit className="h-4 w-4" />
+ 편집
+ </Button>
+ )}
+ </div>
+ <div className="bg-gray-50 border rounded-lg p-4">
+ {information?.informationContent ? (
+ <div className="text-sm text-gray-600 whitespace-pre-wrap max-h-40 overflow-y-auto">
+ {information.informationContent}
+ </div>
+ ) : (
+ <div className="text-center text-gray-500">
+ 안내사항이 없습니다
+ </div>
+ )}
</div>
</div>
- </div>
- )}
- {/* 첨부파일 */}
- {information?.attachmentFileName && (
- <div className="space-y-3">
- <h4 className="font-semibold">첨부파일</h4>
- <div className="bg-gray-50 border rounded-lg p-4">
- <div className="flex items-center justify-between p-3 bg-white rounded border">
- <div className="flex-1">
- <div className="text-sm font-medium">
- {information.attachmentFileName}
- </div>
- {information.attachmentFileSize && (
- <div className="text-xs text-gray-500 mt-1">
- {information.attachmentFileSize}
+ {/* 첨부파일 */}
+ <div className="space-y-3">
+ <h4 className="font-semibold">첨부파일</h4>
+ <div className="bg-gray-50 border rounded-lg p-4">
+ {information?.attachmentFileName ? (
+ <div className="flex items-center justify-between p-3 bg-white rounded border">
+ <div className="flex-1">
+ <div className="text-sm font-medium">
+ {information.attachmentFileName}
+ </div>
+ {information.attachmentFileSize && (
+ <div className="text-xs text-gray-500 mt-1">
+ {information.attachmentFileSize}
+ </div>
+ )}
</div>
- )}
- </div>
- <Button
- size="sm"
- variant="outline"
- onClick={handleDownload}
- className="flex items-center gap-1"
- >
- <Download className="h-3 w-3" />
- 다운로드
- </Button>
+ <Button
+ size="sm"
+ variant="outline"
+ onClick={handleDownload}
+ className="flex items-center gap-1"
+ >
+ <Download className="h-3 w-3" />
+ 다운로드
+ </Button>
+ </div>
+ ) : (
+ <div className="text-center text-gray-500">
+ 첨부파일이 없습니다
+ </div>
+ )}
</div>
</div>
</div>
)}
-
- {!information && notices.length === 0 && (
- <div className="text-center py-8 text-gray-500">
- <p>이 페이지에 대한 정보가 없습니다.</p>
- </div>
- )}
</div>
</DialogContent>
</Dialog>