Skip to content
Snippets Groups Projects
Select Git revision
  • 2e0dd521b4a29930d5670a2c142a4400d7cffc1a
  • master default protected
2 results

index.html

Blame
  • ScheduleDetail.vue 7.85 KiB
    <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>