wing-ops/frontend/src/tabs/assets/components/AssetUpload.tsx

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;