Skip to content

Commit

Permalink
Merge pull request #37 from Triumers/feat/manager
Browse files Browse the repository at this point in the history
[Feature] 직원 조회 기능 구현 및 직책 관리, 직급 관리 기능 구현
  • Loading branch information
Leegiyeon authored Jun 6, 2024
2 parents 1109bd8 + a140d96 commit 6141922
Show file tree
Hide file tree
Showing 6 changed files with 520 additions and 15 deletions.
3 changes: 3 additions & 0 deletions src/components/common/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
</li>
</ul>
</li>
<li class="nav-item">
<router-link class="nav-link" to="/search-employee">직원 조회</router-link>
</li>
</div>
</template>

Expand Down
131 changes: 131 additions & 0 deletions src/components/employee/SearchEmployee.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<template>
<div class="container">
<div>
<h1>직원 조회</h1>
</div>
<div style="height: 20px;"></div>
<div class="search-container">
<input
type="text"
v-model="searchKeyword"
placeholder="이름 검색"
class="search-input"
@input="searchEmployees"
/>
</div>
<div v-if="employees.length === 0 && searchKeyword !== ''" class="no-results">
검색 결과가 없습니다.
</div>
<div class="employee-list">
<div
v-for="employee in employees"
:key="employee.id"
class="employee-item"
>
<div class="employee-name">{{ employee.name }}</div>
<div class="employee-email">{{ employee.email }}</div>
<div class="employee-team">{{ employee.team.name }}</div>
<div class="employee-position">{{ employee.position.name }}</div>
<div class="employee-rank">{{ employee.rank.name }}</div>
<div class="employee-start-date">{{ employee.startDate }}</div>
<div class="employee-end-date">{{ employee.endDate }}</div>
<div class="employee-phone-number">{{ employee.phoneNumber }}</div>
</div>
</div>
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';
const searchKeyword = ref('');
const employees = ref([]);
onMounted(async () => {
await searchEmployees();
});
async function searchEmployees() {
try {
const token = localStorage.getItem('token');
const response = await axios.post('http://localhost:5000/employee/find/name', {
name: searchKeyword.value,
}, {
headers: {
Authorization: token,
},
});
employees.value = response.data.employee;
} catch (error) {
console.error('Failed to search employees:', error);
alert('직원 검색에 실패했습니다. 다시 시도해주세요.');
}
}
</script>

<style scoped>
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.search-container {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.search-input {
flex: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.search-button-wrapper {
margin-left: 10px;
}
.search-button {
padding: 10px 20px;
background-color: #042444;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}
.search-button:hover {
background-color: #1b2cba;
}
.no-results {
text-align: center;
font-style: italic;
color: #888;
margin-bottom: 20px;
}
.employee-list {
display: grid;
grid-template-columns: repeat(1, 1fr);
gap: 20px;
}
.employee-item {
background-color: #f5f5f5;
padding: 20px;
border-radius: 4px;
}
.employee-name {
font-size: 18px;
font-weight: bold;
margin-bottom: 5px;
}
.employee-email,
.employee-team,
.employee-position,
.employee-rank,
.employee-start-date,
.employee-end-date,
.employee-phone-number {
font-size: 14px;
color: #888;
margin-bottom: 5px;
}
</style>
168 changes: 168 additions & 0 deletions src/components/manager/ManagePosition.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<template>
<div class="container">
<h2>직책 관리</h2>
<div class="form-container">
<h3>직책 생성</h3>
<input type="text" v-model="newPosition" placeholder="새로운 직책명" />
<button @click="createPosition">생성</button>
</div>
<div class="form-container">
<h3>직책 수정</h3>
<select v-model="selectedPositionId">
<option v-for="position in positions" :key="position.id" :value="position.id">
{{ position.name }}
</option>
</select>
<input type="text" v-model="editedPosition" placeholder="수정할 직책명" />
<button @click="updatePosition">수정</button>
</div>
<div class="form-container">
<h3>직책 삭제</h3>
<select v-model="selectedPositionIdToDelete">
<option v-for="position in positions" :key="position.id" :value="position.id">
{{ position.name }}
</option>
</select>
<button @click="deletePosition">삭제</button>
</div>
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';
const positions = ref([]);
const newPosition = ref('');
const selectedPositionId = ref('');
const editedPosition = ref('');
const selectedPositionIdToDelete = ref('');
onMounted(async () => {
await fetchPositions();
});
async function fetchPositions() {
try {
const token = localStorage.getItem('token');
const response = await axios.get('http://localhost:5000/duty/find/position/all', {
headers: {
Authorization: token,
},
});
positions.value = response.data.position;
} catch (error) {
console.error('Failed to fetch positions:', error);
alert('직책 정보를 불러오는데 실패했습니다. 다시 시도해주세요.');
}
}
async function createPosition() {
try {
const token = localStorage.getItem('token');
await axios.post('http://localhost:5000/manager/duty/add/position', {
positionName: newPosition.value,
}, {
headers: {
Authorization: token,
},
});
newPosition.value = '';
await fetchPositions();
} catch (error) {
console.error('Failed to create position:', error);
alert('직책 생성에 실패했습니다. 다시 시도해주세요.');
}
}
async function updatePosition() {
try {
const token = localStorage.getItem('token');
await axios.put('http://localhost:5000/manager/duty/edit/position', {
positionId: selectedPositionId.value,
positionName: editedPosition.value,
}, {
headers: {
Authorization: token,
},
});
editedPosition.value = '';
selectedPositionId.value = '';
await fetchPositions();
} catch (error) {
console.error('Failed to update position:', error);
alert('직책 수정에 실패했습니다. 다시 시도해주세요.');
}
}
async function deletePosition() {
try {
const token = localStorage.getItem('token');
await axios.delete('http://localhost:5000/manager/duty/remove/position', {
data: {
positionId: selectedPositionIdToDelete.value,
},
headers: {
Authorization: token,
},
});
selectedPositionIdToDelete.value = '';
await fetchPositions();
} catch (error) {
console.error('Failed to delete position:', error);
alert('직책 삭제에 실패했습니다. 다시 시도해주세요.');
}
}
</script>

<style scoped>
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.form-container {
margin-bottom: 20px;
}
h2 {
font-size: 24px;
margin-bottom: 20px;
}
h3 {
font-size: 18px;
margin-bottom: 10px;
}
input[type="text"] {
width: 300px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
margin-right: 10px;
}
select {
width: 300px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
margin-right: 10px;
}
button {
padding: 10px 20px;
background-color: #042444;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}
button:hover {
background-color: #1b2cba;
}
</style>
Loading

0 comments on commit 6141922

Please sign in to comment.