Merge branch 'ASTRA-108' into 'master'

Resolve ASTRA-108

See merge request andrusyakka/urban-couscous!413
This commit is contained in:
Vasiliy Gavrilin
2023-06-09 17:29:28 +00:00
10 changed files with 491 additions and 53 deletions

View File

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.84087 4.11519C7.4338 4.68057 7.29199 5.37779 7.29199 5.83333V8.54167H12.7087V5.83333C12.7087 5.37779 12.5669 4.68057 12.1598 4.11519C11.7757 3.58168 11.13 3.125 10.0003 3.125C8.87069 3.125 8.22499 3.58168 7.84087 4.11519ZM13.9587 8.54167V5.83333C13.9587 5.17776 13.7671 4.20832 13.1742 3.38481C12.5583 2.52943 11.5374 1.875 10.0003 1.875C8.46329 1.875 7.44232 2.52943 6.82645 3.38481C6.23352 4.20832 6.04199 5.17776 6.04199 5.83333V8.54167H4.16699C3.82181 8.54167 3.54199 8.82149 3.54199 9.16667V17.5C3.54199 17.8452 3.82181 18.125 4.16699 18.125H15.8337C16.1788 18.125 16.4587 17.8452 16.4587 17.5V9.16667C16.4587 8.82149 16.1788 8.54167 15.8337 8.54167H13.9587ZM4.79199 9.79167V16.875H15.2087V9.79167H4.79199Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 883 B

View File

@@ -1,9 +1,9 @@
<template lang="pug">
base-input-container.gap-y-2(:label="label", :style="{width: width + 'px' }")
base-input-container.gap-y-2(:important="important", :label="label", :style="{width: width + 'px' }")
q-input(
v-model="value",
:name="name",
:multiple="multiple"
:multiple="multiple",
:class="{'circle': circle, 'font-input': true, 'doc': doc}",
:input-style="{ color: textColor, borderColor: borderColor, resize: resize, fontSize: fontSize, fontWeight: fontWeight, lineHeight: lineHeight}",
:borderless="borderless",
@@ -26,7 +26,7 @@
:standout="standout"
:accept="accept",
:debounce="debounce",
:shadow-text="shadowText"
:shadow-text="shadowText",
hide-bottom-space
)
template(v-slot:prepend, v-if="iconLeft")
@@ -116,6 +116,7 @@ export default {
iconLeft: Boolean,
iconRight: Boolean,
name: String,
important: Boolean,
},
emits: ["update:modelValue"],
computed: {

View File

@@ -1,6 +1,7 @@
<template lang="pug">
.flex.flex-col.gap-y-2
.label.font-semibold.text-sm.opacity-40(v-if="label") {{ label }}
span.-mt-2(v-if="important", :style="{color: 'var(--font-obligatory-color)'}") *
slot
</template>
@@ -9,6 +10,7 @@ export default {
name: "BaseInputContainer",
props: {
label: String,
important: Boolean,
},
};
</script>

View File

@@ -0,0 +1,94 @@
<template lang="pug">
.flex.gap-x-3.w-full.py-6
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)
</template>
<script>
import BaseModal from "./BaseModal.vue";
import BaseInput from "./BaseInput.vue";
import addImageIcon from "@/assets/icons/photo.svg";
export default {
name: "BaseInputFullName",
components: { BaseModal, BaseInput },
props: { infoClient: Object },
data() {
return {
defaultIcon: addImageIcon,
showModal: false,
showPopup: false,
image: addImageIcon,
};
},
methods: {
closeAddImage() {
this.showModal = false;
this.showPopup = false;
},
changeOpenModal() {
this.showModal = true;
this.showPopup = false;
},
previewImage(event) {
let picture = event.target.files;
let reader = new FileReader();
reader.onload = (e) => {
this.image = e.target.result;
};
reader.readAsDataURL(picture[0]);
},
},
watch: {
showModal: function () {
if (this.showModal === false) {
this.closeAddImage();
}
},
},
};
</script>
<style lang="sass" scoped>
.avatar-wrapper
width: 400px
height: 400px
border-radius: 50%
.avatar
height: 100%
border-radius: 50%
</style>

View File

