import { useEffect, useRef, useState } from 'react' import { addSharedFile, deleteSharedFile, getSharedFiles, sharedFileDownloadUrl, updateSharedFileDescription, type SharedFile, } from '../api/client' /** * 자료실 — 공용 양식 보관소(요구사항 [26]). * * 기관에 딸리지 않는 서식을 여기 올려 두고, 어느 기관 일을 하든 내려받아 씁니다. * 기관별 자료는 기관관리 > 자료 탭에 그대로 있습니다. */ function formatSize(bytes: number): string { if (bytes < 1024) { return `${bytes} B` } if (bytes < 1024 * 1024) { return `${(bytes / 1024).toFixed(1)} KB` } return `${(bytes / 1024 / 1024).toFixed(1)} MB` } function formatDate(ms: number): string { const d = new Date(ms) const pad = (n: number) => String(n).padStart(2, '0') return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` } export default function SharedFiles() { const [files, setFiles] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [busy, setBusy] = useState(false) const [description, setDescription] = useState('') const [editingId, setEditingId] = useState(null) const [editingText, setEditingText] = useState('') const inputRef = useRef(null) async function load() { setLoading(true) try { setFiles(await getSharedFiles()) setError(null) } catch (e) { setError((e as Error).message) } finally { setLoading(false) } } useEffect(() => { void load() }, []) async function handleUpload(file: File) { setBusy(true) setError(null) try { setFiles(await addSharedFile(file, description.trim())) setDescription('') } catch (e) { setError((e as Error).message) } finally { setBusy(false) } } async function handleDelete(file: SharedFile) { if (!window.confirm(`「${file.fileName}」을(를) 지울까요?`)) { return } setBusy(true) try { await deleteSharedFile(file.id) await load() } finally { setBusy(false) } } async function saveDescription(file: SharedFile) { setBusy(true) try { setFiles(await updateSharedFileDescription(file.id, editingText.trim())) setEditingId(null) } catch (e) { setError((e as Error).message) } finally { setBusy(false) } } return (

자료실

기관에 딸리지 않는 공용 서식을 올려 둡니다. 기관별 자료는 기관관리 > 자료 탭에 있습니다.

setDescription(e.target.value)} placeholder="설명(선택)" className="w-72 rounded-md border border-gray-300 px-2 py-1.5 text-sm" /> { const file = e.target.files?.[0] if (file) void handleUpload(file) e.target.value = '' }} />
{error &&

{error}

} {loading ? (

불러오는 중…

) : files.length === 0 ? (

올려둔 자료가 없습니다.

) : ( {files.map((file) => ( ))}
파일명 설명 크기 올린 사람 올린 날짜
{file.fileName} {editingId === file.id ? (
setEditingText(e.target.value)} className="w-56 rounded-md border border-gray-300 px-2 py-1 text-sm" />
) : ( )}
{formatSize(file.byteSize)} {file.uploadedBy} {formatDate(file.uploadedAt)}
)}
) }