[WIP] Добавил формы на модальном окне создания записи

This commit is contained in:
megavrilinvv
2023-06-09 19:41:04 +03:00
parent 900cc7b2ba
commit 10c72e8b61
10 changed files with 297 additions and 86 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"> <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( q-input(
v-model="value", v-model="value",
:name="name", :name="name",
:multiple="multiple" :multiple="multiple",
:class="{'circle': circle, 'font-input': true, 'doc': doc}", :class="{'circle': circle, 'font-input': true, 'doc': doc}",
:input-style="{ color: textColor, borderColor: borderColor, resize: resize, fontSize: fontSize, fontWeight: fontWeight, lineHeight: lineHeight}", :input-style="{ color: textColor, borderColor: borderColor, resize: resize, fontSize: fontSize, fontWeight: fontWeight, lineHeight: lineHeight}",
:borderless="borderless", :borderless="borderless",
@@ -26,7 +26,7 @@
:standout="standout" :standout="standout"
:accept="accept", :accept="accept",
:debounce="debounce", :debounce="debounce",
:shadow-text="shadowText" :shadow-text="shadowText",
hide-bottom-space hide-bottom-space
) )
template(v-slot:prepend, v-if="iconLeft") template(v-slot:prepend, v-if="iconLeft")
@@ -116,6 +116,7 @@ export default {
iconLeft: Boolean, iconLeft: Boolean,
iconRight: Boolean, iconRight: Boolean,
name: String, name: String,
important: Boolean,
}, },
emits: ["update:modelValue"], emits: ["update:modelValue"],
computed: { computed: {

View File

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

View File

@@ -1,41 +1,40 @@
<template lang="pug"> <template lang="pug">
.flex.gap-x-4.h-fit .flex.gap-x-3.w-full.py-6
.flex.gap-x-3.w-full q-btn(
q-btn( color="secondary",
color="secondary", text-color="primary",
text-color="primary", style="width: 40px; height: 40px",
style="width: 40px; height: 40px", rounded,
rounded no-caps,
no-caps padding="0 16px"
padding="0 16px" )
) q-icon(v-if="image === defaultIcon", name="app:icon-download")
q-icon(v-if="image === defaultIcon", name="app:icon-download") q-avatar(v-else, size="40px", round)
q-avatar(v-else, size="40px", round) img(:src="image")
img(:src="image") q-menu(anchor="bottom middle", self="top right", v-model="showPopup")
q-menu(anchor="bottom middle", self="top right", v-model="showPopup") .flex.flex-col.p-4.gap-y-3
.flex.flex-col.p-4.gap-y-3 .flex.items-center.gap-x-2.cursor-pointer(@click="changeOpenModal")
.flex.items-center.gap-x-2.cursor-pointer(@click="changeOpenModal") q-icon(name="app:computer", size="18px", color="primary")
q-icon(name="app:computer", size="18px", color="primary") span.text-smm.title Загрузить с компьютера
span.text-smm.title Загрузить с компьютера .flex.items-center.gap-x-2.cursor-pointer
.flex.items-center.gap-x-2.cursor-pointer q-icon(name="app:camera", size="18px", color="primary")
q-icon(name="app:camera", size="18px", color="primary") span.text-smm.title Сделать фото
span.text-smm.title Сделать фото base-modal(v-model="showModal", title="Загрузить изображение")
base-modal(v-model="showModal", title="Загрузить изображение") .flex.flex-col.items-center.justify-center(
.flex.flex-col.items-center.justify-center( :style="{padding: '153px 370px'}"
:style="{padding: '153px 370px'}" )
) .avatar-wrapper.flex.relative
.avatar-wrapper.flex.relative base-input(
base-input( circle,
circle, type="file",
type="file", id="image-upload",
id="image-upload", accept="image/*",
accept="image/*", @change="(e) => previewImage(e)"
@change="(e) => previewImage(e)" )
) .avatar.flex.absolute.items-center.gap-x-6
.avatar.flex.absolute.items-center.gap-x-6 img.avatar.object-cover(for="image-upload", :src="image", v-if="image")
img.avatar.object-cover(for="image-upload", :src="image", v-if="image") q-btn(round, color="primary", @click="closeAddImage", icon="app:icon-ok")
q-btn(round, color="primary", @click="closeAddImage", icon="app:icon-ok") base-input.w-full(v-model="infoClient.basic.full_name", placeholder="ФИО пациента*", outlined)
base-input.w-full(v-model="infoClient.basic.full_name", placeholder="ФИО*", outlined)
</template> </template>
<script> <script>

View File

@@ -6,7 +6,7 @@
ref="dialog" ref="dialog"
) )
.base-content( .base-content(
:class="{'draggable': draggable, 'base-content-default': !defaultPadding}", :class="{'draggable': draggable, 'base-content-default': !defaultPadding, 'base-modal-default': modalPadding}",
ref="contentRef", ref="contentRef",
:style="{...contentStyles, height}" :style="{...contentStyles, height}"
) )
@@ -30,6 +30,7 @@ export default {
draggable: Boolean, draggable: Boolean,
hideOverlay: Boolean, hideOverlay: Boolean,
defaultPadding: Boolean, defaultPadding: Boolean,
modalPadding: Boolean,
hideHeader: Boolean, hideHeader: Boolean,
height: { height: {
type: String, type: String,
@@ -135,6 +136,9 @@ export default {
.base-content-default .base-content-default
padding: 32px 40px padding: 32px 40px
.base-modal-default
padding: 28px 32px
.base-content .base-content
width: auto width: auto
background-color: var(--default-white) 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" type="date"
v-model="basicInfo.birth_date", v-model="basicInfo.birth_date",
label="Дата рождения", label="Дата рождения",
outlined outlined,
important
) )
base-input( base-input(
v-model="phone.username", v-model="phone.username",
placeholder="+7 (915) 6449223", placeholder="+7 (915) 6449223",
mask="+7 (###) ###-##-##", mask="+7 (###) ###-##-##",
label="Номер телефона", label="Номер телефона",
outlined outlined,
important
) )
base-input( base-input(
v-model="email.username", v-model="email.username",
placeholder="user@yandex.ru", placeholder="user@yandex.ru",
label="Email", label="Email",
outlined outlined,
important
) )
.flex.flex-col.col-start-1.col-end-3.w-100(class="gap-y-1.5") .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 Ссылки на соцсети span.text-sm.font-semibold.opacity-40.input-info Ссылки на соцсети

View File

@@ -3,8 +3,8 @@
calendar-sidebar(v-if="!isOpen", :open-sidebar="openSidebar", :create-form="createForm") calendar-sidebar(v-if="!isOpen", :open-sidebar="openSidebar", :create-form="createForm")
calendar-open-sidebar(v-else, :open-sidebar="openSidebar", :create-form="createForm") calendar-open-sidebar(v-else, :open-sidebar="openSidebar", :create-form="createForm")
calendar-wrapper.ml-2(:open-sidebar="isOpen") calendar-wrapper.ml-2(:open-sidebar="isOpen")
base-modal(v-model="isShowForm", title="Создание записи") base-modal(v-model="isShowForm", title="Создание записи", modal-padding)
record-creation-form(v-model="isShowForm") record-creation-form(v-model="isShowForm", :close-form="closeForm")
</template> </template>
<script> <script>
@@ -38,6 +38,9 @@ export default {
createForm() { createForm() {
this.isShowForm = true; this.isShowForm = true;
}, },
closeForm() {
this.isShowForm = false;
},
}, },
}; };
</script> </script>

