145 lines
5.7 KiB
TypeScript
145 lines
5.7 KiB
TypeScript
import React, { useEffect } from 'react';
|
|
import { IdcServer } from '../data/idcData';
|
|
|
|
interface ServerDetailModalProps {
|
|
server: IdcServer;
|
|
onClose: () => void;
|
|
}
|
|
|
|
const ServerDetailModal: React.FC<ServerDetailModalProps> = ({ server, onClose }) => {
|
|
// ESC 키로 모달 닫기
|
|
useEffect(() => {
|
|
const handleEsc = (event: KeyboardEvent) => {
|
|
if (event.key === 'Escape') {
|
|
onClose();
|
|
}
|
|
};
|
|
window.addEventListener('keydown', handleEsc);
|
|
return () => {
|
|
window.removeEventListener('keydown', handleEsc);
|
|
};
|
|
}, [onClose]);
|
|
|
|
return (
|
|
<div className="modal-overlay" onClick={onClose}>
|
|
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
|
<div className="modal-header">
|
|
<h2 style={{ margin: 0, fontSize: '1.125rem', fontWeight: 600 }}>{server.category} ({server.serverNo})</h2>
|
|
<button className="modal-close-btn" onClick={onClose} aria-label="Close modal">×</button>
|
|
</div>
|
|
|
|
<div className="modal-body">
|
|
<div className="detail-grid">
|
|
{/* Row 1 */}
|
|
<div className="detail-item">
|
|
<label>회사 구분</label>
|
|
<div className="detail-value">{server.company}</div>
|
|
</div>
|
|
<div className="detail-item">
|
|
<label>서버 번호</label>
|
|
<div className="detail-value" style={{ color: 'var(--primary-color)', fontWeight: 600 }}>{server.serverNo}</div>
|
|
</div>
|
|
|
|
{/* Row 2 */}
|
|
<div className="detail-item">
|
|
<label>자산명(용도)</label>
|
|
<div className="detail-value">{server.category}</div>
|
|
</div>
|
|
<div className="detail-item">
|
|
<label>설치 위치</label>
|
|
<div className="detail-value">{server.location}</div>
|
|
</div>
|
|
|
|
{/* Row 3: 관리자 추가 */}
|
|
<div className="detail-item full-width">
|
|
<label>관리 담당자</label>
|
|
<div className="detail-value">
|
|
<span style={{ fontWeight: 600, color: 'var(--text-main)' }}>정: {server.managerPrimary}</span>
|
|
<span style={{ marginLeft: '16px', color: 'var(--text-muted)' }}>부: {server.managerSecondary}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Row 4 */}
|
|
<div className="detail-item">
|
|
<label>IP 주소 1</label>
|
|
<div className="detail-value">{server.ip1 || '-'}</div>
|
|
</div>
|
|
<div className="detail-item">
|
|
<label>IP 주소 2</label>
|
|
<div className="detail-value">{server.ip2 || '-'}</div>
|
|
</div>
|
|
|
|
{/* Row 5 */}
|
|
<div className="detail-item full-width">
|
|
<label>원격 접속 정보</label>
|
|
<div className="detail-value">
|
|
{server.remoteAccess.length > 0 ? (
|
|
<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>
|
|
{server.remoteAccess.map((access, idx) => (
|
|
<div key={idx} style={{ display: 'flex', alignItems: 'center', gap: '8px', padding: '4px 8px', backgroundColor: 'var(--bg-muted)', borderRadius: '4px', border: '1px solid var(--border-color)' }}>
|
|
<span style={{ fontSize: '0.75rem', fontWeight: 600, color: 'var(--text-muted)' }}>{access.tool}</span>
|
|
<span style={{ fontWeight: 500 }}>{access.id}</span>
|
|
<span style={{ color: 'var(--border-color)' }}>|</span>
|
|
<span>PW: <span style={{ color: 'var(--text-main)' }}>{access.pw}</span></span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : '-'}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Row 6 */}
|
|
<div className="detail-item">
|
|
<label>제조사 및 모델명</label>
|
|
<div className="detail-value">{server.model || '-'}</div>
|
|
</div>
|
|
<div className="detail-item">
|
|
<label>OS</label>
|
|
<div className="detail-value">{server.os || '-'}</div>
|
|
</div>
|
|
|
|
{/* Row 7 */}
|
|
<div className="detail-item">
|
|
<label>CPU</label>
|
|
<div className="detail-value">{server.cpu || '-'}</div>
|
|
</div>
|
|
<div className="detail-item">
|
|
<label>RAM</label>
|
|
<div className="detail-value">{server.ram || '-'}</div>
|
|
</div>
|
|
|
|
{/* Row 8 */}
|
|
<div className="detail-item full-width">
|
|
<label>Storage (디스크 구성)</label>
|
|
<div className="detail-value">{server.storage.length > 0 ? server.storage.join(' + ') : '-'}</div>
|
|
</div>
|
|
|
|
{/* Row 9 */}
|
|
<div className="detail-item">
|
|
<label>구매일자</label>
|
|
<div className="detail-value">{server.purchaseDate || '-'}</div>
|
|
</div>
|
|
<div className="detail-item">
|
|
<label>모니터링 여부</label>
|
|
<div className="detail-value">{server.monitoring || '-'}</div>
|
|
</div>
|
|
|
|
{/* Row 10 */}
|
|
<div className="detail-item full-width">
|
|
<label>비고 및 특이사항</label>
|
|
<div className="detail-value" style={{ minHeight: '40px' }}>{server.remarks || '-'}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="modal-footer">
|
|
<button className="btn btn-outline" onClick={onClose} style={{ marginRight: '8px' }}>닫기</button>
|
|
<button className="btn btn-primary" onClick={onClose}>수정(저장)</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ServerDetailModal;
|