@@ -6,7 +6,7 @@
ref="dialog"
)
.base-content(
:class="{'draggable': draggable, 'base-content-default': !defaultPadding}",
:class="{'draggable': draggable, 'base-content-default': !defaultPadding, 'base-modal-default': modalPadding}",
ref="contentRef",
:style="{...contentStyles, height}"
)
@@ -30,6 +30,7 @@ export default {
draggable: Boolean,
hideOverlay: Boolean,
defaultPadding: Boolean,
modalPadding: Boolean,
hideHeader: Boolean,
height: {
type: String,
@@ -135,6 +136,9 @@ export default {
.base-content-default
padding: 32px 40px
.base-modal-default
padding: 28px 32px
.base-content
width: auto
background-color: var(--default-white)

View File

@@ -0,0 +1,91 @@
<template lang="pug">
.flex.flex-col.gap-y-6.pt-6
.table-time.flex.p-4
.flex.flex-col.gap-1(v-for="time in timeCoil")
.flex {{ time }}
.side.flex.p-1.h-9(:style="{columnGap: '2px'}")
q-btn.left-side(size="9px", padding="0 8px", color="primary")
q-icon(name="app:icon-ok")
q-btn.right-side(size="4px", padding="0 4px")
img(:src="lockIcon")
.flex.justify-between.items-center
.flex.gap-2
q-btn(
color="primary",
outline,
size="16px",
no-caps,
label="Отмена",
:style="{width: '108px', height: '40px'}",
padding="0",
@click="closeModalTime"
)
q-btn(
color="primary",
size="16px",
no-caps,
label="Сохранить"
:style="{width: '132px', height: '40px'}",
padding="0",
@click="closeModalTime"
)
.text.font-bold.text-6xl {{`${times.from} - ${times.to}`}}
</template>
<script>
import lockIcon from "@/assets/icons/locked.svg";
export default {
name: "BaseTimeModal",
props: { times: Object, closeModalTime: Function },
data() {
return { lockIcon, select: false };
},
computed: {
validateStartTime() {
return this.verifyTime("8:00");
},
validateEndTime() {
return this.verifyTime("19:00");
},
timeCoil() {
let time = [];
for (let i = this.validateStartTime; i <= this.validateEndTime; i++) {
time.push(`${i}:00`);
}
return time;
},
},
methods: {
verifyTime(dayTime) {
let timeArray = dayTime.split(":").map((elem) => parseInt(elem, 10));
let newTime = timeArray[1] > 30 ? timeArray[0] + 1 : timeArray[0];
return newTime;
},
},
};
</script>
<style lang="sass" scoped>
.table-time
width: 463px
height: 174px
border: 1px solid var(--border-light-grey-color)
border-radius: 6px
flex-wrap: wrap !important
.text
color: var(--font-dark-blue-color)
.side
border-left: 1px solid var(--border-light-grey-color)
border-right: 1px solid var(--border-light-grey-color)
.left-side
border-radius: 6px 1px 1px 6px
background: #4772F2
.right-side
border-radius: 1px 6px 6px 1px
background: #FF6565
</style>

View File

@@ -11,20 +11,23 @@
type="date"
v-model="basicInfo.birth_date",
label="Дата рождения",
outlined
outlined,
important
)
base-input(
v-model="phone.username",
placeholder="+7 (915) 6449223",
mask="+7 (###) ###-##-##",
label="Номер телефона",
outlined
outlined,
important
)
base-input(
v-model="email.username",
placeholder="user@yandex.ru",
label="Email",
outlined
outlined,
important
)
.flex.flex-col.col-start-1.col-end-3.w-100(class="gap-y-1.5")
span.text-sm.font-semibold.opacity-40.input-info Ссылки на соцсети

View File

@@ -3,7 +3,8 @@
calendar-sidebar(v-if="!isOpen", :open-sidebar="openSidebar", :create-form="createForm")
calendar-open-sidebar(v-else, :open-sidebar="openSidebar", :create-form="createForm")
calendar-wrapper.ml-2(:open-sidebar="isOpen")
record-creation-form(:is-show-form="isShowForm")
base-modal(v-model="isShowForm", title="Создание записи", modal-padding)
record-creation-form(v-model="isShowForm", :close-form="closeForm")
</template>
<script>
@@ -12,6 +13,7 @@ import CalendarOpenSidebar from "@/pages/newCalendar/components/CalendarOpenSide
import CalendarWrapper from "@/pages/newCalendar/components/CalendarWrapper";
import RecordCreationForm from "@/pages/newCalendar/components/RecordCreationForm";
import * as moment from "moment/moment";
import BaseModal from "@/components/base/BaseModal.vue";
export default {
name: "TheCalendar",
@@ -20,6 +22,7 @@ export default {
CalendarOpenSidebar,
CalendarWrapper,
RecordCreationForm,
BaseModal,
},
data() {
return {
@@ -35,6 +38,9 @@ export default {
createForm() {
this.isShowForm = true;
},
closeForm() {
this.isShowForm = false;
},
},
};
</script>

View File

@@ -1,66 +1,215 @@
<template lang="pug">
base-modal(v-model="isShowForm", title="Создание записи")
.flex.flex-col.pt-6.gap-y-4(:style="{maxWidth: '682px'}")
.flex.gap-x-10
.flex.flex-col.gap-y-4.text-smm
.flex.gap-x-3.items-center
.text.font-semibold Статус
.flex.gap-x-1
.input.flex.items-center.pl-4
.text-input.font-medium Не принят
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="folder")
.flex.gap-x-3.items-center
.text.font-semibold Дата:
.flex.gap-x-1
.input.flex.items-center.pl-4
.text-input.font-medium 24 мая 2020
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="calendar")
.flex.gap-x-3.items-center
.text.font-semibold Время:
.flex.gap-x-1
.input.flex.items-center.pl-4
.text-input.font-medium 13:00 - 14:00
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="time")
.flex.h-14.gap-x-3.items-center.text-smm
.text.font-semibold Медкарта:
.flex.flex-col.pt-6.gap-y-4(:style="{maxWidth: '682px'}")
.flex.gap-x-10
.flex.flex-col.gap-y-4.text-smm
.flex.gap-x-3.items-center
.text.font-semibold Статус
.flex.gap-x-1
.name.flex.items-center.px-4.pt-2.pb-1.gap-x-2
.photo.flex.h-10.w-10.items-center.justify-center
img(:src="noname")
.flex.flex-col.font-medium
.text-input Имя Фамилия
.name-date.text-xsx Дата
.change.flex.items-center
q-btn(dense, padding="24px 8px")
q-icon(name="app:icon-plus", size="12px")
.flex.items-center.gap-x-3
.text.font-semibold.text-smm Услуги
.input.flex.items-center.pl-4.gap-x-1
img(:src="currentStatus.icon")
.text-input.font-medium {{currentStatus.name}}
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="folder")
q-menu
.status.flex.items-center.gap-x-1.font-medium.text-smm(
v-for="status in patientData.statuses",
@click="choiceStatus(status)",
v-close-popup
)
img(:src="status.icon")
span {{status.name}}
.flex.gap-x-3.items-center
.text.font-semibold Дата:
.flex.gap-x-1
.input.flex.items-center.pl-4
.text-input.font-medium {{currentDate.format("DD MMMM YYYY")}}
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="calendar")
q-menu(
transition-show="scale",
transition-hide="scale",
self="top middle",
:offset="[118, 14]",
)
base-calendar(v-model="currentDate")
.flex.gap-x-3.items-center
.text.font-semibold Время:
.flex.gap-x-1
.input.flex.items-center.pl-4
.text-input.font-medium 13:00 - 14:00
q-btn.change.flex.w-7.h-7(@click="isShowTime = true", dense, padding="4px 4px")
img(:src="time")
base-modal(v-model="isShowTime", title="Время", modal-padding)
base-time-modal(:times="times", :close-modal-time="closeModalTime")
.flex.h-14.gap-x-3.items-center.text-smm
.text.font-semibold Медкарта:
.flex.gap-x-1
.services.flex
.change.flex.w-7.h-7
.name.flex.items-center.px-4.pt-2.pb-1.gap-x-2
.photo.flex.h-10.w-10.items-center.justify-center
img(:src="noname")
.flex.flex-col.font-medium
.text-input Имя Фамилия
.name-date.text-xsx Дата
.change.flex.items-center
q-btn(dense, padding="24px 8px")
q-icon(name="app:icon-plus", size="12px")
.flex.items-center.gap-x-3.text-smm
.text.font-semibold Услуги:
.flex.gap-x-1
.services.flex.items-center.px-4.font-medium.text
span Выберите услуги
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="folder")
base-input-full-name(:info-client="patientData")
.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="patientData.basic",
:phone="patientData.phone",
:email="patientData.email",
:add-network="addNewNetwork",
:priority-list="patientData.priorityList",
:identity-document="patientData.identity_document",
:addresses="patientData.addresses",
:save-file="saveDocFile",
:networks-list="getNetworksList",
)
.footer.flex.gap-2
q-btn(
color="primary",
outline,
size="16px",
no-caps,
label="Отменить"
:style="{width: '126px', height: '40px'}",
padding="0",
@click="closeForm"
)
q-btn(
color="primary",
size="16px",
no-caps,
label="Создать запись"
:style="{width: '174px', height: '40px'}",
padding="0",
@click="closeForm"
)
</template>
<script>
import { column } from "@/pages/clients/utils/tableConfig";
import { v_model } from "@/shared/mixins/v-model";
import BaseModal from "@/components/base/BaseModal.vue";
import noname from "@/assets/icons/noname.svg";
import folder from "@/assets/icons/folder.svg";
import time from "@/assets/icons/time.svg";
import calendar from "@/assets/icons/calendar-grey.svg";
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.vue";
import BaseInputFullName from "@/components/base/BaseInputFullName.vue";
import { patientData } from "@/pages/newCalendar/utils/calendarConfig.js";
import BaseCalendar from "@/components/base/BaseCalendar.vue";
import BaseTimeModal from "@/components/base/BaseTimeModal.vue";
import * as moment from "moment/moment";
export default {
name: "RecordCreationForm",
components: { BaseModal },
props: { isShowForm: Boolean },
components: {
BaseModal,
FormCreateBasicInfo,
FormCreateIdentityDocuments,
FormCreateAddresses,
BaseInput,
BaseInputFullName,
BaseCalendar,
BaseTimeModal,
},
props: { isShowForm: Boolean, closeForm: Function },
mixins: [v_model],
data() {
return { noname, folder, time, calendar, isPhoto: false };
return {
noname,
folder,
time,
calendar,
isPhoto: false,
patientData: patientData,
currentStatus: patientData.statuses.find((e) => e.name === "Не принят"),
currentDate: moment().clone(),
isShowTime: false,
times: { from: "8:30", to: "10:30" },
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",
networksSettings: column.find((el) => el.name === "networks")?.settings,
};
},
computed: {
getNetworksList() {
let contacts = [];
this.patientData.basic.contacts.forEach((elem) =>
contacts.push(elem.kind.id)
);
let filteredNetworks = this.networksSettings.filter(
({ id }) => !contacts.includes(id)
);
return filteredNetworks;
},
},
methods: {
changePhoto() {
this.isPhoto = true;
},
selectForm(componentName) {
this.currentForm = this.forms.find(
(elem) => elem.component === componentName
)?.component;
},
saveDocFile(e) {
this.patientData.doc = e.target.files;
},
addNewNetwork() {
const newNetwork = this.getNetworksList;
if (newNetwork[0])
this.patientData.basic.contacts.push({
kind: {
id: newNetwork[0].id,
icon: newNetwork[0].icon,
},
username: "",
});
},
choiceStatus(e) {
this.currentStatus = e;
},
closeModalTime() {
this.isShowTime = false;
},
},
};
</script>
@@ -102,4 +251,27 @@ export default {
border-radius: 6px
height: 28px
width: 560px
.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)
.footer
border-top: 1px solid var(--border-light-grey-color)
margin: 40px -32px 0px
padding: 16px 32px 0px 32px
.status
border-radius: 4px
height: 28px
padding: 8px 8px 8px 5px
&:hover
background: var(--bg-light-grey)
cursor: pointer
</style>

View File

@@ -136,3 +136,65 @@ export const patientList = [
choice: false,
},
];
export const patientData = {
basic: {
full_name: "",
birth_date: null,
priority: {
id: null,
label: "",
},
contacts: [
{
kind: {
id: "TELEGRAM",
icon: "app:icon-tg",
},
username: "",
},
],
},
identity_document: {
pass: {
series_number: "",
issued_by_org: "",
issued_by_date: null,
issued_by_org_code: "",
},
snils: {
kind: "СНИЛС",
number: "",
},
inn: {
kind: "ИНН",
number: "",
},
},
phone: { username: "" },
email: { username: "" },
addresses: {},
priorityList: [
{
id: 1,
label: "Высокий",
},
{
id: 2,
label: "Средний",
},
{
id: 3,
label: "Низкий",
},
{
id: 4,
label: "-",
},
],
statuses: [
{ name: "Отказ", icon: rejected, check: false },
{ name: "Не принят", icon: not_accepted, check: true },
{ name: "На приеме", icon: reception, check: false },
{ name: "Принят", icon: accepted, check: false },
],
};