View File

@@ -5,24 +5,42 @@
.flex.gap-x-3.items-center .flex.gap-x-3.items-center
.text.font-semibold Статус .text.font-semibold Статус
.flex.gap-x-1 .flex.gap-x-1
.input.flex.items-center.pl-4 .input.flex.items-center.pl-4.gap-x-1
.text-input.font-medium Не принят img(:src="currentStatus.icon")
.text-input.font-medium {{currentStatus.name}}
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px") q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="folder") 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 .flex.gap-x-3.items-center
.text.font-semibold Дата: .text.font-semibold Дата:
.flex.gap-x-1 .flex.gap-x-1
.input.flex.items-center.pl-4 .input.flex.items-center.pl-4
.text-input.font-medium 24 мая 2020 .text-input.font-medium {{currentDate.format("DD MMMM YYYY")}}
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px") q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="calendar") 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 .flex.gap-x-3.items-center
.text.font-semibold Время: .text.font-semibold Время:
.flex.gap-x-1 .flex.gap-x-1
.input.flex.items-center.pl-4 .input.flex.items-center.pl-4
.text-input.font-medium 13:00 - 14:00 .text-input.font-medium 13:00 - 14:00
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px") q-btn.change.flex.w-7.h-7(@click="isShowTime = true", dense, padding="4px 4px")
img(:src="time") 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 .flex.h-14.gap-x-3.items-center.text-smm
.text.font-semibold Медкарта: .text.font-semibold Медкарта:
.flex.gap-x-1 .flex.gap-x-1
@@ -42,7 +60,7 @@
span Выберите услуги span Выберите услуги
q-btn.change.flex.w-7.h-7(dense, padding="4px 4px") q-btn.change.flex.w-7.h-7(dense, padding="4px 4px")
img(:src="folder") img(:src="folder")
base-input-full-name(:info-client="infoClient") base-input-full-name(:info-client="patientData")
.flex.flex-col.flex-auto.l.gap-y-8 .flex.flex-col.flex-auto.l.gap-y-8
.flex .flex
button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm( button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm(
@@ -54,16 +72,36 @@
) {{form.title}} ) {{form.title}}
component( component(
v-bind:is="currentForm", v-bind:is="currentForm",
:basic-info="infoClient.basic", :basic-info="patientData.basic",
:phone="infoClient.phone", :phone="patientData.phone",
:email="infoClient.email", :email="patientData.email",
:add-network="addNewNetwork", :add-network="addNewNetwork",
:priority-list="priorityList", :priority-list="patientData.priorityList",
:identity-document="infoClient.identity_document", :identity-document="patientData.identity_document",
:addresses="infoClient.addresses", :addresses="patientData.addresses",
:save-file="saveDocFile", :save-file="saveDocFile",
:networks-list="getNetworksList", :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> </template>
<script> <script>
@@ -79,6 +117,10 @@ import FormCreateIdentityDocuments from "@/pages/clients/components/FormCreateId
import FormCreateAddresses from "@/pages/clients/components/FormCreateAddresses"; import FormCreateAddresses from "@/pages/clients/components/FormCreateAddresses";
import BaseInput from "@/components/base/BaseInput.vue"; import BaseInput from "@/components/base/BaseInput.vue";
import BaseInputFullName from "@/components/base/BaseInputFullName.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 { export default {
name: "RecordCreationForm", name: "RecordCreationForm",
@@ -89,8 +131,10 @@ export default {
FormCreateAddresses, FormCreateAddresses,
BaseInput, BaseInput,
BaseInputFullName, BaseInputFullName,
BaseCalendar,
BaseTimeModal,
}, },
props: { isShowForm: Boolean }, props: { isShowForm: Boolean, closeForm: Function },
mixins: [v_model], mixins: [v_model],
data() { data() {
return { return {
@@ -99,13 +143,11 @@ export default {
time, time,
calendar, calendar,
isPhoto: false, isPhoto: false,
infoClient: { patientData: patientData,
basic: { contacts: [] }, currentStatus: patientData.statuses.find((e) => e.name === "Не принят"),
phone: { username: "" }, currentDate: moment().clone(),
email: { username: "" }, isShowTime: false,
identity_document: {}, times: { from: "8:30", to: "10:30" },
addresses: {},
},
forms: [ forms: [
{ {
title: "Основное", title: "Основное",
@@ -124,31 +166,13 @@ export default {
}, },
], ],
currentForm: "form-create-basic-info", currentForm: "form-create-basic-info",
priorityList: [
{
id: 1,
label: "Высокий",
},
{
id: 2,
label: "Средний",
},
{
id: 3,
label: "Низкий",
},
{
id: 4,
label: "-",
},
],
networksSettings: column.find((el) => el.name === "networks")?.settings, networksSettings: column.find((el) => el.name === "networks")?.settings,
}; };
}, },
computed: { computed: {
getNetworksList() { getNetworksList() {
let contacts = []; let contacts = [];
this.infoClient.basic.contacts.forEach((elem) => this.patientData.basic.contacts.forEach((elem) =>
contacts.push(elem.kind.id) contacts.push(elem.kind.id)
); );
let filteredNetworks = this.networksSettings.filter( let filteredNetworks = this.networksSettings.filter(
@@ -167,12 +191,12 @@ export default {
)?.component; )?.component;
}, },
saveDocFile(e) { saveDocFile(e) {
this.infoClient.doc = e.target.files; this.patientData.doc = e.target.files;
}, },
addNewNetwork() { addNewNetwork() {
const newNetwork = this.getNetworksList; const newNetwork = this.getNetworksList;
if (newNetwork[0]) if (newNetwork[0])
this.infoClient.basic.contacts.push({ this.patientData.basic.contacts.push({
kind: { kind: {
id: newNetwork[0].id, id: newNetwork[0].id,
icon: newNetwork[0].icon, icon: newNetwork[0].icon,
@@ -180,6 +204,12 @@ export default {
username: "", username: "",
}); });
}, },
choiceStatus(e) {
this.currentStatus = e;
},
closeModalTime() {
this.isShowTime = false;
},
}, },
}; };
</script> </script>
@@ -231,4 +261,17 @@ 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)
.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> </style>

View File

@@ -136,3 +136,65 @@ export const patientList = [
choice: false, 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 },
],
};