Skip to content

Instantly share code, notes, and snippets.

@ElpixZero
Created October 5, 2020 16:06
Show Gist options
  • Save ElpixZero/19e976d617ba1cb200eef24be2e5aca7 to your computer and use it in GitHub Desktop.
Save ElpixZero/19e976d617ba1cb200eef24be2e5aca7 to your computer and use it in GitHub Desktop.
<template>
<section class="widget">
<div class="widget__content">
<div class="olimp">
<template v-if="!isLoading">
<h2 class="olimp__title olimp__title--welcome">
Чемпионат сочинений "Своими словами"
</h2>
<h2 class="olimp__title">
Выберите направление и площадку проведения регионального этапа
</h2>
<form class="olimp__form" @submit.prevent="checkBeforeSending">
<div class="olimp__form-body">
<ul class="olimp__list olimp__list--address">
<li class="olimp__item olimp__item--address">
<span class="olimp__title-input">Населенный пункт*</span>
<el-autocomplete
v-model.trim="$v.address.$model"
:fetch-suggestions="searchAddress"
:disabled="isRegisteredOlympics"
@input="addressOnInput"
@select="addressOnSelect"
/>
</li>
<li class="olimp__item">
<span class="olimp__title-input">Номер школы*</span>
<el-input
placeholder=""
v-model.trim="$v.school.$model"
:disabled="isRegisteredOlympics"
/>
</li>
<li class="olimp__item">
<span class="olimp__title-input">Направление олимпиады*</span>
<el-select
v-model.trim="$v.olympiadDirection.$model"
placeholder=""
:disabled="isRegisteredOlympics"
>
<el-option
v-for="direction in olympiadDirections"
:key="direction.id"
:label="direction.name"
:value="direction.id"
>
</el-option>
</el-select>
</li>
</ul>
<ul class="olimp__list olimp__list--university">
<li class="olimp__item olimp__item--before">
ВУЗ соорганизатор
</li>
<li class="olimp__item olimp__item--main">
<span class="olimp__title-input">Основной*</span>
<el-select
v-model.trim="$v.universityMain.$model"
:disabled="isRegisteredOlympics"
placeholder=""
@change="updateUniversityAdditional"
>
<el-option
v-for="university in universities"
:key="university.id"
:label="university.name"
:value="university.id"
>
</el-option>
</el-select>
</li>
<li class="olimp__item">
<span class="olimp__title-input">Дополнительный</span>
<el-select
v-model="universityAdditional"
multiple
:disabled="isRegisteredOlympics"
:class="{ 'olim__select-disabled': isRegisteredOlympics }"
placeholder=""
>
<el-option
v-for="university in dataUniversityAdditional"
:key="university.id"
:label="university.name"
:value="university.id"
>
</el-option>
</el-select>
</li>
</ul>
</div>
<div class="olimp__btn">
<button
class="btn btn--olimp"
:class="{
'btn--primary-disabled': $v.validationGroup.$invalid,
}"
type="submit"
:disabled="false"
>
<template v-if="!isRegisteredOlympics">Сохранить</template>
<template v-else>Отменить</template>
</button>
</div>
</form>
</template>
<loading v-else />
</div>
</div>
</section>
</template>
<script>
import Axios from '@/utils/Elk-Axios';
import setNotification from '@/utils/setNotification';
import {
GET_OLIMP_INFO,
SET_OLIMPIAD_PARTICIPANT,
DELETE_OLYMPIAD_PARTICIPANT,
} from '@/api';
import loading from '@/components/common/elkLoading';
import getDadata from '@/utils/getDadata';
import { required } from 'vuelidate/lib/validators';
export default {
name: 'form-olimp',
data() {
return {
olympiadDirection: null,
address: null,
school: null,
universityMain: null,
universityAdditional: null,
data: null,
isLoading: false,
isRegisteredOlympics: false,
olympiadDirections: [],
universities: [],
isChosenAddressValid: false,
};
},
validations: {
olympiadDirection: { required },
address: {
required,
isChosenAddressValid: function () {
return this.isChosenAddressValid;
},
},
school: { required },
universityMain: { required },
validationGroup: [
'olympiadDirection',
'address',
'school',
'universityMain',
],
},
computed: {
dataUniversityAdditional() {
if (this.universityMain) {
return this.universities.filter(
(item) => item.id !== this.universityMain
);
}
return this.universities;
},
},
components: {
loading,
},
methods: {
setNotification,
getDadata,
addressOnInput() {
if (this.isChosenAddressValid) {
this.isChosenAddressValid = false;
}
},
addressOnSelect() {
if (!this.isChosenAddressValid) {
this.isChosenAddressValid = true;
}
},
updateUniversityAdditional() {
this.universityAdditional = this.universityAdditional.filter(
(item) => item !== this.universityMain
);
},
checkBeforeSending() {
if (
this.isRegisteredOlympics === false &&
!this.$v.validationGroup.$invalid
) {
this.setOlympiadParticipant();
}
if (this.isRegisteredOlympics === true) {
this.deleteOlympiadParticipant();
}
},
updateIsRegisteredOlympics(data) {
const {
olympiad_direction,
school_number,
settlement_name,
university,
} = data;
this.isRegisteredOlympics = !!(
olympiad_direction &&
school_number &&
settlement_name &&
university
);
},
addStoredInformation(data) {
const {
olympiad_direction,
school_number,
second_university,
settlement_name,
university,
} = data;
this.olympiadDirection = olympiad_direction;
this.school = school_number;
this.universityAdditional = second_university;
this.address = settlement_name;
this.universityMain = university;
},
async searchAddress(queryString, cb) {
if (queryString) {
try {
const data = await this.getDadata('urlAddress', queryString);
if (data) {
const address = data.suggestions.map((item) => ({
value: item.value,
}));
cb(address);
} else {
cb([]);
}
} catch (err) {
cb([]);
if (!err.isHandled) {
this.setNotification({
message: `Не удалось получить адреса. Попробуйте позже или обратитесь в службу поддержки`,
});
}
}
} else {
cb([]);
}
},
async getOlimpInfo() {
try {
this.isLoading = true;
const { data } = await Axios.get(GET_OLIMP_INFO);
if (
data &&
Array.isArray(data.olympiad_directions) &&
Array.isArray(data.universities) &&
typeof data.stored_information['olympiad_direction'] !==
'undefined' &&
typeof data.stored_information['school_number'] !== 'undefined' &&
typeof data.stored_information['second_university'] !== 'undefined' &&
typeof data.stored_information['university'] !== 'undefined' &&
typeof data.stored_information['settlement_name'] !== 'undefined'
) {
this.addStoredInformation(data.stored_information);
this.updateIsRegisteredOlympics(data.stored_information);
this.universities = data.universities;
this.olympiadDirections = data.olympiad_directions;
} else {
// sentry
throw new Error();
}
} catch (err) {
if (!err.isHandled) {
this.setNotification({
message: `Не удалось получить информацию о олимпиадах. Попробуйте позже или обратитесь в службу поддержки`,
});
}
} finally {
this.isLoading = false;
}
},
async setOlympiadParticipant() {
try {
this.isLoading = true;
const { status } = await Axios.post(SET_OLIMPIAD_PARTICIPANT, {
settlement_name: this.address,
school_number: this.school,
olympiad_direction_id: this.olympiadDirection,
university_id: this.universityMain,
second_university_id: this.universityAdditional,
});
if (status === 200) {
this.isRegisteredOlympics = true;
} else {
// sentry
throw new Error();
}
} catch (err) {
if (!err.isHandled) {
this.setNotification({
message: `Не удалось зарегистрироваться на олимпиаду. Попробуйте позже или обратитесь в службу поддержки`,
});
}
} finally {
this.isLoading = false;
}
},
async deleteOlympiadParticipant() {
try {
this.isLoading = true;
const { status } = await Axios.delete(DELETE_OLYMPIAD_PARTICIPANT);
if (status === 200) {
this.isRegisteredOlympics = false;
this.olympiadDirection = null;
this.school = null;
this.universityAdditional = null;
this.address = null;
this.universityMain = null;
}
} catch (err) {
if (!err.isHandled) {
this.setNotification({
message: `Не удалось отменить регистрацию на олимпиаду. Попробуйте позже или обратитесь в службу поддержки`,
});
}
} finally {
this.isLoading = false;
}
},
},
created() {
this.getOlimpInfo();
},
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment