jichoi / calendar star
최정임 최정임 05-08
250508 최정임
@4df4c810c4dc3bc533743c08a485ab0f0ba3cb10
 
client/resources/img/account.png (Binary) (added)
+++ client/resources/img/account.png
Binary file is not shown
 
client/resources/img/date.png (Binary) (added)
+++ client/resources/img/date.png
Binary file is not shown
 
client/resources/img/file.png (Binary) (added)
+++ client/resources/img/file.png
Binary file is not shown
 
client/resources/img/h3icon.png (Binary) (added)
+++ client/resources/img/h3icon.png
Binary file is not shown
 
client/resources/img/icon.png (Binary) (added)
+++ client/resources/img/icon.png
Binary file is not shown
 
client/resources/img/id.png (Binary) (added)
+++ client/resources/img/id.png
Binary file is not shown
 
client/resources/img/img.png (Binary) (added)
+++ client/resources/img/img.png
Binary file is not shown
 
client/resources/img/img1.png (Binary) (added)
+++ client/resources/img/img1.png
Binary file is not shown
 
client/resources/img/loginicon.png (Binary) (added)
+++ client/resources/img/loginicon.png
Binary file is not shown
 
client/resources/img/logo.png (Binary) (added)
+++ client/resources/img/logo.png
Binary file is not shown
 
client/resources/img/logout.png (Binary) (added)
+++ client/resources/img/logout.png
Binary file is not shown
 
client/resources/img/menuicon.png (Binary) (added)
+++ client/resources/img/menuicon.png
Binary file is not shown
 
client/resources/img/more.png (Binary) (added)
+++ client/resources/img/more.png
Binary file is not shown
 
client/resources/img/password.png (Binary) (added)
+++ client/resources/img/password.png
Binary file is not shown
 
client/resources/img/photo_icon.png (Binary) (added)
+++ client/resources/img/photo_icon.png
Binary file is not shown
 
client/resources/img/require.png (Binary) (added)
+++ client/resources/img/require.png
Binary file is not shown
 
client/resources/img/start.png (Binary) (added)
+++ client/resources/img/start.png
Binary file is not shown
 
client/resources/img/stop.png (Binary) (added)
+++ client/resources/img/stop.png
Binary file is not shown
 
