diff --git a/src/components/TrainerField.vue b/src/components/TrainerField.vue new file mode 100644 index 0000000000000000000000000000000000000000..a1e233ee2e6f3862de6a8c29af0ed0582494c1c4 --- /dev/null +++ b/src/components/TrainerField.vue @@ -0,0 +1,168 @@ +<template> + <v-dialog + v-model="dialog" + > + <template + v-slot:activator="{ on }" + > + <v-text-field + label="트레이너" + readonly + v-model="trainer.name" + v-on="on" + ></v-text-field> + </template> + <v-card> + <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="trainerList.searchKeyword" + ></v-text-field> + </v-col> + </v-row> + <v-data-table + :headers="trainerList.headers" + item-key="id" + :items="trainerList.data" + :loading="isProcessing" + loading-text="데이터를 불러오는 중입니다." + no-results-text="일치하는 트레이너를 찾지 못했습니다." + :search="trainerList.searchKeyword" + > + <template + v-slot:item.action="{ item }" + > + <v-btn + color="success" + outlined + small + @click="select(item)" + > + <v-icon + left + > + mdi-check + </v-icon> + 선택 + </v-btn> + </template> + </v-data-table> + </v-card-text> + <v-card-actions> + <v-spacer></v-spacer> + <v-btn + color="secondary" + outlined + @click="close()" + > + <v-icon + left + >mdi-close</v-icon> + 닫기 + </v-btn> + </v-card-actions> + </v-card> + </v-dialog> +</template> + +<script> +import APISetting from '@/settings/api'; + +export default { + name: 'TrainerField', + + props: ['trainer'], + + data: () => ({ + isProcessing: false, + error: { + isError: false, + message: '', + }, + dialog: false, + trainerList: { + headers: [ + { + text: '#', + value: 'id', + }, + { + text: '이름', + value: 'name', + }, + { + text: '닉네임', + value: 'nickname', + }, + { + text: '이메일', + value: 'email', + }, + { + text: '연락처', + value: 'phone', + }, + { + text: '소개', + value: 'bio', + }, + { + text: '', + value: 'action', + sortable: false, + }, + ], + data: [], + searchKeyword: '', + }, + }), + + methods: { + getTrainerList() { + this.error.isError = false; + this.error.message = ''; + this.isProcessing = true; + + fetch(APISetting.endpoints.trainer.list, APISetting.settings.get) + .then((res) => { + if (res.status === 200) return res.json(); + throw new Error('알 수 없는 응답입니다.'); + }) + .then((json) => { + this.trainerList.data = json.trainers; + }) + .catch((e) => { + this.error.message = e.message; + this.error.isError = true; + }) + .finally(() => { + this.isProcessing = false; + }); + }, + select(trainer) { + this.$emit('update:trainer', trainer); + this.close(); + }, + close() { + this.dialog = false; + }, + }, + + created() { + this.getTrainerList(); + }, +}; +</script>