본문 바로가기
ERP Project

뷰페이지 구성

by kwh_coding 2023. 7. 15.

나는 우선 HTML, CSS, JS에 정말 자신이 없고 못한다.

 

미적 감각에도 영 재능이 없어 아이디어도 잘 떠오르지 않는다.

(보험 드는 거 맞음. 근데 진짜 진심임.........)

 

이전에 진행했던 프로젝트에서 로직을 모두 구현한 후에 뷰페이지를 구현하고 입히려고 하니 안 그래도 잘 다루지 못하는 프론트엔드 쪽에서 발목이 잡혀 고생했던 경험이 있다. CSS가 중복되는 등 오류가 발생하면 404에러가 나와 정말 짜증났었다.

 

그렇기 때문에 이번에는 간단히라도 틀은 짜두고 기능 구현을 시작하는 것으로 결정됐다.

 

내 나름의 최선을 다 해서 기본 틀만 잡아보기로 했다. 

 


[CSS]

.box {
        position: relative; 
        background-color: #5c54d1;
        width: 1000px;
        height: 300px;
        opacity: 0.5;
        margin: 0 auto;
        margin-top: 50px;
        border-radius: 20px;
    }
    .box img {
        position: absolute; 
        width: 80px;
        height: 80px; 
    }
    .image-link {
        display: block;
        position: relative; 
    }
    
    .divider {
        position: absolute; 
        width: 100%; 
        height: 2px; 
        background-color: #ffffff;
        top: 50%; 
        transform: translateY(-50%); 
    }
    
  
    .image-link:nth-child(1) {
        top: calc(50% - 40px); 
        left: 0; 
    }
    
    .image-link:nth-child(2) {
        top: calc(50% - 40px); 
        left: 100px; 
    }
    
    .image-link:nth-child(3) {
        top: calc(50% - 40px);
        left: 200px;
    }
    
    .image-link:nth-child(4) {
        top: calc(50% - 40px); 
        left: 300px; 
    }
    
    .image-link:nth-child(5) {
        top: calc(50% - 40px); 
        right: 300px;
    }
    
    .image-link:nth-child(6) {
        top: calc(50% - 40px);
        right: 200px; 
    }
    
    .image-link:nth-child(7) {
        top: calc(50% + 20px); 
        left: 0; 
    }
    
    .image-link:nth-child(8) {
        top: calc(50% + 20px); 
        left: 100px; 
    }
    
    .image-link:nth-child(9) {
        top: calc(50% + 20px);
        left: 200px;
    }
    
    .image-link:nth-child(10) {
        top: calc(50% + 20px);
        left: 300px; 
    }
    
    .image-link:nth-child(11) {
        top: calc(50% + 20px);
        right: 300px;
    }
    
    .image-link:nth-child(12) {
        top: calc(50% + 20px);
        right: 200px;
    }
    
    .image-link:nth-child(13) {
        top: calc(50% + 20px);
        right: 100px;
    }
    

    .sidebar {
    position: fixed;
    top: 20px;
    left: 20px;
    transform: translateY(0%);
    width: 40px;
    max-height: 50px;
    background-color: #f2f2f2;
    border-radius: 5px;
    transition: all 0.3s ease;
    opacity: 0.7;
    z-index: 999;
}
    .sidebar:hover {
        opacity: 1;
    }
    .sidebar-icon {
    position: fixed;
    top: 20px;
    left: 20px;
    transform: translateY(0%);
    width: 30px;
    height: 50px;
    background-color: white;
    border-radius: 5px;
    transition: all 0.3s ease;
    opacity: 0.7;
    z-index: 999;
}

    .sidebar-icon img {
    	position: fixed;
        width: 40px;
        height: 50px;
    }

 

[HTML]

<div class="box">
        <div class="divider"></div>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('home/rjfo').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 0; top: 30px;">
            <img src="${pageContext.request.contextPath }/resources/materials/거래처2.png" alt="이미지1" >
        </a>
        
       <a class="image-link" href="javascript:void(0)" onclick="fetch('home/aptlswj').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 120px; top: 30px;">
            <img src="${pageContext.request.contextPath }/resources/materials/메신저2.png" alt="이미지2">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 240px; top: 30px;">
            <img src="${pageContext.request.contextPath }/resources/materials/물류2.png" alt="이미지3">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 360px; top: 30px;">
            <img src="${pageContext.request.contextPath }/resources/materials/발주2.png" alt="이미지4">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 480px; top: 30px;">
            <img src="${pageContext.request.contextPath }/resources/materials/부서별 매출2.png" alt="이미지5">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 600px; top: 30px;">
            <img src="${pageContext.request.contextPath }/resources/materials/이메일2.png" alt="이미지6">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 0px; top: 180px;">
            <img src="${pageContext.request.contextPath }/resources/materials/일정2.png" alt="이미지7">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 120px; top: 180px;">
            <img src="${pageContext.request.contextPath }/resources/materials/잔여연차2.png" alt="이미지8">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 240px; top: 180px;">
            <img src="${pageContext.request.contextPath }/resources/materials/재고2.png" alt="이미지9">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 360px; top: 180px;">
            <img src="${pageContext.request.contextPath }/resources/materials/재무제표2.png" alt="이미지10">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 480px; top: 180px;">
            <img src="${pageContext.request.contextPath }/resources/materials/조직도2.png" alt="이미지11">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 600px; top: 180px;">
            <img src="${pageContext.request.contextPath }/resources/materials/주소록2.png" alt="이미지12">
        </a>
        
        <a class="image-link" href="javascript:void(0)" onclick="fetch('test/sidebar').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})" style="left: 720px; top: 180px;">
            <img src="${pageContext.request.contextPath }/resources/materials/프로젝트2.png" alt="이미지13">
        </a>
    </div>
    
    <div class="sidebar">
        <div class="sidebar-icon">
            <img src="${pageContext.request.contextPath }/resources/materials/sidebar/사이드바.png" alt="사이드바 아이콘" onclick="fetch('test/sidebar').then(function(response){
                    response.text().then(function(text){
                        document.querySelector('article').innerHTML = text;
                    })
                    })">
        </div>
    </div>

    <br>
    <div align="center">
    	<input type="button" value="경영기획팀" onclick="fetch('test/ruddud').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="전략기획팀" onclick="fetch('test/wjsfir').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="회계팀" onclick="fetch('test/ghlrP').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="재무팀" onclick="fetch('test/woan').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="인사팀" onclick="fetch('test/dlstk').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="총무팀" onclick="fetch('test/chdan').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="해외영업팀" onclick="fetch('test/godhl').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="국내영업팀" onclick="fetch('test/rnrso').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="매장영업팀" onclick="fetch('test/aowkd').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="영업관리팀" onclick="fetch('test/duddjq').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="생산팀" onclick="fetch('test/todtks').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="구매팀" onclick="fetch('test/rnao').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="품질관리팀" onclick="fetch('test/vnawlf').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    	<input type="button" value="물류팀" onclick="fetch('test/anffb').then(function(response){
					response.text().then(function(text){
						document.querySelector('article').innerHTML = text;
					})
					})">
    </div>
    
    <article>
    
    </article>

임의로 저장해 둔 아이콘 이미지들 각각에 a태그를 걸고 onclick으로 fetch API를 사용하여 ajax와 같은 효과를 부여했다.

 

여기서 fetch API가 무엇인지 알아갈 필요성이 있는데,

fetch란 ES6부터 들어온 JavaScript 내장 라이브러리로 Promise 기반으로 만들어졌기 때문에 데이터를 다루기가 쉽고 내장 라이브러리라는 장점으로 사용하기가 상당히 편리하다.

 

장점

  • 자바스크립트의 내장 라이브러리 이므로 별도로 import 할 필요가 없음
  • Promise 기반으로 만들어졌기 때문에 데이터 다루기 편리
  • 내장 라이브러리이기 때문에 업데이트에 따른 에러 방지가 가능

단점

  • 지원하지 않는 브라우저가 존재 (IE11...)
  • 네트워크 에러 발생 시 response timeout이 없어 기다려야 함
  • JSON으로 변환해주는 과정 필요
  • 상대적으로 axios에 비해 기능이 부족

div image-link 클래스엔 아직 컨트롤러를 만들지 않아 경로를 따로 지정해 주지 않았고

 

사이드바 이미지 아이콘을 클릭하게 되면

 

사이드바의 div가 출력되도록 했다.

 

아직 완성되려면 한참 남았고 수정될 때마다 업로드 하도록 하겠다...

'ERP Project' 카테고리의 다른 글

뷰페이지 구성 에러 해결(1)  (0) 2023.07.28
뷰페이지 구성(2)  (0) 2023.07.28
DB 세팅  (0) 2023.07.15
구현 범위 선정  (0) 2023.07.10
개발 툴 선정2 (프로그래밍 언어)  (0) 2023.06.28