client/resources/scss/admin/content.scss (added)
+++ client/resources/scss/admin/content.scss
@@ -0,0 +1,473 @@
+.login{
+    background-color: #EFF1FA;
+    height: 100vh;
+    .card{
+        padding-top: 30rem;
+        .card-body{
+           
+            background-color: #fff;
+            margin: 0 auto;
+            width: 600px;
+            height: 450px;
+            padding: 5rem;
+            border-radius: 5rem;
+            display: flex;
+            gap: 30px;
+            flex-direction: column;
+        }
+        .card-title{
+            text-align: center;
+        }
+        .form-label{
+            display: flex
+            ;
+                align-items: center;
+                font-weight: 700;
+                font-size: 15px;
+                margin-bottom: 10px;
+                img{margin-right: 3px;}
+        }
+        .box{margin-bottom: 30px;
+            button{width: 100%; background-color: #1F3F99;
+                img{margin-right: 10px;}
+            }
+        }
+    }
+}
+.sidemenu{
+    width: 350px; 
+    margin-right: 20px;
+    .myinfo{
+        text-align: center;
+        padding: 25px 20px 20px 20px;
+        margin-bottom: 20px;
+        border-radius: 20px;
+        background: linear-gradient(to bottom, #1F3F99, #3354CE);
+        .name-box{
+            margin-bottom: 30px;
+            .img-area{
+                margin: 0 auto;
+                width: 165px;
+    
+                .name{
+                    font-size: 25px;
+                    font-weight: 700;
+                    color: #fff;
+                }
+                .info{
+                    background-color: #0A216D;
+                    border-radius: 100px;
+                    display: flex;
+                    align-items: center;
+                    gap: 10px;
+                    justify-content: center;
+                   
+                    p{color: #fff; font-size: 15px;}
+                }
+            }
+        }
+        
+        .info-box{
+            background-color: #fff;
+            border-radius: 15px;
+            display: flex;
+            justify-content: space-between;
+            li{text-align: center; border-right: 1px solid #E7EAF4; width: 25%;
+                p{font-size: 35px; font-weight: 700; margin: 20px 0;}
+            }
+            li:last-child{border: 0;}
+            .name{
+                text-align: center;
+                display: flex;
+                justify-content: center;
+                justify-self: center;
+                margin-bottom: 12px;
+                width: 58px;
+                height: 25px;
+                font-size: 16px;
+                font-weight: 700;
+                background-color: #999999;
+                color: #fff;
+                border-radius: 100px;
+            }
+            .name.yellow{background-color:#EDAB0C;}
+            .name.blue{background-color:#1D75E1;}
+            .name.red{background-color:#E92727;}
+        }
+    }
+    .myinfo.profile{
+        background: #fff;
+        .name-box{margin: 20px 0;}
+        .img-area{
+            width: 100%;
+            .img{
+                position: relative;
+                width: 150px;  height: 190px; border: 1px solid #D7DCF1; 
+                padding: 10px;
+                margin: 0 auto;
+                .close-btn{position: absolute; top: 0; right: 10px;}
+                img{height: 100%; object-fit: cover; }
+            }
+            .info{
+                border-top: 1px solid #9498A94D;
+                margin: 0 auto;
+                padding-top: 30px;
+                margin-top: 30px;
+                width: 240px;
+                background-color: transparent;
+                border-radius: 0;
+                .file {
+                    background-color: #EFF1FA; width: 120px; border: #213F9A 1px solid ; border-radius: 10px; padding: 7px 0;
+                    margin-top: 10px;
+                  }
+                  
+                  .file-label {
+                    display: flex;
+                    gap: 5px;
+                    justify-content: center;
+                    cursor: pointer;
+                    p{color: #000;}
+                  }
+                  
+                  input[type="file"] {
+                    display: none;
+                  }
+               }
+        }
+    }
+    .myinfo.simple{
+        background: transparent;
+        .img-area{
+            img{width: 75px;
+             height: 75px;}
+             .info{
+                background-color: #DEE2F5;
+                p{color: #000;}              
+                .fa-bars{
+                    width: 2px;
+                    height: 14px;
+                    background-color: #213F9A1A;
+                }
+             }
+             .name{color: #000;}
+        }
+        h2{ background: #213F9A; color: #fff; border-radius: 10px; font-size: 17px; text-align: left; padding: 10px 15px;}
+    }
+    .menu-box{
+        margin-top: 20px;
+        li{
+            margin-bottom: 10px;
+            a{display: flex; justify-content: space-between;}
+            a:focus{outline: 0;}
+        }
+    }
+    .boxs{
+        background-color: #fff; border-radius: 20px; padding: 20px; margin-bottom: 20px;
+        .box{display: flex; justify-content: space-between; margin-bottom: 15px;
+            h3{text-align: center;
+                color: #fff;
+                font-size: 16px;
+                font-weight: 700;}
+        }
+        .img-area{margin: 0 12.5px;}
+        h4{
+            font-size: 19px;
+                font-weight: 700;
+                text-align: center;
+                line-height: 22px;
+                img{margin-right: 10px;}
+                margin-bottom: 15px;
+        }
+        i.fa-bars{display: block; width: 2px; height: 14px; background-color: #D7DCF1;}
+        .sm-box{
+            width: 185px;
+            background-color: #F4F6FD;
+            border-radius: 10px;
+            text-align: center;
+            h3{
+                background-color: #213F9A;
+                border-radius: 10px;
+                height: 35px;
+                line-height: 35px;
+            }
+            p{
+                font-size: 30px;
+                font-weight: 700;
+            }
+        }
+        .bd-box{
+            border: 1px solid #D7DCF1;
+            border-radius: 10px;
+            padding: 19px 40px 19px 40px;
+            display: flex;
+            align-items: center;
+            gap: 30px;
+            div{font-size: 18px; 
+                span{font-size: 18px; font-weight: 800; margin-left:23px;}
+            }
+        }
+        .color-boxs{
+            display: flex;
+            justify-content: space-between;
+            .box{
+                display: block;
+                text-align: center;
+                width: 96px;
+                background-color: #F9F9F9;
+                font-size: 30px;
+                font-weight: 700;
+                border-radius: 10px;
+                padding-bottom: 24px;
+                h3{background-color: #999999; border-top-left-radius: 10px; border-top-right-radius: 10px; width: 100%; height: 33px;
+                    line-height: 33px;
+                    margin-bottom: 17px;}
+            }
+            .box.red{
+                background-color: #FEF3F3;
+                h3{background-color: #E92727;}
+
+            }
+            .box.green{
+                background-color: #EFF9FB;
+                h3{background-color: #3C97AB;}
+
+            }
+
+        }
+        
+    }
+    .router-link-active p {
+        color: #213F9A; /* 원하는 색상으로 변경 */
+        font-weight: 700;
+      }
+      
+      
+}
+.content{
+    .pagination{
+        margin-top: 20px;
+        ul {
+            display: flex;
+            list-style: none;
+            padding: 0;
+            gap: 8px;
+            justify-content: center;
+            align-items: center;
+          }
+          
+          li {
+            width: 35px;
+            height: 35px;
+            text-align: center;
+    line-height: 35px;
+            border: 1px solid #BDCBE8;
+            border-radius: 4px;
+            cursor: pointer;
+            background-color: #fff;
+            color: #333;
+            transition: 0.2s;
+          }
+          
+          li:hover:not(.disabled) {
+            background-color: #f0f0f0;
+          }
+          
+          li.active {
+            background-color: #1D75E1;
+            color: white;
+            font-weight: bold;
+          }
+          
+          li.arrow {
+            font-weight: bold;
+          }
+          
+          li.disabled {
+            opacity: 0.5;
+            cursor: not-allowed;
+          }
+    }
+    
+    .title{
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+        
+        h2{font-size: 24px; font-weight: 700; display: flex; gap: 20px;
+            span{border: 1px solid #E92727; border-radius: 100px; color: #E92727; font-size: 15px; text-align: center; padding: 5px 20px;}
+        }
+        .sub{display: flex; align-items: center; gap: 3px;}
+    }
+    .top-content{display: flex; justify-content: space-between; gap: 40px; margin-bottom: 15px;}
+    .boxs{
+        width: 550px;
+    
+        .blue-box{
+            background-color: #D7DCF1;
+            border-radius: 10px; 
+            padding: 30px;
+            
+            .box{background-color: #fff; text-align: center; 
+                padding: 29px 0;
+                border-radius: 10px;
+                .time{font-size: 35px; font-weight: 700;} 
+                
+            }
+            .buttons{
+                display: flex; gap: 25px;
+                align-items: center;
+                justify-content: center;
+                margin-top: 10px;
+                i.fa-bars{display: block; width: 1px; height: 40px; background-color: #fff;}
+            }
+        }
+        .board{
+            border: 1px solid #DDDDDD; border-radius: 10px;
+            table{
+
+                tr{ border-bottom: 1px solid #DDDDDD;}
+                tr:last-child{border: 0;}
+                td{
+                    border-radius: 10px;
+                    border: 0;
+                    text-align: center;
+                    p{
+                        padding: 4px 0;
+                        border-radius: 5px;
+                        width: 85px;
+                    }
+                }
+                    .category-service p{
+                        background-color: #FED9AC; 
+                      }
+                      
+                      .category-internal p{
+                        background-color: #EFF1FA; 
+                      }
+                      
+                      .category-government p{
+                        background-color: #DFD4F0; 
+                      }
+                      .status p{
+                        border: 2px solid #AAAAAA;
+                        border-radius: 100px;
+                        color: #AAAAAA;
+                        font-size: 15px;
+                      }
+                      .status-in-progress p{ border-color: #1D75E1; color: #1D75E1;}
+                      .status-complete p{ color: rgb(39, 96, 55); border-color: rgb(39, 96, 55);  }
+               
+            }
+        }
+    }
+    .card{
+        
+        .sch-form-wrap {
+            justify-self: end;
+            margin: 20px 0 ;
+            .input-group{
+                .form-select, .form-control{
+                    height: 40px;
+                    border-color: #C7CFE3;
+                    font-size: 16px;
+                }
+            }
+            
+          }
+          .sch-form-wrap.title-wrap{justify-content: space-between; width: 100%;
+            h3{
+                img{margin: 5px 5px 0 0;}
+            }
+            .input-group{width: auto; 
+                .form-control{padding-right: 30px;}
+                .ico-sch{right: 5px;}
+            }
+        }
+          .tbl-wrap{
+            th,td{text-align: center !important; font-size: 16px !important;}
+            .status-approved {
+                color: #1D75E1;
+                font-weight: 700;
+              }
+              
+              .status-pending {
+                color: #E92727;
+                font-weight: 700;
+              }
+              .expired td{
+                background-color: #F6F6F6; /* 연회색 배경 */
+                filter: grayscale(50%);
+                opacity: 0.6;
+              }
+          }
+        p.require{
+            text-align: right;
+            img{margin-top: 9px;}
+            }
+        .card-body{
+           
+            form{
+                margin-bottom:5rem;
+                border: 1px solid #C7CFE3;
+            border-radius: 10px; overflow: hidden;}
+            .col-12{
+                width: 100%;
+                display: flex;
+                border-bottom: 1px solid #C7CFE3;
+                label{width: 140px ;background: #EFF1FA; font-weight: 600; font-size: 16px; text-align: center; line-height: 70px; flex-shrink: 0; position: relative;}
+                p.require{
+                    position: absolute;
+                    right: 44px;
+                    top: 26px;
+                }
+               select, input{margin: 15px 10px; border-color: #DDDDDD; height: var(--tk-input-h-sm);}
+               .form-control[readonly]{background-color: #EFF1FA;}
+               .invalid-feedback{color: #E92727; font-size: 13px;}
+               .box{
+                margin: 15px 10px;
+                input{margin: 0;}
+                p{margin-top: 5px;}
+               }
+            }
+            .border-x{border: 0;}
+            .buttons{display: flex; gap: 10px; justify-content: end;
+                .btn-red{border-color: #E92727; color: #E92727; background-color: #EFF1FA;}
+                
+            }
+            
+        }
+    }
+}
+
+.modal-overlay {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(0, 0, 0, 0.4);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    z-index: 1000;
+  }
+  
+  .modal-box {
+    background: white;
+    padding: 20px 30px;
+    border-radius: 8px;
+    text-align: center;
+  }
+  
+  .modal-box button {
+    margin: 10px;
+    padding: 8px 16px;
+    font-size: 14px;
+  }
+  
+  .modal-box .cancel {
+    background: #ccc;
+  }
+
+  .primary{background-color: #213F9A;}(파일 끝에 줄바꿈 문자 없음)
client/resources/scss/admin/layout.scss
--- client/resources/scss/admin/layout.scss
+++ client/resources/scss/admin/layout.scss
@@ -1,18 +1,37 @@
 header{
-    background-color: #f8f9fa;
-    padding: 10px 0;
-    border-bottom: 1px solid #e9ecef;
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 20px;
+    .title{width: 350px; flex-shrink: 0; text-align: center;}
     .user-info{
         display: flex;
-        justify-content: flex-end;
+        justify-self: flex-end;
         align-items: center;
         .user-name{
             font-size: var(--fz-body-md);
             font-weight: 600;
+            img{margin-right: 3.5px;}
         }
         .user-logout{
             color: #007bff;
             cursor: pointer;
+            margin-left: 20px;
         }
     }
+}
+.menu{
+    display: flex;
+    align-items: center ;
+    li{
+        width: 160px;
+        text-align: center;
+        a span{font-size: 18px; font-weight: 500;}
+    }
+    i.fa-bars{width: 1px; height: 16px; background-color: #8893B4;}
+}
+.container{height: 100%; padding: 2rem; background-color: #EFF1FA;}
+.main-wrap{
+    display: flex;
+    .sidemenu{flex-shrink: 0;}
+    .content{width: 100%; padding: 30px; background-color: #fff; border-radius: 20px;}
 }
(파일 끝에 줄바꿈 문자 없음)
client/resources/scss/main.scss
--- client/resources/scss/main.scss
+++ client/resources/scss/main.scss
@@ -7,4 +7,5 @@
 
 
 // admin
-@import "./admin/layout.scss"
(파일 끝에 줄바꿈 문자 없음)
+@import "./admin/layout.scss";
+@import "./admin/content.scss"
(파일 끝에 줄바꿈 문자 없음)
client/views/component/GoogleCalendar.vue
--- client/views/component/GoogleCalendar.vue
+++ client/views/component/GoogleCalendar.vue
@@ -1,6 +1,6 @@
 <template>
     <div>
-      <FullCalendar :options="calendarOptions" />
+      <FullCalendar  :options="calendarOptions" />
     </div>
   </template>
   
@@ -33,11 +33,10 @@
         plugins: [dayGridPlugin],
         initialView: 'dayGridMonth',
         events: [],
-      titleFormat: { // 월 제목을 원하는 형식으로 변경
-        month: 'long', // 'long' 은 'February' 형식으로
-        year: 'numeric', // '2025' 형식으로
-        day: 'numeric' // '4' 형식으로
-      },
+        titleFormat: {
+  year: 'numeric',
+  month: '2-digit'
+},
       locale: 'ko', // 한국어로 설정
       headerToolbar: {
         left: 'prev,next today',
@@ -49,9 +48,11 @@
         month: '월',
         week: '주',
         day: '일'
-      }
+      },
+      showNonCurrentDates: false,
+      fixedWeekCount: false, 
       });
-      
+
       const loadClient = () => {
         if (window.gapi) {
           window.gapi.client.init({
@@ -107,8 +108,7 @@
   </script>
   
   <style scoped>
-/* FullCalendar 스타일을 CDN을 통해 불러오기 */
-@import url('https://cdn.jsdelivr.net/npm/@fullcalendar/core@3.10.2/main.css');
-@import url('https://cdn.jsdelivr.net/npm/@fullcalendar/daygrid@3.10.2/main.css');
-</style>
-  
(파일 끝에 줄바꿈 문자 없음)
+  .fc .fc-daygrid-day-frame {
+  background-color: #fff !important;
+}
+</style>
(파일 끝에 줄바꿈 문자 없음)
client/views/layout/AdminHeader.vue
--- client/views/layout/AdminHeader.vue
+++ client/views/layout/AdminHeader.vue
@@ -1,23 +1,34 @@
 <template>
     <header>
+        <div class="title"><img :src="logo" alt="로고"></div>
+        <Menu></Menu>
         <div class="user-info">
             <div class="user-name">관리자</div>
-            <button class="user-logout">로그아웃</button>
+            <button @click="logout" class="user-logout">로그아웃</button>
         </div>
     </header>
 </template>
 
 <script>
-
+import Menu from '../layout/Menu.vue';
 export default {
     data() {
         return {
+            logo: "/client/resources/img/logo.png",
         };
     },
-    methods: {},
+    methods: {
+        logout(){
+            localStorage.removeItem('isLoggedIn');
+this.$router.push('/login.page'); 
+
+        }
+    },
     watch: {},
     computed: {},
-    components: {},
+    components: {
+        'Menu': Menu,
+    },
     created() {},
     mounted() {},
     beforeUnmount() {},
client/views/layout/Header.vue
--- client/views/layout/Header.vue
+++ client/views/layout/Header.vue
@@ -1,54 +1,40 @@
 <template>
-  <!-- ======= Header ======= -->
-  <header id="header" class="header d-flex fixed-top  align-items-center">
-
-    <div class=" align-items-center logo">
-      <a href="/" class="  align-items-center">
-        <img :src="logo" alt="">
-        <span class="d-none d-lg-block"></span>
-      </a>
-      <i class="bi bi-list toggle-sidebar-btn" @click="toggleSidebar"></i>
-    </div><!-- End Logo -->
-
-
-    <nav class="header-nav ms-auto">
-      <ul class="d-flex align-items-center">
-
-
-
-        <li class="nav-item dropdown pe-3">
-
-          <a class="nav-link nav-profile d-flex align-items-center pe-0" href="#" data-bs-toggle="dropdown">
-            <span class="d-none d-md-block dropdown-toggle ps-2">{{ userName }}</span>
-          </a><!-- End Profile Iamge Icon -->
-
-          
-        </li><!-- End Profile Nav -->
-
-      </ul>
-    </nav><!-- End Icons Navigation -->
-
-  </header><!-- End Header -->
+  <header>
+      <div class="title"><router-link to="/"><img :src="logo" alt="로고"></router-link></div>
+      <Menu></Menu>
+      <div class="user-info">
+          <div class="user-name"> <router-link 
+            to="/MyPage.page"><img :src="accounticon" alt="">관리자</router-link></div>
+          <button @click="logout" class="user-logout"><img :src="logouticon" alt=""></button>
+      </div>
+  </header>
 </template>
 
 <script>
+import Menu from '../layout/Menu.vue';
 export default {
-  name: "ProfileImage",
   data() {
-    return {
-      userName: '',
-      logo: "/client/resources/img/logo_t.png", // 경로를 Vue 프로젝트 구조에 맞게 설정
-    };
+      return {
+          logo: "/client/resources/img/logo.png",
+          accounticon: "/client/resources/img/account.png",
+          logouticon: "/client/resources/img/logout.png",
+      };
   },
   methods: {
-    toggleSidebar() {
-      // `toggle-sidebar` 클래스가 있으면 제거, 없으면 추가
-      document.body.classList.toggle("toggle-sidebar");
-    },
-  },
-  components: {
-  },
-};
-</script>
+      logout(){
+          localStorage.removeItem('isLoggedIn');
+this.$router.push('/login.page'); 
 
-<style></style>
(파일 끝에 줄바꿈 문자 없음)
+      }
+  },
+  watch: {},
+  computed: {},
+  components: {
+      'Menu': Menu,
+  },
+  created() {},
+  mounted() {},
+  beforeUnmount() {},
+};
+
+</script>
(파일 끝에 줄바꿈 문자 없음)
 
client/views/layout/Menu.vue (added)
+++ client/views/layout/Menu.vue
@@ -0,0 +1,78 @@
+<template>
+    <ul class="menu">
+      <li class="nav-item">
+        <router-link to="/approval-management.page" class="nav-link " active-class="active">
+          <span>결재관리</span></router-link>
+      </li><!-- End Dashboard Nav -->
+      <i class="fa-solid fa-bars"></i>
+
+      <li class="nav-item">
+        <router-link to="/attendance-management.page" class="nav-link " active-class="active">
+          <span>근태관리</span></router-link>
+      </li>
+      <i class="fas fa-bars"></i>
+      <li class="nav-item">
+        <router-link to="/task-management.page" class="nav-link " active-class="active">
+          <span>업무관리</span></router-link>
+      </li>
+      <i class="fas fa-bars"></i>
+      <li class="nav-item">
+        <router-link to="/financial-management.page" class="nav-link " active-class="active">
+          <span>재무관리</span></router-link>
+      </li>
+      <i class="fas fa-bars"></i>
+      <li class="nav-item">
+        <router-link to="/asset-management.page" class="nav-link " active-class="active">
+          <span>자산관리</span></router-link>
+      </li><!-- End Register Page Nav -->
+      <i class="fas fa-bars"></i>
+      <li class="nav-item">
+        <router-link to="/hr-management.page" class="nav-link " active-class="active">
+          <span>인사관리</span></router-link>
+      </li><!-- End Login Page Nav -->
+      <i class="fas fa-bars"></i>
+      <li class="nav-item">
+        <router-link to="/system-management.page" class="nav-link " active-class="active">
+          <span>시스템관리</span></router-link>
+      </li>
+    
+
+    </ul><!-- End Profile Dropdown Items -->
+   
+</template>
+
+<script>
+export default {
+  name: "ProfileImage",
+  data() {
+    return {
+      isLoggedIn: false,
+      userName: '',
+      logo: "/client/resources/img/logo.png", 
+    };
+  },
+  methods: {
+    handleLogout() {
+      // Clear login-related data from localStorage
+      localStorage.removeItem('loggedInUser');
+      this.isLoggedIn = false; // Update login status
+      this.$router.push("/login"); // Redirect to login page after logout
+    },
+    toggleSidebar() {
+      // `toggle-sidebar` 클래스가 있으면 제거, 없으면 추가
+      document.body.classList.toggle("toggle-sidebar");
+    },
+  },
+  created() {
+    // Check if there is any login data in localStorage
+    const loggedInUser = localStorage.getItem('loggedInUser');
+    if (loggedInUser) {
+      this.isLoggedIn = true;
+    }
+  },
+  components: {
+  },
+};
+</script>
+
+<style></style>(파일 끝에 줄바꿈 문자 없음)
 
client/views/layout/SideBar.vue (deleted)
--- client/views/layout/SideBar.vue
@@ -1,155 +0,0 @@
-<template>
-  <!-- ======= Sidebar ======= -->
-  <aside id="sidebar" class="sidebar hide-in-mobile">
-    <div class=" align-items-center logo">
-      <a href="/" class="  align-items-center">
-        <img :src="logo" alt="">
-        <span class="d-none d-lg-block"></span>
-      </a>
-      <i class="bi bi-list toggle-sidebar-btn" @click="toggleSidebar"></i>
-    </div><!-- End Logo -->
-    <ul class="d-flex profile">
-
-      <li>
-        <router-link to="/MyPage" class="nav-link " active-class="active"><i class="bi bi-grid"></i>
-          <span>마이페이지</span></router-link>
-      </li>
-
-      <li>
-        <a class="dropdown-item d-flex align-items-center" href="#">
-          <i class="bi bi-box-arrow-right"></i>
-          <router-link v-if="!isLoggedIn" to="/Login" class="nav-link" active-class="active">
-      <i class="bi bi-grid"></i>
-      <span>로그인</span>
-    </router-link>
-
-    <router-link v-if="isLoggedIn" @click="handleLogout" class="nav-link" active-class="active">
-      <i class="bi bi-box-arrow-right"></i>
-      <span>로그아웃</span>
-    </router-link>
-        </a>
-      </li>
-
-    </ul><!-- End Profile Dropdown Items -->
-    <ul class="sidebar-nav" id="sidebar-nav">
-
-      <li class="nav-item">
-        <router-link to="/" class="nav-link " active-class="active"><i class="bi bi-grid"></i>
-          <span>Home</span></router-link>
-      </li><!-- End Dashboard Nav -->
-
-
-
-      <li class="nav-item">
-        <a class="nav-link collapsed" data-bs-target="#Chuljang-nav" data-bs-toggle="collapse" href="#">
-          <i class="bi bi-journal-text"></i>
-          <span>출장관리</span><i class="bi bi-chevron-down ms-auto"></i>
-        </a>
-        <ul id="Chuljang-nav" class="nav-content collapse " data-bs-parent="#sidebar-nav">
-          <li>
-            <router-link to="/ChuljangInsert" class="nav-link " active-class="active"><i
-                class="bi bi-circle"></i><span>출장신청</span></router-link>
-          </li>
-          <li>
-            <router-link to="/ChuljangList" class="nav-link " active-class="active"><i
-                class="bi bi-circle"></i><span>출장내역</span></router-link>
-          </li>
-
-        </ul>
-      </li>
-      <li class="nav-item">
-        <a class="nav-link collapsed" data-bs-target="#hyuga-nav" data-bs-toggle="collapse" href="#">
-          <i class="bi bi-journal-text"></i>
-          <span>휴가관리</span><i class="bi bi-chevron-down ms-auto"></i>
-        </a>
-        <ul id="hyuga-nav" class="nav-content collapse " data-bs-parent="#sidebar-nav">
-          <li>
-            <router-link to="/HyugaInsert" class="nav-link " active-class="active"><i
-                class="bi bi-circle"></i><span>휴가신청</span></router-link>
-          </li>
-          <li>
-            <router-link to="/HyugaList" class="nav-link " active-class="active"><i
-                class="bi bi-circle"></i><span>휴가내역</span></router-link>
-          </li>
-          <li>
-            <router-link to="/HyugaOk" class="nav-link " active-class="active"><i
-                class="bi bi-circle"></i><span>휴가승인</span></router-link>
-          </li>
-
-        </ul>
-      </li>
-      <li class="nav-item">
-        <a class="nav-link collapsed" data-bs-target="#project-nav" data-bs-toggle="collapse" href="#">
-          <i class="bi bi-journal-text"></i>
-          <span>프로젝트관리</span><i class="bi bi-chevron-down ms-auto"></i>
-        </a>
-        <ul id="project-nav" class="nav-content collapse " data-bs-parent="#sidebar-nav">
-          <li>
-            <router-link to="/ProjectInsert" class="nav-link " active-class="active"><i
-                class="bi bi-circle"></i><span>프로젝트 등록</span></router-link>
-          </li>
-
-          <li>
-            <router-link to="/ProjectList" class="nav-link " active-class="active"><i class="bi bi-journal-text"></i>
-              <span>프로젝트 내역</span></router-link>
-          </li>
-
-        </ul>
-      </li>
-
-      <li class="nav-item">
-        <router-link to="/NoticeList" class="nav-link " active-class="active"><i class="bi bi-journal-text"></i>
-          <span>공지사항</span></router-link>
-      </li><!-- End Register Page Nav -->
-
-      <li class="nav-item">
-        <router-link to="/EmployeeList" class="nav-link " active-class="active"><i class="bi bi-person"></i>
-          <span>직원관리</span></router-link>
-      </li><!-- End Login Page Nav -->
-
-      <li class="nav-item">
-        <router-link to="/DeptList" class="nav-link " active-class="active"><i class="bi bi-person"></i>
-          <span>부서관리</span></router-link>
-      </li><!-- End Error 404 Page Nav -->
-
-
-    </ul>
-
-  </aside><!-- End Sidebar-->
-</template>
-
-<script>
-export default {
-  name: "ProfileImage",
-  data() {
-    return {
-      isLoggedIn: false,
-      userName: '',
-      logo: "/client/resources/img/logo_t.png", // 경로를 Vue 프로젝트 구조에 맞게 설정
-    };
-  },
-  methods: {
-    handleLogout() {
-      // Clear login-related data from localStorage
-      localStorage.removeItem('loggedInUser');
-      this.isLoggedIn = false; // Update login status
-      this.$router.push("/login"); // Redirect to login page after logout
-    },
-    toggleSidebar() {
-      // `toggle-sidebar` 클래스가 있으면 제거, 없으면 추가
-      document.body.classList.toggle("toggle-sidebar");
-    },
-  },
-  created() {
-    // Check if there is any login data in localStorage
-    const loggedInUser = localStorage.getItem('loggedInUser');
-    if (loggedInUser) {
-      this.isLoggedIn = true;
-    }
-  },
-  components: {
-  },
-};
-</script>
-
-<style></style>(파일 끝에 줄바꿈 문자 없음)
client/views/pages/App.vue
--- client/views/pages/App.vue
+++ client/views/pages/App.vue
@@ -1,23 +1,21 @@
 <template>
-   <div v-if="this.$route.path.startsWith('/adm')">
-      <AdminHeader />
-      <SideBar></SideBar>
-      <main class="main-wrap">
-         <router-view/>
-      </main>
+     <div v-if="isLoginPage" class="login">
+     <!-- 로그인 페이지에는 헤더 없음 -->
+     <router-view />
    </div>
-   <div v-else>
-      <main class="main-wrap">
-         <SideBar></SideBar>
-         <router-view/>
-      </main>
+   <div v-else class="container">
+      <Header />
+      
+     <main class="main-wrap">
+       <router-view />
+     </main>
    </div>
+   
 </template>
 
 <script>
-import AdminHeader from '../layout/AdminHeader.vue';
 import Header from '../layout/Header.vue';
-import SideBar from '../layout/SideBar.vue';
+
 import Footer from '../layout/Footer.vue';
 
 const App = {
@@ -26,11 +24,14 @@
    },
    methods: {},
    watch: {},
-   computed: {},
+   computed: {
+     isLoginPage() {
+       return this.$route.path === '/login.page';
+     },
+   },
    components: {
-      'AdminHeader': AdminHeader,
       'Header': Header,
-      'SideBar': SideBar,
+      
       'Footer': Footer,
    },
    mounted: () => {}
client/views/pages/AppRouter.js
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
@@ -12,38 +12,58 @@
 
 // 직원
 import ChuljangList from '../pages/Employee/ChuljangList.vue';
-import ChuljangInsert from '../pages/Employee/ChuljangInsert.vue';
 import HyugaList from '../pages/Employee/HyugaList.vue';
-import HyugaInsert from '../pages/Employee/HyugaInsert.vue';
 import HyugaOk from '../pages/Employee/HyugaOk.vue';
-import ProjectList from '../pages/Employee/ProjectList.vue';
-import ProjectInsert from '../pages/Employee/ProjectInsert.vue';
 // 관리자
-import DeptList from '../pages/Manager/DeptList.vue';
-import EmployeeList from '../pages/Manager/EmployeeList.vue';
-import NoticeList from '../pages/Manager/NoticeList.vue';
-import NoticeInsert from '../pages/Manager/NoticeInsert.vue';
-import PubHoliyday from '../pages/Manager/PubHoliyday.vue';
+import approval from '../pages/Manager/approval/approval.vue';
+import approvalList from '../pages/Manager/approval/approvalList.vue';
+import approvalRequest from '../pages/Manager/approval/approvalRequest.vue';
+import HyugaInsert from '../pages/Manager/approval/HyugaInsert.vue';
+import ChuljangInsert from '../pages/Manager/approval/ChuljangInsert.vue';
+import attendance from '../pages/Manager/attendance/attendance.vue';
+import task from '../pages/Manager/task/task.vue';
+import financial from '../pages/Manager/financial/financial.vue';
+import asset from '../pages/Manager/asset/asset.vue';
+import hr from '../pages/Manager/hr/hr.vue';
+import system from '../pages/Manager/system/system.vue';
 
 const routes = [
     /* 메인화면 */
     { path: '/', name: '/', component: Main},
-    { path: '/Login', name: 'Login', component: Login},
-    { path: '/Join', name: 'Join', component: Join},
-    { path: '/MyPage', name: 'MyPage', component: MyPage},
+    { path: '/login.page', name: 'Login', component: Login},
+    { path: '/join.page', name: 'Join', component: Join},
+    { path: '/MyPage.page', name: 'MyPage', component: MyPage},
     
-    { path: '/ChuljangList', name: 'ChuljangList', component: ChuljangList },
-    { path: '/ChuljangInsert', name: 'ChuljangInsert', component: ChuljangInsert },
-    { path: '/HyugaList', name: 'HyugaList', component: HyugaList },
-    { path: '/HyugaInsert', name: 'HyugaInsert', component: HyugaInsert },
-    { path: '/HyugaOk', name: 'HyugaOk', component: HyugaOk },
-    { path: '/ProjectInsert', name: 'ProjectInsert', component: ProjectInsert },
-    { path: '/ProjectList', name: 'ProjectList', component: ProjectList },
-    { path: '/DeptList', name: 'DeptList', component: DeptList },
-    { path: '/EmployeeList', name: 'EmployeeList', component: EmployeeList },
-    { path: '/NoticeList', name: 'NoticeList', component: NoticeList },
-    { path: '/NoticeInsert', name: 'NoticeInsert', component: NoticeInsert },
-    { path: '/PubHoliyday', name: 'PubHoliyday', component: PubHoliyday },
+    { path: '/ChuljangList.page', name: 'ChuljangList', component: ChuljangList },
+    { path: '/HyugaList.page', name: 'HyugaList', component: HyugaList },
+    
+    { path: '/HyugaOk.page', name: 'HyugaOk', component: HyugaOk },
+    
+    { path: '/approval-management.page', name: 'approval', component: approval,
+        children: [
+            {
+              path: '/approvalRequest.page', // => /approval-management.page/list
+              name: 'approvalRequest',
+              component: approvalRequest,
+              children: [
+                
+              ]
+            },
+            {
+              path: '/approvalList.page', // => /approval-management.page/detail/123
+              name: 'approvalList',
+              component: approvalList
+            },
+            { path: '/ChuljangInsert.page', name: 'ChuljangInsert', component: ChuljangInsert },
+            { path: '/HyugaInsert.page', name: 'HyugaInsert', component: HyugaInsert },
+          ]
+     }, //결재관리
+    { path: '/attendance-management.page', name: 'attendance', component: attendance }, //근태관리
+    { path: '/task-management.page', name: 'task', component: task }, //업무관리
+    { path: '/financial-management.page', name: 'financial', component: financial }, //재무관리
+    { path: '/asset-management.page', name: 'asset', component: asset }, //자산관리
+    { path: '/hr-management.page', name: 'hr', component: hr }, //인사관리
+    { path: '/system-management.page', name: 'system', component: system },  //시스템관리
 ];
 
 
@@ -52,4 +72,23 @@
     routes,
 });
 
+// Add navigation guard
+AppRouter.beforeEach((to, from, next) => {
+    // Check login status
+    const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true';
+  
+    // If not logged in and trying to access any page other than login, redirect to login page
+    if (!isLoggedIn && to.path !== '/login.page') {
+      next('/login.page');
+    } 
+    // If logged in and trying to access login page, redirect to main page
+    else if (isLoggedIn && to.path === '/login.page') {
+      next('/');
+    } 
+    else {
+      next(); // Proceed to requested route
+    }
+  });
+  
+
 export default AppRouter;
(파일 끝에 줄바꿈 문자 없음)
 
client/views/pages/Manager/NoticeInsert copy.vue (deleted)
--- client/views/pages/Manager/NoticeInsert copy.vue
@@ -1,308 +0,0 @@
-<template>
-  <div class="pagetitle">
-    <h2>공지사항 등록</h2>
-  </div>
-  <section class="section">
-    <div class="card">
-      <div class="card-body pt-3">
-        <table class="form-table" style="width: 100%;">
-          <tbody>
-            <tr>
-              <th class="text-lf">
-                <span>제목</span>
-              </th>
-              <td>
-                <input
-                  type="text"
-                  class="form-control"
-                  v-model="notice.title"
-                  placeholder="제목을 입력하세요."
-                />
-              </td>
-            </tr>
-            <tr class="border-top">
-              <th colspan="4" class="text-lf">
-                <span>내용</span>
-              </th>
-            </tr>
-            <tr style="max-height: 600px">
-              <td colspan="4" style="height: 100%" class="pt-0">
-                <textarea name="editor" id="editor" class="form-control" style="width:100%"></textarea>
-              </td>
-            </tr>
-
-            <!-- 첨부파일 -->
-            <tr class="border-top">
-              <th class="text-lf">
-                첨부파일
-              </th>
-              <td colspan="2">
-                <div class="gd-12 pr0">
-                  <div class="gd-2 pl0 pr0">
-                    <label for="file" class="btn btn-outline-primary">파일찾기</label>
-                    <input
-                      type="file"
-                      id="file"
-                      ref="file"
-                      @change="handleFileInsert"
-                      multiple
-                    />
-                  </div>
-                  <div class="gd-12 pl0 pr0" v-if="fileList.length > 0">
-                    <ul>
-                      <li
-                        v-for="(file, idx) in fileList"
-                        :key="idx"
-                        class="pd-10 mt-10"
-                      >
-                        <div v-if="file.name" class="flex justify-between file-wrap">
-                          <p>{{ file.name }}</p>
-                          <button class="del-btn" @click="handleFileDelete(file, idx)">
-                            X
-                          </button>
-                        </div>
-                      </li>
-                    </ul>
-                  </div>
-                </div>
-              </td>
-            </tr>
-
-            <!-- 공지글 -->
-            <tr class="border-top">
-              <th class="text-lf">
-                공지글
-              </th>
-              <td colspan="3">
-                <div class="d-flex no-gutters">
-                  <div class="col-md-4">
-                    <input
-                      type="radio"
-                      name="notice"
-                      id="notice-y"
-                      class="mr5"
-                      value="Y"
-                      v-model="notice.isNotice"
-                    />
-                    <label for="notice-y">사용</label>
-                  </div>
-                  <div class="col-md-4">
-                    <input
-                      type="radio"
-                      name="notice"
-                      id="notice-n"
-                      class="mr5"
-                      value="N"
-                      v-model="notice.isNotice"
-                    />
-                    <label for="notice-n">미사용</label>
-                  </div>
-                </div>
-              </td>
-            </tr>
-
-            <!-- 공지글 게시기간 -->
-            <tr class="border-top">
-              <th class="text-lf">
-                공지글 게시기간
-              </th>
-              <td colspan="3">
-                <div class="d-flex no-gutters">
-                  <div class="col-md-4">
-                    <input
-                      type="datetime-local"
-                      class="form-control"
-                      v-model="notice.startDate"
-                      @change="checkDateValidity('startDate', $event)"
-                    />
-                  </div>
-                  <div class="pd-1">-</div>
-                  <div class="col-md-4">
-                    <input
-                      type="datetime-local"
-                      class="form-control"
-                      v-model="notice.endDate"
-                      @change="checkDateValidity('endDate', $event)"
-                    />
-                  </div>
-                </div>
-              </td>
-            </tr>
-
-            <!-- 비밀글 -->
-            <tr class="border-top">
-              <th class="text-lf">
-                비밀글
-              </th>
-              <td colspan="3">
-                <div class="d-flex no-gutters">
-                  <div class="col-md-4">
-                    <input
-                      type="radio"
-                      name="private"
-                      id="private-y"
-                      class="mr5"
-                      value="Y"
-                      v-model="notice.isPrivate"
-                    />
-                    <label for="private-y">사용</label>
-                  </div>
-                  <div class="col-md-4">
-                    <input
-                      type="radio"
-                      name="private"
-                      id="private-n"
-                      class="mr5"
-                      value="N"
-                      v-model="notice.isPrivate"
-                    />
-                    <label for="private-n">미사용</label>
-                  </div>
-                </div>
-              </td>
-            </tr>
-          </tbody>
-        </table>
-        <div class="text-end">
-          <button class="btn btn-primary" @click="handleInsert">
-            {{ notice.id == null ? "등록" : "수정" }}
-          </button>
-          <button class="btn btn-secondary" @click="handleCancel">취소</button>
-        </div>
-      </div>
-    </div>
-  </section>
-</template>
-
-<script>
-import UploadAdapter from './UploadAdapter.js'
-
-
-export default {
-  data() {
-    return {
-      editor: null,
-      notice: {
-        id: null,
-        title: "",
-        isNotice: "Y",
-        startDate: null,
-        endDate: null,
-        isPrivate: "N",
-        
-      },
-      fileList: [],
-    };
-  },
-  methods: {
-    handleCancel() {
-      if (!confirm("등록을 취소하시겠습니까?")) {
-        return;
-      }
-      this.$router.push({ path: "/list.page" });
-    },
-
-    handleFileInsert() {
-      this.fileList = [...this.fileList, ...Array.from(this.$refs.file.files)];
-    },
-
-    handleFileDelete(file, index) {
-      this.fileList.splice(index, 1);
-    },
-
-    handleInsert() {
-      if (!this.validate()) {
-        return;
-      }
-
-      if (this.notice.id == null) {
-        this.saveNotice();
-      } else {
-        this.updateNotice();
-      }
-    },
-
-    saveNotice() {
-      alert("공지사항이 등록되었습니다.");
-      this.$router.push({ path: "/view.page", query: { pageId: this.notice.id } });
-    },
-
-    updateNotice() {
-      alert("공지사항이 수정되었습니다.");
-      this.$router.push({ path: "/view.page", query: { pageId: this.notice.id } });
-    },
-
-    validate() {
-      if (!this.notice.title.trim()) {
-        alert("제목을 입력해주세요.");
-        return false;
-      }
-
-      if (!this.notice.content.trim()) {
-        alert("내용을 입력해주세요.");
-        return false;
-      }
-
-      if (this.notice.isNotice === "Y" && (!this.notice.startDate || !this.notice.endDate)) {
-        alert("공지기간을 올바르게 설정해주세요.");
-        return false;
-      }
-
-      return true;
-    },
-
-    checkDateValidity(field, event) {
-      const val = event.target.value;
-      if (field === "startDate" && this.notice.endDate && this.notice.endDate < val) {
-        alert("시작일은 종료일보다 클 수 없습니다.");
-        this.notice.startDate = null;
-      } else if (field === "endDate" && this.notice.startDate && this.notice.startDate > val) {
-        alert("종료일은 시작일보다 작을 수 없습니다.");
-        this.notice.endDate = null;
-      }
-    },
-
-    beforeUnmount() {
-      if (this.editor) {
-        this.editor.destroy().then(() => {
-          this.editor = null;
-        });
-      }
-    },
-
-    MyCustomUploadAdapterPlugin: function(editor) {
-        editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
-            console.log('loader', loader);
-            return new UploadAdapter(loader);
-        }
-    }
-  },
-  mounted() {
-},
-
-MyCustomUploadAdapterPlugin(editor) {
-   editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
-       console.log('loader', loader);
-       return new UploadAdapter(loader);
-   }
-},
-};
-</script>
-
-<style scoped>
-td,
-th {
-  padding: 1rem;
-}
-th {
-  width: 10rem;
-}
-#file {
-  position: absolute;
-  width: 0;
-  height: 0;
-  padding: 0;
-  overflow: hidden;
-  border: 0;
-}
-</style>
client/views/pages/Manager/approval/ChuljangInsert.vue (Renamed from client/views/pages/Employee/ChuljangInsert.vue)
--- client/views/pages/Employee/ChuljangInsert.vue
+++ client/views/pages/Manager/approval/ChuljangInsert.vue
No changes
client/views/pages/Manager/approval/HyugaInsert.vue (Renamed from client/views/pages/Employee/HyugaInsert.vue)
--- client/views/pages/Employee/HyugaInsert.vue
+++ client/views/pages/Manager/approval/HyugaInsert.vue
No changes
client/views/pages/Manager/approval/approval.vue (Renamed from client/views/pages/Manager/DeptList.vue)
--- client/views/pages/Manager/DeptList.vue
+++ client/views/pages/Manager/approval/approval.vue
@@ -1,64 +1,46 @@
 <template>
-  <div class="pagetitle">
-    <h2>부서관리</h2>
+  <div class="sidemenu">
+    <div class="myinfo simple">
+            <div class="name-box">
+                <div class="img-area">
+                    <div><img :src="photoicon" alt="">
+                        <p class="name">OOO과장</p>
+                    </div>
+                    <div class="info">
+                        <p>솔루션 개발팀</p>
+                        <i class="fa-bars"></i>
+                        <p>팀장</p>
+                    </div>
+                </div>
+            </div>
+           
+            <h2>결재</h2>
+            <ul class="menu-box">
+              <li>
+      <router-link to="/approvalRequest.page" exact-active-class="active-link" v-slot="{ isExactActive }">
+        <p>결재 요청</p>
+        <div class="icon" v-if="isExactActive">
+          <img :src="menuicon" alt="">
+        </div>
+      </router-link>
+      
+    </li>
+    <li>
+      <router-link to="/approvalList.page" exact-active-class="active-link" v-slot="{ isExactActive }">
+        <p>승인 대기 목록</p>
+        <div class="icon" v-if="isExactActive">
+          <img :src="menuicon" alt="">
+        </div>
+      </router-link>
+    </li>
+                </ul>
+        </div>
   </div>
   <!-- End Page Title -->
-  <section class="section">
-    <div class="row">
+  <div class="content">
+    <router-view></router-view>
 
-
-      <div class="col-lg-12">
-        <div class="card">
-          <div class="card-body">
-            <h5 class="card-title">부서관리</h5>
-            <div class="d-flex pb-3 justify-content-end ">
-
-              <div class="d-flex justify-content-end ">
-                <button @click="onClickSubmit">api 요청하기</button>
-                <button type="button" class="btn btn-outline-primary" @click="registerLeave">
-                  등록
-                </button>
-                <button type="button" class="btn btn-outline-success" @click="saveChanges">
-                  저장
-                </button>
-                <button type="button" class="btn btn-outline-secondary" @click="deletePending">
-                  삭제
-                </button>
-              </div>
-
-            </div>
-            <!-- Table  -->
-            <table id="myTable" class="table datatable table-hover">
-              <!-- 동적으로 <th> 생성 -->
-              <thead>
-                <tr>
-                  <th>No </th>
-                  <th>부서명</th>
-                  <th>인원</th>
-                </tr>
-              </thead>
-              <!-- 동적으로 <td> 생성 -->
-              <tbody>
-                <tr v-for="(item, index) in DeptData">
-                  <td>
-                    <div class="form-check">
-                      <label class="form-check-label" for="acceptTerms">{{ index + 1 }}</label>
-                      <input v-model="item.acceptTerms" class="form-check-input" type="checkbox" />
-                    </div>
-                  </td>
-                  <td><input type="text" v-model="item.deptNM" /></td>
-                  <td><input type="text" v-model="item.member" /></td>
-
-                </tr>
-              </tbody>
-            </table>
-
-            <!-- End Table -->
-          </div>
-        </div>
-      </div>
-    </div>
-  </section>
+</div>
 </template>
 
 <script>
@@ -67,6 +49,8 @@
 export default {
   data() {
     return {
+      photoicon: "/client/resources/img/photo_icon.png",
+      menuicon: "/client/resources/img/menuicon.png",
       // 데이터 초기화
       years: [2023, 2024, 2025], // 연도 목록
       months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록
 
client/views/pages/Manager/approval/approvalList.vue (added)
+++ client/views/pages/Manager/approval/approvalList.vue
@@ -0,0 +1,233 @@
+<template>
+  <div class="col-lg-12">
+    <div class="card">
+      <div class="card-body">
+        <h2 class="card-title">승인 대기 목록</h2>
+        <div class="sch-form-wrap title-wrap">
+          <h3><img :src="h3icon" alt="">승인 대기</h3>
+          <div class="input-group">
+            <select name="" id="" class="form-select">
+              <option value="">년도</option>
+            </select>
+            <select name="" id="" class="form-select">
+              <option value="">월</option>
+            </select>
+            <div class="sch-input">
+              <input type="text" class="form-control">
+              <button class="ico-sch"><SearchOutlined /></button>
+            </div>
+          </div>
+        </div>
+
+        <!-- Table  -->
+        <div class="tbl-wrap">
+          <table id="myTable" class="tbl data">
+            <!-- 동적으로 <th> 생성 -->
+            <thead>
+              <tr>
+                <th>구분 </th>
+                <th>결재구분</th>
+                <th>신청자</th>
+                <th>기간</th>
+                <th>신청일</th>
+                <th>상태</th>
+              </tr>
+            </thead>
+            <!-- 동적으로 <td> 생성 -->
+            <tbody>
+              <tr v-for="(item, index) in listData" :key="index" :class="{ 'expired': isPastPeriod(item.period) }">
+                <td>{{ item.type }}</td>
+                <td>{{ item.approvalType }}</td>
+                <td>{{ item.applicant }}</td>
+                <td>{{ item.period }}</td>
+                <td>{{ item.requestDate }}</td>
+                <td :class="getStatusClass(item.status)">{{ item.status }}</td>
+              </tr>
+            </tbody>
+          </table>
+
+        </div>
+        <div class="pagination">
+          <ul>
+            <!-- 왼쪽 화살표 (이전 페이지) -->
+            <li class="arrow" :class="{ disabled: currentPage === 1 }" @click="changePage(currentPage - 1)">
+              &lt;
+            </li>
+
+            <!-- 페이지 번호 -->
+            <li v-for="page in totalPages" :key="page" :class="{ active: currentPage === page }"
+              @click="changePage(page)">
+              {{ page }}
+            </li>
+
+            <!-- 오른쪽 화살표 (다음 페이지) -->
+            <li class="arrow" :class="{ disabled: currentPage === totalPages }" @click="changePage(currentPage + 1)">
+              &gt;
+            </li>
+          </ul>
+        </div>
+        <div class="sch-form-wrap title-wrap">
+          <h3><img :src="h3icon" alt="">승인 이력</h3>
+          <div class="input-group">
+            <select name="" id="" class="form-select">
+              <option value="">년도</option>
+            </select>
+            <select name="" id="" class="form-select">
+              <option value="">월</option>
+            </select>
+            <select name="" id="" class="form-select">
+              <option value="">상태</option>
+            </select>
+            <div class="sch-input">
+              <input type="text" class="form-control">
+              <button class="ico-sch"><SearchOutlined /></button>
+            </div>
+          </div>
+        </div>
+
+        <!-- Table  -->
+        <div class="tbl-wrap">
+          <table id="myTable" class="tbl data">
+            <!-- 동적으로 <th> 생성 -->
+            <thead>
+              <tr>
+                <th>구분 </th>
+                <th>결재구분</th>
+                <th>신청자</th>
+                <th>기간</th>
+                <th>신청일</th>
+                <th>상태</th>
+              </tr>
+            </thead>
+            <!-- 동적으로 <td> 생성 -->
+            <tbody>
+              <tr v-for="(item, index) in listData" :key="index" :class="{ 'expired': isPastPeriod(item.period) }">
+                <td>{{ item.type }}</td>
+                <td>{{ item.approvalType }}</td>
+                <td>{{ item.applicant }}</td>
+                <td>{{ item.period }}</td>
+                <td>{{ item.requestDate }}</td>
+                <td :class="getStatusClass(item.status)">{{ item.status }}</td>
+              </tr>
+            </tbody>
+          </table>
+
+        </div>
+        <div class="pagination">
+          <ul>
+            <!-- 왼쪽 화살표 (이전 페이지) -->
+            <li class="arrow" :class="{ disabled: currentPage === 1 }" @click="changePage(currentPage - 1)">
+              &lt;
+            </li>
+
+            <!-- 페이지 번호 -->
+            <li v-for="page in totalPages" :key="page" :class="{ active: currentPage === page }"
+              @click="changePage(page)">
+              {{ page }}
+            </li>
+
+            <!-- 오른쪽 화살표 (다음 페이지) -->
+            <li class="arrow" :class="{ disabled: currentPage === totalPages }" @click="changePage(currentPage + 1)">
+              &gt;
+            </li>
+          </ul>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { ref } from 'vue';
+import { SearchOutlined } from '@ant-design/icons-vue';
+export default {
+  data() {
+    return {
+      currentPage: 1,
+      totalPages: 3,
+      photoicon: "/client/resources/img/photo_icon.png",
+      h3icon: "/client/resources/img/h3icon.png",
+      // 데이터 초기화
+      years: [2023, 2024, 2025], // 연도 목록
+      months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록
+      selectedYear: '',
+      selectedMonth: '',
+      listData: [
+        {
+          type: '연차',
+          approvalType: '결재',
+          applicant: '홍길동',
+          period: '2025-05-10 ~ 2025-15-03',
+          requestDate: '2025-04-25',
+          status: '대기'
+        }, {
+          type: '반차',
+          approvalType: '전결',
+          applicant: '홍길동',
+          period: '2025-05-01 ~ 2025-05-03',
+          requestDate: '2025-04-25',
+          status: '승인'
+        }],
+      filteredData: [],
+    };
+  },
+  computed: {
+  },
+  components:{
+    SearchOutlined
+  },
+  methods: {
+    changePage(page) {
+      if (page < 1 || page > this.totalPages) return;
+      this.currentPage = page;
+      this.$emit('page-changed', page); // 필요 시 부모에 알림
+    },
+    async onClickSubmit() {
+      // `useMutation` 훅을 사용하여 mutation 함수 가져오기
+      const { mutate, onDone, onError } = useMutation(mygql);
+
+      try {
+        const result = await mutate();
+        console.log(result);
+      } catch (error) {
+        console.error('Mutation error:', error);
+      }
+    },
+    registerLeave() {
+      console.log("등록 버튼 클릭됨");
+
+      // Vue의 반응성 문제를 피하기 위해, 새로운 객체를 추가합니다.
+      this.DeptData = [
+        ...this.DeptData,
+        { member: '', deptNM: '', acceptTerms: false }
+      ];
+
+      console.log(this.DeptData); // 배열 상태 출력
+    },
+    getStatusClass(status) {
+      if (status === '승인') return 'status-approved';
+      if (status === '대기') return 'status-pending';
+      return '';
+    },
+    isPastPeriod(period) {
+      // 예: '2025-05-01 ~ 2025-05-03' → 종료일 추출
+      const endDateStr = period.split('~')[1]?.trim();
+      if (!endDateStr) return false;
+
+      const endDate = new Date(endDateStr);
+      const today = new Date();
+
+      // 현재 날짜보다 과거면 true
+      return endDate < today;
+    }
+  },
+  created() {
+  },
+  mounted() {
+
+
+  },
+};
+</script>
+
+<style scoped></style>(파일 끝에 줄바꿈 문자 없음)
 
client/views/pages/Manager/approval/approvalRequest.vue (added)
+++ client/views/pages/Manager/approval/approvalRequest.vue
@@ -0,0 +1,186 @@
+<template>
+<div class="col-lg-12">
+  <div class="card">
+    <div class="card-body">
+      <h2 class="card-title">결재 요청</h2>
+      <div class="sch-form-wrap">
+        <div class="input-group">
+          <select name="" id="" class="form-select">
+          <option value="">년도</option>
+        </select>
+          <select name="" id="" class="form-select">
+          <option value="">월</option>
+        </select>
+          <select name="" id="" class="form-select">
+          <option value="">구분</option>
+        </select>
+        </div>
+      </div>
+     
+      <!-- Table  -->
+      <div class="tbl-wrap">
+        <table id="myTable" class="tbl data">
+          <!-- 동적으로 <th> 생성 -->
+          <thead>
+            <tr>
+              <th>구분 </th>
+              <th>결재구분</th>
+              <th>신청자</th>
+              <th>기간</th>
+              <th>신청일</th>
+              <th>상태</th>
+            </tr>
+          </thead>
+          <!-- 동적으로 <td> 생성 -->
+          <tbody>
+            <tr v-for="(item, index) in listData" :key="index" :class="{ 'expired': isPastPeriod(item.period) }">
+    <td>{{ item.type }}</td>
+    <td>{{ item.approvalType }}</td>
+    <td>{{ item.applicant }}</td>
+    <td>{{ item.period }}</td>
+    <td>{{ item.requestDate }}</td>
+    <td :class="getStatusClass(item.status)">{{ item.status }}</td>
+  </tr>
+          </tbody>
+        </table>
+  
+      </div>
+      <div class="pagination">
+        <ul>
+      <!-- 왼쪽 화살표 (이전 페이지) -->
+      <li 
+        class="arrow" 
+        :class="{ disabled: currentPage === 1 }" 
+        @click="changePage(currentPage - 1)"
+      >
+      &lt;
+      </li>
+
+      <!-- 페이지 번호 -->
+      <li 
+        v-for="page in totalPages" 
+        :key="page" 
+        :class="{ active: currentPage === page }" 
+        @click="changePage(page)"
+      >
+        {{ page }}
+      </li>
+
+      <!-- 오른쪽 화살표 (다음 페이지) -->
+      <li 
+        class="arrow" 
+        :class="{ disabled: currentPage === totalPages }" 
+        @click="changePage(currentPage + 1)"
+      >
+      &gt;
+      </li>
+    </ul>
+  </div>
+      <!-- End Table -->
+      <div class="buttons">
+    <button type="button" class="btn sm primary" @click="showOptions = true">
+      등록
+    </button>
+
+    <!-- 신청 종류 선택 모달 -->
+    <div v-if="showOptions" class="modal-overlay">
+      <div class="modal-box">
+        <p>신청 종류를 선택하세요</p>
+        <button @click="goToPage('휴가')">휴가신청</button>
+        <button @click="goToPage('출장')">출장신청</button>
+        <button class="cancel" @click="showOptions = false">취소</button>
+      </div>
+    </div>
+  </div>
+    </div>
+  </div>
+</div>
+</template>
+
+<script>
+import { ref } from 'vue';
+
+export default {
+  data() {
+    return {
+      showOptions: false,
+      currentPage: 1,
+      totalPages: 3,
+      photoicon: "/client/resources/img/photo_icon.png",
+      // 데이터 초기화
+      years: [2023, 2024, 2025], // 연도 목록
+      months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록
+      selectedYear: '',
+      selectedMonth: '',
+      listData: [
+  {
+    type: '연차',
+    approvalType: '결재',
+    applicant: '홍길동',
+    period: '2025-05-10 ~ 2025-15-03',
+    requestDate: '2025-04-25',
+    status: '대기'
+  },   {
+    type: '반차',
+    approvalType: '전결',
+    applicant: '홍길동',
+    period: '2025-05-01 ~ 2025-05-03',
+    requestDate: '2025-04-25',
+    status: '승인'
+  }],
+      filteredData: [],
+    };
+  },
+  computed: {
+  },
+  methods: {
+    changePage(page) {
+      if (page < 1 || page > this.totalPages) return;
+      this.currentPage = page;
+      this.$emit('page-changed', page); // 필요 시 부모에 알림
+    },
+    async onClickSubmit() {
+      // `useMutation` 훅을 사용하여 mutation 함수 가져오기
+      const { mutate, onDone, onError } = useMutation(mygql);
+
+      try {
+        const result = await mutate();
+        console.log(result);
+      } catch (error) {
+        console.error('Mutation error:', error);
+      }
+    },
+    goToPage(type) {
+  if (type === '휴가') {
+    this.$router.push('/HyugaInsert.page');
+  } else if (type === '출장') {
+    this.$router.push('/ChuljangInsert.page');
+  }
+},
+    getStatusClass(status) {
+      if (status === '승인') return 'status-approved';
+      if (status === '대기') return 'status-pending';
+      return '';
+    },
+    isPastPeriod(period) {
+    // 예: '2025-05-01 ~ 2025-05-03' → 종료일 추출
+    const endDateStr = period.split('~')[1]?.trim();
+    if (!endDateStr) return false;
+
+    const endDate = new Date(endDateStr);
+    const today = new Date();
+
+    // 현재 날짜보다 과거면 true
+    return endDate < today;
+  }
+  },
+  created() {
+  },
+  mounted() {
+
+
+  },
+};
+</script>
+
+<style scoped></style>
client/views/pages/Manager/asset/asset.vue (Renamed from client/views/pages/Manager/PubHoliyday.vue)
--- client/views/pages/Manager/PubHoliyday.vue
+++ client/views/pages/Manager/asset/asset.vue
No changes
client/views/pages/Manager/attendance/attendance.vue (Renamed from client/views/pages/Manager/EmployeeList.vue)
--- client/views/pages/Manager/EmployeeList.vue
+++ client/views/pages/Manager/attendance/attendance.vue
No changes
client/views/pages/Manager/financial/financial.vue (Renamed from client/views/pages/Manager/NoticeInsert.vue)
--- client/views/pages/Manager/NoticeInsert.vue
+++ client/views/pages/Manager/financial/financial.vue
No changes
client/views/pages/Manager/hr/hr.vue (Renamed from client/views/pages/Employee/ProjectInsert.vue)
--- client/views/pages/Employee/ProjectInsert.vue
+++ client/views/pages/Manager/hr/hr.vue
No changes
client/views/pages/Manager/system/system.vue (Renamed from client/views/pages/Employee/ProjectList.vue)
--- client/views/pages/Employee/ProjectList.vue
+++ client/views/pages/Manager/system/system.vue
No changes
client/views/pages/Manager/task/task.vue (Renamed from client/views/pages/Manager/NoticeList.vue)
--- client/views/pages/Manager/NoticeList.vue
+++ client/views/pages/Manager/task/task.vue
No changes
client/views/pages/User/Join.vue
--- client/views/pages/User/Join.vue
+++ client/views/pages/User/Join.vue
@@ -87,7 +87,7 @@
       level: '',
       acceptTerms: false,
       formSubmitted: false,
-      logo: "/client/resources/img/logo_t.png", // 경로를 Vue 프로젝트 구조에 맞게 설정
+      logo: "/client/resources/img/logo.png", // 경로를 Vue 프로젝트 구조에 맞게 설정
     };
   },
   methods: {
client/views/pages/User/Login.vue
--- client/views/pages/User/Login.vue
+++ client/views/pages/User/Login.vue
@@ -1,68 +1,30 @@
 <template>
-  <div class="container">
-
-    <section class="section register min-vh-100 d-flex flex-column align-items-center justify-content-center py-4">
-      <div class="container">
-        <div class="row justify-content-center">
-          <div class="col-lg-4 col-md-6  align-items-center justify-content-center">
-            <div class="d-flex justify-content-center py-4">
-              <a href="index.html" class="logo d-flex align-items-center w-auto">
-
-                <!-- <span class="d-none d-lg-block"> <img :src="logo" alt=""></span> -->
-              </a>
-            </div><!-- End Logo -->
-
-            <div class="card mb-3">
-
+  <div class="">
+    <div class="card mb-3">
               <div class="card-body">
-
-                <div class=" pb-2">
-                  <h2 class="card-title text-center pb-0 fs-4">로그인</h2>
+                <div class="pb-2">
+                  <h2 class="card-title text-center pb-0 fs-4"><img :src="logo" alt="로고"></h2>
                 </div>
 
-                <form class="row g-3 needs-validation" :class="{ 'was-validated': formSubmitted }" novalidate
-                  @submit.prevent="handleLogin">
-
-                  <div class="col-12">
-                    <label for="yourUsername" class="form-label">E-mail</label>
+                <form class="row g-3 needs-validation" :class="{ 'was-validated': formSubmitted }" novalidate @submit.prevent="handleLogin">
+                  <div class="box">
+                    <label for="yourUsername" class="form-label"><img :src="idIcon" alt="아이디 아이콘">아이디</label>
                     <div class="input-group has-validation">
-                      <input v-model="email" type="text" name="username" class="form-control" id="yourUsername"
-                        required>
-                      <div class="invalid-feedback">회사 이메일을 입력해주세요.</div>
+                      <input v-model="id" type="text" name="username" class="form-control" id="yourUsername" placeholder="아이디를 입력하세요." required>
                     </div>
                   </div>
 
-                  <div class="col-12">
-                    <label for="yourPassword" class="form-label">Password</label>
-                    <input v-model="password" type="password" name="password" class="form-control" id="yourPassword"
-                      required>
-                    <div class="invalid-feedback">비밀번호를 입력해주세요.</div>
+                  <div class="box">
+                    <label for="yourPassword" class="form-label"><img :src="passwordIcon" alt="비밀번호 아이콘">비밀번호</label>
+                    <input v-model="password" type="password" name="password" class="form-control" id="yourPassword" placeholder="비밀번호를 입력하세요." required>
                   </div>
 
-                  <div class="col-12">
-                    <div class="form-check">
-                      <input class="form-check-input" type="checkbox" name="remember" value="true" id="rememberMe">
-                      <label class="form-check-label" for="rememberMe">로그인 유지하기</label>
-                    </div>
-                  </div>
-                  <div class="col-12">
-                    <button class="btn btn-primary w-100" type="submit">로그인</button>
-                  </div>
-                  <div class="col-12">
-                    <p class="small mb-0"> <router-link to="Join">회원가입</router-link></p>
+                  <div class="box">
+                    <button class="btn" type="submit"><img :src="loginIcon" alt="로그인 아이콘">로그인</button>
                   </div>
                 </form>
-
               </div>
             </div>
-
-
-          </div>
-        </div>
-      </div>
-
-    </section>
-
   </div>
 </template>
 
@@ -71,40 +33,31 @@
   data() {
     return {
       // 임시 로그인 정보
-      email: '',
-      password: '',
+      idIcon: "/client/resources/img/id.png",
+      passwordIcon: "/client/resources/img/password.png",
+      loginIcon: "/client/resources/img/loginicon.png",
       formSubmitted: false,
-      logo: "/client/resources/img/logo_t.png", // 경로를 Vue 프로젝트 구조에 맞게 설정
+      logo: "/client/resources/img/logo.png", // 경로를 Vue 프로젝트 구조에 맞게 설정
+      id: "admin", // 임시 아이디
+      password: "1234", // 임시 비밀번호
     };
   },
   methods: {
     handleLogin() {
       this.formSubmitted = true;
-      if (!this.email.includes('@')) {
-        alert('이메일은 @를 포함해야 합니다.');
-        return; // Stop further processing if email is invalid
-      }
-      console.log('Email:', this.email);
-      console.log('Password:', this.password);
-      const user = JSON.parse(localStorage.getItem("UserInfo"));
-      if (user) {
-        console.log('Stored Email:', user.email);
-        console.log('Stored Password:', user.password);
 
-        // 이메일과 비밀번호 비교
-        if (this.email === user.email && this.password === user.password) {
-          alert('로그인 성공!');
-          this.$router.push("/"); // 로그인 성공 후 메인 페이지로 이동
-        } else {
-          alert('로그인 실패: 이메일 또는 비밀번호가 잘못되었습니다.');
-        }
+      // Check if credentials are correct
+      if (this.id === "admin" && this.password === "1234") {
+        // Set logged in status in localStorage
+        localStorage.setItem('isLoggedIn', 'true');
+
+        // Redirect to the main page after successful login
+        this.$router.push('/');
       } else {
-        console.log('등록되지 않은 회원입니다.');
+        // Handle incorrect login attempt
+        console.log("아이디 또는 비밀번호가 틀렸습니다.");
       }
-
     },
   },
 };
 </script>
-
-<style scoped></style>
(파일 끝에 줄바꿈 문자 없음)
client/views/pages/User/MyPage.vue
--- client/views/pages/User/MyPage.vue
+++ client/views/pages/User/MyPage.vue
@@ -1,5 +1,23 @@
 <template>
-  <div class="container">
+  <div class="sidemenu">
+    <div class="myinfo profile">
+            <div class="name-box">
+              <div class="img-area">
+    <div class="img">
+      <img :src="previewImg || placeholder" alt="미리보기 이미지" />
+      <button class="close-btn" @click="removeImage">&#215;</button>
+    </div>
+    <div class="info">
+      <div class="file">
+        <label for="fileUpload" class="file-label"><div><img :src="file" alt=""></div><p>업로드</p></label>
+        <input id="fileUpload" type="file" @change="handleFileUpload" accept="image/*" />
+      </div>
+    </div>
+  </div>
+            </div>
+        </div>
+  </div>
+  <div class="content">
 
         <div class="d-flex justify-content-center py-4">
           <a href="index.html" class="logo d-flex align-items-center w-auto">
@@ -8,65 +26,69 @@
         </div><!-- End Logo -->
 
         <div class="card mb-3">
-
+          <p class="require"><img :src="require" alt=""> 필수입력</p>
           <div class="card-body">
-
-            <div class=" pb-2">
-              <h2 class="card-title text-center pb-0 fs-4">마이페이지</h2>
-            </div>
 
             <form class="row g-3 needs-validation "  :class="{ 'was-validated': formSubmitted }" @submit.prevent="handleRegister" novalidate>
               <div class="col-12">
-                <label for="yourName" class="form-label">이름</label>
-                <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required>
-                <div class="invalid-feedback">이름을 입력해주세요.</div>
+                <label for="yourName" class="form-label">아이디</label>
+                <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required readonly placeholder="admin">
               </div>
-              <div class="col-12">
-            <label for="yourdept" class="form-label">부서</label>
-            <select v-model="dept" id="inputState" class="form-select">
-              <option value="" disabled selected>부서를 선택하세요</option>
-      <option v-for="(item, index) in DeptData" :key="index" :value="item.deptNM">
-        {{ item.deptNM }}
-      </option>
-            </select>
+              <div class="col-12 ">
+                <div class="col-12 border-x">
+                  <label for="youremail" class="form-label ">이름<p class="require"><img :src="require" alt=""></p></label>
+                  <input  v-model="email" type="text" name="username" class="form-control" id="youremail" required >
+                </div>
+  
+                <div class="col-12 border-x">
+                  <label for="yourPassword" class="form-label">부서</label>
+                  <input  v-model="password" type="password" name="password" class="form-control" id="yourPassword" required  readonly placeholder="주식회사 테이큰 소프트"> 
+                </div>
+             </div>
+             <div class="col-12">
+                <div class="col-12 border-x">
+                  <label for="youremail" class="form-label">직급</label>
+                  <input  v-model="email" type="text" name="username" class="form-control" id="youremail" required readonly placeholder="과장">
+                </div>
+  
+                <div class="col-12 border-x">
+                  <label for="yourPassword" class="form-label">직책</label>
+                  <input  v-model="password" type="password" name="password" class="form-control" id="yourPassword" required readonly placeholder="팀장"> 
+                </div>
+             </div>
+             <div class="col-12">
+                <label for="yourName" class="form-label">연락처</label>
+                <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required>
           </div>
           <div class="col-12">
-                <label for="yourlevel" class="form-label">직급</label>
-                <select v-model="level" id="yourlevel" class="form-select">
-                  <option value="" disabled selected>직급을 선택하세요</option>
-              <option value="level0">계약직(인턴)</option>
-              <option value="level1">사원</option>
-              <option value="level2">주임</option>
-              <option value="level3">대리</option>
-              <option value="level4">과장</option>
-            </select>
-              </div>
-              <div class="col-12">
-                <label for="youremail" class="form-label">Email</label>
-                <div class="input-group has-validation">
-                  <input  v-model="email" type="text" name="username" class="form-control" id="youremail" required readonly>
-                  <div class="invalid-feedback">회사 이메일을 입력해주세요.</div>
-                </div>
-              </div>
-
-              <div class="col-12">
-                <label for="yourPassword" class="form-label">비밀번호 변경</label>
-                <input  v-model="password" type="password" name="password" class="form-control" id="yourPassword" required > 
-                <div class="invalid-feedback">비밀번호를 입력해주세요.</div>
-              </div>
-
-              <div class="col-12">
-                <div class="form-check">
-                  <!-- <input v-model="acceptTerms"  class="form-check-input" name="terms" type="checkbox" value="" id="acceptTerms" required> -->
-                  <!-- <label class="form-check-label" for="acceptTerms">이용약관에 동의합니다.</label> -->
-                  <div class="invalid-feedback">이용약관에 동의하셔야 합니다.</div>
-                </div>
-              </div>
-              <div class="col-12">
-                <button class="btn btn-primary w-100"  type="submit">수정</button>
-              </div>
+                <label for="yourName" class="form-label">생년월일</label>
+                <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required>
+          </div>
+          <div class="col-12">
+                <label for="yourName" class="form-label">입사일</label>
+                <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required readonly  placeholder="2025-01-01">
+          </div>
+          <div class="col-12">
+                <label for="yourName" class="form-label">현재 비밀번호</label>
+                <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required>
+          </div>
+          <div class="col-12">
+                <label for="yourName" class="form-label">새 비밀번호</label>
+               <div class="box">
+                  <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required>
+                  <div class="invalid-feedback">※ 비밀번호는 6~12자의 영문자와 숫자, 특수기호조합으로 작성해주세요.</div>
+               </div>
+          </div>
+          <div class="col-12 border-x">
+                <label for="yourName" class="form-label">연락처</label>
+                <input  v-model="name" type="text" name="name" class="form-control" id="yourName" required>
+          </div>
+              
             </form>
-
+            <div class="buttons">
+                <button class="btn btn-red w-100"  type="submit">회원탈퇴</button>
+                <button class="btn secondary w-100"  type="submit">수정</button>
+              </div>
           </div>
         </div>
   </div>
@@ -77,6 +99,10 @@
     export default {
   data() {
     return {
+      previewImg: null,
+      placeholder: "/client/resources/img/img1.png",
+      require: "/client/resources/img/require.png",
+      file: "/client/resources/img/file.png",
       name: '',
       email: '',
       password: '',
@@ -84,10 +110,27 @@
       level: '',
       acceptTerms: false,
       formSubmitted: false,
-      logo: "/client/resources/img/logo_t.png", // 경로를 Vue 프로젝트 구조에 맞게 설정
     };
   },
   methods: {
+    handleFileUpload(event) {
+      const file = event.target.files[0];
+      if (file && file.type.startsWith('image/')) {
+        const reader = new FileReader();
+        reader.onload = (e) => {
+          this.previewImg = e.target.result; // 파일 읽기 완료 후 미리보기 이미지 설정
+        };
+        reader.readAsDataURL(file); // 파일을 데이터 URL로 읽기
+      } else {
+        alert('이미지 파일만 선택할 수 있습니다.');
+      }
+    },
+    
+    // 이미지 삭제 함수
+    removeImage() {
+      this.previewImg = null; // 미리보기 이미지 삭제
+      this.$refs.fileUpload.value = null; // 파일 input 초기화
+    },
     handleRegister() {
       this.formSubmitted = true; 
       // 이메일과 비밀번호가 빈 값이 아니어야 한다
client/views/pages/main/Main.vue
--- client/views/pages/main/Main.vue
+++ client/views/pages/main/Main.vue
@@ -1,17 +1,167 @@
 <template>
-    <div> <GoogleCalendar/></div>
+    <div class="sidemenu">
+        <div class="myinfo">
+            <div class="name-box">
+                <div class="img-area">
+                    <div><img :src="photoicon" alt="">
+                        <p class="name">OOO과장</p>
+                    </div>
+                    <div class="info">
+                        <p>솔루션 개발팀</p>
+                        <i class="fa-bars"></i>
+                        <p>팀장</p>
+                    </div>
+                </div>
+            </div>
+            <ul class="info-box">
+                <li>
+                    <p>5</p>
+                    <div class="name yellow">신청</div>
+                </li>
+                <li>
+                    <p>5</p>
+                    <div class="name ">신청</div>
+                </li>
+                <li>
+                    <p>5</p>
+                    <div class="name blue">신청</div>
+                </li>
+                <li>
+                    <p>5</p>
+                    <div class="name red">신청</div>
+                </li>
+            </ul>
+        </div>
+        <div class="boxs">
+            <div class="box">
+                <div class="img-area"><img :src="img1" alt=""></div>
+                <div class="sm-box">
+                    <h3>연차 잔여일수</h3>
+                    <p>11.5</p>
+                </div>
+            </div>
+            <div class="bd-box">
+                <div>전체 <span>15</span></div>
+                <i class="fa-bars"></i>
+                <div>사용 <span>3.5</span></div>
+            </div>
+        </div>
+        <div class="boxs">
+            <h4><img :src="icon1" alt="">01월 근태현황</h4>
+            <div class="color-boxs">
+                <div class="box red">
+                    <h3>지각</h3>
+                    3
+                </div>
+                <div class="box">
+                    <h3>조기퇴근</h3>
+                    3
+                </div>
+                <div class="box green">
+                    <h3>결근</h3>
+                    3
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="content">
+        <div class="top-content">
+            <div class="boxs">
+
+                <div class="title">
+                    <h2>근무체크 <span>출근전</span></h2>
+                    <div class="sub"><img :src="dateicon" alt="">{{ today }}</div>
+                </div>
+                <div class="blue-box">
+                    <div class="box">
+                        <p class="time">{{ time }}</p>
+                    </div>
+                    <div class="buttons">
+                        <button><img :src="startbtn" alt=""></button>
+                        <i class="fa-bars"></i>
+                        <button><img :src="stopbtn" alt=""></button>
+                    </div>
+                </div>
+
+            </div>
+            <div class="boxs">
+                <div class="title">
+                    <h2>오늘의 주요 </h2>
+                    <div class="sub">더보기<img :src="moreicon" alt=""></div>
+                </div>
+                <div class="board tbl-wrap">
+                    <table class="tbl data">
+                        <tbody>
+                            <tr v-for="(item, index) in requestList" :key="index" >
+                                <td :class="getCategoryClass(item.category)">
+                                    <p>{{ item.category }}</p>
+                                </td>
+                                <td>{{ item.name }}</td>
+                                <td>{{ item.startdate }} ~ {{ item.enddate }}</td>
+                                <td class="status" :class="getStatusClass(item.status)">
+                                    <p>{{ item.status }}</p>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+        <GoogleCalendar />
+    </div>
 </template>
 
 <script>
 import GoogleCalendar from "../../component/GoogleCalendar.vue"
 
 export default {
-    data () {
+    data() {
         return {
+            photoicon: "/client/resources/img/photo_icon.png",
+            img1: "/client/resources/img/img.png",
+            icon1: "/client/resources/img/icon.png",
+            dateicon: "/client/resources/img/date.png",
+            startbtn: "/client/resources/img/start.png",
+            stopbtn: "/client/resources/img/stop.png",
+            moreicon: "/client/resources/img/more.png",
+            today: new Date().toLocaleDateString('ko-KR', {
+                year: 'numeric',
+                month: '2-digit',
+                day: '2-digit',
+                weekday: 'short',
+            }),
+            time: this.getCurrentTime(),
+            requestList: [
+                { category: '용역', name: '프로젝트1', startdate: '2025-04-30', enddate: '2025-04-30', status: '진행중' },
+                { category: '내부', name: '프로젝트2', startdate: '2025-05-01', enddate: '2025-04-30', status: '진행전' },
+                { category: '국가과제', name: '프로젝트2', startdate: '2025-05-01', enddate: '2025-04-30', status: '완료' }
+            ]
         }
     },
     methods: {
-
+        getCurrentTime() {
+            const now = new Date();
+            const hours = String(now.getHours()).padStart(2, '0');
+            const minutes = String(now.getMinutes()).padStart(2, '0');
+            const seconds = String(now.getSeconds()).padStart(2, '0');
+            return `${hours}:${minutes}:${seconds}`;
+        },
+        getCategoryClass(category) {
+        switch (category) {
+            case '용역': return 'category-service';
+            case '내부': return 'category-internal';
+            case '국가과제': return 'category-government';
+            default: return '';
+        }
+    },
+    getStatusClass(status) {
+        switch (status) {
+            case '진행중': return 'status-in-progress';
+            case '진행전': return 'status-not-started';
+            case '완료': return 'status-complete';
+            default: return '';
+        }
+    }
     },
     watch: {
 
@@ -24,6 +174,9 @@
     },
     mounted() {
         console.log('main mounted');
+        setInterval(() => {
+            this.time = this.getCurrentTime();
+        }, 1000);
     }
 }
 </script>
(파일 끝에 줄바꿈 문자 없음)
package-lock.json
--- package-lock.json
+++ package-lock.json
@@ -1,5 +1,5 @@
 {
-  "name": "vue_setting_scss-master",
+  "name": "calendar",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
Add a comment
List