199 lines
7.4 KiB
TypeScript
199 lines
7.4 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { fetchUploadLogs } from '../services/assetsApi';
|
|
import type { UploadLogItem } from '../services/assetsApi';
|
|
|
|
function AssetUpload() {
|
|
const [uploadMode, setUploadMode] = useState<'add' | 'replace'>('add');
|
|
const [uploaded, setUploaded] = useState(false);
|
|
const [uploadHistory, setUploadHistory] = useState<UploadLogItem[]>([]);
|
|
|
|
useEffect(() => {
|
|
fetchUploadLogs(10)
|
|
.then(setUploadHistory)
|
|
.catch((err) => console.error('[assets] 업로드 이력 로드 실패:', err));
|
|
}, []);
|
|
|
|
const handleUpload = () => {
|
|
setUploaded(true);
|
|
setTimeout(() => setUploaded(false), 3000);
|
|
};
|
|
|
|
return (
|
|
<div className="flex gap-8 h-full overflow-auto">
|
|
{/* Left - Upload */}
|
|
<div className="flex-1 max-w-[580px]">
|
|
<div className="text-title-4 font-bold mb-3.5 font-korean">📤 자산 데이터 업로드</div>
|
|
|
|
{/* Drop Zone */}
|
|
<div className="border-2 border-dashed border-stroke-light rounded-md py-10 px-5 text-center mb-5 cursor-pointer hover:border-[rgba(6,182,212,0.4)] transition-colors">
|
|
<div className="text-4xl mb-2.5 opacity-50">📁</div>
|
|
<div className="text-sm font-semibold mb-1.5 font-korean">
|
|
파일을 드래그하거나 클릭하여 업로드
|
|
</div>
|
|
<div className="text-label-2 text-fg-disabled mb-4 font-korean">
|
|
엑셀(.xlsx), CSV 파일 지원 · 최대 10MB
|
|
</div>
|
|
<button
|
|
className="px-7 py-2.5 text-title-4 font-semibold rounded-sm text-white border-none cursor-pointer font-korean"
|
|
style={{ background: 'linear-gradient(135deg, var(--color-info), #2563eb)' }}
|
|
>
|
|
파일 선택
|
|
</button>
|
|
</div>
|
|
|
|
{/* Asset Classification */}
|
|
<div className="mb-4">
|
|
<label className="block text-xs font-semibold mb-1.5 text-fg-sub font-korean">
|
|
자산 분류
|
|
</label>
|
|
<select className="prd-i w-full">
|
|
<option>장비자재</option>
|
|
<option>방제선</option>
|
|
<option>경비함정</option>
|
|
<option>방제창고</option>
|
|
<option>공단·지자체</option>
|
|
<option>MPRS·행안부</option>
|
|
</select>
|
|
</div>
|
|
|
|
{/* Jurisdiction */}
|
|
<div className="mb-4">
|
|
<label className="block text-xs font-semibold mb-1.5 text-fg-sub font-korean">
|
|
업로드 대상 관할
|
|
</label>
|
|
<select className="prd-i w-full">
|
|
<option>남해청 - 여수서</option>
|
|
<option>남해청 - 부산서</option>
|
|
<option>남해청 - 울산서</option>
|
|
<option>서해청 - 목포서</option>
|
|
<option>중부청 - 인천서</option>
|
|
<option>동해청 - 동해서</option>
|
|
<option>제주청 - 제주서</option>
|
|
</select>
|
|
</div>
|
|
|
|
{/* Upload Mode */}
|
|
<div className="mb-5">
|
|
<label className="block text-xs font-semibold mb-1.5 text-fg-sub font-korean">
|
|
업로드 방식
|
|
</label>
|
|
<div className="flex gap-4 text-xs text-fg-sub font-korean">
|
|
<label className="flex items-center gap-1.5 cursor-pointer">
|
|
<input
|
|
type="radio"
|
|
checked={uploadMode === 'add'}
|
|
onChange={() => setUploadMode('add')}
|
|
className="accent-primary-blue"
|
|
/>
|
|
추가 (기존 + 신규)
|
|
</label>
|
|
<label className="flex items-center gap-1.5 cursor-pointer">
|
|
<input
|
|
type="radio"
|
|
checked={uploadMode === 'replace'}
|
|
onChange={() => setUploadMode('replace')}
|
|
className="accent-primary-blue"
|
|
/>
|
|
전체 교체
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Upload Button */}
|
|
<button
|
|
onClick={handleUpload}
|
|
className={`w-full py-3.5 rounded-sm text-sm font-bold font-korean border-none cursor-pointer transition-all ${
|
|
uploaded
|
|
? 'bg-[rgba(34,197,94,0.2)] text-color-success border border-status-green'
|
|
: 'text-white'
|
|
}`}
|
|
style={
|
|
!uploaded
|
|
? { background: 'linear-gradient(135deg, var(--color-info), #2563eb)' }
|
|
: undefined
|
|
}
|
|
>
|
|
{uploaded ? '✅ 업로드 완료!' : '📤 업로드 실행'}
|
|
</button>
|
|
</div>
|
|
|
|
{/* Right - Permission & History */}
|
|
<div className="flex-1 max-w-[480px]">
|
|
{/* Permission System */}
|
|
<div className="text-title-4 font-bold mb-3.5 font-korean">🔐 수정 권한 체계</div>
|
|
<div className="flex flex-col gap-2 mb-7">
|
|
{[
|
|
{
|
|
icon: '👑',
|
|
role: '본청 관리자',
|
|
desc: '전체 자산 조회·수정·삭제·업로드',
|
|
color: 'text-color-danger',
|
|
bg: 'rgba(239,68,68,0.15)',
|
|
},
|
|
{
|
|
icon: '🏛',
|
|
role: '지방청 담당자',
|
|
desc: '소속 지방청 및 하위 해경서 자산 수정·업로드',
|
|
color: 'text-color-warning',
|
|
bg: 'rgba(249,115,22,0.15)',
|
|
},
|
|
{
|
|
icon: '⚓',
|
|
role: '해경서 담당자',
|
|
desc: '소속 해경서 자산 수정·업로드',
|
|
color: 'text-color-info',
|
|
bg: 'rgba(59,130,246,0.15)',
|
|
},
|
|
{
|
|
icon: '👤',
|
|
role: '일반 사용자',
|
|
desc: '조회·다운로드만 가능',
|
|
color: 'text-fg-sub',
|
|
bg: 'rgba(100,116,139,0.15)',
|
|
},
|
|
].map((p, i) => (
|
|
<div
|
|
key={i}
|
|
className="flex items-center gap-3 p-3.5 px-4 bg-bg-card border border-stroke rounded-sm"
|
|
>
|
|
<div
|
|
className="w-9 h-9 rounded-full flex items-center justify-center text-base"
|
|
style={{ background: p.bg }}
|
|
>
|
|
{p.icon}
|
|
</div>
|
|
<div>
|
|
<div className={`text-xs font-bold font-korean ${p.color}`}>{p.role}</div>
|
|
<div className="text-caption text-fg-disabled font-korean">{p.desc}</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Upload History */}
|
|
<div className="text-title-4 font-bold mb-3.5 font-korean">📋 최근 업로드 이력</div>
|
|
<div className="flex flex-col gap-2">
|
|
{uploadHistory.map((h) => (
|
|
<div
|
|
key={h.logSn}
|
|
className="flex justify-between items-center p-3.5 px-4 bg-bg-card border border-stroke rounded-sm"
|
|
>
|
|
<div>
|
|
<div className="text-xs font-semibold font-korean">{h.fileNm}</div>
|
|
<div className="text-caption text-fg-disabled mt-0.5 font-korean">
|
|
{new Date(h.regDtm).toLocaleString('ko-KR')} · {h.uploaderNm} · {h.uploadCnt}건
|
|
</div>
|
|
</div>
|
|
<span className="px-2 py-0.5 rounded-full text-caption font-semibold bg-[rgba(34,197,94,0.15)] text-color-success">
|
|
완료
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default AssetUpload;
|