Files
astra-frontend/src/components/base/BaseClientFormCreate.vue
2023-02-14 18:51:45 +03:00

529 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template lang="pug">
base-modal(v-model="value", hide-overlay, title="Создание клиента", draggable, height="696px" )
.wrapper-create.gap-y-8.flex.flex-col.pt-8
.flex.gap-x-4.h-fit
.flex.gap-x-3.w-full
q-btn(
color="secondary",
text-color="primary",
style="width: 40px; height: 40px",
rounded
no-caps
padding="0 16px"
)
q-icon(
v-if="image === defaultIcon"
name="app:icon-download",
)
q-avatar(
v-else,
size="40px",
round
)
img(:src="image")
q-menu(
anchor="bottom middle",
self="top right",
v-model="showPopup"
)
.flex.flex-col.p-4.gap-y-3
.flex.items-center.gap-x-2.cursor-pointer(@click="changeOpenModal")
q-icon(
name="app:computer",
size="18px",
color="primary"
)
span.text-smm.title Загрузить с компьютера
.flex.items-center.gap-x-2.cursor-pointer
q-icon(
name="app:camera",
size="18px",
color="primary"
)
span.text-smm.title Сделать фото
base-modal(v-model="showModal", title="Загрузить изображение")
.flex.flex-col.items-center.justify-center(
:style="{padding: '153px 370px'}"
)
.avatar-wrapper.flex.relative
base-input(
circle,
type="file",
id="image-upload",
accept="image/*",
@change="(e) => previewImage(e)"
)
.avatar.flex.absolute.items-center.gap-x-6
img.avatar.object-cover(for="image-upload", :src="image", v-if="image")
q-btn(
round,
color="primary",
@click="closeAddImage",
icon="app:icon-ok"
)
base-input.w-full(v-model="infoClient.basic.full_name", placeholder="ФИО*", outlined)
.flex.flex-col.flex-auto.l.gap-y-8
.flex
button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm(
v-for="form in forms",
@click="selectForm(form.component)",
:class="{active: form.component === currentForm}",
:key="form.id",
:id="form.id"
) {{form.title}}
component(
v-bind:is="currentForm",
:basic-info="infoClient.basic",
:phone="infoClient.phone",
:email="infoClient.email",
:save-network-id="saveNetworkId",
:add-network="addNewNetwork",
:choose-option="chooseOptionNetworks",
:choose-priority="choosePriority",
:priority-list="priorityList",
:identity-document="infoClient.identity_document",
:addresses="infoClient.addresses",
:save-file="saveDocFile",
)
q-btn(
label="Создать клиента",
color="primary",
style="height: 40px; width: 180px",
no-caps,
padding="8px 24px",
@click="saveClient",
)
</template>
<script>
import { column } from "@/pages/clients/utils/tableConfig";
import { fetchWrapper } from "@/shared/fetchWrapper";
import FormCreateBasicInfo from "@/pages/clients/components/FormCreateBasicInfo";
import FormCreateIdentityDocuments from "@/pages/clients/components/FormCreateIdentityDocuments";
import FormCreateAddresses from "@/pages/clients/components/FormCreateAddresses";
import BaseInput from "@/components/base/BaseInput";
import BasePopup from "@/components/base/BasePopup";
import BaseModal from "@/components/base/BaseModal";
import addImageIcon from "@/assets/icons/photo.svg";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { addNotification } from "@/components/Notifications/notificationContext";
import * as moment from "moment";
import { v_model } from "@/shared/mixins/v-model";
export default {
name: "BaseClientFormClient",
components: {
BaseInput,
FormCreateBasicInfo,
FormCreateIdentityDocuments,
FormCreateAddresses,
BasePopup,
BaseModal,
addImageIcon,
TheNotificationProvider,
},
props: {
setUpdatedClients: Function,
writeCreatedClientId: Function,
},
mixins: [v_model],
data() {
return {
networksSettings: column.find((el) => el.name === "networks"),
prioritySettings: column.find((el) => el.name === "priority"),
networkId: "",
infoClient: {
basic: {
full_name: "",
birth_date: null,
priority: {
id: null,
label: "",
},
contacts: [
{
id: "network",
kind: "TELEGRAM",
username: "",
icon: "icon-tg",
},
],
},
phone: {
kind: "PHONE",
username: "",
},
email: {
kind: "EMAIL",
username: "",
},
identity_document: {
pass: {
series_number: "",
issued_by_org: "",
issued_by_date: null,
issued_by_org_code: "",
},
snils: {
kind: "СНИЛС",
number: "",
},
inn: {
kind: "ИНН",
number: "",
},
},
addresses: {
full_address: "",
region: "",
city: "",
street: "",
house_number: "",
apartment_number: "",
zip_code: "",
},
additional: [
{
id: "add",
header: "",
description: "",
file: {},
},
],
},
forms: [
{
title: "Основное",
id: "basic",
component: "form-create-basic-info",
},
{
title: "ДУЛ",
id: "doc",
component: "form-create-identity-documents",
},
{
title: "Адрес",
id: "address",
component: "form-create-addresses",
},
],
currentForm: "form-create-basic-info",
priorityList: [
{
id: 1,
label: "Высокий",
},
{
id: 2,
label: "Средний",
},
{
id: 3,
label: "Низкий",
},
{
id: 4,
label: "-",
},
],
defaultIcon: addImageIcon,
showModal: false,
showPopup: false,
image: addImageIcon,
imageData: null,
};
},
computed: {
getPriorityList() {
return this.prioritySettings.settings.map((el) => {
return { label: el.text, id: el.id };
});
},
},
methods: {
previewImage(event) {
let picture = event.target.files;
let reader = new FileReader();
reader.onload = (e) => {
this.image = e.target.result;
};
reader.readAsDataURL(picture[0]);
this.imageData = [...event.target.files];
},
closeAddImage() {
this.showModal = false;
this.showPopup = false;
},
closePopup() {
this.showPopup = false;
},
closeModal() {
!this.showModal ? this.closeForm() : null;
},
createIdentityDocument(id) {
let filteredData = Object.keys(
this.filterDataEmptyProperty(this.infoClient.identity_document.pass)
);
if (filteredData.length > 0) {
if (filteredData.length < 4) {
this.addErrorNotification(
"Паспортные данные заполнены не полностью",
"Паспортные данные не будут записаны в профиль клиента"
);
} else if (
moment(this.infoClient.identity_document.pass.issued_by_date).isAfter(
moment().format("YYYY-MM-DD")
)
) {
this.addErrorNotification(
"Некорректная дата выдачи паспорта",
"Паспортные данные не будут записаны в профиль клиента"
);
} else
fetchWrapper.post("general/identity_document/create/", {
series_number: this.infoClient.identity_document.pass.series_number,
issued_by_org: this.infoClient.identity_document.pass.issued_by_org,
issued_by_date: moment(
this.infoClient.identity_document.pass.issued_by_date
).format("YYYY-MM-DD"),
issued_by_org_code:
this.infoClient.identity_document.pass.issued_by_org_code,
person: id,
kind: "Паспорт",
});
}
},
createAddress(id) {
Object.keys(this.filterDataEmptyProperty(this.infoClient.addresses))
.length > 0 &&
fetchWrapper.post("general/address/create/", {
...this.filterDataEmptyProperty(this.infoClient.addresses),
person: id,
});
},
createContacts(id) {
if (this.infoClient.phone.username)
fetchWrapper.post("general/contact/create/", {
...this.filterDataEmptyProperty(this.infoClient.phone),
person: id,
});
if (this.infoClient.email.username)
fetchWrapper.post("general/contact/create/", {
...this.filterDataEmptyProperty(this.infoClient.email),
person: id,
});
this.infoClient.basic.contacts.forEach((el) => {
if (el.username)
fetchWrapper.post("general/contact/create/", {
kind: el.kind,
username: el.username,
person: id,
});
});
},
postNewClient() {
const formData = new FormData();
formData.append("full_name", this.infoClient.basic.full_name);
if (this.imageData) formData.append("photo", this.imageData[0]);
if (this.infoClient.basic.birth_date)
formData.append(
"birth_date",
moment(this.infoClient.basic.birth_date).format("YYYY-MM-DD")
);
let foundElement = this.prioritySettings.settings.find(
(el) => el.priority === this.infoClient.basic.priority.id
);
if (foundElement.priority)
formData.append("priority", foundElement.priority);
fetchWrapper
.post("general/person/create/", formData, "formData")
.then((result) => {
if (result.id) {
this.createIdentityDocument(result.id);
this.createAddress(result.id);
this.createContacts(result.id);
this.writeCreatedClientId(result.id);
this.setUpdatedClients();
this.addSuccessNotification();
} else {
this.addErrorNotification(
"Клиент не создан",
"Произошла ошибка сервера"
);
}
});
},
filterDataEmptyProperty(data) {
let postData = data;
let keys = Object.keys(postData);
keys.forEach((key) => {
if (!postData[key]) {
delete postData[key];
}
});
return postData;
},
saveNetworkId(e) {
this.networkId = e.currentTarget.id;
},
choosePriority(e) {
this.infoClient.basic.priority = e.target.id;
},
chooseOptionNetworks(e) {
let index = this.infoClient.basic.contacts.findIndex(
(el) => el.id === this.networkId
);
let icon = this.networksSettings.settings.find(
(el) => el.network === e.target.id
).icon;
this.infoClient.basic.contacts[index].kind = e.target.id;
this.infoClient.basic.contacts[index].icon = icon;
},
saveClient() {
if (this.checkFormFullness()) {
this.postNewClient();
this.closeForm();
}
},
changeOpenModal() {
this.showModal = true;
this.showPopup = false;
},
saveDocFile(e) {
this.infoClient.doc = e.target.files;
},
saveAdditionalFiles(e) {
this.infoClient.additional.find((el) => el.id === e.target.id).file =
e.target.file;
},
addNewAdditionalInfo() {
this.infoClient.additional.push({
id:
this.infoClient.additional[0].id + this.infoClient.additional.length,
header: "",
description: "",
file: {},
});
},
addNewNetwork() {
this.infoClient.basic.contacts.push({
id:
this.infoClient.basic.contacts[0].id +
this.infoClient.basic.contacts.length,
kind: "TELEGRAM",
username: "",
icon: "icon-tg",
});
},
selectForm(componentName) {
this.currentForm = this.forms.find(
(elem) => elem.component === componentName
)?.component;
},
checkFormFullness() {
if (!this.infoClient.basic.full_name) {
this.addErrorNotification(
"Не заполнено ФИО клиента",
"Заполните ФИО клиента"
);
return false;
} else if (
this.infoClient.basic.birth_date &&
moment(this.infoClient.basic.birth_date).isAfter(
moment().format("YYYY-MM-DD")
)
) {
this.addErrorNotification(
"Некорректная дата рождения",
"Дата рождения позже текущего дня"
);
return false;
} else if (
this.infoClient.phone.username &&
this.infoClient.phone.username.length < 18
) {
this.addErrorNotification(
"Некорректный номер телефона",
"Введите мобильный номер, состоящий из 11 цифр"
);
return false;
}
return true;
},
addErrorNotification(title, message) {
addNotification(title, title, message, "error", 5000);
},
addSuccessNotification() {
addNotification(
"Клиент успешно создан",
"Клиент успешно создан",
"",
"success",
5000
);
},
},
watch: {
showModal: function () {
if (this.showModal === false) {
this.closeAddImage();
}
},
},
};
</script>
<style lang="sass" scoped>
.wrapper-create
width: 570px
.title
color: var(--font-dark-blue-color)
.export-avatar
min-width: 40px
height: 40px
border-radius: 50%
background-color: var(--bg-btn-icons-color)
color: var(--btn-blue-color)
&:hover
color: var(--default-white)
background-color: var(--btn-blue-color)
.title-info
color: var(--font-grey-color)
border-bottom: 1.5px solid var(--font-grey-color)
&:hover
color: var(--btn-blue-color)
border-bottom: 1.5px solid var(--btn-blue-color)
&.active
color: var(--btn-blue-color)
border-bottom: 1.5px solid var(--btn-blue-color)
.avatar-wrapper
width: 400px
height: 400px
border-radius: 50%
.avatar
height: 100%
border-radius: 50%
.current-avatar
cursor: pointer
height: 100%
border-radius: 50%
background-size: cover
background-repeat: no-repeat
background-position: center
&:hover
display: none
.wrapper-img
background-size: 20px
background-repeat: no-repeat
background-position: center
background-image: url(@/assets/icons/download.svg)
</style>