Skip to content
Snippets Groups Projects
Commit 1b7e09f7 authored by JunGu Kang's avatar JunGu Kang
Browse files

Merge branch '#21' into 'development'

#21 Add Schedule Detail View

See merge request !26
parents 8b155d63 57117601
Branches
No related tags found
2 merge requests!37Deploy,!26#21 Add Schedule Detail View
Pipeline #4334 passed
......@@ -43,6 +43,11 @@ const routes = [
name: 'ScheduleCreate',
component: () => import('../views/ScheduleCreate.vue'),
},
{
path: '/schedule/:id',
name: 'ScheduleDetail',
component: () => import('@/views/ScheduleDetail.vue'),
},
{
path: '/trainee',
name: 'TraineeList',
......
<template>
<div class="schedule-detail">
<v-row>
<v-col
cols="12"
>
<v-card
:loading="isProcessing"
>
<v-card-title>일정 정보</v-card-title>
<v-card-text>
<v-alert
v-if="error.isError"
dense
text
type="error"
>
{{ error.message }}
</v-alert>
<v-text-field
label="등록번호"
readonly
v-model="id"
></v-text-field>
<program-field
:program.sync="schedule.program"
></program-field>
<trainer-field
:trainer.sync="schedule.trainer"
></trainer-field>
<v-text-field
label="최대 예약 가능 인원"
v-model="schedule.maxTrainee"
></v-text-field>
<date-time-field
:datetime.sync="schedule.startAt"
></date-time-field>
<v-text-field
label="등록 시각"
readonly
v-model="schedule.createdAt"
></v-text-field>
<v-text-field
label="최종 수정 시각"
readonly
v-model="schedule.updatedAt"
></v-text-field>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="error"
outlined
@click="deleteSchedule(id)"
>
<v-icon
left
>
mdi-delete
</v-icon>
삭제
</v-btn>
<v-btn
color="primary"
outlined
@click="updateSchedule(id)"
>
<v-icon
left
>
mdi-content-save
</v-icon>
저장
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<v-row>
<v-col
cols="12"
>
<v-card
:loading="isProcessing"
>
<v-card-title>예약자</v-card-title>
<v-card-text>
<v-row
justify="end"
>
<v-col
cols="12"
sm="4"
md="3"
lg="3"
xl="2"
>
<v-text-field
append-icon="mdi-magnify"
clearable
label="회원 검색"
v-model="traineeList.searchKeyword"
></v-text-field>
</v-col>
</v-row>
<v-data-table
:headers="traineeList.headers"
item-key="id"
:items="schedule.trainees"
:loading="isProcessing"
loading-text="데이터를 불러오는 중입니다."
:search="traineeList.searchKeyword"
no-results-text="일치하는 회원을 찾지 못했습니다."
>
<template v-slot:item.action="{ item }">
<v-icon
small
class="mr-2"
@click="editTrainee(item.id)"
>
mdi-pencil
</v-icon>
<v-icon
small
@click="deleteTrainee(item.id)"
>
mdi-delete
</v-icon>
</template>
</v-data-table>
</v-card-text>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import APISetting from '@/settings/api';
import DateTimeField from '@/components/DateTimeField.vue';
import ProgramField from '@/components/ProgramField.vue';
import TrainerField from '@/components/TrainerField.vue';
export default {
name: 'ScheduleDetail',
components: {
DateTimeField,
ProgramField,
TrainerField,
},
data: () => ({
isProcessing: false,
error: {
isError: false,
message: '',
},
traineeList: {
headers: [
{
text: '#',
value: 'id',
},
{
text: '이름',
value: 'name',
},
{
text: '이메일',
value: 'email',
},
{
text: '연락처',
value: 'phone',
},
{
text: '',
value: 'action',
sortable: false,
},
],
data: [],
searchKeyword: '',
},
schedule: {
program: {
title: '',
},
trainer: {
name: '',
},
maxTrainee: '',
startAt: '',
createdAt: '',
updatedAt: '',
},
}),
computed: {
id() {
if ('id' in this.$route.params) return this.$route.params.id;
return null;
},
},
methods: {
getSchedule(id) {
this.error.isError = false;
this.error.message = '';
this.isProcessing = true;
fetch(APISetting.endpoints.schedule.detail(id), APISetting.settings.get)
.then((res) => {
if (res.status === 404) return Promise.all([null, res]);
if ([200, 400, 500].includes(res.status)) return Promise.all([res.json(), res]);
throw new Error('알 수 없는 응답입니다.');
})
.then((values) => {
const [json, res] = values;
if (res.status === 404) throw new Error('존재하지 않는 데이터입니다.');
if (res.status !== 200) throw new Error(json.message);
this.schedule = json.schedule;
})
.catch((e) => {
this.error.message = e.message;
this.error.isError = true;
})
.finally(() => {
this.isProcessing = false;
});
},
updateSchedule(id) {
this.error.isError = false;
this.error.message = '';
this.isProcessing = true;
fetch(APISetting.endpoints.schedule.detail(id), APISetting.settings.put(this.schedule))
.then((res) => {
if (res.status === 404) return Promise.all([null, res]);
if ([200, 400, 404, 500].includes(res.status)) return Promise.all([res.json(), res]);
throw new Error('알 수 없는 응답입니다.');
})
.then((values) => {
const [json, res] = values;
if (res.status === 404) throw new Error('존재하지 않는 데이터입니다.');
if (res.status !== 200) throw new Error(json.message);
this.schedule = json.schedule;
})
.catch((e) => {
this.error.message = e.message;
this.error.isError = true;
})
.finally(() => {
this.isProcessing = false;
});
},
deleteSchedule(id) {
this.error.isError = false;
this.error.message = '';
this.isProcessing = true;
fetch(APISetting.endpoints.schedule.detail(id), APISetting.settings.delete)
.then((res) => {
if ([204, 404].includes(res.status)) return Promise.all([null, res]);
if ([204, 400, 404, 500].includes(res.status)) return Promise.all([res.json(), res]);
// If response status is not equal to 204, 400, 404, or 500, go to catch.
throw new Error('알 수 없는 응답입니다.');
})
.then((values) => {
const [json, res] = values;
if (res.status === 404) throw new Error('존재하지 않는 데이터입니다.');
if (res.status !== 204) throw new Error(json.message);
return this.$router.push('/schedule');
})
.catch((e) => {
this.error.message = e.message;
this.error.isError = true;
})
.finally(() => {
this.isProcessing = false;
});
},
editTrainee(id) {
this.$router.push(`/trainee/${id}`);
},
},
created() {
this.getSchedule(this.id);
},
};
</script>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment