Merge pull request #165 from dderbentsov/UC-90

[WIP] Добавил возможность добавления аватара клиенту
This commit is contained in:
frontgavrilin
2022-11-29 19:15:42 +03:00
committed by GitHub
7 changed files with 151 additions and 27 deletions

View File

@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.82689 6.1749C6.46581 6.75354 5.86127 7.13398 5.186 7.22994C4.80655 7.28386 4.42853 7.34223 4.05199 7.40497C2.99912 7.58042 2.25 8.50663 2.25 9.57402V18C2.25 19.2426 3.25736 20.25 4.5 20.25H19.5C20.7426 20.25 21.75 19.2426 21.75 18V9.57403C21.75 8.50664 21.0009 7.58043 19.948 7.40498C19.5715 7.34223 19.1934 7.28387 18.814 7.22995C18.1387 7.13398 17.5342 6.75354 17.1731 6.17491L16.3519 4.85889C15.9734 4.25237 15.3294 3.85838 14.6155 3.82005C13.7496 3.77355 12.8775 3.75 12 3.75C11.1225 3.75 10.2504 3.77355 9.3845 3.82005C8.6706 3.85838 8.02658 4.25237 7.64809 4.85889L6.82689 6.1749Z" stroke="#4772F2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16.5 12.75C16.5 15.2353 14.4853 17.25 12 17.25C9.51472 17.25 7.5 15.2353 7.5 12.75C7.5 10.2647 9.51472 8.25 12 8.25C14.4853 8.25 16.5 10.2647 16.5 12.75Z" stroke="#4772F2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.75 10.5H18.7575V10.5075H18.75V10.5Z" stroke="#4772F2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.75 17.25C9.75 16.8358 9.41421 16.5 9 16.5C8.58579 16.5 8.25 16.8358 8.25 17.25H9.75ZM8.12132 20.3787L8.65165 20.909L8.12132 20.3787ZM7.5 21L6.96967 20.4697C6.75517 20.6842 6.691 21.0068 6.80709 21.287C6.92318 21.5673 7.19665 21.75 7.5 21.75V21ZM16.5 21V21.75C16.8033 21.75 17.0768 21.5673 17.1929 21.287C17.309 21.0068 17.2448 20.6842 17.0303 20.4697L16.5 21ZM15.8787 20.3787L16.409 19.8483H16.409L15.8787 20.3787ZM15.75 17.25C15.75 16.8358 15.4142 16.5 15 16.5C14.5858 16.5 14.25 16.8358 14.25 17.25H15.75ZM8.25 17.25V18.2574H9.75V17.25H8.25ZM7.59099 19.8484L6.96967 20.4697L8.03033 21.5303L8.65165 20.909L7.59099 19.8484ZM7.5 21.75H16.5V20.25H7.5V21.75ZM17.0303 20.4697L16.409 19.8483L15.3483 20.909L15.9697 21.5303L17.0303 20.4697ZM15.75 18.2574V17.25H14.25V18.2574H15.75ZM16.409 19.8483C15.9871 19.4264 15.75 18.8541 15.75 18.2574H14.25C14.25 19.2519 14.6451 20.2057 15.3484 20.909L16.409 19.8483ZM8.25 18.2574C8.25 18.8541 8.01295 19.4264 7.59099 19.8484L8.65165 20.909C9.35491 20.2057 9.75 19.2519 9.75 18.2574H8.25ZM5.25 3.75H18.75V2.25H5.25V3.75ZM20.25 5.25V15H21.75V5.25H20.25ZM18.75 16.5H5.25V18H18.75V16.5ZM3.75 15V5.25H2.25V15H3.75ZM5.25 16.5C4.42157 16.5 3.75 15.8284 3.75 15H2.25C2.25 16.6569 3.59315 18 5.25 18V16.5ZM20.25 15C20.25 15.8284 19.5784 16.5 18.75 16.5V18C20.4069 18 21.75 16.6569 21.75 15H20.25ZM18.75 3.75C19.5784 3.75 20.25 4.42157 20.25 5.25H21.75C21.75 3.59315 20.4069 2.25 18.75 2.25V3.75ZM5.25 2.25C3.59315 2.25 2.25 3.59315 2.25 5.25H3.75C3.75 4.42157 4.42157 3.75 5.25 3.75V2.25ZM20.25 5.25V12H21.75V5.25H20.25ZM18.75 13.5H5.25V15H18.75V13.5ZM3.75 12V5.25H2.25V12H3.75ZM5.25 13.5C4.42157 13.5 3.75 12.8284 3.75 12H2.25C2.25 13.6569 3.59315 15 5.25 15V13.5ZM20.25 12C20.25 12.8284 19.5784 13.5 18.75 13.5V15C20.4069 15 21.75 13.6569 21.75 12H20.25Z" fill="#4772F2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,6 @@
<svg width="90" height="90" viewBox="0 0 90 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="45" cy="45" r="44" stroke="#252850" stroke-width="1.5" stroke-linecap="round" stroke-dasharray="8 8"/>
<path d="M36.3781 35.2915C35.7763 36.2559 34.7688 36.89 33.6433 37.0499C33.0109 37.1398 32.3809 37.237 31.7533 37.3416C29.9985 37.634 28.75 39.1777 28.75 40.9567V55C28.75 57.0711 30.4289 58.75 32.5 58.75H57.5C59.5711 58.75 61.25 57.0711 61.25 55V40.9567C61.25 39.1777 60.0015 37.634 58.2467 37.3416C57.6191 37.2371 56.9891 37.1398 56.3567 37.0499C55.2312 36.89 54.2237 36.2559 53.6219 35.2915L52.2532 33.0982C51.6224 32.0873 50.549 31.4306 49.3592 31.3667C47.9159 31.2892 46.4626 31.25 45 31.25C43.5374 31.25 42.0841 31.2892 40.6408 31.3667C39.451 31.4306 38.3776 32.0873 37.7468 33.0982L36.3781 35.2915Z" stroke="#252850" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M52.5 46.25C52.5 50.3921 49.1421 53.75 45 53.75C40.8579 53.75 37.5 50.3921 37.5 46.25C37.5 42.1079 40.8579 38.75 45 38.75C49.1421 38.75 52.5 42.1079 52.5 46.25Z" stroke="#252850" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M56.25 42.5H56.2625V42.5125H56.25V42.5Z" stroke="#252850" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -4,12 +4,47 @@
span.title.text-xl.font-bold.px-4 Создание клиента span.title.text-xl.font-bold.px-4 Создание клиента
.flex.gap-x-4.h-fit.px-4 .flex.gap-x-4.h-fit.px-4
.flex.gap-x-3.w-full .flex.gap-x-3.w-full
base-button(:rounded="true" :secondary="true" :size="40") base-button.relative(
.icon-download.text-xl :rounded="true",
:secondary="true",
:size="40",
@click="changeOpenPopup",
v-for="img in image"
)
.icon-download.text-xl(v-if="img === defaultIcon")
.flex.w-10.h-10(v-else)
img.current-avatar(:src="img")
base-popup.right-5.top-7(v-if="showPopup", :width="230")
.flex.items-center.gap-x-2
img(src="@/assets/icons/computer.svg")
span.text-smm(@click="changeOpenModal") Загрузить с компьютера
.flex.items-center.gap-x-2
img(src="@/assets/icons/camera.svg")
span.text-smm Сделать фото
base-modal(v-model="showModal", title="Загрузить изображение")
.flex.flex-col.items-center.justify-center(
:style="{padding: '153px 370px'}"
)
.avatar-wrapper.flex.relative
input.input(
type="file",
id="image-upload",
accept="image/*",
@change="(e) => previewImages(e)"
)
.avatar.flex.absolute.items-center.gap-x-6(v-for="img in image")
img.avatar(for="image-upload", :src="img", v-if="img")
base-button(:rounded="true", :size="48", @click="closeModal")
.icon-ok
base-input.w-full(v-model:value="infoClient.basic.full_name" placeholder="ФИО*") base-input.w-full(v-model:value="infoClient.basic.full_name" placeholder="ФИО*")
.flex.flex-col.flex-auto.l.gap-y-8 .flex.flex-col.flex-auto.l.gap-y-8
.flex.px-4 .flex.px-4
button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm(v-for="info in listInfoTitle" @click="(e) => selectTab(e)" :class="{active:info.active}" :key="info.key" :id="info.key") {{info.title}} button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm(
v-for="info in listInfoTitle",
@click="(e) => selectTab(e)",
:class="{active:info.active}",
:key="info.key" :id="info.key"
) {{info.title}}
.flex(:style="{display :'block'}" ref="basic") .flex(:style="{display :'block'}" ref="basic")
form-create-basic-info( form-create-basic-info(
:basic-info="infoClient.basic" :basic-info="infoClient.basic"
@@ -53,6 +88,9 @@ import FormCreateAddresses from "@/pages/clients/components/FormCreateAddresses"
import FormCreateAdditional from "@/pages/clients/components/FormCreateAdditional"; import FormCreateAdditional from "@/pages/clients/components/FormCreateAdditional";
import BaseInput from "@/components/base/BaseInput"; import BaseInput from "@/components/base/BaseInput";
import BaseButton from "@/components/base/BaseButton"; import BaseButton from "@/components/base/BaseButton";
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 TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { addNotification } from "@/components/Notifications/notificationContext"; import { addNotification } from "@/components/Notifications/notificationContext";
export default { export default {
@@ -64,6 +102,9 @@ export default {
FormCreateAddresses, FormCreateAddresses,
FormCreateAdditional, FormCreateAdditional,
BaseButton, BaseButton,
BasePopup,
BaseModal,
addImageIcon,
TheNotificationProvider, TheNotificationProvider,
}, },
props: { props: {
@@ -169,6 +210,11 @@ export default {
label: "-", label: "-",
}, },
], ],
defaultIcon: addImageIcon,
showModal: false,
showPopup: false,
image: [addImageIcon],
imageData: [],
}; };
}, },
computed: { computed: {
@@ -179,6 +225,22 @@ export default {
}, },
}, },
methods: { methods: {
closeModal() {
this.showModal = false;
this.showPopup = false;
},
previewImages(event) {
this.image = [];
var pictures = event.target.files;
for (var i = 0; i < pictures.length; i++) {
var reader = new FileReader();
reader.onload = (e) => {
this.image.push(e.target.result);
};
reader.readAsDataURL(pictures[i]);
}
this.imageData = [...this.imageData, ...event.target.files];
},
createIdentityDocument(id) { createIdentityDocument(id) {
Object.keys( Object.keys(
this.filterDataEmptyProperty(this.infoClient.identity_document.pass) this.filterDataEmptyProperty(this.infoClient.identity_document.pass)
@@ -200,20 +262,25 @@ export default {
}); });
}, },
postNewClient() { postNewClient() {
let sentData = { const formData = new FormData();
full_name: this.infoClient.basic.full_name, this.imageData.forEach((e) => {
}; formData.append("photo", e);
formData.append("full_name", this.infoClient.basic.full_name);
});
if (this.infoClient.basic.birth_date) if (this.infoClient.basic.birth_date)
sentData.birth_date = this.infoClient.basic.birth_date; formData.append("birth_date", this.infoClient.basic.birth_date);
let foundElement = this.prioritySettings.settings.find( let foundElement = this.prioritySettings.settings.find(
(el) => el.text === this.infoClient.basic.priority (el) => el.text === this.infoClient.basic.priority
); );
if (foundElement) sentData.priority = foundElement.priority; if (foundElement) formData.append("priority", foundElement.priority);
fetchWrapper.post("general/person/create/", sentData).then((result) => { fetchWrapper
this.createIdentityDocument(result.id); .post("general/person/create/", formData, "formData")
this.createAddress(result.id); .then((result) => {
this.addSuccessNotification(); this.createIdentityDocument(result.id);
}); this.createAddress(result.id);
this.addSuccessNotification();
});
this.$emit("update-client"); this.$emit("update-client");
}, },
filterDataEmptyProperty(data) { filterDataEmptyProperty(data) {
@@ -248,6 +315,14 @@ export default {
this.closeForm(); this.closeForm();
} }
}, },
changeOpenModal() {
this.showModal = true;
this.showPopup = false;
this.image = [addImageIcon];
},
changeOpenPopup() {
this.showPopup = true;
},
saveDocFile(e) { saveDocFile(e) {
this.infoClient.doc = e.target.files; this.infoClient.doc = e.target.files;
}, },
@@ -311,6 +386,13 @@ export default {
); );
}, },
}, },
watch: {
showModal: function () {
if (this.showModal === false) {
this.closeModal();
}
},
},
}; };
</script> </script>
@@ -322,8 +404,10 @@ export default {
width: 634px width: 634px
min-height: 700px min-height: 700px
box-shadow: var(--default-shadow) box-shadow: var(--default-shadow)
.title .title
color: var(--font-dark-blue-color) color: var(--font-dark-blue-color)
.export-avatar .export-avatar
min-width: 40px min-width: 40px
height: 40px height: 40px
@@ -333,6 +417,7 @@ export default {
&:hover &:hover
color: var(--default-white) color: var(--default-white)
background-color: var(--btn-blue-color) background-color: var(--btn-blue-color)
.title-info .title-info
color: var(--font-grey-color) color: var(--font-grey-color)
border-bottom: 1.5px solid var(--font-grey-color) border-bottom: 1.5px solid var(--font-grey-color)
@@ -342,4 +427,29 @@ export default {
&.active &.active
color: var(--btn-blue-color) color: var(--btn-blue-color)
border-bottom: 1.5px solid var(--btn-blue-color) border-bottom: 1.5px solid var(--btn-blue-color)
.avatar-wrapper
width: 400px
height: 400px
border-radius: 50%
.input
width: 100%
height: 100%
border-radius: 50%
z-index: 5
opacity: 0
cursor: pointer
.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
</style> </style>

View File

@@ -1,7 +1,5 @@
<template lang="pug"> <template lang="pug">
.section-wrapper.flex.flex-col.h-fit.cursor-pointer( .section-wrapper.flex.flex-col.h-fit.cursor-pointer(
@click="changeOpenCard",
v-click-outside="clickOutside"
:style="{flexDirection:settings[section].rowFlex && 'row', width: settings[section].width + 'px', height: settings[section].height + 'px', background: changeBackground}" :style="{flexDirection:settings[section].rowFlex && 'row', width: settings[section].width + 'px', height: settings[section].height + 'px', background: changeBackground}"
) )
.section-header.flex.items-center.justify-between.pl-4.pr-3(:class="{small:settings[section].rowFlex}") .section-header.flex.items-center.justify-between.pl-4.pr-3(:class="{small:settings[section].rowFlex}")
@@ -17,12 +15,12 @@
) )
.icon-ok.text-xsm(class="pt-[3px]") .icon-ok.text-xsm(class="pt-[3px]")
.edit.icon-edit.cursor-pointer.text-sm( .edit.icon-edit.cursor-pointer.text-sm(
v-if="openCard && !isChange", v-if="!isChange",
@click="changeClientData" @click="changeClientData"
) )
.flex.relative .flex.relative
base-button( base-button(
v-if="settings[section].addFile && openCard", v-if="settings[section].addFile",
@click="openAddingWrap", @click="openAddingWrap",
:rounded="true", :rounded="true",
:outlined="true", :outlined="true",
@@ -193,12 +191,11 @@ export default {
isOpenPackage: false, isOpenPackage: false,
isOpenAddDoc: false, isOpenAddDoc: false,
showModal: false, showModal: false,
openCard: false,
}; };
}, },
computed: { computed: {
changeBackground() { changeBackground() {
return this.openCard || this.isChange return this.isChange
? "var(--light-grey-bg-color)" ? "var(--light-grey-bg-color)"
: "var(--default-white)"; : "var(--default-white)";
}, },
@@ -234,15 +231,8 @@ export default {
this.showModal = false; this.showModal = false;
this.saveDocs(); this.saveDocs();
}, },
changeOpenCard() {
this.openCard = true;
},
clickOutside() {
this.openCard = false;
},
changeDoc() { changeDoc() {
this.isChange = false; this.isChange = false;
this.openCard = false;
if (this.section === "pass") { if (this.section === "pass") {
this.docId ? this.updateDocument() : this.createDocument(); this.docId ? this.updateDocument() : this.createDocument();
} }

View File

@@ -14,6 +14,7 @@
:value="dataClient", :value="dataClient",
:avatar="dataClient.avatar", :avatar="dataClient.avatar",
:avatar-color="dataClient.color", :avatar-color="dataClient.color",
:photo="dataClient.photo"
:is-open-change="isOpenChange", :is-open-change="isOpenChange",
:width="columnBody.find(el => el.name === 'fullName').width" :width="columnBody.find(el => el.name === 'fullName').width"
) )
@@ -181,6 +182,7 @@ export default {
contacts: [...this.client.contacts], contacts: [...this.client.contacts],
avatar: `${this.client.last_name[0]}${this.client.first_name[0]}`, avatar: `${this.client.last_name[0]}${this.client.first_name[0]}`,
color: this.client.color, color: this.client.color,
photo: this.client.photo,
}; };
}, },
methods: { methods: {

View File

@@ -1,6 +1,8 @@
<template lang="pug"> <template lang="pug">
.flex.box-border.px-4.items-center.gap-x-3.w-full.text-sm(:style="{ minWidth : width + 'px' }") .flex.box-border.px-4.items-center.gap-x-3.w-full.text-sm(:style="{ minWidth : width + 'px' }")
BaseAvatar(:size="36", :color="avatarColor") {{avatar}} base-avatar(:size="36", :color="avatarColor", v-if="!photo") {{avatar}}
base-avatar(:size="36", v-else)
img.h-full(:src="url + photo")
span.font-semibold(v-if="!isOpenChange") {{value.fullName}} span.font-semibold(v-if="!isOpenChange") {{value.fullName}}
base-input(v-if="isOpenChange" type="text" v-model:value="value.fullName" :width-input="300") base-input(v-if="isOpenChange" type="text" v-model:value="value.fullName" :width-input="300")
</template> </template>
@@ -14,11 +16,17 @@ export default {
props: { props: {
value: Object, value: Object,
avatar: String, avatar: String,
photo: String,
width: Number, width: Number,
imgUrl: String, imgUrl: String,
isOpenChange: Boolean, isOpenChange: Boolean,
avatarColor: String, avatarColor: String,
}, },
data() {
return {
url: "http://45.84.227.122:8080",
};
},
}; };
</script> </script>