155 Commits

Author SHA1 Message Date
dderbentsov
92b7bd6d01 global rework patient info 2023-11-02 01:19:05 +03:00
dderbentsov
35e8740f04 ref med card tabs 2023-10-20 01:27:15 +03:00
dderbentsov
fbd6312520 ref карточка пациента 2023-10-20 01:21:11 +03:00
dderbentsov
5b5e04ca12 add edit mode button 2023-10-20 00:51:47 +03:00
dderbentsov
e9929481b3 fix sidebar styles 2023-10-20 00:25:55 +03:00
dderbentsov
516ec12114 first step 2023-10-14 19:32:12 +03:00
dderbentsov
74a4ded35c поиск карт 2023-10-09 00:24:56 +03:00
Kirill Andrusyak
35cc0ee059 Merge branch 'fix-basic-data-forms' into 'master'
Изменила сетки форм

See merge request astra/astra-frontend!511
2023-10-03 17:40:39 +00:00
Daria Golova
019c8c0459 Изменила сетки форм 2023-09-26 18:05:18 +03:00
kandrusyak
615200f4ca medcards list fixes 2023-09-25 21:41:28 +03:00
kandrusyak
7e9632436e base data fixes 2023-09-25 21:30:24 +03:00
kandrusyak
dd9124b1c5 small screen fix 2023-09-25 21:15:32 +03:00
kandrusyak
535c7562c7 small screen fix 2023-09-25 21:12:05 +03:00
kandrusyak
f86c8ad5ba fixes 2023-09-25 20:32:55 +03:00
Kirill Andrusyak
d130bdf40c Merge branch 'add-admin-calendar' into 'master'
Добавлен календарь администратора

See merge request astra/astra-frontend!509
2023-09-21 20:19:22 +00:00
Daria Golova
7b2e07f0d2 Поправила баг в документах 2023-09-19 17:05:29 +03:00
Daria Golova
48e2571c77 WIP Стянула записи приемов с бэка 2023-09-19 13:31:05 +03:00
Daria Golova
fc6c5e61fb WIP Разделила календари 2023-09-18 18:53:45 +03:00
dderbentsov
c2eb6bf1e9 создал homepage 2023-09-17 15:44:30 +03:00
dderbentsov
4bdd665d1f убрал список клиентов с бокового меню 2023-09-17 14:20:51 +03:00
dderbentsov
297f11952b удалил старые pages 2023-09-17 14:10:31 +03:00
dderbentsov
dd5e9eed54 Убрал поиск с хедера 2023-09-17 14:05:18 +03:00
andrusyakka
c986e312fe disable e2e pipeline 2023-09-11 18:53:10 +03:00
Kirill Andrusyak
14424c541c Merge branch 'create_client' into 'master'
Create client

See merge request astra/astra-frontend!508
2023-09-11 15:41:38 +00:00
andrusyakka
71c6ba7a74 add create medical card 2023-09-11 18:40:15 +03:00
kandrusyak
1ee0e8f0e8 add create patient popup 2023-09-11 18:22:55 +03:00
kandrusyak
85b68c726b update pipeline 2023-09-05 02:19:15 +03:00
kandrusyak
11d7f0af42 update pipeline 2023-09-05 02:11:04 +03:00
kandrusyak
b7c45e80c3 fix Dockerfile 2023-09-05 02:05:48 +03:00
kandrusyak
4915cf2506 add e2e 2023-09-05 01:35:25 +03:00
kandrusyak
dc65af6c83 fix create form and fix origin 2023-09-04 21:02:44 +03:00
kandrusyak
66efe5bc95 fix create form and fix origin 2023-09-04 20:57:34 +03:00
Kirill Andrusyak
e7b9cce5a2 Merge branch '8-editing-documents-block' into 'master'
Редактирование блока документы и страховка на мед.карте, исправить отображение плашек в календаре для пациента с большим количеством контактов

See merge request astra/astra-frontend!507
2023-08-29 18:03:22 +00:00
Daria Golova
15e31ebcd7 Исправила отображение контактов на записи 2023-08-25 14:28:47 +03:00
Daria Golova
d1c5dc5683 WIP Сделала валидацию на страховках 2023-08-25 14:28:47 +03:00
Daria Golova
cb41a00ae1 WIP Изменила отправку документов 2023-08-25 14:28:47 +03:00
Daria Golova
4987a3ae09 WIP Изменила инпут, сделала документы 2023-08-25 14:28:47 +03:00
Kirill Andrusyak
817f881159 fix namesapce 2023-08-24 20:41:21 +00:00
Kirill Andrusyak
332fff778a Merge branch '19-design-bugs' into 'master'
Фикс багов дизайна

Closes #19

See merge request astra/astra-frontend!506
2023-08-23 19:35:36 +00:00
megavrilinvv
564b250b66 Фикс багов дизайна 2023-08-23 16:34:44 +03:00
Kirill Andrusyak
e9810c91cf Merge branch '15-fixed-contacts' into 'master'
Контакты: фикс запросов, фикс списка соцсетей

Closes #15

See merge request astra/astra-frontend!505
2023-08-22 19:21:01 +00:00
megavrilinvv
1f47f9abe6 Контакты: фикс запросов, фикс списка соцсетей 2023-08-18 18:21:18 +03:00
Kirill Andrusyak
bc5c694657 Merge branch '10-editing-blocks' into 'master'
Resolve "При нажатии не происходит перехода на мед.карту", "Редактирование основных данных на мед.карте"

Closes #10

See merge request astra/astra-frontend!503
2023-08-17 17:45:43 +00:00
megavrilinvv
6337aa80dd Merge branch '10-editing-blocks' of https://gitlab.dopcore.com/andrusyakka/urban-couscous into 10-editing-blocks 2023-08-17 18:19:35 +03:00
megavrilinvv
fbb89646ea [WIP] Фикс запросов, добавил валидацию основных данных 2023-08-17 18:17:16 +03:00
kandrusyak
65918134ec change disabled method 2023-08-17 16:33:16 +03:00
megavrilinvv
e3ad1396b6 [WIP] Фикс запросов на основыне данные, добавил запросы для контактов 2023-08-17 16:32:44 +03:00
megavrilinvv
15cb788fcc [WIP] Исправил отправку основных данных 2023-08-17 16:32:44 +03:00
megavrilinvv
b7af4b15ca [WIP] Добавил переход на медкарту, возможность редактирования основных данных 2023-08-17 16:32:44 +03:00
Kirill Andrusyak
37f5520796 Merge branch '9-reschedule-calendar-interval' into 'master'
Перенесла интервал календаря в параметры и починила запрос

See merge request astra/astra-frontend!504
2023-08-17 10:15:34 +00:00
Daria Golova
715fc9824e Поправила кнопки на сайдбаре 2023-08-16 23:53:12 +03:00
Daria Golova
8691790a53 Добавила интервал дат в параметры 2023-08-16 23:30:25 +03:00
Daria Golova
f459620040 Merge branch '4-fix-date-display' into 'master'
Поправила отображение даты (4), undefined в хедере мед.карты (13), создание осмотра (12), поменяла индикацию заполненности медкарты (11),

See merge request astra/astra-frontend!502
2023-08-16 20:28:51 +00:00
Daria Golova
dcbbf20916 Поправила url картинок 2023-08-16 23:26:10 +03:00
kandrusyak
e59624e263 change disabled method 2023-08-16 20:19:21 +03:00
megavrilinvv
4dda501a3e [WIP] Исправил отправку основных данных 2023-08-16 17:59:26 +03:00
megavrilinvv
2ab0c765d7 [WIP] Добавил переход на медкарту, возможность редактирования основных данных 2023-08-16 16:44:03 +03:00
Daria Golova
7f655dcdc9 Исправила undefined в хедере медкарты 2023-08-16 14:26:13 +03:00
Daria Golova
c866662384 Исправила отображения дат, статусов, врача 2023-08-16 14:04:21 +03:00
Vasiliy Gavrilin
37f4fdf507 Merge branch '3-transition-medical-card' into 'master'
Добавил параметры роута

Closes #3

See merge request astra/astra-frontend!501
2023-08-16 07:09:47 +00:00
megavrilinvv
cdf9754a36 Убрал localStorage с medicalId и заменил на route 2023-08-16 10:09:22 +03:00
Vasiliy Gavrilin
f67c9be11f Merge branch 'master' into '3-transition-medical-card'
# Conflicts:
#   src/pages/newMedicalCard/TheMedicalCard.vue
#   src/router.js
#   src/store/modules/medicalCard.js
2023-08-16 06:51:22 +00:00
andrusyakka
6c85c5dcf1 WIP rework medical card data 2023-08-15 20:27:33 +03:00
Kirill Andrusyak
bd6064c2c8 Merge branch 'master' into '3-transition-medical-card'
# Conflicts:
#   src/router.js
2023-08-15 16:57:17 +00:00
megavrilinvv
53adfc204b Добавил параметры роута 2023-08-15 19:55:44 +03:00
andrusyakka
cc4ea131f9 WIP rework search 2023-08-15 19:53:50 +03:00
andrusyakka
3f182ae00a remove unnecessary 2023-08-15 19:08:13 +03:00
andrusyakka
b0b6230804 remove unnecessary 2023-08-15 18:53:38 +03:00
Vasiliy Gavrilin
e552ec449a Merge branch '3-transition-medical-card' into 'master'
Resolve "Создание и переход в мед.карту"

Closes #3

See merge request astra/astra-frontend!500
2023-08-15 14:20:25 +00:00
megavrilinvv
c49b4ad050 Фикс роута, если нет id 2023-08-15 17:18:57 +03:00
megavrilinvv
d0ff2da700 Фикс отображения данных при обновлении страницы 2023-08-15 17:14:44 +03:00
Kirill Andrusyak
48f43a0770 Merge branch '1-fix-search-parameter' into 'master'
Resolve "Поправить параметр поиска и убрать пустую плашку, если никого не найдено, заменить в соответствии с дизайном , поправить отображение даты"

See merge request astra/astra-frontend!498
2023-08-15 13:52:04 +00:00
Daria Golova
689a6bf0b6 Убрала лишнее 2023-08-15 16:32:46 +03:00
Daria Golova
ee6c3e795b Поправила строку медкарты и дату 2023-08-15 16:08:25 +03:00
Daria Golova
6b951a5af2 WIP Поправила запрос 2023-08-15 16:08:25 +03:00
Vasiliy Gavrilin
4408b48906 Merge branch '3-transition-medical-card' into 'master'
Добавил маппинг полей на мед карту, переход на медкарту с календаря, фикс дефолтного аватара

Closes #3

See merge request astra/astra-frontend!499
2023-08-15 12:33:12 +00:00
megavrilinvv
ea2076f70e Объединил функции в один метод 2023-08-15 15:29:05 +03:00
megavrilinvv
9a6777c16e Добавил маппинг полей на мед карту, переход на медкарту с календаря, фикс дефолтного аватара 2023-08-15 14:35:38 +03:00
kandrusyak
c0345164cd update frontend deploy 2023-08-08 22:45:01 +03:00
kandrusyak
9fe2ceb867 fix contacts 2023-08-03 02:32:23 +03:00
kandrusyak
76d95ab0b0 add events filter 2023-08-03 01:26:17 +03:00
kandrusyak
081eeacc1d fix calendar 2023-08-03 00:38:57 +03:00
Vasiliy Gavrilin
4def8adf85 Merge branch 'ASTRA-143' into 'master'
Resolve ASTRA-143

See merge request andrusyakka/urban-couscous!497
2023-08-02 13:50:15 +00:00
megavrilinvv
897cb06b85 [WIP] Добавил модальное окно отображения выбранной медкарты, фикс ситлей 2023-08-02 16:49:19 +03:00
megavrilinvv
06631aaee0 [WIP] Фикс процента заполнения медкарты 2023-08-02 13:18:33 +03:00
kandrusyak
ec4cbe35de create event 2023-08-02 03:10:43 +03:00
kandrusyak
9d378c1e62 connect medcards 2023-08-02 02:19:37 +03:00
Kirill Andrusyak
8ab1d8265e Merge branch 'page-govno' into 'master'
Page govno

See merge request andrusyakka/urban-couscous!496
2023-08-01 22:58:02 +00:00
kandrusyak
e682136ed8 only improves 2023-08-02 01:54:50 +03:00
andrusyakka
a9b4a7e185 . 2023-08-01 18:26:47 +03:00
Vasiliy Gavrilin
d1a84fc060 Merge branch 'ASTRA-143' into 'master'
Resolve ASTRA-143

See merge request andrusyakka/urban-couscous!495
2023-08-01 14:26:43 +00:00
megavrilinvv
563b53a409 [WIP] Добавил модальное окно выбора медкарт на форме создания записи 2023-08-01 17:26:05 +03:00
megavrilinvv
39160fc455 [WIP] Фикс формы услуг на форме создания записи 2023-08-01 13:02:16 +03:00
Vasiliy Gavrilin
cc812d511a Merge branch 'ASTRA-168' into 'master'
[WIP] Fixed bugs

See merge request andrusyakka/urban-couscous!494
2023-08-01 09:58:12 +00:00
megavrilinvv
ee9a8fae54 [WIP] Fixed bugs 2023-08-01 12:57:31 +03:00
dderbentsov
ef479d7f11 Merge branch 'master' of https://gitlab.dopcore.com/andrusyakka/urban-couscous 2023-08-01 01:56:06 +03:00
dderbentsov
8f9df6fc1d VIP search fullname 2023-08-01 01:55:25 +03:00
Vasiliy Gavrilin
e054ec6bc2 Merge branch 'ASTRA-143' into 'master'
Resolve ASTRA-143

See merge request andrusyakka/urban-couscous!493
2023-07-31 14:14:27 +00:00
megavrilinvv
64c246a5e3 [WIP] Добавил модальное окно выбора услуг 2023-07-31 17:14:00 +03:00
megavrilinvv
d0c1cccd10 [WIP] Правка модалки времени 2023-07-31 13:43:25 +03:00
Vasiliy Gavrilin
e004009b09 Merge branch 'ASTRA-143' into 'master'
[WIP] Поправил хедер модалки создания записи, обновление пациентов медкарточек

See merge request andrusyakka/urban-couscous!492
2023-07-31 08:50:15 +00:00
megavrilinvv
16f2394eec [WIP] Поправил хедер модалки создания записи, обновление пациентов медкарточек 2023-07-31 11:49:36 +03:00
Vasiliy Gavrilin
98c7cc5f64 Merge branch 'ASTRA-139' into 'master'
[WIP] Фикс багов и скролла страницы медкартотчек

See merge request andrusyakka/urban-couscous!491
2023-07-28 09:39:23 +00:00
megavrilinvv
e1c2dccce6 [WIP] Фикс багов и скролла страницы медкартотчек 2023-07-28 12:38:32 +03:00
dderbentsov
e808c23288 mark fo refactoring 2023-07-28 02:48:15 +03:00
dderbentsov
c53778ba50 remove create client button 2023-07-28 02:37:25 +03:00
kandrusyak
db47f32b8f refactor login page and add user avatar to header 2023-07-28 02:21:33 +03:00
kandrusyak
2120cba2e9 refactor login page and add user avatar to header 2023-07-28 02:18:56 +03:00
Daria Golova
eced313580 Merge branch 'ASTRA-163' into 'master'
WIP Сделала фильтрацию

See merge request andrusyakka/urban-couscous!490
2023-07-27 13:55:19 +00:00
Daria Golova
efd1f97041 WIP Сделала фильтрацию 2023-07-27 16:54:32 +03:00
Vasiliy Gavrilin
b49559ba5e Merge branch 'ASTRA-139' into 'master'
Фикс багов

See merge request andrusyakka/urban-couscous!489
2023-07-27 11:27:50 +00:00
megavrilinvv
a4d6d3ac00 Фикс багов 2023-07-27 14:27:16 +03:00
Daria Golova
20b9ad129b Merge branch 'ASTRA-163' into 'master'
WIP Набросала строки таблицы

See merge request andrusyakka/urban-couscous!488
2023-07-26 15:29:32 +00:00
Daria Golova
a747c1820d WIP Набросала строки таблицы 2023-07-26 18:28:42 +03:00
Vasiliy Gavrilin
2bb879c0cf Merge branch 'ASTRA-139' into 'master'
Resolve ASTRA-139

See merge request andrusyakka/urban-couscous!487
2023-07-26 14:13:40 +00:00
megavrilinvv
d4aa75a690 [WIP] Фикс конфига статусов 2023-07-26 17:02:48 +03:00
megavrilinvv
f113e8ebf5 [WIP] Добавил форму недавно просмотренных медкарт, фикс стилей 2023-07-26 16:37:47 +03:00
Vasiliy Gavrilin
75506acad1 Merge branch 'ASTRA-139' into 'master'
Resolve ASTRA-139

See merge request andrusyakka/urban-couscous!486
2023-07-25 15:10:01 +00:00
megavrilinvv
286b17b77f [WIP] Добавил карточку пациента на приеме 2023-07-25 18:09:39 +03:00
megavrilinvv
4d8d8f410e [WIP] Добавил форму запланированных пациентов 2023-07-25 18:09:39 +03:00
Daria Golova
967814c533 Merge branch 'ASTRA-163' into 'master'
WIP Начала поиск медкарт

See merge request andrusyakka/urban-couscous!485
2023-07-25 14:53:23 +00:00
Daria Golova
1f5c4814a0 WIP Начала поиск медкарт 2023-07-25 17:51:58 +03:00
Daria Golova
c1f65f6294 Merge branch 'ASTRA-163' into 'master'
WIP Поправила часть иконок

See merge request andrusyakka/urban-couscous!484
2023-07-25 12:43:40 +00:00
Daria Golova
759d6953a2 WIP Поправила часть иконок 2023-07-25 15:42:24 +03:00
kandrusyak
14b67dde2b add new endpoint to sidebar 2023-07-25 02:23:05 +03:00
kandrusyak
35ff1150e7 map to new back 2023-07-25 02:11:01 +03:00
Daria Golova
dcaa7b7995 Merge branch 'ASTRA-137' into 'master'
WIP Доделала селект на хедере

See merge request andrusyakka/urban-couscous!483
2023-07-24 15:49:02 +00:00
Daria Golova
9e8fb856eb WIP Доделала селект на хедере 2023-07-24 18:48:08 +03:00
Vasiliy Gavrilin
f04574b4f8 Merge branch 'ASTRA-139' into 'master'
Resolve ASTRA-139

See merge request andrusyakka/urban-couscous!482
2023-07-24 15:40:32 +00:00
megavrilinvv
2e3764c6ac [WIP] Добавил wrapper на формы страницы медкаточек 2023-07-24 18:37:58 +03:00
megavrilinvv
c63fe8c319 Добавил роутинг на страницу медкарточек 2023-07-24 15:40:59 +03:00
megavrilinvv
4c7e62d450 [WIP] Фикс стилей сайдбара календаря 2023-07-24 12:56:56 +03:00
Daria Golova
fd79d62f0a Merge branch 'ASTRA-137' into 'master'
WIP Изменила инпут в хедере

See merge request andrusyakka/urban-couscous!481
2023-07-21 16:08:00 +00:00
Daria Golova
a444fa3637 WIP Изменила инпут в хедере 2023-07-21 19:07:01 +03:00
Vasiliy Gavrilin
f99b584cf4 Merge branch 'ASTRA-139' into 'master'
[WIP] Изменил стили сайдбара календаря в закрытом его состоянии

See merge request andrusyakka/urban-couscous!480
2023-07-21 15:27:32 +00:00
megavrilinvv
1daa24bbf6 [WIP] Изменил стили сайдбара календаря в закрытом его состоянии 2023-07-21 18:26:52 +03:00
Vasiliy Gavrilin
529d949702 Merge branch 'ASTRA-139' into 'master'
Фикс багов

See merge request andrusyakka/urban-couscous!479
2023-07-19 11:57:14 +00:00
megavrilinvv
f5aa1379cc Фикс багов 2023-07-19 14:56:29 +03:00
Daria Golova
76c201c71f Merge branch 'ASTRA-156' into 'master'
Исправила мелкие несоответствия

See merge request andrusyakka/urban-couscous!478
2023-07-19 08:35:44 +00:00
Daria Golova
370970b26c Исправила мелкие несоответствия 2023-07-19 11:35:07 +03:00
Daria Golova
926efdb64a Merge branch 'ASTRA-156' into 'master'
WIP Перемещен инпут

See merge request andrusyakka/urban-couscous!477
2023-07-18 14:45:10 +00:00
Daria Golova
292f44c73c WIP Удалила закомментированный код 2023-07-18 17:44:31 +03:00
Daria Golova
51470f0ed3 WIP Перемещен инпут 2023-07-18 17:40:12 +03:00
Vasiliy Gavrilin
1fdc22a1be Merge branch 'ASTRA-139' into 'master'
Фикс стилей

See merge request andrusyakka/urban-couscous!476
2023-07-18 09:19:09 +00:00
megavrilinvv
2b2a5456d6 Фикс стилей 2023-07-18 12:18:46 +03:00
Daria Golova
e5c0aee940 Merge branch 'ASTRA-156' into 'master'
WIP Исправлен баг на категориях льгот

See merge request andrusyakka/urban-couscous!475
2023-07-17 15:29:09 +00:00
Daria Golova
f86be1b187 WIP Исправлен баг на категориях льгот 2023-07-17 18:21:26 +03:00
Vasiliy Gavrilin
a939097488 Merge branch 'ASTRA-139' into 'master'
[WIP] Исправил стили сайдбара на странице календаря

See merge request andrusyakka/urban-couscous!474
2023-07-14 15:27:15 +00:00
megavrilinvv
67e2c3f22c [WIP] Исправил стили сайдбара на странице календаря 2023-07-14 18:24:13 +03:00
Daria Golova
5fa7e3252d Merge branch 'ASTRA-156' into 'master'
WIP Частично заменила инпуты

See merge request andrusyakka/urban-couscous!473
2023-07-14 15:19:31 +00:00
Daria Golova
27f25a8826 WIP Частично заменила инпуты 2023-07-14 18:17:57 +03:00
Daria Golova
ee3c828a22 Merge branch 'ASTRA-156' into 'master'
WIP Переделала инпуты

See merge request andrusyakka/urban-couscous!472
2023-07-13 15:38:39 +00:00
Daria Golova
25dbf78915 WIP Переделала инпуты 2023-07-13 18:36:28 +03:00
Vasiliy Gavrilin
f0640b6a3d Merge branch 'ASTRA-147' into 'master'
Заменил чекбоксы на радиобатоны

See merge request andrusyakka/urban-couscous!471
2023-07-13 08:53:50 +00:00
megavrilinvv
af146a4998 Заменил чекбоксы на радиобатоны 2023-07-13 11:53:27 +03:00
202 changed files with 17365 additions and 7686 deletions

View File

@@ -1,57 +1,17 @@
image: docker:20.10.16
variables:
# When using dind service, you must instruct Docker to talk with
# the daemon started inside of the service. The daemon is available
# with a network connection instead of the default
# /var/run/docker.sock socket.
DOCKER_HOST: tcp://docker:2376
#
# The 'docker' hostname is the alias of the service container as described at
# https://docs.gitlab.com/ee/ci/services/#accessing-the-services.
# If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
# the variable must be set to tcp://localhost:2376 because of how the
# Kubernetes executor connects services to the job container
# DOCKER_HOST: tcp://localhost:2376
#
# Specify to Docker where to create the certificates. Docker
# creates them automatically on boot, and creates
# `/certs/client` to share between the service and job
# container, thanks to volume mount from config.toml
DOCKER_TLS_CERTDIR: "/certs"
# These are usually specified by the entrypoint, however the
# Kubernetes executor doesn't run entrypoints
# https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
services:
- docker:20.10.16-dind
stages:
- build
- deploy
build-job:
stage: build
tags:
- docker
only:
- master
script:
- docker info
- docker build -t docker-registry.dopcore.com/andrusyakka/urban-couscous .
- echo "$DOCKER_PASSWORD" | docker login docker-registry.dopcore.com -u "$DOCKER_USER" --password-stdin
- docker push docker-registry.dopcore.com/andrusyakka/urban-couscous
deploy-job:
stage: deploy
image: bitnami/kubectl:latest
tags:
- docker
only:
- master
script:
- kubectl version
- kubectl rollout restart deploy/astra-frontend
include:
- project: 'astra/microservice-ci'
ref: main
file: '/templates/microservice.yaml'
#e2e-dev:
# image: node:18.10.0
# stage: deploy
# dependencies:
# - deploy-dev
# only:
# - master
# services:
# - selenium/standalone-chrome
# script:
# - npm ci
# - npm run test:e2e --host=selenium__standalone-chrome --baseUrl=https://astra-dev.dopcore.com

View File

@@ -1,4 +1,4 @@
FROM node:16-alpine AS builder
FROM docker.io/node:16-alpine AS builder
WORKDIR /front
@@ -7,10 +7,10 @@ COPY . .
RUN npm ci
RUN npm run build
FROM nginx:1.21.6-alpine as runner
FROM docker.io/nginx:1.21.6-alpine as runner
COPY ./deploy/nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /front/dist /var/www/html
EXPOSE 8888
EXPOSE 8080

2
deploy/.env Normal file
View File

@@ -0,0 +1,2 @@
SERVICE_REPLICAS=1
SERVICE_PORT=8080

23
deploy/.helmignore Normal file
View File

@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

24
deploy/Chart.yaml Normal file
View File

@@ -0,0 +1,24 @@
apiVersion: v2
name: astra-file-storage
appVersion: latest
description: A Helm chart to deploy app - astra
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.1
engine: gotpl
maintainers:
- name: DOP

View File

@@ -15,7 +15,7 @@ http {
keepalive_timeout 65;
gzip_static on;
server {
listen 8888;
listen 8080;
charset utf-8;
absolute_redirect off;

View File

@@ -0,0 +1 @@
192.168.1.112:8888

View File

@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "astra-frontend.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "astra-frontend.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "astra-frontend.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "astra-frontend.labels" -}}
helm.sh/chart: {{ include "astra-frontend.chart" . }}
{{ include "astra-frontend.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "astra-frontend.selectorLabels" -}}
app.kubernetes.io/name: {{ include "astra-frontend.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "astra-frontend.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "astra-frontend.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,46 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.app.fullName }}
spec:
replicas: {{ .Values.replicas }}
revisionHistoryLimit: 10
selector:
matchLabels:
app: {{ .Values.app.fullName }}
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: {{ .Values.app.fullName }}
spec:
imagePullSecrets:
- name: {{ .Values.images.pullSecret }}
containers:
- name: {{ .Values.app.fullName }}
env:
- name: TZ
value: Europe/Moscow
- name: PORT
value: {{ .Values.app.server.port | quote }}
- name: SHARE_PATH
value: /app/public
{{- .Values.envs | toYaml | nindent 12 }}
image: {{ .Values.app.image }}:{{ .Chart.AppVersion }} #"docker-registry.dopcore.com/andrusyakka/urban-couscous:latest"
imagePullPolicy: Always
ports:
- name: http
containerPort: {{ .Values.app.server.port }}
protocol: TCP
volumeMounts:
- name: data
mountPath: /app/public
volumes:
- name: data
persistentVolumeClaim:
claimName: fileshare

28
deploy/templates/hpa.yaml Normal file
View File

@@ -0,0 +1,28 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include ".Values.app.fullName" . }}
labels:
app: {{ include ".Values.app.fullName" . }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include ".Values.app.fullName" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include ".Values.app.fullName" . -}}
{{- $svcPort := .Values.app.server.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
app: {{ $fullName }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.app.fullName }}
spec:
ports:
- port: {{ .Values.app.server.port }}
protocol: TCP
targetPort: {{ .Values.app.server.port }}
selector:
app: {{ .Values.app.fullName }}
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}

View File

@@ -0,0 +1,16 @@
app:
fullName: ${CI_PROJECT_TITLE}
image: docker-registry.dopcore.com/${CI_PROJECT_PATH}
server:
port: ${SERVICE_PORT}
replicas: ${SERVICE_REPLICAS}
images:
pullSecret: regcred
ingress:
enabled: false
autoscaling:
enabled: false

8992
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,12 +5,14 @@
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
"lint": "vue-cli-service lint",
"test:e2e": "wdio run ./wdio.conf.js"
},
"dependencies": {
"@dop/astra-ui": "^0.1.3",
"@dop/astra-ui": "^0.2.5",
"@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"vue": "^3.2.13",
"vue-router": "^4.1.5",
@@ -23,6 +25,10 @@
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-vuex": "^5.0.8",
"@vue/cli-service": "~5.0.0",
"@wdio/cli": "^8.16.3",
"@wdio/jasmine-framework": "^8.16.3",
"@wdio/local-runner": "^8.16.3",
"@wdio/spec-reporter": "^8.16.3",
"@webdiscus/pug-loader": "^2.9.4",
"eslint": "^8.25.0",
"eslint-config-prettier": "^8.3.0",

View File

@@ -15,9 +15,9 @@ html
height: 8px
::-webkit-scrollbar-track
border-radius: 4px
background-color: var(--bg-ligth-blue-color)
background-color: var(--gray-background)
::-webkit-scrollbar-thumb
background-color: var(--bg-aqua-blue)
background-color: var(--font-grey-color)
border-radius: 4px
#app
font-feature-settings: 'pnum' on, 'lnum' on

View File

@@ -1,6 +1,5 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.6">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.221 7.30769C14.4088 6.00296 15.5381 5 16.9032 5H23.0968C24.4619 5 25.5912 6.00296 25.779 7.30769H29.2903C30.7868 7.30769 32 8.51308 32 10V32.3077C32 33.7946 30.7868 35 29.2903 35H10.7097C9.21316 35 8 33.7946 8 32.3077V10C8 8.51308 9.21316 7.30769 10.7097 7.30769H14.221ZM14.221 9.61538H10.7097C10.4959 9.61538 10.3226 9.78758 10.3226 10V32.3077C10.3226 32.5201 10.4959 32.6923 10.7097 32.6923H29.2903C29.5041 32.6923 29.6774 32.5201 29.6774 32.3077V10C29.6774 9.78758 29.5041 9.61538 29.2903 9.61538H25.779C25.5912 10.9201 24.4619 11.9231 23.0968 11.9231H16.9032C15.5381 11.9231 14.4088 10.9201 14.221 9.61538ZM16.9032 7.30769C16.6894 7.30769 16.5161 7.47989 16.5161 7.69231V9.23077C16.5161 9.44319 16.6894 9.61538 16.9032 9.61538H23.0968C23.3106 9.61538 23.4839 9.44319 23.4839 9.23077V7.69231C23.4839 7.47989 23.3106 7.30769 23.0968 7.30769H16.9032Z" fill="#9294A7"/>
<path d="M10.7097 9.61538H14.221C14.4088 10.9201 15.5381 11.9231 16.9032 11.9231H23.0968C24.4619 11.9231 25.5912 10.9201 25.779 9.61538H29.2903C29.5041 9.61538 29.6774 9.78758 29.6774 10V32.3077C29.6774 32.5201 29.5041 32.6923 29.2903 32.6923H10.7097C10.4959 32.6923 10.3226 32.5201 10.3226 32.3077V10C10.3226 9.78758 10.4959 9.61538 10.7097 9.61538Z" fill="#9294A7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.221 7.30769C14.4088 6.00296 15.5381 5 16.9032 5H23.0968C24.4619 5 25.5912 6.00296 25.779 7.30769H29.2903C30.7868 7.30769 32 8.51308 32 10V32.3077C32 33.7946 30.7868 35 29.2903 35H10.7097C9.21317 35 8 33.7946 8 32.3077V10C8 8.51308 9.21316 7.30769 10.7097 7.30769H14.221ZM16.9032 7.30769C16.6894 7.30769 16.5161 7.47989 16.5161 7.69231V9.23077C16.5161 9.44319 16.6894 9.61538 16.9032 9.61538H23.0968C23.3106 9.61538 23.4839 9.44319 23.4839 9.23077V7.69231C23.4839 7.47989 23.3106 7.30769 23.0968 7.30769H16.9032Z" fill="#9294A7"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 709 B

View File

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="ico/ status round">
<path id="Rectangle 8093 (Stroke)" fill-rule="evenodd" clip-rule="evenodd" d="M3.75 10C3.75 13.4518 6.54822 16.25 10 16.25C13.4518 16.25 16.25 13.4518 16.25 10C16.25 6.54822 13.4518 3.75 10 3.75C6.54822 3.75 3.75 6.54822 3.75 10ZM10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5Z" fill="#9294A7"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 521 B

View File

@@ -1,4 +1,5 @@
<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="M3.75 10C3.75 13.4518 6.54822 16.25 10 16.25C13.4518 16.25 16.25 13.4518 16.25 10C16.25 6.54822 13.4518 3.75 10 3.75C6.54822 3.75 3.75 6.54822 3.75 10ZM10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5Z" fill="#55CD76"/>
<path d="M5 10C5 7.23858 7.23858 5 10 5C12.7614 5 15 7.23858 15 10C15 12.7614 12.7614 15 10 15C7.23858 15 5 12.7614 5 10Z" fill="#55CD76"/>
<g id="ico/ status round">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5Z" fill="#21BA72"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 353 B

View File

@@ -1,5 +1,5 @@
<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="M2.91667 10C2.91667 13.912 6.08798 17.0833 10 17.0833C13.912 17.0833 17.0833 13.912 17.0833 10C17.0833 6.08798 13.912 2.91667 10 2.91667C6.08798 2.91667 2.91667 6.08798 2.91667 10ZM10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5Z" fill="#4772F2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.79167 10C4.79167 12.8765 7.12352 15.2083 10 15.2083C12.8765 15.2083 15.2083 12.8765 15.2083 10C15.2083 7.12352 12.8765 4.79167 10 4.79167C7.12352 4.79167 4.79167 7.12352 4.79167 10ZM10 4.16667C6.77834 4.16667 4.16667 6.77834 4.16667 10C4.16667 13.2217 6.77834 15.8333 10 15.8333C13.2217 15.8333 15.8333 13.2217 15.8333 10C15.8333 6.77834 13.2217 4.16667 10 4.16667Z" fill="#4772F2"/>
<path d="M5.83333 10C5.83333 7.69881 7.69881 5.83333 10 5.83333C12.3012 5.83333 14.1667 7.69881 14.1667 10C14.1667 12.3012 12.3012 14.1667 10 14.1667C7.69881 14.1667 5.83333 12.3012 5.83333 10Z" fill="#4772F2"/>
<g id="ico/ status round">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5Z" fill="#4772F2"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 353 B

View File

@@ -1,4 +1,5 @@
<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="M3.75 10C3.75 13.4518 6.54822 16.25 10 16.25C13.4518 16.25 16.25 13.4518 16.25 10C16.25 6.54822 13.4518 3.75 10 3.75C6.54822 3.75 3.75 6.54822 3.75 10ZM10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5Z" fill="#FF6565"/>
<path d="M5 10C5 7.23858 7.23858 5 10 5C12.7614 5 15 7.23858 15 10C15 12.7614 12.7614 15 10 15C7.23858 15 5 12.7614 5 10Z" fill="#FF6565"/>
<g id="ico/ status round">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5Z" fill="#F34549"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,20 @@
<svg width="301" height="300" viewBox="0 0 301 300" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="148.495" cy="157" r="110" fill="#DDDDE8" fill-opacity="0.7"/>
<path d="M190.995 87H108.495C99.6581 87 92.4946 94.1634 92.4946 103V212C92.4946 220.837 99.6581 228 108.495 228H190.995C199.831 228 206.995 220.837 206.995 212V103C206.995 94.1634 199.831 87 190.995 87Z" fill="white"/>
<path d="M102.495 133.5C102.495 131.015 104.509 129 106.995 129H189.995C192.48 129 194.495 131.015 194.495 133.5C194.495 135.985 192.48 138 189.995 138H106.995C104.509 138 102.495 135.985 102.495 133.5Z" fill="#DDDDE8"/>
<path d="M102.495 158.5C102.495 156.015 104.509 154 106.995 154H189.995C192.48 154 194.495 156.015 194.495 158.5C194.495 160.985 192.48 163 189.995 163H106.995C104.509 163 102.495 160.985 102.495 158.5Z" fill="#DDDDE8"/>
<path d="M102.495 183.5C102.495 181.015 104.509 179 106.995 179H189.995C192.48 179 194.495 181.015 194.495 183.5C194.495 185.985 192.48 188 189.995 188H106.995C104.509 188 102.495 185.985 102.495 183.5Z" fill="#DDDDE8"/>
<path d="M102.495 208.5C102.495 206.015 104.509 204 106.995 204H189.995C192.48 204 194.495 206.015 194.495 208.5C194.495 210.985 192.48 213 189.995 213H106.995C104.509 213 102.495 210.985 102.495 208.5Z" fill="#DDDDE8"/>
<path d="M102.495 108.5C102.495 106.015 104.509 104 106.995 104H143.995C146.48 104 148.495 106.015 148.495 108.5C148.495 110.985 146.48 113 143.995 113H106.995C104.509 113 102.495 110.985 102.495 108.5Z" fill="#252850"/>
<path d="M231.495 170C231.495 197.062 209.557 219 182.495 219C155.433 219 133.495 197.062 133.495 170C133.495 142.938 155.433 121 182.495 121C209.557 121 231.495 142.938 231.495 170Z" fill="#F4F4F6" fill-opacity="0.2"/>
<path d="M189.495 152.5C189.495 148.358 186.137 145 181.995 145C177.852 145 174.495 148.358 174.495 152.5V163H164.495C160.629 163 157.495 166.134 157.495 170C157.495 173.866 160.629 177 164.495 177H174.495V187.5C174.495 191.642 177.852 195 181.995 195C186.137 195 189.495 191.642 189.495 187.5V177H200.495C204.361 177 207.495 173.866 207.495 170C207.495 166.134 204.361 163 200.495 163H189.495V152.5Z" fill="#4772F2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M182.495 229C194.576 229 205.81 225.369 215.163 219.138L244.352 247L258.848 232.504L230.025 204.962C237.234 195.177 241.495 183.086 241.495 170C241.495 137.415 215.079 111 182.495 111C149.91 111 123.495 137.415 123.495 170C123.495 202.585 149.91 229 182.495 229ZM182.495 219C209.557 219 231.495 197.062 231.495 170C231.495 142.938 209.557 121 182.495 121C155.433 121 133.495 142.938 133.495 170C133.495 197.062 155.433 219 182.495 219Z" fill="#B2B5CC"/>
<path d="M265.564 253.902C269.869 249.884 269.909 243.073 265.651 239.005L258.848 232.504L244.352 247L251.5 253.823C255.427 257.571 261.595 257.606 265.564 253.902Z" fill="#B2B5CC"/>
<path d="M265.564 253.902C269.868 249.884 269.908 243.073 265.651 239.005L258.847 232.504L244.352 247L251.5 253.823C255.426 257.571 261.595 257.606 265.564 253.902Z" fill="#252850"/>
<path d="M24.4913 128.559C27.9948 100 65.4948 67 40.4948 75.5C8.2732 86.4553 74.0995 100.359 97.9074 69.4486" stroke="black" stroke-width="2"/>
<circle cx="268.495" cy="197" r="6" fill="#4772F2"/>
<path d="M60.4551 232.772L61.4946 235L62.5342 232.772C64.1236 229.367 66.8612 226.629 70.267 225.04L72.4946 224L70.267 222.96C66.8612 221.371 64.1236 218.633 62.5342 215.228L61.4946 213L60.4551 215.228C58.8657 218.633 56.1281 221.371 52.7223 222.96L50.4946 224L52.7223 225.04C56.1281 226.629 58.8657 229.367 60.4551 232.772Z" stroke="#4772F2" stroke-width="2"/>
<rect x="182.995" y="34.5" width="90" height="40" rx="7.5" fill="white" stroke="#E7E7EF"/>
<circle cx="202.995" cy="54.5" r="4.5" fill="#DDDDE8"/>
<path d="M211.495 54.5C211.495 52.0147 213.509 50 215.995 50H252.995C255.48 50 257.495 52.0147 257.495 54.5C257.495 56.9853 255.48 59 252.995 59H215.995C213.509 59 211.495 56.9853 211.495 54.5Z" fill="#DDDDE8"/>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,20 @@
<svg width="301" height="300" viewBox="0 0 301 300" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="148.495" cy="157" r="110" fill="#DDDDE8" fill-opacity="0.7"/>
<path d="M190.995 87H108.495C99.6586 87 92.4951 94.1634 92.4951 103V212C92.4951 220.837 99.6586 228 108.495 228H190.995C199.832 228 206.995 220.837 206.995 212V103C206.995 94.1634 199.832 87 190.995 87Z" fill="white"/>
<path d="M102.495 133.5C102.495 131.015 104.51 129 106.995 129H189.995C192.48 129 194.495 131.015 194.495 133.5C194.495 135.985 192.48 138 189.995 138H106.995C104.51 138 102.495 135.985 102.495 133.5Z" fill="#DDDDE8"/>
<path d="M102.495 158.5C102.495 156.015 104.51 154 106.995 154H189.995C192.48 154 194.495 156.015 194.495 158.5C194.495 160.985 192.48 163 189.995 163H106.995C104.51 163 102.495 160.985 102.495 158.5Z" fill="#DDDDE8"/>
<path d="M102.495 183.5C102.495 181.015 104.51 179 106.995 179H189.995C192.48 179 194.495 181.015 194.495 183.5C194.495 185.985 192.48 188 189.995 188H106.995C104.51 188 102.495 185.985 102.495 183.5Z" fill="#DDDDE8"/>
<path d="M102.495 208.5C102.495 206.015 104.51 204 106.995 204H189.995C192.48 204 194.495 206.015 194.495 208.5C194.495 210.985 192.48 213 189.995 213H106.995C104.51 213 102.495 210.985 102.495 208.5Z" fill="#DDDDE8"/>
<path d="M102.495 108.5C102.495 106.015 104.51 104 106.995 104H143.995C146.48 104 148.495 106.015 148.495 108.5C148.495 110.985 146.48 113 143.995 113H106.995C104.51 113 102.495 110.985 102.495 108.5Z" fill="#252850"/>
<path d="M231.495 170C231.495 197.062 209.557 219 182.495 219C155.433 219 133.495 197.062 133.495 170C133.495 142.938 155.433 121 182.495 121C209.557 121 231.495 142.938 231.495 170Z" fill="#F4F4F6" fill-opacity="0.2"/>
<path d="M199.68 162.931C202.609 160.002 202.609 155.253 199.68 152.324C196.751 149.395 192.002 149.395 189.073 152.324L181.648 159.749L174.577 152.678C171.844 149.944 167.411 149.944 164.678 152.678C161.944 155.411 161.944 159.843 164.678 162.577L171.749 169.648L164.324 177.073C161.395 180.002 161.395 184.751 164.324 187.679C167.253 190.608 172.002 190.608 174.931 187.679L182.355 180.255L190.134 188.033C192.867 190.767 197.299 190.767 200.033 188.033C202.767 185.299 202.767 180.867 200.033 178.134L192.255 170.355L199.68 162.931Z" fill="#F34549"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M182.495 229C194.577 229 205.81 225.369 215.163 219.138L244.352 247L258.848 232.504L230.025 204.962C237.235 195.177 241.495 183.086 241.495 170C241.495 137.415 215.08 111 182.495 111C149.91 111 123.495 137.415 123.495 170C123.495 202.585 149.91 229 182.495 229ZM182.495 219C209.557 219 231.495 197.062 231.495 170C231.495 142.938 209.557 121 182.495 121C155.433 121 133.495 142.938 133.495 170C133.495 197.062 155.433 219 182.495 219Z" fill="#B2B5CC"/>
<path d="M265.564 253.902C269.869 249.884 269.909 243.073 265.652 239.005L258.848 232.504L244.352 247L251.5 253.823C255.427 257.571 261.596 257.606 265.564 253.902Z" fill="#B2B5CC"/>
<path d="M265.565 253.902C269.869 249.884 269.909 243.073 265.652 239.005L258.848 232.504L244.353 247L251.501 253.823C255.427 257.571 261.596 257.606 265.565 253.902Z" fill="#252850"/>
<path d="M24.4913 128.559C27.9948 100 65.4948 67 40.4948 75.5C8.2732 86.4553 74.0995 100.359 97.9074 69.4486" stroke="black" stroke-width="2"/>
<circle cx="268.495" cy="197" r="6" fill="#F34549"/>
<path d="M60.4555 232.772L61.4951 235L62.5347 232.772C64.1241 229.367 66.8617 226.629 70.2675 225.04L72.4951 224L70.2675 222.96C66.8617 221.371 64.1241 218.633 62.5347 215.228L61.4951 213L60.4555 215.228C58.8662 218.633 56.1286 221.371 52.7228 222.96L50.4951 224L52.7228 225.04C56.1286 226.629 58.8662 229.367 60.4555 232.772Z" stroke="#F34549" stroke-width="2"/>
<rect x="182.995" y="34.5" width="90" height="40" rx="7.5" fill="white" stroke="#E7E7EF"/>
<circle cx="202.995" cy="54.5" r="4.5" fill="#DDDDE8"/>
<path d="M211.495 54.5C211.495 52.0147 213.51 50 215.995 50H252.995C255.48 50 257.495 52.0147 257.495 54.5C257.495 56.9853 255.48 59 252.995 59H215.995C213.51 59 211.495 56.9853 211.495 54.5Z" fill="#DDDDE8"/>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -90,4 +90,12 @@
--bg-chip-blue-color: #d8e3ff
--bg-chip-yellow-color: #fff0ca
--bg-chip-pink-color: #F7D9FF
--gray-thirdly: #f4f4f6
--surface-blue-big: #ecf0fe
--gray-secondary: #dddde8
--system-color-red: #f34549
--system-color-green: #21ba72
--gray-background: #e9e9ed
--aqua-color: #2cc3e5
--system-color-yellow: #ffB931

View File

@@ -1,39 +1,48 @@
<template lang="pug">
div(:class="{active: focused}")
.header-inputs-wrapper.flex.items-center.font-medium.text-base
q-select.w-40.pl-3.pr-2.selected(
v-model="selectedFilter",
:options="filters",
borderless,
dense
.h-full.px-4.py-2.select.flex.items-center
q-menu(
:offset="[0, 6]",
v-model="isOpen",
:style="{'box-shadow': '-4px -4px 8px 0px rgba(9, 10, 21, 0.10), 4px 4px 8px 0px rgba(9, 10, 21, 0.10)'}"
)
template(v-slot:selected)
span(:style="{color: 'var(--btn-blue-color)'}") {{ selectedFilter }}
template(v-slot:prepend)
q-icon.pr-1(
name="app:icon-search",
size="18px",
:style="{color: 'var(--btn-blue-color)', opacity: '0.7'}"
.menu.bg-shite.p-4.flex.flex-col.gap-y-3
.item.text-base.font-medium.flex.gap-x-2.cursor-pointer(v-for="filter in filters", v-close-popup, @click="selectFilter(filter)")
.h-6.w-6.items-center.justify-center.flex
q-icon.ok(name="app:ok", size="24px", v-if="filter === selectedFilter")
.flex.items-center.text-dark {{ filter }}
q-icon.mr-2(
name="app:search",
size="24px"
)
q-input.px-4(
.flex-1.h-full.flex.items-center.justify-between
.text-base.font-medium {{ selectedFilter }}
.h-4.w-4.flex.items-center.pt-1.justify-center.ml-1
q-icon(
name="app:down-arrow",
size="16x",
:class="{'rotate-180': isOpen}"
)
q-input.input.px-4(
type="text",
placeholder="Искать ...",
borderless,
square
square,
@focus="focused = true",
@blur="focused = false"
)
</template>
<script>
import BaseInput from "@/components/base/BaseInput";
import BaseSelect from "@/components/base/BaseSelect";
export default {
name: "HeaderInputs",
components: { BaseInput, BaseSelect },
data() {
return {
selectedFilter: "Календарь",
filters: ["Календарь", "Клиенты"],
isOpen: false,
focused: false,
};
},
methods: {
@@ -49,8 +58,47 @@ export default {
height: 40px
background-color: var(--default-white)
border-radius: 4px
border: 1px solid var(--border-light-grey-color)
border-width: 1.5px
border-style: solid
border-color: #DDDDE8
&:hover
border-color: var(--font-grey-color)
.select
border-right-color: var(--font-grey-color)
.selected
border-right: 1px solid var(--border-light-grey-color)
.active
.header-inputs-wrapper
border-color: var(--font-dark-blue-color)
.select
border-right-color: var(--font-dark-blue-color) !important
.select
border-right-width: 1.5px
border-right-style: solid
border-right-color: var(--border-light-grey-color)
width: 167px
color: var(--font-grey-color)
.input
width: 230px
&:deep(.q-field__native)
font-weight: 500
font-size: 16px
line-height: normal
color: var(--font-dark-blue-color)
&::placeholder
color: var(--font-grey-color)
opacity: 1
.menu
width: 216px
.item:hover
opacity: 0.6
.astra-vicons :deep(path)
fill: var(--font-grey-color)
.ok :deep(path)
fill: var(--font-dark-blue-color)
</style>

View File

@@ -1,5 +1,5 @@
<template lang="pug">
.flex.flex-col.w-full.h-full.gap-y-2.pb-2
.flex.flex-col.w-full.h-full.gap-y-2.pb-2.no-scroll
the-header(
:url="url",
:is-open-form="isOpenForm",
@@ -8,7 +8,7 @@
:set-updated-clients="setUpdatedClients",
:write-created-client-id="writeCreatedClientId"
)
.flex.flex-auto.page-wrapper
.flex.grow.no-scroll
the-sidebar
router-view.mx-2(
:open-form="openForm",
@@ -25,7 +25,7 @@
import TheHeader from "@/components/TheHeader";
import TheSidebar from "@/components/TheSidebar";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { mapState } from "vuex";
export default {
name: "LoggedInLayout",
components: { TheNotificationProvider, TheHeader, TheSidebar },
@@ -33,10 +33,14 @@ export default {
return {
isOpenForm: false,
updatedClients: false,
url: "https://astra-dev.dopcore.com",
createdClientId: "",
};
},
computed: {
...mapState({
url: (state) => state.imgUrl,
}),
},
methods: {
openForm() {
this.isOpenForm = true;
@@ -59,7 +63,3 @@ export default {
},
};
</script>
<style lang="sass" scoped>
.page-wrapper
height: calc(100vh - 56px - 16px)
</style>

View File

@@ -0,0 +1,183 @@
<template lang="pug">
.flex.flex-col.pt-6.gap-y-4(:style="{maxWidth: '682px'}")
base-input-full-name(v-model="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",
:disabled="form.disabled"
) {{form.title}}
component(
v-bind:is="currentForm",
v-model="patientData"
)
.footer.flex.gap-2
base-button(type="secondary", label="Отменить", width="126px", @click="$emit('close')")
base-button(width="168px", label="Создать", @click="createPatient")
</template>
<script>
import { v_model } from "@/shared/mixins/v-model";
import FormCreateBasicInfo from "@/pages/clients/components/FormCreateBasicInfo.vue";
import FormCreateIdentityDocuments from "@/pages/clients/components/FormCreateIdentityDocuments.vue";
import FormCreateAddresses from "@/pages/clients/components/FormCreateAddresses.vue";
import FormCreateAttachments from "@/pages/clients/components/FormCreateAttachments.vue";
import BaseInputFullName from "@/components/base/BaseInputFullName.vue";
import HeaderRecordForm from "../pages/newCalendar/components/HeaderRecordForm.vue";
import BaseCalendar from "@/components/base/Calendar/BaseCalendar.vue";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseModal from "@/components/base/BaseModal.vue";
import ServicesModal from "../pages/newCalendar/components/ServicesModal.vue";
import { fetchWrapper } from "@/shared/fetchWrapper";
const forms = [
{
title: "Основное",
id: "basic",
component: "form-create-basic-info",
},
{
title: "ДУЛ",
id: "doc",
component: "form-create-identity-documents",
disabled: true,
},
{
title: "Адрес",
id: "address",
component: "form-create-addresses",
disabled: true,
},
{
title: "Дополнительное",
id: "additional",
component: "form-create-attachments",
disabled: true,
},
];
export default {
name: "PatientCreationForm",
components: {
FormCreateBasicInfo,
FormCreateIdentityDocuments,
FormCreateAddresses,
FormCreateAttachments,
BaseInputFullName,
BaseCalendar,
HeaderRecordForm,
BaseButton,
BaseModal,
ServicesModal,
},
emits: ["close"],
mixins: [v_model],
data() {
return {
patientData: {
full_name: "",
phone: "",
birth_date: "",
},
currentForm: "form-create-basic-info",
forms,
};
},
computed: {
nameObject() {
const nameArr = this.patientData?.full_name?.split(" ");
return {
last_name: nameArr?.[0] || "",
first_name: nameArr?.[1] || "",
patronymic: nameArr?.[2] || "",
};
},
},
methods: {
async createPatient() {
const body = {
...this.nameObject,
};
if (this.patientData.phone) {
body.contacts = [
{
category: "PHONE",
value: this.patientData.phone,
},
];
}
if (this.patientData.birth_date)
body.birth_date = this.patientData.birth_date;
const data = await fetchWrapper.post("persons/", body);
this.$emit("close", data);
},
handleChangePatientData(val) {
this.patientData = { ...this.patientData, ...val };
},
selectForm(componentName) {
this.currentForm = this.forms.find(
(elem) => elem.component === componentName
)?.component;
},
},
};
</script>
<style lang="sass" scoped>
.dark-blue
color: var(--font-dark-blue-color)
min-width: 50px
.text
color: var(--font-grey-color)
width: 76px
.change
background: var(--bg-light-grey)
color: var(--font-grey-color)
.services
background: var(--bg-light-grey)
color: var(--font-grey-color)
width: 560px
.service
display: -webkit-box
overflow: hidden
.gradient
width: 10%
height: 28px
right: 0
.other
width: 46px
background: var(--bg-light-grey)
.price
background: var(--bg-light-grey)
width: 82px
color: var(--font-grey-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)
.footer
border-top: 1px solid var(--border-light-grey-color)
margin: 40px -32px 0px
padding: 16px 32px 0px 32px
.icon :deep(path)
fill: var(--font-grey-color)
</style>

View File

@@ -1,23 +1,26 @@
<template lang="pug">
svg(width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg")
svg.hover(width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg")
g(v-if="nameSvg === 'calendar'")
path(d="M31 9.75C31.5523 9.75 32 10.1977 32 10.75V15H8V10.75C8 10.1977 8.44772 9.75 9 9.75H13.25V7.75C13.25 7.33579 13.5858 7 14 7C14.4142 7 14.75 7.33579 14.75 7.75V9.75H25.25V7.75C25.25 7.33579 25.5858 7 26 7C26.4142 7 26.75 7.33579 26.75 7.75V9.75H31Z" :fill="active ? '#4772f2' : '#9294A7'")
path(opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M31 32H9C8.44772 32 8 31.5523 8 31V16.5H32V31C32 31.5523 31.5523 32 31 32ZM15 19H13C12.4477 19 12 19.4477 12 20V22C12 22.5523 12.4477 23 13 23H15C15.5523 23 16 22.5523 16 22V20C16 19.4477 15.5523 19 15 19ZM15 25H13C12.4477 25 12 25.4477 12 26V28C12 28.5523 12.4477 29 13 29H15C15.5523 29 16 28.5523 16 28V26C16 25.4477 15.5523 25 15 25ZM21 19H19C18.4477 19 18 19.4477 18 20V22C18 22.5523 18.4477 23 19 23H21C21.5523 23 22 22.5523 22 22V20C22 19.4477 21.5523 19 21 19ZM21 25H19C18.4477 25 18 25.4477 18 26V28C18 28.5523 18.4477 29 19 29H21C21.5523 29 22 28.5523 22 28V26C22 25.4477 21.5523 25 21 25ZM27 19H25C24.4477 19 24 19.4477 24 20V22C24 22.5523 24.4477 23 25 23H27C27.5523 23 28 22.5523 28 22V20C28 19.4477 27.5523 19 27 19ZM27 25H25C24.4477 25 24 25.4477 24 26V28C24 28.5523 24.4477 29 25 29H27C27.5523 29 28 28.5523 28 28V26C28 25.4477 27.5523 25 27 25Z" :fill="active ? '#4772f2' : '#9294A7'")
path(d="M31 9.75C31.5523 9.75 32 10.1977 32 10.75V15H8V10.75C8 10.1977 8.44772 9.75 9 9.75H13.25V7.75C13.25 7.33579 13.5858 7 14 7C14.4142 7 14.75 7.33579 14.75 7.75V9.75H25.25V7.75C25.25 7.33579 25.5858 7 26 7C26.4142 7 26.75 7.33579 26.75 7.75V9.75H31Z" :fill="active ? '#4772f2' : '#bebfca'")
path(opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M31 32H9C8.44772 32 8 31.5523 8 31V16.5H32V31C32 31.5523 31.5523 32 31 32ZM15 19H13C12.4477 19 12 19.4477 12 20V22C12 22.5523 12.4477 23 13 23H15C15.5523 23 16 22.5523 16 22V20C16 19.4477 15.5523 19 15 19ZM15 25H13C12.4477 25 12 25.4477 12 26V28C12 28.5523 12.4477 29 13 29H15C15.5523 29 16 28.5523 16 28V26C16 25.4477 15.5523 25 15 25ZM21 19H19C18.4477 19 18 19.4477 18 20V22C18 22.5523 18.4477 23 19 23H21C21.5523 23 22 22.5523 22 22V20C22 19.4477 21.5523 19 21 19ZM21 25H19C18.4477 25 18 25.4477 18 26V28C18 28.5523 18.4477 29 19 29H21C21.5523 29 22 28.5523 22 28V26C22 25.4477 21.5523 25 21 25ZM27 19H25C24.4477 19 24 19.4477 24 20V22C24 22.5523 24.4477 23 25 23H27C27.5523 23 28 22.5523 28 22V20C28 19.4477 27.5523 19 27 19ZM27 25H25C24.4477 25 24 25.4477 24 26V28C24 28.5523 24.4477 29 25 29H27C27.5523 29 28 28.5523 28 28V26C28 25.4477 27.5523 25 27 25Z" :fill="active ? '#4772f2' : '#bebfca'")
g(v-if="nameSvg === 'clients'")
g(opacity="0.6")
path(d="M24.4001 14.4734C24.4001 16.6089 22.6093 18.34 20.4001 18.34C18.191 18.34 16.4001 16.6089 16.4001 14.4734C16.4001 12.3379 18.191 10.6067 20.4001 10.6067C22.6093 10.6067 24.4001 12.3379 24.4001 14.4734Z" :fill="active ? '#4772f2' : '#9294A7'")
path(d="M12.4001 24.9528C12.4001 21.5523 15.6478 19.0202 19.0858 19.7403C19.952 19.9217 20.8483 19.9217 21.7145 19.7403C25.1524 19.0202 28.4001 21.5523 28.4001 24.9528V27.62C28.4001 28.0471 28.042 28.3934 27.6001 28.3934H13.2001C12.7583 28.3934 12.4001 28.0471 12.4001 27.62V24.9528Z" :fill="active ? '#4772f2' : '#9294A7'")
g(opacity="0.6")
path(d="M31.2 15.6166C31.2 17.1022 29.9464 18.3065 28.4 18.3065C26.8536 18.3065 25.6 17.1022 25.6 15.6166C25.6 14.131 26.8536 12.9268 28.4 12.9268C29.9464 12.9268 31.2 14.131 31.2 15.6166Z" :fill="active ? '#4772f2' : '#9294A7'")
path(d="M14.4 15.6166C14.4 17.1022 13.1464 18.3065 11.6 18.3065C10.0536 18.3065 8.8 17.1022 8.8 15.6166C8.8 14.131 10.0536 12.9268 11.6 12.9268C13.1464 12.9268 14.4 14.131 14.4 15.6166Z" :fill="active ? '#4772f2' : '#9294A7'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M12.52 19.2806C13.2055 19.1379 13.8801 19.1788 14.4945 19.3648C12.5441 20.4847 11.2 22.5391 11.2 24.9528V25.3001H6.56C6.25072 25.3001 6 25.0592 6 24.7621V22.9066C6 20.5411 8.27339 18.7797 10.68 19.2806C11.2863 19.4068 11.9137 19.4068 12.52 19.2806ZM26.0735 19.2376C28.1486 20.3243 29.6 22.4445 29.6 24.9528V25.3001H33.44C33.7493 25.3001 34 25.0592 34 24.7621V22.9066C34 20.5411 31.7266 18.7797 29.32 19.2806C28.7137 19.4068 28.0863 19.4068 27.48 19.2806C27.0002 19.1807 26.5257 19.1708 26.0735 19.2376Z" :fill="active ? '#4772f2' : '#9294A7'")
g(v-if="nameSvg === 'settings'")
path(:fill="active ? '#4772f2' : '#9294A7'" opacity="0.6" d="m20.93202,15.9808l0.0537,0.0933l0.7464,-0.3152c1.3952,-0.5891 3.0106,-0.046 3.7666,1.2662l1.4158,2.4579c0.0964,0.1672 0.175,0.3404 0.2362,0.517l0.7131,0c0.7569,0 1.3951,-0.5638 1.4886,-1.3149l0.0572,-0.4606c0.0358,-0.2873 0.226,-0.5281 0.4757,-0.6745c0.2563,-0.1502 0.568,-0.1912 0.8413,-0.0748l0.3903,0.1662c0.6983,0.2974 1.5087,0.0263 1.8875,-0.6313l0.6179,-1.0726c0.3623,-0.629 0.2011,-1.4292 -0.3765,-1.8688l-0.5924,-0.4509c-0.1152,-0.0876 -0.1561,-0.2372 -0.1561,-0.3819l0,-0.4725c0,-0.1462 0.0546,-0.2908 0.1709,-0.3793l0.5552,-0.4225c0.6004,-0.4569 0.768,-1.2887 0.3914,-1.9424l-0.595,-1.03282c-0.378,-0.65613 -1.1857,-0.92767 -1.8833,-0.6331l-0.4164,0.17583c-0.2694,0.11377 -0.5763,0.0737 -0.8257,-0.07911c-0.2504,-0.15291 -0.4496,-0.39166 -0.4858,-0.68281l-0.0562,-0.45233c-0.0935,-0.75105 -0.7317,-1.31486 -1.4886,-1.31486l-1.1808,0c-0.7569,0 -1.3952,0.56381 -1.4886,1.31486l-0.0573,0.46066c-0.0357,0.28728 -0.2259,0.52807 -0.4757,0.67448c-0.2563,0.1503 -0.568,0.19175 -0.8418,0.07614l-0.4094,-0.17286c-0.6975,-0.29457 -1.5052,-0.02303 -1.8832,0.6331l-0.595,1.03282c-0.3766,0.6537 -0.209,1.4855 0.3913,1.9424l0.5552,0.4225c0.1163,0.0885 0.171,0.2331 0.171,0.3793l0,0.4725c0,0.1466 -0.0549,0.2916 -0.1715,0.3804l-0.5547,0.4221c-0.6003,0.4569 -0.7679,1.2887 -0.3913,1.9424zm6.3762,-0.5308c0.6733,0 1.2479,-0.2392 1.7239,-0.7175c0.4759,-0.4783 0.7139,-1.0558 0.7139,-1.7325c0,-0.6767 -0.238,-1.2542 -0.7139,-1.7325c-0.476,-0.4783 -1.0506,-0.7175 -1.7239,-0.7175c-0.6849,0 -1.2625,0.2392 -1.7329,0.7175c-0.4699,0.4783 -0.7049,1.0558 -0.7049,1.7325c0,0.6767 0.235,1.2542 0.7049,1.7325c0.4704,0.4783 1.048,0.7175 1.7329,0.7175z" clip-rule="evenodd" fill-rule="evenodd")
g
path(transform="rotate(120 15.5172 24.5958)" :fill="active ? '#4772f2' : '#9294A7'" d="m5.28083,29.36488l0.08668,0.14927l1.20485,-0.5043c2.25215,-0.94252 4.85974,-0.0736 6.08008,2.02584l2.2854,3.93248c0.15561,0.26751 0.28249,0.54462 0.38128,0.82717l1.15109,0c1.2218,0 2.25198,-0.90204 2.40291,-2.10376l0.09233,-0.73693c0.05779,-0.45966 0.36481,-0.84493 0.76788,-1.07916c0.41372,-0.24031 0.91687,-0.30591 1.35803,-0.11968l0.63003,0.26591c1.1272,0.47582 2.43536,0.04208 3.04682,-1.01004l0.99742,-1.71609c0.58483,-1.00636 0.32462,-2.28663 -0.60775,-2.98996l-0.95626,-0.72141c-0.18596,-0.14015 -0.25198,-0.3795 -0.25198,-0.61102l0,-0.75597c0,-0.23391 0.08814,-0.46526 0.27587,-0.60686l0.89621,-0.67597c0.96917,-0.73101 1.23971,-2.06184 0.6318,-3.10772l-0.96045,-1.65245c-0.61017,-1.04977 -1.91397,-1.48421 -3.04004,-1.01292l-0.67216,0.28132c-0.43487,0.18202 -0.93027,0.11792 -1.33285,-0.12657c-0.4042,-0.24465 -0.72575,-0.62663 -0.78418,-1.09245l-0.09072,-0.7237c-0.15093,-1.20163 -1.18112,-2.10369 -2.40291,-2.10369l-1.90606,0c-1.2218,0 -2.25215,0.90206 -2.40291,2.10369l-0.09249,0.73703c-0.05763,0.45963 -0.36465,0.84488 -0.76788,1.07913c-0.41372,0.24047 -0.91687,0.30679 -1.35884,0.12182l-0.66086,-0.27656c-1.12591,-0.47129 -2.42971,-0.03685 -3.03988,1.01292l-0.96045,1.65245c-0.60791,1.04588 -0.33737,2.37671 0.63164,3.10772l0.89621,0.67597c0.18773,0.14159 0.27603,0.37295 0.27603,0.60686l0,0.75597c0,0.23455 -0.08862,0.46654 -0.27684,0.60862l-0.8954,0.67533c-0.96901,0.73101 -1.23955,2.06184 -0.63164,3.10772l-0.00001,-0.00001zm10.29253,-0.84925c1.08685,0 2.01437,-0.3827 2.78274,-1.14795c0.7682,-0.76525 1.15238,-1.68921 1.15238,-2.77189c0,-1.08268 -0.38418,-2.00664 -1.15238,-2.77189c-0.76836,-0.76525 -1.69589,-1.14795 -2.78274,-1.14795c-1.10557,0 -2.03794,0.3827 -2.79726,1.14795c-0.75852,0.76525 -1.13786,1.68921 -1.13786,2.77189c0,1.08268 0.37934,2.00664 1.13786,2.77189c0.75932,0.76525 1.69169,1.14795 2.79726,1.14795z" clip-rule="evenodd" fill-rule="evenodd")
path(:fill="active ? '#4772f2' : '#9294A7'" d="m5.27928,29.28626l0.08668,0.14927l1.20485,-0.5043c2.25214,-0.94252 4.85974,-0.0736 6.08008,2.02584l2.2854,3.93248c0.15561,0.26751 0.28249,0.54462 0.38128,0.82717l1.15109,0c1.2218,0 2.25198,-0.90204 2.40291,-2.10376l0.09234,-0.73693c0.05778,-0.45966 0.36481,-0.84492 0.76788,-1.07915c0.41372,-0.24031 0.91687,-0.30591 1.35803,-0.11968l0.63003,0.26591c1.1272,0.47582 2.43536,0.04208 3.04682,-1.01004l0.99742,-1.71609c0.58483,-1.00636 0.32462,-2.28663 -0.60775,-2.98996l-0.95626,-0.72141c-0.18596,-0.14016 -0.25198,-0.37951 -0.25198,-0.61102l0,-0.75597c0,-0.23391 0.08814,-0.46526 0.27587,-0.60685l0.89621,-0.67598c0.96917,-0.73101 1.23971,-2.06184 0.6318,-3.10771l-0.96045,-1.65245c-0.61017,-1.04977 -1.91397,-1.48421 -3.04004,-1.01292l-0.67216,0.28132c-0.43487,0.18202 -0.93027,0.11791 -1.33285,-0.12657c-0.4042,-0.24465 -0.72575,-0.62664 -0.78419,-1.09246l-0.09072,-0.7237c-0.15093,-1.20163 -1.18111,-2.10369 -2.40291,-2.10369l-1.90606,0c-1.22179,0 -2.25214,0.90206 -2.40291,2.10369l-0.0925,0.73703c-0.05762,0.45963 -0.36465,0.84488 -0.76788,1.07913c-0.41372,0.24047 -0.91687,0.30678 -1.35884,0.12181l-0.66086,-0.27656c-1.12591,-0.47129 -2.4297,-0.03685 -3.03988,1.01292l-0.96045,1.65245c-0.60791,1.04587 -0.33737,2.3767 0.63164,3.10771l0.89621,0.67598c0.18773,0.14159 0.27603,0.37294 0.27603,0.60685l0,0.75597c0,0.23455 -0.08862,0.46654 -0.27684,0.60862l-0.8954,0.67533c-0.96901,0.73101 -1.23955,2.06184 -0.63164,3.10772zm10.29253,-0.84925c1.08684,0 2.01437,-0.38271 2.78273,-1.14795c0.7682,-0.76525 1.15239,-1.68922 1.15239,-2.77189c0,-1.08268 -0.38419,-2.00664 -1.15239,-2.77189c-0.76836,-0.76525 -1.69589,-1.14796 -2.78273,-1.14796c-1.10558,0 -2.03794,0.38271 -2.79727,1.14796c-0.75852,0.76525 -1.13786,1.68921 -1.13786,2.77189c0,1.08267 0.37934,2.00664 1.13786,2.77189c0.75933,0.76524 1.69169,1.14795 2.79727,1.14795z" clip-rule="evenodd" fill-rule="evenodd")
path(d="M24.4001 14.4734C24.4001 16.6089 22.6093 18.34 20.4001 18.34C18.191 18.34 16.4001 16.6089 16.4001 14.4734C16.4001 12.3379 18.191 10.6067 20.4001 10.6067C22.6093 10.6067 24.4001 12.3379 24.4001 14.4734Z" :fill="active ? '#4772f2' : '#bebfca'")
path(d="M12.4001 24.9528C12.4001 21.5523 15.6478 19.0202 19.0858 19.7403C19.952 19.9217 20.8483 19.9217 21.7145 19.7403C25.1524 19.0202 28.4001 21.5523 28.4001 24.9528V27.62C28.4001 28.0471 28.042 28.3934 27.6001 28.3934H13.2001C12.7583 28.3934 12.4001 28.0471 12.4001 27.62V24.9528Z" :fill="active ? '#4772f2' : '#bebfca'")
g(opacity="0.6")
path(d="M31.2 15.6166C31.2 17.1022 29.9464 18.3065 28.4 18.3065C26.8536 18.3065 25.6 17.1022 25.6 15.6166C25.6 14.131 26.8536 12.9268 28.4 12.9268C29.9464 12.9268 31.2 14.131 31.2 15.6166Z" :fill="active ? '#4772f2' : '#bebfca'")
path(d="M14.4 15.6166C14.4 17.1022 13.1464 18.3065 11.6 18.3065C10.0536 18.3065 8.8 17.1022 8.8 15.6166C8.8 14.131 10.0536 12.9268 11.6 12.9268C13.1464 12.9268 14.4 14.131 14.4 15.6166Z" :fill="active ? '#4772f2' : '#bebfca'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M12.52 19.2806C13.2055 19.1379 13.8801 19.1788 14.4945 19.3648C12.5441 20.4847 11.2 22.5391 11.2 24.9528V25.3001H6.56C6.25072 25.3001 6 25.0592 6 24.7621V22.9066C6 20.5411 8.27339 18.7797 10.68 19.2806C11.2863 19.4068 11.9137 19.4068 12.52 19.2806ZM26.0735 19.2376C28.1486 20.3243 29.6 22.4445 29.6 24.9528V25.3001H33.44C33.7493 25.3001 34 25.0592 34 24.7621V22.9066C34 20.5411 31.7266 18.7797 29.32 19.2806C28.7137 19.4068 28.0863 19.4068 27.48 19.2806C27.0002 19.1807 26.5257 19.1708 26.0735 19.2376Z" :fill="active ? '#4772f2' : '#bebfca'")
g(v-if="nameSvg === 'settings'")
path(:fill="active ? '#4772f2' : '#bebfca'" opacity="0.6" d="m20.93202,15.9808l0.0537,0.0933l0.7464,-0.3152c1.3952,-0.5891 3.0106,-0.046 3.7666,1.2662l1.4158,2.4579c0.0964,0.1672 0.175,0.3404 0.2362,0.517l0.7131,0c0.7569,0 1.3951,-0.5638 1.4886,-1.3149l0.0572,-0.4606c0.0358,-0.2873 0.226,-0.5281 0.4757,-0.6745c0.2563,-0.1502 0.568,-0.1912 0.8413,-0.0748l0.3903,0.1662c0.6983,0.2974 1.5087,0.0263 1.8875,-0.6313l0.6179,-1.0726c0.3623,-0.629 0.2011,-1.4292 -0.3765,-1.8688l-0.5924,-0.4509c-0.1152,-0.0876 -0.1561,-0.2372 -0.1561,-0.3819l0,-0.4725c0,-0.1462 0.0546,-0.2908 0.1709,-0.3793l0.5552,-0.4225c0.6004,-0.4569 0.768,-1.2887 0.3914,-1.9424l-0.595,-1.03282c-0.378,-0.65613 -1.1857,-0.92767 -1.8833,-0.6331l-0.4164,0.17583c-0.2694,0.11377 -0.5763,0.0737 -0.8257,-0.07911c-0.2504,-0.15291 -0.4496,-0.39166 -0.4858,-0.68281l-0.0562,-0.45233c-0.0935,-0.75105 -0.7317,-1.31486 -1.4886,-1.31486l-1.1808,0c-0.7569,0 -1.3952,0.56381 -1.4886,1.31486l-0.0573,0.46066c-0.0357,0.28728 -0.2259,0.52807 -0.4757,0.67448c-0.2563,0.1503 -0.568,0.19175 -0.8418,0.07614l-0.4094,-0.17286c-0.6975,-0.29457 -1.5052,-0.02303 -1.8832,0.6331l-0.595,1.03282c-0.3766,0.6537 -0.209,1.4855 0.3913,1.9424l0.5552,0.4225c0.1163,0.0885 0.171,0.2331 0.171,0.3793l0,0.4725c0,0.1466 -0.0549,0.2916 -0.1715,0.3804l-0.5547,0.4221c-0.6003,0.4569 -0.7679,1.2887 -0.3913,1.9424zm6.3762,-0.5308c0.6733,0 1.2479,-0.2392 1.7239,-0.7175c0.4759,-0.4783 0.7139,-1.0558 0.7139,-1.7325c0,-0.6767 -0.238,-1.2542 -0.7139,-1.7325c-0.476,-0.4783 -1.0506,-0.7175 -1.7239,-0.7175c-0.6849,0 -1.2625,0.2392 -1.7329,0.7175c-0.4699,0.4783 -0.7049,1.0558 -0.7049,1.7325c0,0.6767 0.235,1.2542 0.7049,1.7325c0.4704,0.4783 1.048,0.7175 1.7329,0.7175z" clip-rule="evenodd" fill-rule="evenodd")
g
path(transform="rotate(120 15.5172 24.5958)" :fill="active ? '#4772f2' : '#bebfca'" d="m5.28083,29.36488l0.08668,0.14927l1.20485,-0.5043c2.25215,-0.94252 4.85974,-0.0736 6.08008,2.02584l2.2854,3.93248c0.15561,0.26751 0.28249,0.54462 0.38128,0.82717l1.15109,0c1.2218,0 2.25198,-0.90204 2.40291,-2.10376l0.09233,-0.73693c0.05779,-0.45966 0.36481,-0.84493 0.76788,-1.07916c0.41372,-0.24031 0.91687,-0.30591 1.35803,-0.11968l0.63003,0.26591c1.1272,0.47582 2.43536,0.04208 3.04682,-1.01004l0.99742,-1.71609c0.58483,-1.00636 0.32462,-2.28663 -0.60775,-2.98996l-0.95626,-0.72141c-0.18596,-0.14015 -0.25198,-0.3795 -0.25198,-0.61102l0,-0.75597c0,-0.23391 0.08814,-0.46526 0.27587,-0.60686l0.89621,-0.67597c0.96917,-0.73101 1.23971,-2.06184 0.6318,-3.10772l-0.96045,-1.65245c-0.61017,-1.04977 -1.91397,-1.48421 -3.04004,-1.01292l-0.67216,0.28132c-0.43487,0.18202 -0.93027,0.11792 -1.33285,-0.12657c-0.4042,-0.24465 -0.72575,-0.62663 -0.78418,-1.09245l-0.09072,-0.7237c-0.15093,-1.20163 -1.18112,-2.10369 -2.40291,-2.10369l-1.90606,0c-1.2218,0 -2.25215,0.90206 -2.40291,2.10369l-0.09249,0.73703c-0.05763,0.45963 -0.36465,0.84488 -0.76788,1.07913c-0.41372,0.24047 -0.91687,0.30679 -1.35884,0.12182l-0.66086,-0.27656c-1.12591,-0.47129 -2.42971,-0.03685 -3.03988,1.01292l-0.96045,1.65245c-0.60791,1.04588 -0.33737,2.37671 0.63164,3.10772l0.89621,0.67597c0.18773,0.14159 0.27603,0.37295 0.27603,0.60686l0,0.75597c0,0.23455 -0.08862,0.46654 -0.27684,0.60862l-0.8954,0.67533c-0.96901,0.73101 -1.23955,2.06184 -0.63164,3.10772l-0.00001,-0.00001zm10.29253,-0.84925c1.08685,0 2.01437,-0.3827 2.78274,-1.14795c0.7682,-0.76525 1.15238,-1.68921 1.15238,-2.77189c0,-1.08268 -0.38418,-2.00664 -1.15238,-2.77189c-0.76836,-0.76525 -1.69589,-1.14795 -2.78274,-1.14795c-1.10557,0 -2.03794,0.3827 -2.79726,1.14795c-0.75852,0.76525 -1.13786,1.68921 -1.13786,2.77189c0,1.08268 0.37934,2.00664 1.13786,2.77189c0.75932,0.76525 1.69169,1.14795 2.79726,1.14795z" clip-rule="evenodd" fill-rule="evenodd")
path(:fill="active ? '#4772f2' : '#bebfca'" d="m5.27928,29.28626l0.08668,0.14927l1.20485,-0.5043c2.25214,-0.94252 4.85974,-0.0736 6.08008,2.02584l2.2854,3.93248c0.15561,0.26751 0.28249,0.54462 0.38128,0.82717l1.15109,0c1.2218,0 2.25198,-0.90204 2.40291,-2.10376l0.09234,-0.73693c0.05778,-0.45966 0.36481,-0.84492 0.76788,-1.07915c0.41372,-0.24031 0.91687,-0.30591 1.35803,-0.11968l0.63003,0.26591c1.1272,0.47582 2.43536,0.04208 3.04682,-1.01004l0.99742,-1.71609c0.58483,-1.00636 0.32462,-2.28663 -0.60775,-2.98996l-0.95626,-0.72141c-0.18596,-0.14016 -0.25198,-0.37951 -0.25198,-0.61102l0,-0.75597c0,-0.23391 0.08814,-0.46526 0.27587,-0.60685l0.89621,-0.67598c0.96917,-0.73101 1.23971,-2.06184 0.6318,-3.10771l-0.96045,-1.65245c-0.61017,-1.04977 -1.91397,-1.48421 -3.04004,-1.01292l-0.67216,0.28132c-0.43487,0.18202 -0.93027,0.11791 -1.33285,-0.12657c-0.4042,-0.24465 -0.72575,-0.62664 -0.78419,-1.09246l-0.09072,-0.7237c-0.15093,-1.20163 -1.18111,-2.10369 -2.40291,-2.10369l-1.90606,0c-1.22179,0 -2.25214,0.90206 -2.40291,2.10369l-0.0925,0.73703c-0.05762,0.45963 -0.36465,0.84488 -0.76788,1.07913c-0.41372,0.24047 -0.91687,0.30678 -1.35884,0.12181l-0.66086,-0.27656c-1.12591,-0.47129 -2.4297,-0.03685 -3.03988,1.01292l-0.96045,1.65245c-0.60791,1.04587 -0.33737,2.3767 0.63164,3.10771l0.89621,0.67598c0.18773,0.14159 0.27603,0.37294 0.27603,0.60685l0,0.75597c0,0.23455 -0.08862,0.46654 -0.27684,0.60862l-0.8954,0.67533c-0.96901,0.73101 -1.23955,2.06184 -0.63164,3.10772zm10.29253,-0.84925c1.08684,0 2.01437,-0.38271 2.78273,-1.14795c0.7682,-0.76525 1.15239,-1.68922 1.15239,-2.77189c0,-1.08268 -0.38419,-2.00664 -1.15239,-2.77189c-0.76836,-0.76525 -1.69589,-1.14796 -2.78273,-1.14796c-1.10558,0 -2.03794,0.38271 -2.79727,1.14796c-0.75852,0.76525 -1.13786,1.68921 -1.13786,2.77189c0,1.08267 0.37934,2.00664 1.13786,2.77189c0.75933,0.76524 1.69169,1.14795 2.79727,1.14795z" clip-rule="evenodd" fill-rule="evenodd")
g(v-if="nameSvg === 'home'")
path(d="M20 5L20.5303 4.46967C20.3897 4.32902 20.1989 4.25 20 4.25C19.8011 4.25 19.6103 4.32902 19.4697 4.46967L20 5ZM8.33331 16.6667L7.80298 16.1363C7.66233 16.277 7.58331 16.4678 7.58331 16.6667L8.33331 16.6667ZM31.6666 16.6667H32.4166C32.4166 16.4678 32.3376 16.277 32.197 16.1363L31.6666 16.6667ZM31.6667 33.3333V34.0833C31.8656 34.0833 32.0563 34.0043 32.197 33.8637C32.3376 33.723 32.4167 33.5322 32.4167 33.3333H31.6667ZM8.33332 33.3333H7.58332C7.58332 33.7475 7.91911 34.0833 8.33332 34.0833V33.3333ZM19.4697 4.46967L7.80298 16.1363L8.86364 17.197L20.5303 5.53033L19.4697 4.46967ZM32.197 16.1363L20.5303 4.46967L19.4697 5.53033L31.1363 17.197L32.197 16.1363ZM30.9166 16.6667L30.9167 33.3333H32.4167L32.4166 16.6667L30.9166 16.6667ZM31.6667 32.5833H8.33332V34.0833H31.6667V32.5833ZM9.08332 33.3333L9.08331 16.6667L7.58331 16.6667L7.58332 33.3333H9.08332Z" :fill="active ? '#4772f2' : '#9294A7'")
path(d="M20 5L20.5303 4.46967C20.3897 4.32902 20.1989 4.25 20 4.25C19.8011 4.25 19.6103 4.32902 19.4697 4.46967L20 5ZM8.33331 16.6667L7.80298 16.1363C7.66233 16.277 7.58331 16.4678 7.58331 16.6667L8.33331 16.6667ZM31.6666 16.6667H32.4166C32.4166 16.4678 32.3376 16.277 32.197 16.1363L31.6666 16.6667ZM31.6667 33.3333V34.0833C31.8656 34.0833 32.0563 34.0043 32.197 33.8637C32.3376 33.723 32.4167 33.5322 32.4167 33.3333H31.6667ZM8.33332 33.3333H7.58332C7.58332 33.7475 7.91911 34.0833 8.33332 34.0833V33.3333ZM19.4697 4.46967L7.80298 16.1363L8.86364 17.197L20.5303 5.53033L19.4697 4.46967ZM32.197 16.1363L20.5303 4.46967L19.4697 5.53033L31.1363 17.197L32.197 16.1363ZM30.9166 16.6667L30.9167 33.3333H32.4167L32.4166 16.6667L30.9166 16.6667ZM31.6667 32.5833H8.33332V34.0833H31.6667V32.5833ZM9.08332 33.3333L9.08331 16.6667L7.58331 16.6667L7.58332 33.3333H9.08332Z" :fill="active ? '#4772f2' : '#bebfca'")
g(v-if="nameSvg === 'medcards'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M8.5 20V31C8.5 32.1046 9.39543 33 10.5 33H29.5C30.6046 33 31.5 32.1046 31.5 31V22.9032C31.5 21.7987 30.6046 20.9032 29.5 20.9032H20.0299C19.5184 20.9032 19.0263 20.7073 18.6549 20.3556L16.7451 18.5476C16.3737 18.196 15.8816 18 15.3701 18H10.5C9.39543 18 8.5 18.8954 8.5 20ZM19.5 25V26H18.5C17.9477 26 17.5 26.4477 17.5 27C17.5 27.5523 17.9477 28 18.5 28H19.5V29C19.5 29.5523 19.9477 30 20.5 30C21.0523 30 21.5 29.5523 21.5 29V28H22.5C23.0523 28 23.5 27.5523 23.5 27C23.5 26.4477 23.0523 26 22.5 26H21.5V25C21.5 24.4477 21.0523 24 20.5 24C19.9477 24 19.5 24.4477 19.5 25Z" :fill="active ? '#4772f2' : '#bebfca'")
path(opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M10.5 9L10.5 16.5H15.3701C16.2652 16.5 17.1263 16.8429 17.7763 17.4583L19.6861 19.2663C19.779 19.3542 19.902 19.4032 20.0299 19.4032H29.5L29.5 11.7986C29.5 11.2859 29.3031 10.7928 28.95 10.4211L26.2914 7.6225C25.9138 7.22504 25.3896 7 24.8414 7H12.5C11.3954 7 10.5 7.89543 10.5 9ZM12.75 10C12.75 9.58579 13.0858 9.25 13.5 9.25H24.5C24.9142 9.25 25.25 9.58579 25.25 10C25.25 10.4142 24.9142 10.75 24.5 10.75H13.5C13.0858 10.75 12.75 10.4142 12.75 10ZM12.75 13.5C12.75 13.0858 13.0858 12.75 13.5 12.75H26.5C26.9142 12.75 27.25 13.0858 27.25 13.5C27.25 13.9142 26.9142 14.25 26.5 14.25H13.5C13.0858 14.25 12.75 13.9142 12.75 13.5Z" :fill="active ? '#4772f2' : '#bebfca'")
</template>
<script>

View File

@@ -6,28 +6,15 @@
alt="Logo",
@click="redirectHomePage"
)
header-inputs
.flex.ml-auto.items-center.gap-x-8
base-button(
type="secondary",
width="80px",
no-padding,
@click="openForm"
)
q-icon(name="app:plus", size="12px")
q-icon(name="app:person", size="20px", right)
base-client-form-create(
v-model="isOpenFormInternal",
:set-updated-clients="setUpdatedClients",
:write-created-client-id="writeCreatedClientId",
)
.flex.ml-auto.items-center.gap-x-4
q-btn(
flat,
dense,
:style="{color: 'var(--font-dark-blue-color)', 'min-width': '24px', 'min-height': '24px'}",
:style="{'min-width': '40px', 'min-height': '40px'}",
round,
)
q-icon(name="app:icon-bell", size="20px")
q-icon.bell(name="app:bell", size="24px")
.flex.justify-centflexer.items-center.relative
q-btn(
@click="openPopup",
@@ -35,11 +22,11 @@
padding="0",
style="color: var(--font-grey-color)"
)
base-avatar(:size="36", :color="userData?.color", v-if="!userData?.photo") {{changeName}}
base-avatar(:size="36", :color="userData?.color", v-if="!userData?.avatar") {{changeName}}
base-avatar(:size="32", v-else)
img.h-full.object-cover(:src="url + userData?.photo", alt="Avatar")
.h-6.w-6.flex.items-center.justify-center.ml-2
q-icon(name="app:icon-down-arrow", size="12px")
img.h-full.object-cover(:src="url + userData?.avatar", alt="Avatar")
.h-6.w-6.flex.items-center.justify-center.ml-1.pt-1
q-icon.arrow(name="app:down-arrow", size="24px")
q-menu(
:offset="[60, 6]"
)
@@ -53,15 +40,15 @@ import chargePersonAvatar from "@/assets/images/charge-person-avatar.svg";
import HeaderInputs from "./HeaderInputs.vue";
import BaseAvatar from "@/components/base/BaseAvatar";
import BasePopup from "@/components/base/BasePopup.vue";
import BaseClientFormCreate from "@/components/base/BaseClientFormCreate";
import BaseButton from "@/components/base/BaseButton.vue";
import { fetchWrapper } from "@/shared/fetchWrapper";
export default {
name: "TheHeader",
components: {
HeaderInputs,
BaseAvatar,
BasePopup,
BaseClientFormCreate,
BaseButton,
},
props: {
@@ -80,7 +67,7 @@ export default {
name: "Гордеев Николай Степанович",
},
showPopup: false,
userData: JSON.parse(localStorage.getItem("userData")),
userData: {},
};
},
computed: {
@@ -101,16 +88,20 @@ export default {
},
methods: {
redirectHomePage() {
this.$router.push("/calendar");
this.$router.push("/");
},
logout() {
localStorage.removeItem("tokenAccess");
async logout() {
await fetchWrapper.post("auth/logout");
this.$router.go("/login");
},
openPopup() {
this.showPopup = !this.showPopup;
},
},
async mounted() {
this.userData = await fetchWrapper.get("users/me");
this.$store.dispatch("setUserData", this.userData);
},
};
</script>
@@ -160,4 +151,14 @@ export default {
display: none
.q-btn :deep(.q-focus-helper)
display: none
.add
&:deep(path)
fill: var(--btn-blue-color)
.add-btn
border: none
.bell :deep(path), .arrow :deep(path)
fill: var(--font-dark-blue-color)
</style>

View File

@@ -0,0 +1,85 @@
<template lang="pug">
.sidebar.h-full.rounded.flex.flex-col.justify-between.pt-4.px-2
.flex.flex-col.gap-y-4
q-btn(
style="width: 48px; height: 48px",
id="print",
rounded,
padding="0px",
icon="print",
text-color="blue",
size="xl"
)
q-btn(
v-if="!editMode",
style="width: 48px; height: 48px",
id="edit",
rounded,
padding="0px",
icon="edit",
text-color="blue",
size="xl",
@click="toggleEditMode",
)
q-btn(
v-if="editMode",
style="width: 48px; height: 48px",
id="edit",
rounded,
padding="0px",
icon="check",
text-color="blue",
size="xl"
@click="save",
)
q-btn(
v-if="editMode",
style="width: 48px; height: 48px",
id="edit",
rounded,
padding="0px",
icon="cancel",
text-color="blue",
size="xl",
@click="cancel",
)
</template>
<script>
export default {
name: "TheRightMenu",
emits: ["save", "cancel", "update:editMode"],
data() {
return {
editMode: false,
};
},
methods: {
toggleEditMode() {
this.editMode = !this.editMode;
this.$emit("update:editMode", this.editMode);
},
save() {
this.toggleEditMode();
this.$emit("save");
},
cancel() {
this.toggleEditMode();
this.$emit("cancel");
},
},
};
</script>
<style lang="sass" scoped>
.sidebar
max-width: 64px
min-width: 64px
background-color: var(--default-white)
.button:hover
background-color: var(--bg-light-blue-color)
color: var(--btn-blue-color)
.hover :deep(path)
fill: #9294A7
</style>

View File

@@ -1,5 +1,5 @@
<template lang="pug">
.sidebar.flex.flex-col.justify-between.flex-auto.pt-4.px-2.pb-7.rounded
.sidebar.flex.flex-col.justify-between.py-4.rounded.items-center
.flex.flex-col.gap-y-4
base-button-sidebar(
v-for="button in pageSettings.filter((el) => el.id !== 'settings')",
@@ -35,10 +35,10 @@ export default {
icon: "calendar",
},
{
id: "user",
path: "#/clients",
id: "medcards",
path: "#/medcards",
active: false,
icon: "clients",
icon: "medcards",
},
{
id: "settings",
@@ -64,17 +64,9 @@ export default {
return this.pageSettings.find((el) => el.id === "settings");
},
},
mounted() {
let href = window.location.href.slice(22);
this.pageSettings.forEach((el, index) => {
el.path === href.substr(href.lastIndexOf("#"))
? (this.pageSettings[index].active = true)
: (this.pageSettings[index].active = false);
});
},
watch: {
"$route.path"() {
if (this.$router.currentRoute._value.fullPath === "/calendar") {
"$route.path"(value) {
if (value === "/calendar") {
this.currentPageBorder = true;
this.pageSettings.forEach((el) =>
el.path === "#/calendar" ? (el.active = true) : (el.active = false)
@@ -82,6 +74,13 @@ export default {
} else this.currentPageBorder = false;
},
},
mounted() {
this.pageSettings.forEach((el, index) => {
el.path === "#" + this.$route.path
? (this.pageSettings[index].active = true)
: (this.pageSettings[index].active = false);
});
},
};
</script>

View File

@@ -1,11 +1,11 @@
<template lang="pug">
.flex.w-full(class="gap-x-1.5")
base-select(:items="items", v-model="network.kind")
base-input.w-full(v-model="network.username", placeholder="Ссылкa", outlined, :rule="ruleInput", no-error-icon)
base-select(:items="items", v-model="network.kind", size="M")
base-input.w-full(v-model="network.username", placeholder="Ссылкa", :rule="ruleInput", size="M")
</template>
<script>
import BaseInput from "@/components/base/BaseInput";
import BaseInput from "@/components/base/BaseInput.vue";
import BaseSelect from "@/components/base/BaseSelect.vue";
export default {
name: "TableAddingNetwork",

View File

@@ -46,18 +46,16 @@ export default {
height: "48px",
"min-height": "48px",
};
if (this.size === "S")
return {
height: "32px",
"min-height": "32px",
};
return {
height: "40px",
"min-height": "40px",
};
},
btnWidth() {
return !this.width === "auto"
? {
"min-width": this.width,
}
: {};
},
miniSize() {
return this.type === "mini";
},
@@ -123,6 +121,24 @@ export default {
background-color: var(--btn-mini-color-active)
color: var(--bg-status-green)
.grey
color: var(--font-dark-blue-color)
border: 1.5px solid var(--gray-secondary)
background-color: var(--gray-thirdly)
font-weight: 500
font-size: 14px
line-height: 19px
&:hover
background-color: var(--btn-blue-sec-color-hover)
&:active
background-color: var(--btn-blue-sec-color-active)
&:disabled, &[disabled]
opacity: 1 !important
color: var(--btn-blue-sec-color-disabled)
background-color: white
border: 1.5px solid var(--btn-blue-sec-border-color-disabled)
.q-btn :deep(.q-focus-helper)
display: none
.q-btn :deep(.q-ripple)

View File

@@ -4,30 +4,29 @@
.flex.flex-col.gap-y-4.h-full
.flex.flex-col.gap-y-6
.flex.font-bold.text-xl Категории
base-input.input(
base-input.search(
placeholder="Поиск",
@keyup.enter="searchCategory",
@input="searchCategory",
v-model="searchBenefit",
debounce="10",
outlined,
:width="300",
size="M",
iconLeft
)
q-icon(
name="app:icon-search",
size="20px",
style="color: var(--font-grey-color)"
)
template(v-slot:iconLeft)
q-icon.icon(name="app:search", size="20px", style="color: var(--font-grey-color)")
.field.flex.flex-col.overflow-y-scroll(:class="{'filed-category': findSelected(selected?.id)}")
.flex.items-center(v-for="benefit in benefitData", :key="benefit.id")
q-item(tag="label", :style="{alignItems: benefit.name.length > 28 ? 'start' : 'center'}")
q-item-section(top)
q-radio(
q-radio.radio(
v-model="selected",
:val="benefit",
:style="{border: 'none', width: '36px'}",
size="32px",
:style="{paddingTop: benefit.name.length > 28 ? '7px' : '2px'}",
size="24px",
checked-icon="check_circle",
unchecked-icon="radio_button_unchecked"
)
q-item-label
.name.flex.items-center.font-medium.text-xm {{benefit.name}}
@@ -41,10 +40,10 @@
base-button(
label="Сохранить",
width="146px",
@click="saveCategories(selected[0])"
@click="saveCategories(selected)"
)
.right-side.flex.px-10.font-bold.relative
q-icon(name="app:icon-cancel").text-sm.absolute.top-4.right-4.cursor-pointer(@click="closeModalCategories")
q-icon(name="app:cancel").text-sm.absolute.top-4.right-4.cursor-pointer(@click="closeModalCategories")
.flex.gap-y-6.flex-col.w-full(v-if="selected?.id && selected?.name !== 'Без льготы'")
.right-header.flex
span.text-6xl {{selected?.name}}
@@ -64,8 +63,8 @@
</template>
<script>
import BaseInput from "@/components/base/BaseInput.vue";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "BaseCategorySelection",
@@ -186,13 +185,16 @@ export default {
.grey-color
color: var(--font-grey-color)
.icon :deep(path)
fill: var(--font-grey-color)
.q-item
padding: 0
min-height: 40px
.q-item__section
width: 36px
min-width: 36px
width: 32px
min-width: 32px
.q-item :deep(.q-focus-helper)
width: 0
@@ -210,4 +212,13 @@ export default {
border: 1px solid var(--font-dark-blue-color)
&:after
border-width: 1px !important
.radio :deep(.q-icon)
font-size: 20px
.radio :deep(.q-radio__inner)
height: 24px
.search :deep(.q-field__prepend)
padding-right: 6px
</style>

View File

@@ -63,7 +63,11 @@
padding="2px 0 0 0"
)
q-icon(name="app:ok", size="20px")
base-input.w-full(v-model="infoClient.basic.full_name", placeholder="ФИО*", outlined)
base-input.w-full(
v-model="infoClient.basic.full_name",
placeholder="ФИО*",
size="M"
)
.flex.flex-col.flex-auto.l.gap-y-8
.flex
button.title-info.px-6.py-2.cursor-pointer.w-full.text-sm(
@@ -94,7 +98,6 @@ 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";
@@ -103,6 +106,7 @@ import { addNotification } from "@/components/Notifications/notificationContext"
import * as moment from "moment";
import { v_model } from "@/shared/mixins/v-model";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "BaseClientFormClient",

View File

@@ -1,22 +1,22 @@
<template lang="pug">
label.download.flex.cursor-pointer.relative.items-center.justify-center.rounded(
label.download.flex.relative.items-center.justify-center.rounded(
:style="{height: `${height}px`, width: width ? `${width}px` : '100%'}"
)
base-input.w-full.h-full(
base-input.w-full(
@change="(e) => addNewFiles(e)",
doc,
type="file",
:accept="getAccept",
id="upload"
borderless,
:multiple="multiple"
:size="`${height}px`"
:height="`${height}px`"
)
q-icon.absolute(
v-if="withIcon",
name="app:download",
:size="sizeIcon"
)
.flex.flex-col.items-center.justify-center.absolute.font-medium.text-smm.w-full(
.flex.flex-col.items-center.justify-center.absolute.font-medium.text-base.w-full(
v-else,
:style="{color: 'var(--font-grey-color)'}"
)
@@ -42,7 +42,7 @@ export default {
multiple: Boolean,
height: {
type: Number,
default: 93,
default: 92,
},
width: Number,
type: {
@@ -91,15 +91,9 @@ export default {
</script>
<style lang="sass" scoped>
#upload :deep(.q-field__native)
cursor: pointer
height: 100%
padding: 0
#upload :deep(.q-field__control)
height: 100%
.download
border: 1px dashed var(--font-grey-color)
background-color: var(--default-white)
background-color: var(--bg-light-grey)
border-radius: 4px
&:hover .q-icon
opacity: 0.6
& .q-icon

View File

@@ -0,0 +1,55 @@
<template lang="pug">
.flex
template(v-if="value")
q-btn(
@click="toggleEditMode",
:style="{backgroundColor: 'var(--bg-light-grey)', color: 'blue'}",
padding="10px",
)
q-icon(
name="edit",
size="20px",
)
template(v-else)
q-btn.mr-2(
@click="save",
:style="{backgroundColor: 'var(--bg-light-grey)', color: 'blue'}",
padding="10px",
)
q-icon(
name="check",
size="20px",
)
q-btn(
@click="cancel",
:style="{backgroundColor: 'var(--bg-light-grey)', color: 'blue'}",
padding="10px",
)
q-icon(
name="cancel",
size="20px",
)
</template>
<script>
import { v_model } from "@/shared/mixins/v-model";
export default {
name: "BaseEditModeSwitcher",
mixins: [v_model],
emits: ["save", "cancel"],
methods: {
toggleEditMode() {
this.value = !this.value;
},
save() {
this.toggleEditMode();
this.$emit("save");
},
cancel() {
this.toggleEditMode();
this.$emit("cancel");
},
},
};
</script>

View File

@@ -0,0 +1,58 @@
<template lang="pug">
.XXX.p-2
template(v-if="!editMode")
template(v-if="value.length")
template(v-for="elem in value", :key="elem.id")
.text-m.pb-1 {{ elem.label }}
.font-medium.text-xl.pb-3 {{ elem.value }}
.flex.flex-col.justify-evenly.items-center.content-center(v-else, style="height:100px")
q-icon(
name="help_outline",
size="40px",
class="icon",
id="empty"
)
.text {{ emptyMessage }}
template(v-else)
template(v-for="elem in value", :key="elem.id")
.text-m.pb-1 {{ elem.label }}
base-input.pb-3(
v-model="elem.value",
size="M",
)
.flex.justify-center
q-btn-dropdown(label="Добавить", icon="add", outline, color="blue-6")
q-list(v-for="option in options", :key="option")
q-item(clickable, v-close-popup, @click="addOption(option)")
q-item-label {{ option }}
</template>
<script>
import BaseInput from "@/components/base/BaseInput.vue";
import { v_model } from "@/shared/mixins/v-model";
export default {
name: "BaseFieldList",
components: { BaseInput },
mixins: [v_model],
props: {
editMode: Boolean,
options: Array,
emptyMessage: String,
},
data() {
return {};
},
methods: {
addOption(option) {
this.value.push({ label: option, value: "" });
},
},
};
</script>
<style lang="sass" scoped>
.XXX
min-height: 100px
</style>

View File

@@ -1,40 +1,39 @@
<template lang="pug">
base-input-container.gap-y-2(:important="important", :label="label", :style="{width: width + 'px' }")
q-input(
base-input-container.gap-y-2(:important="important", :label="label", :style="{width: widthInternal, ...sizeVariable}")
q-input.input(
v-model="value",
:name="name",
:multiple="multiple",
:class="{'circle': circle, 'font-input': true, 'doc': doc}",
:input-style="{ color: textColor, borderColor: borderColor, resize: resize, fontSize: fontSize, fontWeight: fontWeight, lineHeight: lineHeight, minHeight: minHeight}",
:input-style="{resize: resize, height: height}",
:borderless="borderless",
:placeholder="placeholder",
:outlined="outlined",
:dense="dense",
outlined,
:type="type",
:readonly="readonly",
:disable="disabled",
:filled="filled",
:bg-color="filled || standout ? '' : 'white'",
:rules="rule",
:lazy-rules="lazyRule",
:item-aligned="itemAligned",
:no-error-icon="noErrorIcon",
no-error-icon,
:standout="readonly",
:mask="mask",
:maxlength="maxLength",
:autogrow="autogrow",
:square="square",
:standout="standout"
:accept="accept",
:debounce="debounce",
:shadow-text="shadowText",
:autofocus="autofocus",
hide-bottom-space
:error="error",
@focus="e => $emit('focus', e)"
)
template(v-slot:prepend, v-if="iconLeft")
slot
slot(name="iconLeft")
template(v-slot:append, v-if="iconRight")
slot
slot.cursor-pointer(v-if="!iconLeft && !iconRight")
slot(name="iconRight")
template(#error v-if="error")
slot(name="error")
slot(v-if="!iconLeft && !iconRight")
</template>
<script>
@@ -45,41 +44,8 @@ export default {
components: { BaseInputContainer },
props: {
multiple: Boolean,
circle: Boolean,
doc: Boolean,
autofocus: Boolean,
dense: {
type: Boolean,
default: true,
},
fontSize: {
type: String,
default: "14px",
},
fontWeight: {
type: Number,
default: 500,
},
minHeight: {
type: String,
default: "0px",
},
lineHeight: {
type: String,
default: "19px",
},
outlined: {
type: Boolean,
default: false,
},
square: {
type: Boolean,
default: false,
},
filled: {
type: Boolean,
default: false,
},
borderless: {
type: Boolean,
default: false,
@@ -89,12 +55,9 @@ export default {
default: false,
},
type: {
type: String,
default: "text",
},
standout: {
type: [Boolean, String],
default: false,
},
accept: {
type: String,
default: "",
@@ -106,13 +69,9 @@ export default {
shadowText: String,
mask: String,
debounce: [String, Number],
width: Number,
maxLength: Number,
textColor: String,
borderColor: String,
width: [String, Number],
rule: Array,
lazyRule: [Boolean, String],
noErrorIcon: Boolean,
itemAligned: Boolean,
modelValue: [String, Date, Number],
placeholder: String,
@@ -123,8 +82,12 @@ export default {
iconRight: Boolean,
name: String,
important: Boolean,
size: String,
circle: Boolean,
height: String,
error: Boolean,
},
emits: ["update:modelValue"],
emits: ["update:modelValue", "focus"],
computed: {
value: {
get() {
@@ -141,6 +104,59 @@ export default {
: this.$emit("update:modelValue", value);
},
},
sizeVariable() {
if (this.size === "XS")
return {
"--input-height": "28px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
if (this.size === "S")
return {
"--input-height": "32px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
if (this.size === "M")
return {
"--input-height": "40px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
if (this.size === "L")
return {
"--input-height": "48px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
if (this.size)
return {
"--input-height": this.size,
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
return {
"--input-height": "56px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
},
widthInternal() {
if (typeof this.width === "number") return this.width + "px";
return this.width;
},
},
};
</script>
@@ -162,13 +178,69 @@ export default {
height: 100%
z-index: 5
opacity: 0
cursor: pointer
cursor: pointer !important
::file-selector-button
cursor: pointer
</style>
<style lang="sass">
.q-field--standout.q-field--readonly .q-field__control:before
border: none !important
.q-field--standout .q-field__control
.input :deep(input[type="file" i])
cursor: pointer
.input :deep(.q-field__native)
font-weight: 500
font-size: var(--text-size)
line-height: var(--line-height)
color: var(--font-dark-blue-color)
padding: var(--py)
&::placeholder
color: var(--font-grey-color)
opacity: 1
.input :deep(.q-field__control)
height: var(--input-height) !important
color: var(--font-dark-blue-color)
padding: var(--px)
&:before
border-color: var(--border-light-grey-color) !important
transition: none
&:hover:before
border-color: var(--font-grey-color) !important
&:after
border-width: 1px !important
transition: none
transform: none !important
.q-field--disabled :deep(.q-field__control > div)
opacity: 1 !important
.q-field--outlined.q-field--disabled :deep(.q-field__native)
color: var(--font-grey-color)
.q-field--outlined.q-field--disabled :deep(.q-field__control)
background: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__control)
background: var(--bg-light-grey) !important
&:before
border-color: var(--bg-light-grey) !important
transition: none
&:hover:before
border-color: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__native)
cursor: default
.q-field--error :deep(.q-field__bottom)
padding: 4px 0 0 0
font-weight: 500
font-size: 12px
line-height: 135% !important
.input :deep(.q-field__marginal)
height: auto !important
.input :deep(.q-field__shadow)
opacity: 0.5
top: 3px
color: var(--font-grey-color)
margin-left: 8px
</style>

View File

@@ -1,6 +1,6 @@
<template lang="pug">
.flex.flex-col.gap-y-2
.label.font-semibold.text-sm.opacity-40(v-if="label") {{ label }}
.flex.flex-col.gap-y-6px
.label.font-semibold.text-sm(v-if="label") {{ label }}
span.-mt-2(v-if="important", :style="{color: 'var(--font-obligatory-color)'}") *
slot
</template>
@@ -14,3 +14,9 @@ export default {
},
};
</script>
<style lang="sass" scoped>
.label
color: var(--font-grey-color)
line-height: 135%
</style>

View File

@@ -1,90 +1,53 @@
<template lang="pug">
base-input-container.gap-y-2(:label="label", :style="{width: width + 'px' }")
q-input(
base-input-container.gap-y-2(:label="label", :style="{width: widthInternal, ...sizeVariable }")
q-input.input(
v-model="value",
:name="name",
:class="{'circle': circle, 'font-input': true}",
:input-style="{ color: textColor, borderColor: borderColor, resize: resize}",
:borderless="borderless",
:input-style="{resize: resize}",
:placeholder="placeholder",
:outlined="outlined",
:dense="dense",
outlined,
:readonly="readonly",
:disable="disabled",
:filled="filled",
mask="##.##.####"
:bg-color="filled || standout ? '' : 'white'",
:rules="[checkInput]",
mask="##.##.####",
:rules="[(val) => rule ? rule(val) : defaultRule(val)]",
:lazy-rules="lazyRule",
:item-aligned="itemAligned",
:no-error-icon="noErrorIcon",
:maxlength="maxLength",
:autogrow="autogrow",
:square="square",
:standout="standout"
no-error-icon,
:accept="accept",
:debounce="debounce",
hide-bottom-space,
lazy-rules
)
template(v-slot:append)
q-icon(
template(v-slot:append, v-if="!readonly && !disabled")
q-icon.calendar-icon(
name="app:calendar",
class="cursor-pointer",
size="16px"
size="20px"
)
q-popup-proxy(cover, transition-show="scale", transition-hide="scale")
q-date(
v-model="value",
mask="DD.MM.YYYY",
minimal
q-menu(
:style="{'margin-top': '6px !important'}",
v-model="calendarVisibility",
transition-show="scale",
transition-hide="scale",
self="top middle",
:offset="[118, 14]",
)
.flex.items-center.justify-end
q-btn(
v-close-popup,
label="Закрыть",
color="primary",
flat,
no-caps
base-calendar(
v-model="internalDate",
:start-year="2000",
:save="closeCalendar",
@update:model-value="transmitInternalDate"
)
</template>
<script>
import BaseInputContainer from "@/components/base/BaseInputContainer.vue";
import * as moment from "moment/moment";
import BaseCalendar from "@/components/base/Calendar/BaseCalendar.vue";
export default {
name: "BaseInputDate",
components: { BaseInputContainer },
components: { BaseInputContainer, BaseCalendar },
props: {
circle: Boolean,
dense: {
type: Boolean,
default: true,
},
outlined: {
type: Boolean,
default: false,
},
square: {
type: Boolean,
default: false,
},
filled: {
type: Boolean,
default: false,
},
borderless: {
type: Boolean,
default: false,
},
autogrow: {
type: Boolean,
default: false,
},
standout: {
type: [Boolean, String],
default: false,
},
accept: {
type: String,
default: "",
@@ -94,52 +57,116 @@ export default {
default: "none",
},
debounce: [String, Number],
width: Number,
maxLength: Number,
textColor: String,
borderColor: String,
width: [String, Number],
lazyRule: [Boolean, String],
noErrorIcon: Boolean,
itemAligned: Boolean,
modelValue: Date,
rule: Function,
modelValue: String,
placeholder: String,
disabled: Boolean,
label: String,
readonly: Boolean,
iconLeft: Boolean,
name: String,
size: String,
},
emits: ["update:modelValue"],
data() {
return {
calendarVisibility: false,
internalDate: null,
};
},
computed: {
value: {
get() {
if (
moment(this.modelValue).isValid() &&
typeof this.modelValue === "object"
)
return moment(this.modelValue).format("DD.MM.YYYY");
if (moment(this.convertFormat(this.modelValue)).isValid())
return this.modelValue;
return null;
},
set(value) {
this.$emit(
"update:modelValue",
moment(this.convertFormat(value)).isValid()
? new Date(moment(this.convertFormat(value)))
this.changeInternalDate(
moment(this.checkFormat(this.modelValue)).isValid()
? moment(this.modelValue)
: null
);
return this.convertISOFormat(this.modelValue);
},
set(value) {
this.$emit("update:modelValue", this.convertRUFormat(value));
},
},
sizeVariable() {
switch (this.size) {
case "XS":
return {
"--input-height": "28px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
case "S":
return {
"--input-height": "32px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
case "M":
return {
"--input-height": "40px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
case "L":
return {
"--input-height": "48px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
default:
return {
"--input-height": "56px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
}
},
widthInternal() {
if (typeof this.width === "number") return this.width + "px";
return this.width;
},
},
methods: {
convertFormat(date) {
return date && date?.length === 10
? date.split(".").reverse().join("-")
: null;
convertISOFormat(date) {
return date?.split("-")?.reverse()?.join(".");
},
checkInput(val) {
return moment(this.convertFormat(val)).isValid();
convertRUFormat(date) {
return date?.split(".")?.reverse()?.join("-");
},
checkFormat(date) {
return date && date?.length === 10 ? date : null;
},
defaultRule(val) {
return (
!val ||
moment(
this.checkFormat(val) ? this.convertRUFormat(val) : null
).isValid()
);
},
closeCalendar() {
this.calendarVisibility = false;
},
changeInternalDate(value) {
this.internalDate = value;
},
transmitInternalDate(value) {
this.value = value?.format("DD.MM.YYYY");
},
},
};
@@ -149,17 +176,59 @@ export default {
.font-input
font-feature-settings: 'pnum' on, 'lnum' on
.circle
width: 100%
height: 100%
border-radius: 50%
z-index: 5
opacity: 0
cursor: pointer
</style>
<style lang="sass">
.q-field--standout.q-field--readonly .q-field__control:before
border: none !important
.q-field--standout .q-field__control
.input :deep(.q-field__native)
font-weight: 500
font-size: var(--text-size)
line-height: var(--line-height)
color: var(--font-dark-blue-color)
padding: var(--py)
&::placeholder
color: var(--font-grey-color)
opacity: 1
.input :deep(.q-field__control)
height: var(--input-height) !important
color: var(--font-dark-blue-color)
padding: var(--px)
&:before
border-color: var(--border-light-grey-color) !important
transition: none
&:hover:before
border-color: var(--font-grey-color) !important
&:after
border-width: 1px !important
transition: none
transform: none !important
.q-field--disabled :deep(.q-field__control > div)
opacity: 1 !important
.q-field--outlined.q-field--disabled :deep(.q-field__native)
color: var(--font-grey-color)
.q-field--outlined.q-field--disabled :deep(.q-field__control)
background: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__control)
background: var(--bg-light-grey) !important
&:before
border-color: var(--bg-light-grey) !important
transition: none
&:hover:before
border-color: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__native)
cursor: default
.q-field--error :deep(.q-field__bottom)
padding: 4px 0 0 0
font-weight: 500
font-size: 12px
line-height: 135% !important
.input :deep(.q-field__marginal)
height: auto !important
.calendar-icon :deep(path)
fill: var(--font-dark-blue-color)
</style>

View File

@@ -29,7 +29,7 @@
type="file",
id="image-upload",
accept="image/*",
@change="(e) => previewImage(e)"
@change="(e) => previewImage(e)",
)
.avatar.flex.absolute.items-center.gap-x-6
img.avatar.object-cover(for="image-upload", :src="image", v-if="image")
@@ -41,19 +41,20 @@
padding="2px 0 0 0"
)
q-icon(name="app:ok", size="20px")
base-input.w-full(v-model="infoClient.basic.full_name", placeholder="ФИО пациента*", outlined)
base-input.w-full(v-model="value.full_name", placeholder="ФИО пациента*", size="M")
</template>
<script>
import BaseModal from "./BaseModal.vue";
import BaseInput from "./BaseInput.vue";
import addImageIcon from "@/assets/icons/photo.svg";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue";
import { v_model } from "@/shared/mixins/v-model";
export default {
name: "BaseInputFullName",
components: { BaseModal, BaseInput, BaseButton },
props: { infoClient: Object },
mixins: [v_model],
data() {
return {
defaultIcon: addImageIcon,

View File

@@ -1,30 +1,23 @@
<template lang="pug">
base-input-container.gap-y-2(:label="label", :style="{width: width + 'px' }")
q-input(
base-input-container.gap-y-2(:label="label", :style="{width: width + 'px', ...sizeVariable }")
q-input.input(
ref="numberInput"
v-model="value",
:name="name",
:multiple="multiple",
:class="{'circle': circle, 'font-input': true, 'doc': doc}",
:input-style="{ color: textColor, borderColor: borderColor, resize: resize }",
:borderless="borderless",
:class="{'circle': circle, 'font-input': true}",
:input-style="{ resize: resize }",
:placeholder="placeholder",
:outlined="outlined",
:dense="dense",
outlined,
type="number",
:readonly="readonly",
:disable="disabled",
:filled="filled",
:bg-color="filled || standout ? '' : 'white'",
:rules="rule || ruleNumberInput",
:lazy-rules="lazyRule",
:item-aligned="itemAligned",
:no-error-icon="noErrorIcon",
no-error-icon,
:mask="mask",
:maxlength="maxLength",
:autogrow="autogrow",
:square="square",
:standout="standout"
:accept="accept",
:debounce="null",
:shadow-text="shadowText"
@@ -48,14 +41,13 @@
</template>
<script>
import BaseInput from "@/components/base/BaseInput";
import BaseInputContainer from "@/components/base/BaseInputContainer.vue";
import { ruleNumberInput } from "@/shared/utils/rulesInputs";
import { roundNumber } from "@/shared/utils/methodsObjects";
export default {
name: "BaseInputNumber",
components: { BaseInput, BaseInputContainer },
components: { BaseInputContainer },
data() {
return {
intervalId: 0,
@@ -80,35 +72,10 @@ export default {
reverseValue: Boolean,
multiple: Boolean,
circle: Boolean,
doc: Boolean,
dense: {
type: Boolean,
default: true,
},
outlined: {
type: Boolean,
default: false,
},
square: {
type: Boolean,
default: false,
},
filled: {
type: Boolean,
default: false,
},
borderless: {
type: Boolean,
default: false,
},
autogrow: {
type: Boolean,
default: false,
},
standout: {
type: [Boolean, String],
default: false,
},
accept: {
type: String,
default: "",
@@ -121,15 +88,8 @@ export default {
mask: String,
debounce: [String, Number],
width: Number,
maxLength: Number,
textColor: String,
borderColor: String,
rule: Array,
lazyRule: String,
noErrorIcon: {
type: Boolean,
default: true,
},
itemAligned: Boolean,
modelValue: [Number],
placeholder: String,
@@ -138,6 +98,7 @@ export default {
readonly: Boolean,
iconLeft: Boolean,
name: String,
size: String,
},
emits: ["update:modelValue"],
methods: {
@@ -197,6 +158,59 @@ export default {
rounding() {
return String(this.step).split(".")[1]?.length || 0;
},
sizeVariable() {
switch (this.size) {
case "XS":
return {
"--input-height": "28px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
case "S":
return {
"--input-height": "32px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
case "M":
return {
"--input-height": "40px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "2px 0",
};
case "L":
return {
"--input-height": "48px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
case "auto":
return {
"--input-height": "auto",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
default:
return {
"--input-height": "56px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
}
},
},
};
</script>
@@ -214,4 +228,57 @@ input[type=number]::-webkit-inner-spin-button
color: var(--font-grey-color)
&:hover
color: var(--font-dark-blue-color)
.input :deep(.q-field__native)
font-weight: 500
font-size: var(--text-size)
line-height: var(--line-height)
color: var(--font-dark-blue-color)
padding: var(--py)
&::placeholder
color: var(--font-grey-color)
opacity: 1
.input :deep(.q-field__control)
height: var(--input-height) !important
color: var(--font-dark-blue-color)
padding: var(--px)
&:before
border-color: var(--border-light-grey-color) !important
transition: none
&:hover:before
border-color: var(--font-grey-color) !important
&:after
border-width: 1px !important
transition: none
transform: none !important
.q-field--disabled :deep(.q-field__control > div)
opacity: 1 !important
.q-field--outlined.q-field--disabled :deep(.q-field__native)
color: var(--font-grey-color)
.q-field--outlined.q-field--disabled :deep(.q-field__control)
background: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__control)
background: var(--bg-light-grey) !important
&:before
border-color: var(--bg-light-grey) !important
transition: none
&:hover:before
border-color: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__native)
cursor: default
.q-field--error :deep(.q-field__bottom)
padding: 4px 0 0 0
font-weight: 500
font-size: 12px
line-height: 135% !important
.input :deep(.q-field__marginal)
height: auto !important
</style>

View File

@@ -1,36 +1,28 @@
<template lang="pug">
base-input-container.gap-y-2(:label="label", :style="{width: width + 'px' }")
q-input(
base-input-container.gap-y-2(:label="label", :style="{width: width + 'px', ...sizeVariable }")
q-input.input(
v-model="value",
:name="name",
:class="{'circle': circle, 'font-input': true}",
:input-style="{ color: textColor, borderColor: borderColor, resize: resize}",
:borderless="borderless",
:class="{'font-input': true}",
:input-style="{ resize: resize}",
:placeholder="placeholder",
:outlined="outlined",
:dense="dense",
outlined,
:readonly="readonly",
:disable="disabled",
:filled="filled",
:bg-color="filled || standout ? '' : 'white'",
:rules="[checkTime]",
:lazy-rules="lazyRule",
:item-aligned="itemAligned",
:no-error-icon="noErrorIcon",
mask="time",
:maxlength="maxLength",
:autogrow="autogrow",
:square="square",
:standout="standout"
:accept="accept",
:debounce="debounce",
hide-bottom-space
hide-bottom-space,
no-error-icon
)
template(v-slot:append)
template(v-slot:append, v-if="!readonly && !disabled")
q-icon(
name="app:time",
class="cursor-pointer",
size="16px"
size="19px"
)
q-popup-proxy(cover, transition-show="scale", transition-hide="scale")
q-time(v-model="value", mask="HH:mm")
@@ -51,35 +43,6 @@ export default {
name: "BaseInputTime",
components: { BaseInputContainer },
props: {
circle: Boolean,
dense: {
type: Boolean,
default: true,
},
outlined: {
type: Boolean,
default: false,
},
square: {
type: Boolean,
default: false,
},
filled: {
type: Boolean,
default: false,
},
borderless: {
type: Boolean,
default: false,
},
autogrow: {
type: Boolean,
default: false,
},
standout: {
type: [Boolean, String],
default: false,
},
accept: {
type: String,
default: "",
@@ -90,12 +53,8 @@ export default {
},
debounce: [String, Number],
width: Number,
maxLength: Number,
textColor: String,
borderColor: String,
rule: Array,
lazyRule: [Boolean, String],
noErrorIcon: Boolean,
itemAligned: Boolean,
modelValue: String,
placeholder: String,
@@ -104,6 +63,7 @@ export default {
readonly: Boolean,
iconLeft: Boolean,
name: String,
size: String,
},
emits: ["update:modelValue"],
computed: {
@@ -115,6 +75,50 @@ export default {
this.$emit("update:modelValue", this.checkTime(value) ? value : null);
},
},
sizeVariable() {
switch (this.size) {
case "XS":
return {
"--input-height": "28px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
case "S":
return {
"--input-height": "32px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
case "M":
return {
"--input-height": "40px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
case "L":
return {
"--input-height": "48px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
default:
return {
"--input-height": "56px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
}
},
},
methods: {
checkTime(val) {
@@ -133,17 +137,56 @@ export default {
.font-input
font-feature-settings: 'pnum' on, 'lnum' on
.circle
width: 100%
height: 100%
border-radius: 50%
z-index: 5
opacity: 0
cursor: pointer
</style>
<style lang="sass">
.q-field--standout.q-field--readonly .q-field__control:before
border: none !important
.q-field--standout .q-field__control
.input :deep(.q-field__native)
font-weight: 500
font-size: var(--text-size)
line-height: var(--line-height)
color: var(--font-dark-blue-color)
padding: var(--py)
&::placeholder
color: var(--font-grey-color)
opacity: 1
.input :deep(.q-field__control)
height: var(--input-height) !important
color: var(--font-dark-blue-color)
padding: var(--px)
&:before
border-color: var(--border-light-grey-color) !important
transition: none
&:hover:before
border-color: var(--font-grey-color) !important
&:after
border-width: 1px !important
transition: none
transform: none !important
.q-field--disabled :deep(.q-field__control > div)
opacity: 1 !important
.q-field--outlined.q-field--disabled :deep(.q-field__native)
color: var(--font-grey-color)
.q-field--outlined.q-field--disabled :deep(.q-field__control)
background: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__control)
background: var(--bg-light-grey) !important
&:before
border-color: var(--bg-light-grey) !important
transition: none
&:hover:before
border-color: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__native)
cursor: default
.q-field--error :deep(.q-field__bottom)
padding: 4px 0 0 0
font-weight: 500
font-size: 12px
line-height: 135% !important
.input :deep(.q-field__marginal)
height: auto !important
</style>

View File

@@ -0,0 +1,122 @@
<template lang="pug">
.flex
.col
base-select.search(
width="100%",
size="M",
placeholder="Найти пациента",
icon-left,
hide-dropdown-icon,
use-input
:input-debounce="500"
:items="candidates",
custom-option,
:filter-fn="filterFn",
:popup-content-style="{height: candidates?.length > 3 ? '216px' : ''}"
v-model="value"
ref="selectRef"
@blur="pasteFullName"
)
template(v-slot:iconLeft)
q-icon.search-icon(name="app:search", size="20px")
template(v-slot:customOption="{props, data}")
.w-full.item.px-4.py-2.flex.gap-x-3.cursor-pointer(
v-bind="props"
)
.flex.flex-col.gap-y-1
.text-dark.text-sm.font-medium {{ data.last_name + ' ' + data.first_name + ' ' + data.patronymic }}
template(v-slot:beforeOptions)
.h-10.w-full.px-4.pt-3.pb-2.flex.items-center
span.text-m.grey-color {{message}}
span.text-m.primary-color.cursor-pointer.pl-1(@click="createPerson") Создать
template(v-slot:noOption)
.h-10.w-full.px-4.pt-3.pb-2.flex.items-center
span.text-m.grey-color {{message}}
span.text-m.primary-color.cursor-pointer.pl-1(@click="createPerson") Создать
</template>
<script>
import BaseInput from "./BaseInput.vue";
import { fetchWrapper } from "@/shared/fetchWrapper";
import { v_model } from "@/shared/mixins/v-model";
import BaseSelect from "@/components/base/BaseSelect.vue";
export default {
name: "BaseInputWithSearch",
components: {
BaseInput,
BaseSelect,
},
mixins: [v_model],
emits: ["create-person"],
data() {
return {
fullName: "",
message: "",
showMessageBar: true,
candidates: [],
person: null,
};
},
computed: {
pickedFullName() {
if (!this.value.first_name) return "";
return (
this.value.last_name +
" " +
this.value.first_name +
" " +
this.value.patronymic
);
},
},
watch: {
pickedFullName() {
this.pasteFullName();
},
},
methods: {
createPerson() {
this.$refs?.selectRef?.hidePopup();
this.$emit("create-person");
},
filterFn(val, update) {
fetchWrapper.get(`persons/?full_name=${val}`).then((result) => {
update(() => {
this.candidates = result;
this.showMessageBar = true;
this.message = `Нужный ${val} не найден?`;
});
});
},
pasteFullName() {
this.$nextTick(() => {
this.$refs?.selectRef?.updateInputValue(this.pickedFullName, true);
});
},
},
};
</script>
<style lang="sass" scoped>
.search-icon :deep(path)
fill: var(--font-grey-color)
.search :deep(.q-field__prepend)
padding-right: 4px
.plus :deep(path)
fill: var(--default-white)
.grey-color
color: var(--font-grey-color)
.primary-color
color: var(--btn-blue-color)
.item
border-bottom: 1px solid var(--gray-secondary)
&:last-child
border-bottom: none
&:hover
background-color: var(--gray-thirdly)
</style>

View File

@@ -6,7 +6,7 @@
ref="dialog"
)
.base-content(
:class="{'draggable': draggable, 'base-content-default': !defaultPadding, 'base-modal-default': modalPadding}",
:class="{'draggable': draggable, 'none-padding': nonePadding, 'base-content-default': !defaultPadding, 'base-modal-default': modalPadding}",
ref="contentRef",
:style="{...contentStyles, height}"
)
@@ -29,6 +29,7 @@ export default {
showCloseIcon: Boolean,
draggable: Boolean,
hideOverlay: Boolean,
nonePadding: Boolean,
defaultPadding: Boolean,
modalPadding: Boolean,
hideHeader: Boolean,
@@ -139,8 +140,11 @@ export default {
.base-modal-default
padding: 28px 32px
.none-padding
padding: 0px
.base-content
overflow-x: hidden
overflow: hidden
width: auto
background-color: var(--default-white)
box-shadow: 4px 4px 8px rgba(9, 10, 21, 0.1), -4px -4px 8px rgba(9, 10, 21, 0.1)

View File

@@ -1,36 +1,50 @@
<template lang="pug">
.flex.flex-col.gap-y-2
base-input-container(:label="label", :style="{width: width}")
q-select(
base-input-container(:label="label", :style="{width: widthInternal, ...sizeVariable}")
q-select.select(
ref="selectRef"
v-model="value",
:options="items",
:readonly="readonly"
:disable="disable",
:hide-dropdown-icon="hideDropdownIcon"
:borderless="borderless",
:outlined="outlined",
:bg-color="bgColor",
:standout="standout",
dense,
:disable="disabled",
:hide-dropdown-icon="hideDropdownIcon || disabled || readonly"
outlined,
:behavior="behavior",
emit-value,
map-options,
:clearable="clearable"
:clearable="clearable",
dropdown-icon="app:down-arrow",
:menu-offset="[0, 8]",
:use-input="useInput",
:input-debounce="inputDebounce",
:placeholder="useInput && placeholder ? placeholder : ''",
@filter="filterFn",
:popup-content-style="popupContentStyle"
@blur="$emit('blur')"
)
template(v-slot:selected)
span(v-if="!value?.icon") {{ textSelect }}
q-icon(
v-else,
:name="iconSelect",
size="20px"
)
template(
v-slot:option="scope",
v-if="value?.icon"
)
q-item(v-bind="scope.itemProps", style="justify-content: center")
template(#selected)
slot(name="selected")
template(v-slot:option="scope", v-if="!customOption")
q-item(v-bind="scope.itemProps", style="justify-content: center", v-if="value?.icon")
q-item-section(avatar, style="padding: 0px; min-width: 0px")
q-icon(:name="scope.opt.icon", size="20px")
q-icon.icon(:name="scope.opt.icon", size="24px")
q-item.item.px-4.py-2(v-bind="scope.itemProps", style="justify-content: center", v-else)
q-item-section
q-item-label.text-dark.text-base.font-medium {{ scope.opt.label }}
template(v-slot:option="{itemProps, opt}", v-else)
slot(
name="customOption",
:props="itemProps",
:data="opt"
)
template(v-slot:prepend, v-if="iconLeft")
slot(name="iconLeft")
template(v-slot:append, v-if="iconRight")
slot(name="iconRight")
template(v-slot:before-options)
slot(name="beforeOptions")
template(v-slot:no-option)
slot(name="noOption")
</template>
<script>
@@ -43,20 +57,7 @@ export default {
props: {
placeholder: String,
hideDropdownIcon: Boolean,
borderless: Boolean,
modelValue: [Object, String],
bgColor: {
type: String,
default: "white",
},
outlined: {
type: Boolean,
default: true,
},
standout: {
type: [Boolean, String],
default: false,
},
items: {
type: Array,
default: () => [],
@@ -65,21 +66,21 @@ export default {
type: String,
default: "menu",
},
icon: {
type: String,
default: null,
},
size: {
type: Number,
default: 18,
},
disable: Boolean,
disabled: Boolean,
label: String,
readonly: Boolean,
width: String,
clearable: Boolean,
size: String,
useInput: Boolean,
inputDebounce: Number,
iconLeft: Boolean,
iconRight: Boolean,
customOption: Boolean,
filterFn: Function,
popupContentStyle: Object,
},
emits: ["update:modelValue"],
emits: ["update:modelValue", "blur"],
computed: {
value: {
get() {
@@ -91,19 +92,167 @@ export default {
},
textSelect() {
if (typeof this.modelValue === "string") return this.value;
return this.value?.label ? this.value.label : this.placeholder;
return this.value?.label
? this.value.label
: !this.useInput
? this.placeholder
: "";
},
iconSelect() {
return this.value?.icon ? this.value.icon : this.placeholder;
},
sizeVariable() {
if (this.size === "XS")
return {
"--input-height": "28px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
if (this.size === "S")
return {
"--input-height": "32px",
"--text-size": "12px",
"--line-height": "135%",
"--px": "0 8px",
"--py": "10px 0",
};
if (this.size === "M")
return {
"--input-height": "40px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
if (this.size === "L")
return {
"--input-height": "48px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
if (this.size)
return {
"--input-height": this.size,
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
return {
"--input-height": "56px",
"--text-size": "16px",
"--line-height": "normal",
"--px": "0 16px",
"--py": "8px 0",
};
},
placeholderColor() {
return {
placeholder: !this.useInput && this.placeholder,
selected:
typeof this.modelValue === "string"
? !!this.value
: !!this.value?.label,
};
},
widthInternal() {
if (typeof this.width === "number") return this.width + "px";
return this.width;
},
},
methods: {
updateInputValue(value, noFilter) {
this.$refs?.selectRef?.updateInputValue(value, noFilter);
},
hidePopup() {
this.$refs?.selectRef?.hidePopup();
},
},
};
</script>
<style lang="sass">
.q-menu
font-feature-settings: 'pnum' on, 'lnum' on !important
.q-btn--outline:before, .q-field--outlined .q-field__control:before
border-width: 1px !important
.q-field__marginal
.placeholder
color: var(--font-grey-color)
.selected
color: var(--font-dark-blue-color)
.q-placeholder
font-weight: 500 !important
&::placeholder
opacity: 1 !important
color: var(--font-grey-color) !important
.q-field--auto-height .q-field__native
min-height: var(--input-height) !important
font-weight: 500
font-size: var(--text-size)
line-height: var(--line-height)
color: var(--font-dark-blue-color)
padding: var(--py)
.q-field--auto-height .q-field__control
min-height: var(--input-height) !important
height: var(--input-height) !important
color: var(--font-dark-blue-color)
padding: var(--px) !important
&:before
border-color: var(--border-light-grey-color) !important
transition: none
&:hover:before
border-color: var(--font-grey-color) !important
&:after
border-width: 1px !important
transition: none
transform: none !important
.q-field--disabled .q-field__control > div
opacity: 1 !important
.q-field--outlined.q-field--disabled .q-field__native
color: var(--font-grey-color)
.q-field--outlined.q-field--disabled .q-field__control
background: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly .q-field__control
background: var(--bg-light-grey) !important
&:before
border-color: var(--bg-light-grey) !important
transition: none
&:hover:before
border-color: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly .q-field__native
cursor: default
.q-field--error :deep(.q-field__bottom)
padding: 4px 0 0 0
font-weight: 500
font-size: 12px
line-height: 135% !important
.q-field__marginal
height: var(--input-height) !important
.q-select__dropdown-icon path
fill: var(--font-dark-blue-color)
.q-select__dropdown-icon
width: 20px
height: 20px
.item
border-bottom: 1px solid var(--gray-secondary)
&:last-child
border-bottom: none
&:hover
background-color: var(--gray-thirdly)
.q-menu
box-shadow: 1px 1px 8px 0px rgba(37, 40, 80, 0.15) !important
font-feature-settings: 'pnum' on, 'lnum' on !important
//max-height: var(--input-height) !important
</style>

View File

@@ -35,9 +35,15 @@ export default {
.button
background-color: transparent
.active
background-color: var(--btn-blue-color-1)
background-color: var(--bg-light-blue-color)
color: var(--btn-blue-color)
.button:hover
background-color: var(--btn-blue-color-1)
background-color: var(--bg-light-blue-color)
color: var(--btn-blue-color)
.hover :deep(path)
fill: #9294A7
.q-btn :deep(.q-focus-helper)
display: none
.q-btn :deep(.q-ripple)
display: none
</style>

View File

@@ -0,0 +1,137 @@
<template lang="pug">
base-input-container.gap-y-2(:label="label", :style="{width: width + 'px', ...paddingVariable}")
q-input.input(
v-model="value",
:name="name",
:multiple="multiple",
:input-style="{resize: resize, 'font-input': true, height: height}",
:placeholder="placeholder",
outlined,
type="textarea",
:readonly="readonly",
:disable="disabled",
:rules="rule",
:lazy-rules="lazyRule",
:item-aligned="itemAligned",
no-error-icon,
:autogrow="autogrow",
:accept="accept",
:debounce="debounce",
:shadow-text="shadowText",
:autofocus="autofocus",
hide-bottom-space
)
</template>
<script>
import BaseInputContainer from "@/components/base/BaseInputContainer.vue";
export default {
name: "BaseInput",
components: { BaseInputContainer },
props: {
multiple: Boolean,
autofocus: Boolean,
autogrow: {
type: Boolean,
default: false,
},
accept: {
type: String,
default: "",
},
resize: {
type: String,
default: "none",
},
shadowText: String,
mask: String,
debounce: [String, Number],
width: Number,
rule: Array,
lazyRule: [Boolean, String],
itemAligned: Boolean,
modelValue: [String, Date, Number],
placeholder: String,
disabled: Boolean,
label: String,
readonly: Boolean,
name: String,
height: String,
padding: {
type: String,
default: "12px 16px",
},
},
emits: ["update:modelValue"],
computed: {
value: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
},
},
paddingVariable() {
return {
"--padding": this.padding,
};
},
},
};
</script>
<style lang="sass" scoped>
.font-input
font-feature-settings: 'pnum' on, 'lnum' on
.input :deep(.q-field__native)
font-weight: 500
font-size: 16px
line-height: normal
color: var(--font-dark-blue-color)
padding: var(--padding)
&::placeholder
color: var(--font-grey-color)
opacity: 1
.input :deep(.q-field__control)
color: var(--font-dark-blue-color)
padding: 0 0
&:before
border-color: var(--border-light-grey-color) !important
transition: none
&:hover:before
border-color: var(--font-grey-color) !important
&:after
border-width: 1px !important
transition: none
transform: none !important
.q-field--disabled :deep(.q-field__control > div)
opacity: 1 !important
.q-field--outlined.q-field--disabled :deep(.q-field__native)
color: var(--font-grey-color)
.q-field--outlined.q-field--disabled :deep(.q-field__control)
background: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__control)
background: var(--bg-light-grey) !important
&:before
border-color: var(--bg-light-grey) !important
transition: none
&:hover:before
border-color: var(--bg-light-grey) !important
.q-field--outlined.q-field--readonly :deep(.q-field__native)
cursor: default
.q-field--error :deep(.q-field__bottom)
padding: 4px 0 0 0
font-weight: 500
font-size: 12px
line-height: 135% !important
</style>

View File

@@ -1,13 +1,15 @@
<template lang="pug">
.flex.flex-col.gap-y-6.pt-6
.flex.flex-col.gap-y-6.pt-6.dark-blue
.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")
.top-block.flex.flex-col.-mr-4(v-for="time in timeCoil")
.timeline.flex.text-smm.font-medium {{time.hour}}
.side.flex.p-1.h-9
q-btn.left-btn(:class="{'default-btn': !checkStartTime(time.hour)}", size="9px", padding="0 8px")
q-icon.icon(v-if="checkStartTime(time.hour)", name="app:lock", size="20px")
q-icon.icon-grey(v-else, name="app:plus", size="20px")
q-btn.right-btn(:class="{'default-btn': !checkEndTime(time.hour)}", size="4px", padding="0 4px")
q-icon.icon(v-if="checkEndTime(time.hour )", name="app:lock", size="20px")
q-icon.icon-grey(v-else, name="app:plus", size="20px")
.flex.justify-between.items-center
.flex.gap-2
base-button(
@@ -21,19 +23,18 @@
label="Сохранить",
@click="closeModalTime"
)
.text.font-bold.text-6xl {{`${times.from} - ${times.to}`}}
.dark-blue.font-bold.text-6xl {{`${times.from} - ${times.to}`}}
</template>
<script>
import lockIcon from "@/assets/icons/locked.svg";
import BaseButton from "@/components/base/BaseButton.vue";
export default {
name: "BaseTimeModal",
props: { times: Object, closeModalTime: Function },
props: { times: Object, closeModalTime: Function, data: Array },
components: { BaseButton },
data() {
return { lockIcon, select: false };
return { select: false };
},
computed: {
validateStartTime() {
@@ -45,7 +46,7 @@ export default {
timeCoil() {
let time = [];
for (let i = this.validateStartTime; i <= this.validateEndTime; i++) {
time.push(`${i}:00`);
time.push({ hour: `${i}:00`, check: false });
}
return time;
},
@@ -56,6 +57,17 @@ export default {
let newTime = timeArray[1] > 30 ? timeArray[0] + 1 : timeArray[0];
return newTime;
},
checkStartTime(time) {
return this.data.find((e) => e.start === time || e.end === time)
? true
: false;
},
checkEndTime(time) {
let subtime = time.substr(0, 2) + ":30";
return this.data.find((e) => e.end === subtime || e.start === subtime)
? true
: false;
},
},
};
</script>
@@ -64,22 +76,35 @@ export default {
.table-time
width: 463px
height: 174px
border: 1px solid var(--border-light-grey-color)
border-radius: 6px
flex-wrap: wrap !important
border: 1px solid var(--gray-secondary)
.text
.dark-blue
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)
border-left: 1px solid var(--font-dark-blue-color)
margin-left: 16px
margin-bottom: 24px
height: 36px
.left-side
.left-btn
width: 29px
border-radius: 6px 1px 1px 6px
background: #4772F2
border: 1px solid var(--gray-secondary)
.right-side
.right-btn
width: 29px
border-radius: 1px 6px 6px 1px
background: #FF6565
border: 1px solid var(--gray-secondary)
.icon :deep(path)
fill: var(--system-color-red)
.icon-grey :deep(path)
fill: var(--font-grey-color)
.default-btn
background: var(--gray-thirdly)
</style>

View File

@@ -21,14 +21,14 @@
round,
padding="2px 0 0 0"
)
q-icon(name="app:ok", size="20px")
q-icon.icon(name="app:ok", size="40px")
</template>
<script>
import BaseInput from "./BaseInput.vue";
import addImageIcon from "@/assets/icons/photo.svg";
import { v_model } from "@/shared/mixins/v-model";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "BaseModalUploadPhoto",
@@ -118,4 +118,7 @@ export default {
min-height: 400px
height: 100%
border-radius: 50%
.icon :deep(path)
fill: var(--default-white)
</style>

View File

@@ -56,7 +56,16 @@ export default {
type: Function,
default: () => {},
},
cancel: {
type: Function,
default: () => {},
},
width: {
type: String,
default: "286px",
},
},
emits: ["update:modelValue"],
data() {
return {
internalDate: moment(),
@@ -91,10 +100,10 @@ export default {
},
},
internalMonth() {
let formattedMonth = this.internalDate.format("MMMM");
let formattedMonth = this.internalDate?.format("MMMM");
return `${
formattedMonth[0].toUpperCase() + formattedMonth.slice(1)
} ${this.internalDate.format("YYYY")}`;
} ${this.internalDate?.format("YYYY")}`;
},
},
methods: {
@@ -102,6 +111,7 @@ export default {
this.currentForm = this.forms.find((elem) => elem.component === form);
},
changeDate() {
if (this.value) {
if (this.range) {
this.internalDate = this.value?.from?.clone();
this.externalValue = {
@@ -112,10 +122,23 @@ export default {
this.internalDate = this.value?.clone();
this.externalValue = this.value?.clone();
}
} else {
if (this.range) {
this.internalDate = moment();
this.externalValue = {
from: null,
to: null,
};
} else {
this.internalDate = moment();
this.externalValue = null;
}
}
},
cancelChanges() {
this.changeDate();
this.changeForm("CalendarDates");
this.cancel();
},
saveExternalChanges() {
if (this.range)

View File

@@ -163,7 +163,7 @@ export default {
},
selectDate(date) {
if (!this.range) {
this.externalValue = date;
this.externalValue = date.clone();
return;
}
if (this.rangeCount) {

View File

@@ -1,7 +1,7 @@
<template lang="pug">
base-input-container(:label="label")
.relative
base-input(type="text", v-model="value.label", outlined)
base-input(type="text", v-model="value.label", size="M")
template(#icon)
.icon(@click="isExpand = !isExpand")
.menu(v-if="isExpand")

View File

@@ -1,7 +1,7 @@
<template lang="pug">
base-input-container(:label="label")
.relative
base-input(type="text", v-model="value.label", outlined)
base-input(type="text", v-model="value.label", size="M")
template(#icon)
.icon(@click="isExpand = !isExpand")
.menu(v-if="isExpand")

View File

@@ -116,11 +116,11 @@
:placeholder="settings[section].placeholder[key] || settings[section].placeholder"
:sharp="settings[section].sharps[key] && section === 'pass' ? settings[section].sharps[key] : ''"
)
.bg-white(v-else-if="isChange && section !== 'docs' && section !== 'additional'",)
base-input(
type="date",
v-else-if="isChange && section !== 'docs' && section !== 'additional'",
v-model="sectionInfo.issued_by_date",
outlined
size="S"
)
.copy.icon-copy.cursor-pointer(
v-if="item.copy",
@@ -194,6 +194,7 @@ import exelIcon from "@/assets/icons/exel.svg";
import * as moment from "moment";
import BaseLoader from "@/components/Loader/BaseLoader.vue";
import StepperCreateAgreement from "./StepperCreateAgreement";
import BaseInputDate from "@/components/base/BaseInputDate.vue";
export default {
name: "ClientDetailInfoSection",
@@ -209,6 +210,7 @@ export default {
TableChoiceAddingDoc,
TableCreateNote,
StepperCreateAgreement,
BaseInputDate,
},
props: {
saveNewDoc: Function,

View File

@@ -1,4 +1,5 @@
<template lang="pug">
.bg-white
base-input(
:type="choiceType"
v-model="value",
@@ -6,7 +7,7 @@
:maxLength="maxLength",
:mask="sharp",
:autogrow="choiceGrow",
outlined
:size="!choiceGrow ? 'S' : 'auto'"
)
slot
</template>

View File

@@ -6,25 +6,22 @@
labelStyle="text-xxs",
placeholder="Введите город",
v-model="dopeAddress.city",
label="Город"
label="Город",
size="S"
)
base-input(
disabled,
placeholder="Введите область",
labelStyle="text-xxs",
textStyle="text-sm",
v-model="dopeAddress.region",
label="Область",
outlined
size="S"
)
base-input(
disabled,
placeholder="Введите улицу",
labelStyle="text-xxs",
textStyle="text-sm",
v-model="dopeAddress.street",
label="Улица",
outlined
size="S"
)
.flex.gap-x-4
base-input(
@@ -32,17 +29,14 @@
placeholder="Дом",
label="Дом"
v-model="dopeAddress.house",
labelStyle="text-xxs",
textStyle="text-sm",
size="S"
)
base-input(
disabled,
placeholder="Квартира",
label="Квартира",
v-model="dopeAddress.flat",
labelStyle="text-xxs",
textStyle="text-sm",
outlined
size="S"
)
base-input(
disabled,
@@ -50,9 +44,7 @@
placeholder="000000",
label="Индекс",
v-model="dopeAddress.index",
labelStyle="text-xxs",
textStyle="text-sm",
outlined
size="S"
)
</template>

View File

@@ -141,7 +141,7 @@ export default {
},
computed: {
dataClientsPresence() {
return this.dataClients[0]?.initialization;
return this.dataClients?.[0]?.initialization;
},
},
methods: {
@@ -184,12 +184,11 @@ export default {
}
},
async fetchDataClients() {
let response = {};
if (this.textSearch) {
response = await fetchWrapper.get(
`general/person/?last_name=${this.textSearch}&limit=${
this.limit
}&offset=${(this.currentTablePage - 1) * this.limit}`
const response = await fetchWrapper.get(
`persons/?limit=${this.limit}&offset=${
(this.currentTablePage - 1) * this.limit
}`
);
this.saveDataClients(response);
this.saveFilteredClientsCount(response);
@@ -198,8 +197,8 @@ export default {
length: this.calculatePageCount(this.filteredClientsCount),
};
} else {
response = await fetchWrapper.get(
`general/person/?limit=${this.limit}&offset=${
const response = await fetchWrapper.get(
`persons/?limit=${this.limit}&offset=${
(this.currentTablePage - 1) * this.limit
}`
);
@@ -212,9 +211,7 @@ export default {
}
},
async fetchCreatedClientData() {
fetchWrapper
.get(`general/person/${this.createdClientId}/detail/`)
.then((response) => {
fetchWrapper.get(`persons/${this.createdClientId}/`).then((response) => {
this.dataClients = [response];
this.createdClientName = `${response.last_name ?? ""} ${
response?.first_name ?? ""

View File

@@ -2,16 +2,16 @@
.flex.justify-between.w-full.h-fit
.flex.gap-2.w-fit.h-fit
.input
base-input(
:with-icon="true",
icon-position="left",
base-input.search(
v-model="searchClient",
placeholder="Введите фамилию",
@keyup.enter="searchLastName",
outlined
size="M",
:width="280",
:icon-left="!searchClient"
)
.flex.items-center.cursor-pointer
.icon-search
template(v-slot:iconLeft, v-if="!searchClient")
q-icon.search-icon(name="app:search", size="20px")
base-button(
v-if="createdClientName === ''",
@click="searchLastName",
@@ -31,19 +31,19 @@
type="secondary",
width="64px"
)
q-icon(name="app:export", size="16px")
q-icon.export(name="app:export", size="20px")
base-button(
@click="openForm",
width="144px"
)
q-icon(name="app:plus", size="12px", left)
q-icon.plus(name="app:plus", size="24px", left)
span Создать
</template>
<script>
import ClientsTableHeaderActions from "@/pages/clients/components/ClientsTableHeaderActions";
import BaseInput from "@/components/base/BaseInput";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "ClientsTableHat",
@@ -96,5 +96,16 @@ export default {
.input
min-width: 280px
.on-left
margin-right: 10px
margin-right: 6px
.search :deep(.q-field__prepend)
padding-right: 6px !important
.search-icon :deep(path)
fill: var(--font-grey-color)
.export :deep(path)
fill: var(--btn-blue-color)
.plus :deep(path)
fill: var(--default-white)
</style>

View File

@@ -1,85 +1,94 @@
<template lang="pug">
.wrapper-addresses.h-full
.wrapper-form.h-full
.flex.flex-col.gap-y-6
base-input(
v-model="addresses.full_address",
v-model="form.full_address",
placeholder="Введите адрес целиком",
label="Полный адрес",
outlined
size="M"
)
.flex.items-center.justify-center.relative
.line.absolute
span.text-sm.separator.px-2 или
.grid.grid-cols-2.gap-y-6.gap-x-4
base-input(
disabled,
filled,
placeholder="Введите город",
v-model="addresses.city",
v-model="form.city",
label="Город",
outlined
placeholder="Введите город",
disabled,
size="M"
)
base-input(
disabled,
filled,
placeholder="Введите область",
v-model="addresses.region",
v-model="form.region",
label="Область",
outlined
placeholder="Введите область",
disabled,
size="M"
)
base-input(
disabled,
filled,
placeholder="Введите улицу",
v-model="addresses.street",
v-model="form.street",
label="Улица",
outlined
placeholder="Введите улицу",
disabled,
size="M"
)
base-input(
disabled,
filled,
placeholder="Номер дома",
v-model="addresses.house_number",
v-model="form.house",
label="Дом",
outlined
placeholder="Номер дома",
disabled,
size="M"
)
base-input(
disabled,
filled,
placeholder="Номер квартиры",
v-model="addresses.apartment_number",
v-model="form.flat",
label="Квартира",
outlined
placeholder="Номер квартиры",
disabled,
size="M"
)
base-input(
disabled,
filled,
placeholder="000000",
mask="######",
v-model="addresses.zip_code",
v-model="form.zip_code",
label="Индекс",
outlined
mask="######",
placeholder="000000",
disabled,
size="M"
)
</template>
<script>
import BaseInput from "@/components/base/BaseInput";
import BaseCustomSelect from "@/components/base/BaseCustomSelect";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "FormCreateAddresses",
components: { BaseInput, BaseCustomSelect },
props: {
addresses: Object,
saveClient: Function,
saveFile: Function,
emits: ["change"],
data() {
return {
form: {
full_address: "",
city: "",
region: "",
street: "",
house: "",
flat: "",
zip_code: "",
},
};
},
watch: {
form(val) {
this.$emit("change", val);
},
},
};
</script>
<style lang="sass" scoped>
.wrapper-addresses
height: 368px
.wrapper-form
height: 380px
width: 570px
overflow-y: auto
&::-webkit-scrollbar
width: 4px

View File

@@ -2,7 +2,7 @@
.wrapper.flex.flex-col.flex-auto.h-full.gap-y-8.justify-between
.place.flex.flex-col.justify-center.items-center.py-3
.upload.text-center.text-sm.flex.w-fit
input.hidden(@change="(e) => addAttachment(e)" type="file" id="file-upload")
input.hidden(@change="() => {}" type="file" id="file-upload")
span Загрузите элемент
label.label.cursor-pointer(for="file-upload") с компьютера
span или перетащите их сюда
@@ -11,9 +11,6 @@
<script>
export default {
name: "FormCreateAttachments",
props: {
addAttachment: Function,
},
};
</script>

View File

@@ -1,51 +1,29 @@
<template lang="pug">
.wrapper-info.h-full
.wrapper-info
.grid.grid-cols-2.gap-x-4.gap-y-6
base-select(
:items="priorityList",
placeholder="Приоритет клиента",
v-model="basicInfo.priority",
label="Приоритет"
)
base-input(
type="date"
v-model="basicInfo.birth_date",
base-input-date(
v-model="value.birth_date",
size="M",
important,
label="Дата рождения",
outlined,
important
placeholder="Дата рождения"
)
base-input(
v-model="phone.username",
v-model="value.phone",
placeholder="+7 (915) 6449223",
mask="+7 (###) ###-##-##",
label="Номер телефона",
outlined,
size="M",
important
)
base-input(
v-model="email.username",
placeholder="user@yandex.ru",
label="Email",
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 Ссылки на соцсети
.flex(class="gap-x-1.5" v-for="network in basicInfo.contacts" :key="network.kind.id")
base-adding-network(
:items="networksList",
:network="network",
)
span.add-network.cursor-pointer(
v-show="networksList.length !== 0",
@click="addNetwork"
) Добавить соцсеть
</template>
<script>
import BaseInput from "@/components/base/BaseInput";
import BaseAddingNetwork from "@/components/base/BaseAddingNetwork";
import BaseSelect from "@/components/base/BaseSelect";
import BaseInput from "@/components/base/BaseInput.vue";
import BaseInputDate from "@/components/base/BaseInputDate.vue";
import { v_model } from "@/shared/mixins/v-model";
export default {
name: "FormCreateBasicInfo",
@@ -53,23 +31,14 @@ export default {
BaseInput,
BaseAddingNetwork,
BaseSelect,
BaseInputDate,
},
props: {
priorityList: Array,
phone: Object,
email: Object,
basicInfo: Object,
saveClient: Function,
addNetwork: Function,
networksList: Array,
},
mixins: [v_model],
};
</script>
<style lang="sass" scoped>
.wrapper-info
max-height: 336px
min-height: 272px
overflow-y: auto
&::-webkit-scrollbar
width: 4px

View File

@@ -4,62 +4,76 @@
span.title-info.text-base.font-bold Паспортные данные
.grid.grid-cols-2.gap-x-4.gap-y-6
base-input(
v-model="form.series_number",
mask="#### ######",
v-model="identityDocument.pass.series_number",
placeholder="0000 000000",
label="Серия и номер",
outlined
size="M"
)
base-input(
v-model="identityDocument.pass.issued_by_org",
v-model="form.issued_by_org",
placeholder="Точно как в паспорте",
label="Кем выдан",
outlined
size="M"
)
base-input(
v-model="form.issued_by_org_code",
mask="###-###",
v-model="identityDocument.pass.issued_by_org_code",
placeholder="000000",
label="Код подразделения",
outlined
size="M"
)
base-input(
type="date"
v-model="identityDocument.pass.issued_by_date",
base-input-date(
v-model="form.issued_by_date",
placeholder="Дата",
label="Дата выдачи",
outlined
size="M"
)
.flex.flex-col.gap-y-6
span.title-info.text-base.font-bold СНИЛС и ИНН
.grid.grid-cols-2.gap-x-4.gap-y-6
base-input(
disabled,
filled,
v-model="form.snils",
mask="###-###-### ##",
v-model="identityDocument.snils.number",
placeholder="000000000 00",
label="Номер СНИЛС"
label="Номер СНИЛС",
disabled,
size="M"
)
base-input(
disabled,
filled,
mask="############",
v-model="identityDocument.inn.number",
v-model="form.inn",
placeholder="000000000000",
label="Номер ИНН"
mask="############",
label="Номер ИНН",
disabled,
size="M"
)
</template>
<script>
import BaseInput from "@/components/base/BaseInput";
import BaseInput from "@/components/base/BaseInput.vue";
import BaseInputDate from "@/components/base/BaseInputDate.vue";
export default {
name: "FormCreateIdentityDocuments",
components: { BaseInput },
props: {
identityDocument: Object,
saveClient: Function,
components: { BaseInput, BaseInputDate },
emits: ["change"],
data() {
return {
form: {
series_number: "",
issued_by_org: "",
issued_by_org_code: "",
issued_by_date: "",
snils: "",
inn: "",
},
};
},
watch: {
form(val) {
this.$emit("change", val);
},
},
};
</script>

View File

@@ -19,8 +19,6 @@
</template>
<script>
import BaseInput from "@/components/base/BaseInput";
import BaseSelect from "@/components/base/BaseSelect";
import MedicalBaseData from "@/pages/oldMedicalCard/components/MedicalBaseData";
import MedicalIdentityDocuments from "@/pages/oldMedicalCard/components/MedicalIdentityDocuments";
import MedicalPolicyDocuments from "@/pages/oldMedicalCard/components/MedicalPolicyDocuments";
@@ -33,8 +31,6 @@ export default {
name: "FormCreateMedicalCard",
mixins: [v_model],
components: {
BaseInput,
BaseSelect,
MedicalBaseData,
MedicalIdentityDocuments,
MedicalPolicyDocuments,

View File

@@ -5,32 +5,34 @@
placeholder="Категория договора",
v-model="category",
:items="categories",
label="Категория"
label="Категория",
size="M"
)
.flex.justify-between.gap-4
base-input(
type="date",
v-model="signedDate",
label="Дата подписания",
outlined
size="M"
)
base-input(
type="date",
v-model="startDate",
label="Начало оказания услуг"
outlined
size="M"
)
base-input(
type="date",
v-model="endDate",
label="Окончание оказания услуг"
outlined
size="M"
)
base-select(
placeholder="Поручить",
v-model="employee",
:items="employees",
label="Исполнитель"
label="Исполнитель",
size="M"
)
</template>

View File

@@ -4,8 +4,8 @@
base-input(
label="ФИО пациента",
v-model="patientFullName",
disabled
outlined
disabled,
size="M"
)
//-.flex.justify-between
base-select.w-80(

View File

@@ -5,32 +5,34 @@
placeholder="Категория договора",
v-model="category",
:items="categories",
label="Категория"
label="Категория",
size="M"
)
.flex.gap-x-4
base-input(
type="date",
v-model="signedDate",
label="Дата подписания"
outlined
label="Дата подписания",
size="M"
)
base-input(
type="date",
v-model="startDate",
label="Начало оказания услуг"
outlined
label="Начало оказания услуг",
size="M"
)
base-input(
type="date",
v-model="endDate",
label="Окончание оказания услуг"
outlined
label="Окончание оказания услуг",
size="M"
)
base-select(
placeholder="Поручить",
v-model="employee",
:items="employees",
label="Исполнитель"
label="Исполнитель",
size="M"
)
</template>

View File

@@ -3,7 +3,7 @@
.corner
.wrap.flex.flex-col.p-4.gap-y-4
.flex.flex-col.gap-y-1
base-input(:with-icon="true" v-model="newAdditionalData.header" icon-position="right" :max-length="140" placeholder="Заголовок")
base-input(v-model="newAdditionalData.header", placeholder="Заголовок")
span.counter {{`${newAdditionalData.header.length}/140`}}
.description.flex.px-4.py-3
textarea.w-full.h-full.outline-0.resize-none(:value="newAdditionalData.value" @input="$emit('update:newAdditionalData.value', $event.target.value)" placeholder="Описание" style="py-10")

View File

@@ -1,7 +1,7 @@
<template lang="pug">
.flex.flex-col.gap-y-3.p-4(:style="{'width': '485px'}")
.flex.flex-col.gap-y-3.relative
base-input.text-smm(placeholder="Заголовок", v-model="title", :maxLength="40", outlined)
base-input.text-smm(placeholder="Заголовок", v-model="title", :maxLength="40")
.text.flex.absolute.text-xsx.right-7.top-3 {{`${changeValue}/40`}}
.input-wrapper.flex.gap-x-2.px-4.box-border.w-max-fit.text-smm(class="py-2.5")
textarea.place-input.w-full.outline-0.not-italic.resize-none(

View File

@@ -18,22 +18,21 @@
base-input(
v-model="patient",
placeholder="Введите название для пакета документов",
outlined
)
span.counter
.flex.gap-x-4
.flex.flex-col.w-full(class="gap-y-1.5")
.counter.font-semibold.text-smm Тип документа
base-select.h-10(placeholder="Выберите тип")
base-select.h-10(placeholder="Выберите тип", size="M")
.flex.flex-col(class="gap-y-1.5")
.counter.font-semibold.text-smm Дата подписания
.input-date.flex.h-10.justify-center
base-input(type="date", :width-input="277", outlined)
base-input(type="date", :width-input="277")
.flex.flex-col.gap-y-6
span.font-bold Дополнительное
.flex.flex-col.mb-124px(class="gap-y-1.5")
.counter.font-semibold.text-smm Риски
base-select.h-10(placeholder="Выберите риски")
base-select.h-10(placeholder="Выберите риски", size="M")
.services.flex.flex-col.gap-y-6(v-else)
.flex.flex-col.gap-y-6
.flex.flex-col.gap-y-2
@@ -46,10 +45,9 @@
icon-position="left",
:width-input="310",
placeholder="Поиск",
outlined
)
.counter.icon-search
base-select.h-10(placeholder="Вид услуги")
base-select.h-10(placeholder="Вид услуги", size="M")
.flex.items-center.px-11px.py-9px(
:style="{borderBottom: '1px solid var(--btn-grey-color)'}"
)

View File

@@ -3,13 +3,13 @@
:style="{ width : width + 'px'}"
)
span(v-if="!isOpenChange") {{ birthday }}
base-input(
base-input.bg-white(
:width="140"
type="date",
v-if="isOpenChange",
@click.stop,
v-model="value.age",
outlined
size="M"
)
</template>

View File

@@ -8,12 +8,12 @@
@mouseleave="changeHover"
) {{maxValue}}
.email
base-input(
base-input.bg-white(
v-if="isOpenChange",
@click.stop,
v-model="value.email.username",
:placeholder="value.email.username",
outlined
size="M"
)
</template>

View File

@@ -7,11 +7,11 @@
img.h-full.object-cover(:src="url + photo")
span.font-semibold(v-if="!isOpenChange") {{value.fullName}}
.name(v-if="isOpenChange")
base-input(
base-input.bg-white(
@click.stop,
v-model="value.fullName",
placeholder="Фамилия Имя Отчество",
outlined
size="M"
)
</template>

View File

@@ -4,12 +4,12 @@
v-if="!isOpenChange"
) {{value.phone.username.replace(/\+7(\d{3})(\d{3})(\d{2})(\d{2})/, '+7 ($1) $2-$3-$4')}}
.phone(v-if="isOpenChange")
base-input(
base-input.bg-white(
@click.stop,
v-model="value.phone.username",
:placeholder="value.phone.username",
mask="+7 (###) ###-##-##",
outlined
size="M"
)
</template>

View File

@@ -9,7 +9,8 @@
@click.stop,
:items="getPriorityList",
v-model="value.priority",
:placeholder="value.priority"
:placeholder="value.priority",
size="M"
)
</template>

View File

@@ -67,23 +67,23 @@ export const column = [
settings: [
{
id: "VK",
icon: "app:icon-vk",
icon: "app:vk",
},
{
id: "TELEGRAM",
icon: "app:icon-tg",
icon: "app:tg",
},
{
id: "GMAIL",
icon: "app:icon-google",
icon: "app:google",
},
{
id: "SLACK",
icon: "app:icon-slack",
icon: "app:slack",
},
{
id: "DISCORD",
icon: "app:icon-discord",
icon: "app:discord",
},
{
id: "VIBER",

View File

@@ -0,0 +1,29 @@
<template lang="pug">
.wrapper.flex.flex-col.w-full.bg-white.p-4
.text-xxl.font-bold.pa-3
.text Добрый день, %username%!
.text.pt-3.cursor-pointer(@click="gotoCalendar") Расписание приемов
.text.pt-3.cursor-pointer(@click="gotoMedicalCards") Медицинские карты
</template>
<script>
export default {
name: "TheHome",
methods: {
gotoCalendar() {
this.$router.push("/calendar");
},
gotoMedicalCards() {
this.$router.push("/medcards");
},
},
};
</script>
<style lang="sass" scoped>
.wrapper
overflow: auto
border-top-left-radius: 4px
border-top-right-radius: 4px
</style>

View File

@@ -2,7 +2,7 @@
.flex.h-full.w-full.relative.overflow-hidden
.left-col.flex.flex-col.items-center.justify-center
.logo-wrapper.absolute.left-12.top-12
img(:src="logoMark")
img(:src="logo")
.login-panel.flex.flex-col.justify-center.gap-y-10
.flex.flex-col.gap-y-2
.flex.not-italic.font-bold.text-5xl.letter-spacing Добро пожаловать!
@@ -11,34 +11,34 @@
) Войдите в аккаунт, чтобы начать пользоваться сервисом «Астра».
.flex.flex-col.gap-y-5
.flex.flex-col.gap-y-px
base-input.input(
:rule="[wrongData => !!wrongData]",
base-input.blue-color(
:error="authError"
v-model="user.username",
placeholder="+7 (915) 2242131",
label="Номер телефона",
outlined,
no-error-icon
size="L"
@keypress.enter="login"
)
.red-color.text-smm.font-semibold(v-if="wrongData") Этого телефона нет в системе
template(#error) Этого телефона нет в системе
.flex.flex-col.gap-y-px
base-input.input(
:rule="[wrongData => !!wrongData]",
base-input.blue-color(
:error="authError"
v-model="user.password",
:type="changeType",
:type="passwordInputType",
placeholder="Введите ваш пароль",
label="Пароль",
outlined,
no-error-icon
size="L"
@keypress.enter="login"
)
.flex.items-center.cursor-pointer(@click="changeView", v-if="!wrongData && user.password")
img(:src="eye_close", v-if="!isView")
img(:src="eye_open", v-else)
.red-color.text-smm.font-semibold(v-if="wrongData") Неверный пароль
.flex.items-center.gap-x-8px.-ml-2
q-checkbox(@click="persist", v-model="person", type="checkbox")
.flex.non-italic.font-medium.base Запомнить меня
.flex.items-center.cursor-pointer(@click="changePasswordInputType", v-if="user.password")
q-icon(name="app:eye" v-if="showPassword")
q-icon(name="app:eye-open" v-else)
template(#error) Неверный логин или пароль
.flex.items-center.-ml-2
q-checkbox(v-model="rememberMe", type="checkbox")
.font-medium.base Запомнить меня
base-button(
:disable="disabledButton",
:disable="canPressLoginButton",
label="Войти в аккаунт",
size="L",
@click="login",
@@ -49,83 +49,47 @@
<script>
import { fetchWrapper } from "@/shared/fetchWrapper";
import BaseInput from "@/components/base/BaseInput";
import logoMark from "@/assets/images/logoMark.svg";
import logo from "@/assets/images/logoMark.svg";
import BaseButton from "@/components/base/BaseButton.vue";
import eye_open from "@/assets/icons/eye_open.svg";
import eye_close from "@/assets/icons/eye_close.svg";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "TheLogin",
components: { BaseInput, BaseButton },
data() {
return {
isView: false,
logoMark,
eye_close,
eye_open,
showPassword: false,
logo,
authorized: true,
user: { username: "", password: "" },
userData: {},
person: false,
user: {},
rememberMe: false,
authError: false,
};
},
computed: {
wrongData() {
return !this.authorized && !this.user.username && !this.user.password;
passwordInputType() {
return !this.showPassword ? "password" : "text";
},
changeType() {
return !this.isView ? "password" : "text";
},
disabledButton() {
return this.user.username && this.user.password ? false : true;
},
showBorder() {
return !this.authorized && !this.user.username && !this.user.password
? true
: false;
canPressLoginButton() {
return !(this.user.username && this.user.password);
},
},
methods: {
changeView() {
this.isView = !this.isView;
},
persist() {
if (!this.person) return;
localStorage.username = this.user.username;
localStorage.password = this.user.password;
},
async auth() {
let res = await fetchWrapper.get("auth/users/me/");
res = await res;
let data = await fetchWrapper.get(`accounts/users/${res.id}/detail`);
data = await data;
this.userData = data;
localStorage.setItem("userData", JSON.stringify(this.userData));
changePasswordInputType() {
this.showPassword = !this.showPassword;
},
login() {
fetchWrapper
.post("auth/jwt/create/", {
username: this.user.username,
.post("auth/login", {
user_name: this.user.username,
password: this.user.password,
})
.then((token) => {
if (token.access) {
localStorage.setItem("tokenAccess", token.access);
this.auth().then(() => this.$router.push("/"));
} else {
this.authorized = false;
this.user.username = "";
this.user.password = "";
this.$router.push("/login");
}
.then((data) => {
if (!data) this.authError = true;
else this.$router.push("/");
});
},
},
mounted() {
if (localStorage.username) this.user.username = localStorage.username;
if (localStorage.password) this.user.password = localStorage.password;
},
};
</script>
@@ -161,15 +125,6 @@ export default {
.q-btn
height: 48px
.input :deep(.label)
opacity: 1
.blue-color :deep(.label)
color: var(--font-dark-blue-color)
line-height: 135%
.input :deep(.q-field__control)
color: var(--font-dark-blue-color)
&:hover:before
border: 1px solid var(--font-dark-blue-color)
&:after
border-width: 1px !important
</style>

View File

@@ -0,0 +1,20 @@
<template lang="pug">
.medcards-wrapper.flex.flex-col.gap-y-2.h-full
medical-card-search
</template>
<script>
import MedicalCardSearch from "./components/MedicalCardSearch.vue";
import TablePatients from "./components/TablePatients.vue";
export default {
name: "TheMedcards",
components: { MedicalCardSearch, TablePatients },
};
</script>
<style lang="sass">
.medcards-wrapper
width: calc(100vw - 72px)
overflow: hidden
</style>

View File

@@ -0,0 +1,150 @@
<template lang="pug">
medcard-form-wrapper(v-if="patient", title="Пациент на приеме", title-link="Медкарта")
.flex.flex-col.h-full
.header.flex.px-6.py-5.justify-between
.flex.text-base.font-medium.gap-x-3
img.h-14.w-14.object-cover.rounded-full(:src="patient?.avatar")
.flex.flex-col.justify-center.gap-y-1
.font-bold.text-xll {{patient.last_name + " " + patient.first_name + " " + patient.patronymic}}
.grey-color.text-smm {{patient?.birthday}}
.flex.flex-col.gap-y-1.text-smm.font-medium
.flex.items-center.gap-x-2
.priority.flex(:class="choiceClass(patient.priority)")
.text-smm(:class="choiceColor(patient.priority)") {{choicePriority(patient.priority)}}
.grey-color.text-smm Приоритет
.flex.h-full
.data.flex.w-full.h-full.flex-col.px-6.py-4.gap-y-6.overflow-hidden(v-for="item in data")
.text-m.font-bold {{item.title}}
.flex.flex-col.text-smm.overflow-hidden.relative.gap-y-1
.grey-color {{item.firstLabel}}
.insurance.flex.font-medium {{item.firstDescription}}
.flex.flex-col.text-smm.gap-y-1
.grey-color {{item.secondLabel}}
.font-medium {{item.secondDescription}}
</template>
<script>
import MedcardFormWrapper from "@/pages/medcards/components/MedcardFormWrapper.vue";
import { patientList } from "@/pages/newCalendar/utils/calendarConfig";
import * as moment from "moment";
export default {
name: "CurrentPatientForm",
components: { MedcardFormWrapper },
data() {
return {
patient: patientList
.find(({ label }) => label === "Пациенты")
.data.find(
(e) =>
e.time.from <= moment().format("HH:MM") &&
e.time.to >= moment().format("HH:MM") &&
e.reception === moment().format("DD.MM.YYYY")
),
prioritys: [
{ name: "Без приоритета", id: 0, class: "none-priority" },
{ name: "Высокий", id: 1, class: "high-priority" },
{ name: "Средний", id: 2, class: "middle-priority" },
{ name: "Низский", id: 3, class: "low-priority" },
],
data: [
{ title: "Запись", firstLabel: "Дата", secondLabel: "Время" },
{ title: "Данные", firstLabel: "Телефон", secondLabel: "Email" },
{ title: "Страхование", firstLabel: "Компания", secondLabel: "Полис" },
],
};
},
methods: {
choiceClass(priority) {
return this.prioritys.find(({ id }) => id === priority).class;
},
choicePriority(priority) {
return this.prioritys.find(({ id }) => id === priority).name;
},
choiceColor(priority) {
return {
"none-priority": !priority,
"red-color": priority === 1,
"blue-color": priority === 2,
"green-color": priority === 3,
};
},
},
watch: {
patient: {
deep: true,
immediate: true,
handler() {
this.data[0].firstDescription = moment().format("DD MMMM");
this.data[0].secondDescription =
this.patient?.time?.from + "-" + this.patient?.time?.to;
this.data[1].firstDescription = this.patient?.phone;
this.data[1].secondDescription = this.patient?.email;
this.data[2].firstDescription = this.patient?.company;
this.data[2].secondDescription = this.patient?.policy;
},
},
},
};
</script>
<style lang="sass" scoped>
.header
border-bottom: 1px solid var(--gray-secondary)
.priority
height: 8px
width: 8px
border-radius: 50%
.data
border-right: 1px solid var(--gray-scondary)
&:first-child
max-width: 154px
&:last-child
@media (max-width: 1820px)
max-width: 282px
border-right: none
max-width: 214px
.insurance
width: 209px
overflow: hidden
&:after
content: ""
text-align: right
position: absolute
bottom: 0
right: 0
width: 72px
height: 24px
background: linear-gradient(270deg, #FFF 0%, rgba(255, 255, 255, 0.24) 50.73%, rgba(255, 255, 255, 0.00) 100%)
pointer-events: none
@media (max-width: 1820px)
width: 234px
.high-priority
background: var(--system-color-red)
.middle-priority
background: var(--btn-blue-color)
.low-priority
background: var(--system-color-green)
.none-priority
border: 1.5px solid var(--font-grey-color)
.grey-color
color: var(--font-grey-color)
.red-color
color: var(--system-color-red)
.blue-color
color: var(--btn-blue-color)
.green-color
color: var(--system-color-green)
</style>

View File

@@ -0,0 +1,170 @@
<template lang="pug">
medcard-form-wrapper.relative(
title="Пациенты на сегодня",
:quantity="patientsData.length",
:link="redirectCalendar",
title-link="В календарь"
)
.form-wrapper.flex.flex-col.overflow-y-auto(
@scroll="scrollTo",
id="scroll",
:class="{'default-form': patientsData.length <= 3}"
)
.patient.flex.items-center.p-4.justify-between(
v-for="(patient, index) in patientsData",
:class="{'default-patient': patientsData.length <= 3}",
@click="changeView(patient.id)"
)
.flex.text-base.font-medium.gap-x-3
img.h-11.w-11.object-cover.rounded-full(:src="patient.avatar")
.flex.flex-col.justify-center.gap-y-1
.name.flex.relative {{trimName(patient.last_name, patient.first_name, patient.patronymic)}}
.grey-color.text-smm {{trimBirthday(patient.birthday)}}
.flex.flex-col.justify-center.w-full(:style="{width: '140px'}")
.text-m.font-bold {{patient.time.from + " - " + patient.time.to}}
.grey-color.font-medium.text-smm(
:class="{'red-color': !index}"
) {{index ? "Время посещения" : "Скоро прием" }}
.flex
q-btn.btn(
icon="app:medcard",
size="18px",
dense,
padding="8px",
style="color: var(--font-grey-color); background: var(--bg-light-grey)"
)
.gradient-name.flex.absolute(v-if="isGradient")
</template>
<script>
import * as moment from "moment";
import MedcardFormWrapper from "@/pages/medcards/components/MedcardFormWrapper.vue";
import { patientList } from "@/pages/newCalendar/utils/calendarConfig";
export default {
name: "TodaysPatientsForm",
components: { MedcardFormWrapper },
data() {
return {
patientsData: patientList
.find(({ label }) => label === "Пациенты")
.data.sort((a, b) => {
if (a.time.from > b.time.from) return 1;
if (a.time.from < b.time.from) return -1;
return 0;
})
.filter(
(e) =>
e.reception === moment().format("DD.MM.YYYY") &&
e.time.from > moment().format("HH:MM")
),
isGradient: false,
};
},
methods: {
trimBirthday(birthday) {
return moment(birthday, "DD MM YYYY").format("DD MMMM YYYY") + " г.";
},
trimName(last, first, patronymic) {
let fullName = last + " " + first + " " + patronymic;
if (fullName.length > 30) return fullName.slice(0, 30);
return fullName;
},
changeView(id) {
let view = [];
this.patientsData.map((e) => {
if (e.id === id) {
e.view = true;
view.push(e);
e.viewDate = moment().format("DD.MM.YYYY");
}
});
localStorage.view = JSON.stringify(view);
},
redirectCalendar() {
this.$router.push("/calendar");
},
scrollTo(event) {
if (
Math.abs(
event.currentTarget.scrollHeight -
event.currentTarget.clientHeight -
event.currentTarget.scrollTop
) < 1
)
return (this.isGradient = false);
this.isGradient = true;
},
checkScroll() {
let elem = document.getElementById("scroll");
if (Math.abs(elem.scrollHeight - elem.clientHeight - elem.scrollTop))
this.isGradient = true;
},
},
mounted() {
this.checkScroll();
},
};
</script>
<style lang="sass" scoped>
.form-wrapper
margin-right: 8px
&::-webkit-scrollbar
width: 4px
&::-webkit-scrollbar-track:vertical
margin-top: 16px
margin-bottom: 16px
.name
width: 272px
&:after
content: ""
text-align: right
position: absolute
bottom: 0
right: 0
width: 72px
height: 24px
background: linear-gradient(270deg, #FFF 0%, rgba(255, 255, 255, 0.24) 50.73%, rgba(255, 255, 255, 0.00) 100%)
pointer-events: none
@media (max-width: 1820px)
width: 340px
.patient
border-bottom: 1px solid var(--gray-secondary)
border-right: 1px solid var(--gray-secondary)
margin-right: 8px
height: 77px
&:last-child
border-bottom: none
.default-patient
margin-right: 0px
border-right: none
&:last-child
border-bottom: 1px solid var(--gray-secondary)
.default-form
margin-right: 0px
&:last-child
border-bottom: none
.gradient-name
background: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FFF 100%)
width: 580px
height: 43px
bottom: 0
left: 0
.btn
border: 1px solid var(--gray-secondary)
color: var(--font-grey-color)
background: var(--bg-light-grey)
.grey-color
color: var(--font-grey-color)
.red-color
color: var(--system-color-red)
</style>

View File

@@ -0,0 +1,157 @@
<template lang="pug">
medcard-form-wrapper.relative(title="Недавно просмотренные медкарты")
.form-wrapper.flex.flex-col.overflow-y-auto(
@scroll="scrollTo",
id="scroll-view",
:class="{'default-form': viewPatients.length <= 3}"
)
.patient.flex.items-center.p-4.justify-between(
v-for="(patient, index) in viewPatients",
:class="{'default-patient': viewPatients.length <= 3}"
)
.flex.text-base.font-medium.gap-x-3
img.h-11.w-11.object-cover.rounded-full(:src="patient.avatar")
.flex.flex-col.justify-center.gap-y-1
.name.flex.relative {{trimName(patient.last_name, patient.first_name, patient.patronymic)}}
.grey-color.text-smm {{"Медкарта #" + patient.id}}
.flex.flex-col.font-medium.text-m.gap-y-1(:style="{width: '140px'}")
span {{patient.viewDate}}
.grey-color.text-smm Дата просмотра
.flex
q-btn.btn(
icon="app:medcard",
size="18px",
dense,
padding="8px",
style="color: var(--font-grey-color); background: var(--bg-light-grey)"
)
.gradient-name.flex.absolute(v-if="isGradient")
</template>
<script>
import MedcardFormWrapper from "@/pages/medcards/components/MedcardFormWrapper.vue";
import { patientList } from "@/pages/newCalendar/utils/calendarConfig";
export default {
name: "ViewedMedicalRecordsForm",
components: { MedcardFormWrapper },
data() {
return {
viewPatients: [],
patientsData: patientList.find(({ label }) => label === "Пациенты").data,
isGradient: false,
};
},
methods: {
trimName(last, first, patronymic) {
let fullName = last + " " + first + " " + patronymic;
if (fullName.length > 30) return fullName.slice(0, 30);
return fullName;
},
scrollTo(event) {
if (
Math.abs(
event.currentTarget.scrollHeight -
event.currentTarget.clientHeight -
event.currentTarget.scrollTop
) < 1
)
return (this.isGradient = false);
this.isGradient = true;
},
checkScroll() {
let elem = document.getElementById("scroll-view");
if (Math.abs(elem.scrollHeight - elem.clientHeight - elem.scrollTop) < 1)
this.isGradient = true;
},
},
watch: {
patientsData: {
immediate: true,
deep: true,
handler() {
if (localStorage.getItem("view"))
this.viewPatients.push(...JSON.parse(localStorage.getItem("view")));
},
},
viewPatients: {
immediate: true,
deep: true,
handler() {
if (this.viewPatients.length > 3) this.checkScroll();
},
},
},
mounted() {
this.checkScroll();
},
};
</script>
<style lang="sass" scoped>
.form-wrapper
margin-right: 8px
&::-webkit-scrollbar
width: 4px
&::-webkit-scrollbar-track:vertical
margin-top: 16px
margin-bottom: 16px
.name
width: 272px
&:after
content: ""
text-align: right
position: absolute
bottom: 0
right: 0
width: 72px
height: 24px
background: linear-gradient(270deg, #FFF 0%, rgba(255, 255, 255, 0.24) 50.73%, rgba(255, 255, 255, 0.00) 100%)
pointer-events: none
.patient
border-bottom: 1px solid var(--gray-secondary)
border-right: 1px solid var(--gray-secondary)
margin-right: 8px
height: 77px
&:last-child
border-bottom: none
.default-form
margin-right: 0px
&:last-child
border-bottom: none
.default-patient
margin-right: 0px
border-right: none
&:last-child
border-bottom: 1px solid var(--gray-secondary)
.btn
border: 1px solid var(--gray-secondary)
color: var(--font-grey-color)
background: var(--bg-light-grey)
.gradient
background: linear-gradient(90deg, #FFF 0%, rgba(255, 255, 255, 0.24) 50.73%, rgba(255, 255, 255, 0.00) 100%)
width: 72px
height: 24px
right: 0
top: 0
transform: rotate(180deg)
.gradient-name
background: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FFF 100%)
width: 580px
height: 43px
bottom: 0
left: 0
.grey-color
color: var(--font-grey-color)
.red-color
color: var(--system-color-red)
</style>

View File

@@ -0,0 +1,41 @@
<template lang="pug">
.wrapper.flex.flex-col.w-full.rounded
.header.flex.items-center.text-sm.font-bold.justify-between.w-full.px-6.py-5
.left-side.flex.gap-x-2.items-center
span {{title}}
.grey-color(v-if="quantity") {{quantity}}
.link.flex.items-center.cursor-pointer(v-if="titleLink", @click="link")
span.font-medium {{ titleLink }}
slot
</template>
<script>
export default {
name: "MedcardFormWrapper",
props: {
title: String,
titleLink: String,
link: Function,
quantity: Number,
},
};
</script>
<style lang="sass" scoped>
.wrapper
height: 360px
background: var(--default-white)
color: var(--font-dark-blue-color)
.header
max-height: 62px
border-bottom: 1px solid var(--gray-secondary)
.grey-color
color: var(--font-grey-color)
.link
color: var(--btn-blue-color)
&:hover
opacity: 0.7
</style>

View File

@@ -0,0 +1,70 @@
<template lang="pug">
.medical-wrapper.rounded.h-full
list-header(@search="getMedcards")
list-contents(
:medicalCards="medicalCards",
:data-status="dataStatus"
)
</template>
<script>
import ListHeader from "@/pages/medcards/components/MedicalCardSearchHeader.vue";
import ListContents from "@/pages/medcards/components/MedicalCardSearchList.vue";
import { fetchWrapper } from "@/shared/fetchWrapper";
import nothingChooseImg from "@/assets/images/nothing-choose.svg";
import nothingSearchImg from "@/assets/images/nothing-search.svg";
export default {
name: "MedicalCardSearch",
components: { ListHeader, ListContents },
data() {
return {
medicalCards: [],
dataStatus: {
title: "no data",
message: "Введите данные Пациента для поиска",
img: nothingChooseImg,
},
};
},
methods: {
async getMedcards(value) {
if (!value) {
this.dataStatus = {
title: "no data",
message: "Введите ФИО Пациента",
img: nothingChooseImg,
};
this.medicalCards = [];
return;
}
const data = await fetchWrapper.post("persons/search", {
full_name: value,
});
if (data?.length === 0) {
this.medicalCard = [];
this.dataStatus = {
title: "not found",
message: `По запросу «${value}» Пациентов не найдено.
Переформулируйте запрос и попробуйте снова`,
img: nothingSearchImg,
};
return;
}
this.medicalCards = data;
this.dataStatus = {
title: "found",
};
return;
},
},
};
</script>
<style lang="sass" scoped>
.medical-wrapper
background-color: var(--default-white)
display: flex
flex-direction: column
overflow: hidden
</style>

View File

@@ -0,0 +1,93 @@
<template lang="pug">
.header-wrapper.flex.w-full.justify-between.p-4
.flex.items-center.justify-center.gap-x-2
base-input.search(
:width="438",
size="M",
placeholder="ФИО Пациента",
icon-left,
v-model="filterString"
)
template(#iconLeft)
q-icon.search-icon(name="app:search", size="20px")
base-button(@click="showCreateModal = true")
q-icon.plus.mr-2(name="app:plus", size="18px")
span Новая медкарта
base-modal(v-model="showCreateModal", title="Создать медицинскую карту", modal-padding)
patient-creation-form(@close="handleClosePatientForm")
</template>
<script>
import BaseInput from "@/components/base/BaseInput.vue";
import BaseSelect from "@/components/base/BaseSelect.vue";
import BaseButton from "@/components/base/BaseButton.vue";
import debounce from "lodash/debounce";
import BaseModal from "@/components/base/BaseModal.vue";
import PatientCreationForm from "@/components/PatientCreationForm.vue";
import { mapActions } from "vuex";
export default {
name: "MedicalCardSearchHeader",
components: {
PatientCreationForm,
BaseModal,
BaseInput,
BaseSelect,
BaseButton,
},
emits: ["search"],
data() {
return {
filterString: "",
showCreateModal: false,
};
},
methods: {
handleClosePatientForm(val) {
this.showCreateModal = false;
if (!val) return;
this.getMedicalCardData({
personId: val.id,
successCallback: (id) => this.$router.push("medical-card/" + id),
});
},
...mapActions({
getMedicalCardData: "getMedicalCardDataByPersonId",
}),
},
watch: {
filterString: debounce(function (value) {
this.$emit("search", value);
}, 300),
},
};
</script>
<style lang="sass" scoped>
.header-wrapper
height: 72px
border-bottom: 1px solid var(--gray-secondary)
.search-icon :deep(path)
fill: var(--font-grey-color)
.search :deep(.q-field__prepend)
padding-right: 12px
.plus :deep(path)
fill: var(--default-white)
.grey-color
color: var(--font-grey-color)
.item
border-bottom: 1px solid var(--gray-secondary)
&:last-child
border-bottom: none
&:hover
background-color: var(--gray-thirdly)
span
cursor: default
</style>

View File

@@ -0,0 +1,72 @@
<template lang="pug">
.scroll-wrapper
.list-wrapper.rounded.w-full.bg-white.h-full
.w-full.h-full.flex.items-center.justify-center(v-if="dataStatus.title !== 'found'")
.flex.flex-col.gap-y-2.h-96.items-center
img.image(:src="dataStatus.img")
.font-bold.text-xll.grey-color.whitespace-pre-line.text-center {{dataStatus.message}}
.flex.flex-col.w-full.h-full(v-else)
.w-full.header.h-10.flex
.h-full.py-10px.px-4.flex.items-center.justify-start.font-semibold.text-sm.grey-color(
v-for="field in headerConfig",
:key="field.title",
:style="headerStyle(field)"
) {{ field.title }}
.body.w-full
row(
v-for="medcard in medicalCards",
:key="medcard.id"
:header-style="headerStyle",
:person="medcard",
)
</template>
<script>
import { searchListConfig } from "@/pages/medcards/utils/medcardsConfig.js";
import Row from "@/pages/medcards/components/MedicalCardSearchRow.vue";
export default {
name: "MedicalCardSearchList",
props: {
medicalCards: Array,
dataStatus: Object,
},
components: { Row },
data() {
return {
headerConfig: searchListConfig,
};
},
methods: {
headerStyle(field) {
return {
...field,
};
},
},
};
</script>
<style lang="sass" scoped>
.scroll-wrapper
flex-grow: 1
overflow-y: hidden
.list-wrapper
overflow: hidden
min-width: min-content
.header
background-color: var(--gray-thirdly)
border-bottom: 1px solid var(--gray-secondary)
.grey-color
color: var(--font-grey-color)
.body
overflow-y: auto
&::-webkit-scrollbar-track
margin: 24px 0 24px 0
background: #E9E9ED
&::-webkit-scrollbar-thumb
background: var(--font-grey-color)
.image
width: 300px
height: 300px
</style>

View File

@@ -0,0 +1,108 @@
<template lang="pug">
.w-full.row-wrapper.h-14.flex
.field(:style="headerStyle(headerConfig[0])")
template(v-if="person.medical_card_id")
base-button(size="S", @click="openMedicalCard", label="Открыть", color="green")
template(v-else)
base-button(size="S", @click="createMedCard", label="Создать")
.field.gap-x-3(:style="headerStyle(headerConfig[1])")
span.font-semibold.text-dark {{patientName}}
.field(:style="headerStyle(headerConfig[2])")
span.text-dark {{ birthDate }}
.field(:style="{...headerStyle(headerConfig[3])}")
span.text-dark {{ phones }}
</template>
<script>
import { searchListConfig } from "@/pages/medcards/utils/medcardsConfig.js";
import * as moment from "moment/moment";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { mapActions } from "vuex";
import BaseButton from "@/components/base/BaseButton.vue";
export default {
name: "MedicalCardSearchRow",
components: { TheNotificationProvider, BaseButton },
props: {
headerStyle: Function,
person: Object,
},
data() {
return {
headerConfig: searchListConfig,
};
},
computed: {
patientName() {
return `${this.person?.last_name} ${this.person?.first_name} ${this.person?.patronymic}`;
},
birthDate() {
let retVal =
this.person?.birth_date &&
moment(this.person?.birth_date)?.format("DD MMMM YYYY");
return retVal ? retVal + " г." : "";
},
phones() {
return this.person?.contacts
?.filter((el) => el.category === "PHONE")
.map((el) => el.value)
.join(", ");
},
},
methods: {
...mapActions({
getMedicalCardData: "getMedicalCardDataByPersonId",
createMedicalCard: "createMedicalCard",
getPerson: "GET_PERSON",
}),
openMedicalCard() {
this.getPerson(this.person.id)
.then(() =>
this.$router.push("medical-card/" + this.person["medical_card_id"])
)
.catch((error) => alert(error));
},
createMedCard() {
this.createMedicalCard({
personId: this.person.id,
}).then(() => {
this.openMedicalCard();
});
},
},
};
</script>
<style lang="sass" scoped>
.row-wrapper
border-bottom: 1px solid var(--gray-secondary)
& > .field
height: 100%
padding: 10px 16px
display: flex
align-items: center
justify-content: start
font-size: 14px
line-height: 135%
.medcard-number
border: 1px solid var(--gray-secondary)
background: var(--gray-thirdly)
&:hover
background: var(--gray-secondary)
.copy :deep(path)
fill: var(--font-grey-color)
.medcard :deep(path)
fill: var(--btn-blue-color)
span
cursor: default
.track
background: var(--gray-thirdly)
.grey-color
color: var(--font-grey-color)
</style>

View File

@@ -0,0 +1,27 @@
<template lang="pug">
.table-wrapper.flex.gap-x-2
todays-patients-form
current-patient-form
viewed-medical-records-form.viev
</template>
<script>
import CurrentPatientForm from "./BasicDataForms/CurrentPatientForm.vue";
import TodaysPatientsForm from "./BasicDataForms/TodaysPatientsForm.vue";
import ViewedMedicalRecordsForm from "./BasicDataForms/ViewedMedicalRecordsForm.vue";
export default {
name: "TablePatients",
components: {
TodaysPatientsForm,
CurrentPatientForm,
ViewedMedicalRecordsForm,
},
};
</script>
<style lang="sass" scoped>
.viev
@media (max-width: 1820px)
display: none
</style>

View File

@@ -0,0 +1,19 @@
export const searchListConfig = [
{
title: "Медкарта",
minWidth: "140px",
},
{
title: "ФИО",
width: "100%",
minWidth: "350px",
},
{
title: "Дата рождения",
minWidth: "220px",
},
{
title: "Телефон",
minWidth: "220px",
},
];

View File

@@ -2,9 +2,12 @@
.w-full.flex
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")
component.ml-2(
v-bind:is="calendarComponent",
:open-sidebar="isOpen",
)
base-modal(v-model="isShowForm", title="Создание записи", modal-padding)
record-creation-form(v-model="isShowForm", :close-form="closeForm")
create-event-form(:close-form="closeForm")
base-modal(v-model="previewVisibility", :hideHeader="true", :modalPadding="true")
calendar-record-preview(v-model:preview-visibility="previewVisibility")
</template>
@@ -12,8 +15,9 @@
<script>
import CalendarSidebar from "@/pages/newCalendar/components/CalendarSidebar";
import CalendarOpenSidebar from "@/pages/newCalendar/components/CalendarOpenSidebar";
import CalendarWrapper from "@/pages/newCalendar/components/CalendarWrapper";
import RecordCreationForm from "@/pages/newCalendar/components/RecordCreationForm";
import DoctorCalendarWrapper from "@/pages/newCalendar/components/doctorCalendar/CalendarWrapper";
import ManagerCalendarWrapper from "@/pages/newCalendar/components/managerCalendar/CalendarWrapper";
import CreateEventForm from "@/pages/newCalendar/components/CreateEventForm";
import * as moment from "moment/moment";
import BaseModal from "@/components/base/BaseModal.vue";
import CalendarRecordPreview from "./components/CalendarRecordPreview.vue";
@@ -23,8 +27,9 @@ export default {
components: {
CalendarSidebar,
CalendarOpenSidebar,
CalendarWrapper,
RecordCreationForm,
DoctorCalendarWrapper,
ManagerCalendarWrapper,
CreateEventForm,
BaseModal,
CalendarRecordPreview,
},
@@ -39,7 +44,14 @@ export default {
computed: {
...mapState({
selectedRecordId: (state) => state.calendar.selectedRecordId,
selectedDates: (state) => state.calendar.selectedDates,
calendarShape: (state) => state.calendarShape,
}),
calendarComponent() {
return this.calendarShape === "doctor"
? "doctor-calendar-wrapper"
: "manager-calendar-wrapper";
},
},
methods: {
openSidebar() {
@@ -53,7 +65,12 @@ export default {
},
...mapActions({
changeSelectedRecordId: "changeSelectedRecordId",
changeSelectedDates: "changeSelectedDates",
getEvents: "getEvents",
}),
convertDate(date) {
return moment(date?.split(".")?.reverse()?.join("-"));
},
},
watch: {
selectedRecordId(value) {
@@ -62,6 +79,61 @@ export default {
previewVisibility(value) {
if (!value) this.changeSelectedRecordId(null);
},
"$route.query": {
immediate: true,
deep: true,
handler(value) {
if (this.$route.path === "/calendar") {
let dateType = this.calendarShape === "doctor" ? "week" : "day";
if (!value?.start || !value?.end) {
this.changeSelectedDates({
from: moment().clone().startOf(dateType),
to: moment().clone().endOf(dateType),
});
this.$router.replace({
query: {
start: this.selectedDates?.from?.format("DD.MM.YYYY"),
end: this.selectedDates?.to?.format("DD.MM.YYYY"),
},
});
} else if (
value?.start !== this.selectedDates?.from?.format("DD.MM.YYYY") ||
value?.end !== this.selectedDates?.to?.format("DD.MM.YYYY")
) {
this.changeSelectedDates({
from: this.convertDate(value?.start).clone().startOf("day"),
to: this.convertDate(value?.end).clone().endOf("day"),
});
}
}
},
},
selectedDates: {
deep: true,
immediate: true,
handler(newVal, oldVal) {
if (
!newVal?.from?.isSame(oldVal?.from) ||
!newVal?.to?.isSame(oldVal?.to)
) {
this.getEvents();
if (
this.$route.query?.start !== newVal?.from?.format("DD.MM.YYYY") &&
this.$route.query?.end !== newVal?.to?.format("DD.MM.YYYY")
) {
this.$router.replace({
query: {
start: newVal?.from?.format("DD.MM.YYYY"),
end: newVal?.to?.format("DD.MM.YYYY"),
},
});
}
}
},
},
},
beforeUnmount() {
this.$route.query = {};
},
};
</script>

View File

@@ -15,7 +15,7 @@ export default {
timeCoil: Array,
currentTime: String,
dayEndTime: Number,
isCurrentWeek: Boolean,
isCurrent: Boolean,
},
computed: {
currentHour() {
@@ -33,7 +33,7 @@ export default {
if (
convertTime(elem, 0, 3) === this.currentHour &&
!this.isEndDay &&
this.isCurrentWeek
this.isCurrent
) {
return {
"current-time": true,

View File

@@ -1,110 +0,0 @@
<template lang="pug">
.calendar-column-wrapper.flex.flex-col
.header.flex.flex-col.items-center.justify-center.top-0.pt-3.pb-10px
span.font-bold.text-base.color-black {{ date?.format("D MMMM")}}
span.text-smm.color-grey {{ transformDayName(date?.format("dddd"))}}
.body.h-full.px-1.py-1
calendar-record-card(
v-for="record in filteredRecords",
:key="record?.id",
:record="record",
:expanded-type="expandedDisplayType",
:style="eventCardPosition(record.start, record.end)",
@click="changeSelectedRecordId(record?.id)",
)
.footer.flex.items-center.justify-center.bg-white.h-9(v-if="!expandedDisplayType")
span.text-smm.color-grey 0 записей
</template>
<script>
import * as moment from "moment/moment";
import { recordList } from "@/pages/newCalendar/utils/calendarConfig.js";
import CalendarRecordCard from "@/pages/newCalendar/components/CalendarRecordCard.vue";
import { verifyTime } from "@/pages/newCalendar/utils/calendarFunctions.js";
import { mapActions } from "vuex";
export default {
name: "CalendarColumn",
components: { CalendarRecordCard },
props: {
date: Object,
expandedDisplayType: Boolean,
dayEndTime: Number,
dayStartTime: Number,
},
data() {
return {
pixelsPerHour: 76,
};
},
computed: {
filteredRecords() {
return recordList.filter(
(elem) =>
moment.parseZone(elem.start).format("YYYY-MM-DD") ===
this.date.format("YYYY-MM-DD")
);
},
pixelsPerMinute() {
return this.pixelsPerHour / 60;
},
},
methods: {
...mapActions({
changeSelectedRecordId: "changeSelectedRecordId",
}),
transformDayName(name) {
return name[0]?.toUpperCase() + name?.slice(1);
},
eventCardPosition(startTime, endTime) {
let start = startTime
.slice(11, -4)
.split(":")
.map((elem) => parseInt(elem, 10));
let end = endTime.slice(11, -4);
let position =
(start[0] - this.dayStartTime) * this.pixelsPerHour +
start[1] * this.pixelsPerMinute +
4;
if (
parseInt(start[0], 10) < this.dayStartTime ||
verifyTime(end) > this.dayEndTime
) {
return {
top: "0px",
visibility: "hidden",
};
}
return {
top: `${position}px`,
};
},
},
};
</script>
<style lang="sass" scoped>
.calendar-column-wrapper
border-right: 1px solid var(--border-light-grey-color)
&:last-child
border-right: none
.header
position: sticky
z-index: 5
background-color: var(--default-white)
.body
position: relative
z-index: 3
.color-black
color: var(--font-dark-blue-color)
.color-grey
color: var(--font-grey-color)
.footer
border-top: 1px solid var(--border-light-grey-color)
@media(min-height: 1090px)
border-bottom: 1px solid var(--border-light-grey-color)
</style>

View File

@@ -1,65 +1,75 @@
<template lang="pug">
.sidebar-wrapper.flex.flex-col.gap-y-1
.sidebar-wrapper.flex.flex-col.gap-y-px
.form.flex.items-center.justify-end.py-4.pr-4.rounded-t
q-btn.rotate-180(
@click="openSidebar",
q-btn.rotate-180.button-open(
@click="openSidebar(); hideSidebar()",
dense,
padding="8px",
style="color: var(--font-grey-color); background: var(--bg-light-grey)"
)
img(:src="arrow")
.form.flex.p-4
base-button(
width="100%",
@click="createForm",
)
q-icon(name="app:plus", size="12px", left)
base-button(width="100%", @click="createForm")
q-icon.plus(name="app:plus", size="24px", left)
span Создать запись
.flex.flex-col.gap-y-1
.flex.flex-col.gap-y-px
q-expansion-item.expansion.font-bold.text-xm(
expand-icon="app:down-arrow",
v-for="(elem, index) in patientList",
expand-separator,
:label="elem.label",
@click="choiceForm(elem.choice, index)",
:class="{'patient': elem.label === 'Пациенты'}"
)
.select.flex.flex-col.font-medium.text-smm.px-4(
.select.flex.flex-col.font-medium.text-smm.px-2(
v-if="elem.label !== 'Пациенты'",
v-for="item in elem.data"
)
.status.flex.items-center.gap-x-1.px-2
img(:src="item.icon")
q-icon(
v-if="elem.label === 'Первичная медкарта'"
:name="item.icon",
size="20px",
:class="choiceClass(item.id, 'medcard')"
)
.priority.rounded-full.flex.mr-1.5px(
v-if="elem.label === 'Статус приема'",
:class="choiceClass(item.id, 'priority')"
)
span {{item.name}}
.flex.flex-col.p-4.pb-0(:class="choiceState()", v-else)
.flex.flex-col.px-4.pt-6px.pb-0(:class="choiceState()", v-else)
.flex.flex-col.gap-y-2
.flex.h-8.w-full.items-center.justify-between
base-input(
base-input.input(
v-model="foundPerson",
debounce="10",
@keyup.enter="searchPerson",
@input="searchPerson",
id="input",
placeholder="Найти пациента...",
outlined,
:width="160",
iconLeft,
fontSize="12px",
lineHeight="16px",
textColor="var(--font-grey-color)"
:width="160"
size="S",
icon-left
)
q-icon(name="app:icon-search", size="16px", style="color: var(--font-grey-color)")
q-btn.btn.ml-2(
template(v-slot:iconLeft)
q-icon.input-icon(name="app:search", size="16px")
q-btn.ml-2.sort-icon(
@click="sortPerson(elem.data)",
style="color: var(--font-grey-color); background: var(--bg-light-grey)"
:class="sortingClass",
:style="{width: '32px', height: '32px'}",
padding="0"
)
img(:src="sort_word")
.flex.items-center.justify-between.font-medium.text-smm.h-10.py-2.cursor-pointer(
calendar-sidebar-svg(name-svg="sort", :active="sort")
.flex.items-center.justify-between.font-medium.text-smm.h-55.py-2.cursor-pointer(
@click="checkAll(elem.data)"
)
span Все
.flex.items-center.gap-x-2
.all-icon.flex.items-center.justify-center
q-icon.icon-patients(name="app:patients", size="24px")
.flex.flex-col.font-medium
.text-smm Все
.grey-color.text.text-xsx {{ elem.data?.length + " пациентов" }}
img(v-if="selectAll(elem.data)", :src="icon_ok")
.person-wrapper.flex.flex-col
.person-wrapper.flex.flex-col(@scroll="scrollTo", id="persons")
.person.items-center.flex.justify-between.py-2.cursor-pointer(
v-for="(person, index) in choiceData(elem.data)",
@click="checkPerson(index, elem.data)"
@@ -68,8 +78,9 @@
img.h-10.w-10.object-cover.rounded-full(:src="person.avatar")
.flex.flex-col.font-medium
.text-smm {{trimOwnerName(person.last_name, person.first_name, person.patronymic)}}
.text.text-xsx {{person.birthday}}
.grey-color.text-xsx {{trimBirthday(person.birthday)}}
img.h-6.w-6(v-if="person.check", :src="icon_ok")
.gradient.flex.absolute(v-if="isGradient")
</template>
<script>
@@ -80,10 +91,13 @@ import BaseInput from "@/components/base/BaseInput.vue";
import { patientList } from "@/pages/newCalendar/utils/calendarConfig.js";
import { trimName } from "@/pages/newCalendar/utils/calendarFunctions.js";
import BaseButton from "@/components/base/BaseButton.vue";
import CalendarSidebarSvg from "@/pages/newCalendar/components/CalendarSidebarSvg.vue";
import * as moment from "moment";
export default {
name: "CalendarOpenSidebar",
props: { openSidebar: Function, createForm: Function },
components: { BaseInput, BaseButton },
components: { BaseInput, BaseButton, CalendarSidebarSvg },
data() {
return {
val: [],
@@ -94,10 +108,39 @@ export default {
sortData: [],
patientList: patientList,
sort: false,
isGradient: true,
trimOwnerName: trimName,
};
},
computed: {
sortingClass() {
return this.sort
? {
"sort-icon-active": true,
}
: {
"sort-icon-default": true,
};
},
},
methods: {
choiceClass(priority, name) {
if (name === "priority")
return {
"none-priority": !priority,
"red-color": priority === 1,
"blue-color": priority === 2,
"green-color": priority === 3,
};
return {
medcard: !priority,
"medcard-orange": priority === 1,
"medcard-green": priority === 2,
};
},
trimBirthday(birthday) {
return moment(birthday, "DD MM YYYY").format("DD MMMM YYYY");
},
choiceState() {
let num = 0;
let isPrimary = false;
@@ -114,8 +157,13 @@ export default {
};
},
choiceForm(choice, idx) {
if (choice)
if (choice) {
if (idx === 2) {
this.foundPerson = "";
this.sortData = [];
}
return (this.patientList.find((e) => e.id === idx).choice = false);
}
this.patientList.find((e) => e.id === idx).choice = true;
},
checkPerson(index, arr) {
@@ -150,6 +198,29 @@ export default {
arr.sort((a, b) => (b.last_name > a.last_name ? 1 : -1));
}
},
hideSidebar() {
this.patientList.forEach((e) => (e.choice = false));
},
scrollTo(event) {
if (
Math.abs(
event.currentTarget.scrollHeight -
event.currentTarget.clientHeight -
event.currentTarget.scrollTop
) < 1
)
return (this.isGradient = false);
this.isGradient = true;
},
},
watch: {
foundPerson: {
immediate: true,
handler(val) {
if (val && document.getElementById("persons").offsetHeight < 480)
this.isGradient = false;
},
},
},
};
</script>
@@ -168,17 +239,39 @@ export default {
background: var(--default-white)
border-radius: 4px
color: var(--font-dark-blue-color)
&:last-child
border-bottom-left-radius: 0.25rem
border-bottom-right-radius: 0.25rem
.expansion :deep(.q-item__section--side)
color: var(--font-dark-blue-color)
.expansion :deep(.q-icon)
font-size: 20px
.button-open
border: 1px solid var(--gray-secondary)
color: var(--font-grey-color)
background: var(--bg-light-grey)
.select
padding-bottom: 2px
&:last-child
padding-bottom: 16px
.h-55
height: 55px
.all-icon
height: 40px
width: 40px
border-radius: 50%
background: var(--surface-blue-big)
.status
border-radius: 4px
height: 28px
height: 40px
&:hover
background: var(--bg-light-grey)
background: var(--gray-thirdly)
cursor: pointer
.q-expansion-item
@@ -191,10 +284,14 @@ export default {
.patient :deep(.q-expansion-item__content)
padding-bottom: 0px
.btn
.sort-icon-default
background-color: var(--bg-light-grey)
color: var(--font-grey-color)
.sort-icon-active
background-color: var(--btn-blue-color)
color: var(--default-white)
#input :deep(.q-field__control)
height: 32px
.q-field__prepend
@@ -209,46 +306,112 @@ export default {
.q-expansion-item :deep(.q-item)
padding: 10px 16px !important
min-height: 54px
&:hover
opacity: 0.6
.text
.input-icon :deep(path)
fill: var(--font-grey-color) !important
.priority
height: 15px
width: 15px
.grey-color
color: var(--font-grey-color)
.q-expansion-item :deep(.q-item)
height: 54px
.expansion :deep(.q-focus-helper)
display: none
.expansion
&:deep(path)
fill: var(--font-dark-blue-color)
.none-priority
border: 1.5px solid var(--font-grey-color)
.red-color
background: var(--system-color-red)
.blue-color
background: var(--btn-blue-color)
.green-color
background: var(--system-color-green)
.person-wrapper
overflow-y: auto
margin-right: -10px
&::-webkit-scrollbar
width: 4px
&::-webkit-scrollbar-track:vertical
margin-top: -26px
margin-top: -40px
margin-bottom: 26px
.person
height: 56px
width: calc(100% - 10px)
height: 55px
width: calc(100% - 6px)
border-bottom: 1px solid var(--bg-light-grey)
&:first-child
border-top: 1px solid var(--bg-light-grey)
&:last-child
border-bottom: none
.one-form
max-height: calc(100vh - 394px)
max-height: calc(100vh - 382px)
transition: all 0.2s ease-in
.two-form
max-height: calc(100vh - 528px)
max-height: calc(100vh - 558px)
transition: all 0.2s ease-in
.all-form
max-height: calc(100vh - 632px)
max-height: calc(100vh - 694px)
transition: all 0.2s ease-in
.primary-form
max-height: calc(100vh - 498px)
max-height: calc(100vh - 518px)
transition: all 0.2s ease-in
.default
max-height: 0px
transition: all 0.5s ease-in
.input :deep(.q-field__prepend)
padding-right: 4px
.input :deep(.q-field__append)
padding-left: 6px
.gradient
border-bottom-left-radius: 0.25rem
border-bottom-right-radius: 0.25rem
width: 232px
height: 44px
right: 0px
bottom: 0px
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, var(--default-white) 100%)
.on-left
margin-right: 8px
.plus :deep(path)
fill: var(--default-white)
.medcard :deep(path)
fill: var(--font-grey-color)
.medcard-orange :deep(path)
fill: var(--bg-yellow-warning)
.medcard-green :deep(path)
fill: var(--system-color-green)
.icon-patients :deep(path)
fill: var(--btn-blue-color)
.sort-icon :deep(path)
fill: var(--font-grey-color)
</style>

View File

@@ -3,26 +3,29 @@
.header.w-full.flex.gap-x-2px.text-sm
.first-item.color-black.justify-center.gap-x-2(:class="timeClass")
span.font-semibold.color-black(v-if="expandedType || expandedTime") {{ recordTime }}
q-icon.cursor-pointer(
name="arrow_back_ios_new",
size="10px",
q-icon.cursor-pointer.arrow-icon(
name="app:left-arrow",
size="16px",
v-if="expandedTime",
@click.stop="changeTimeDisplay(false)"
)
q-icon.cursor-pointer(
q-icon.cursor-pointer.time-icon(
v-if="!expandedType && !expandedTime",
name="app:time",
size="16px",
size="20px",
@click.stop="changeTimeDisplay(true)"
)
.color-black.pl-4.flex-1.font-semibold.py-6px.relative(
.color-black.pl-4.flex-1.font-semibold.py-6px.relative.cursor-default(
:class="{'pl-6px collapsed-name': expandedTime}"
) {{trimPatientName(record?.member?.last_name, record?.member?.first_name, record?.member?.patronymic)}}
) {{trimPatientName(record?.person?.last_name, record?.person?.first_name, record?.person?.patronymic)}}
.gradient.absolute.w-5.h-full.right-0(v-if="expandedTime")
.info-block.justify-center
img.w-5.h-5(:src="recordingStatus?.icon")
.last-item.info-block.justify-center(v-if="expandedType")
img.w-5.h-5(:src="medicalСardStatus?.icon")
.info-block.justify-center(v-if="expandedType")
q-icon(
:name="record?.person?.has_medical_card ? 'app:medcard-green' : 'app:medcard'",
size="20px",
)
.last-item.info-block.justify-center
.recording-status(:class="recordingStatus?.class")
.body.background-grey.flex.flex-col.justify-between.pl-4.pr-2.color-grey(
:style="bodyHeight",
:class="bodyPadding"
@@ -30,21 +33,19 @@
.flex.gap-x-14(:class="bodyClass")
.flex.gap-x-2.items-center(
v-for="contact in contacts",
:key="contact.value",
:key="contact?.value",
)
q-icon(:name="contact.icon", size="14px")
.text-xxs {{ contact.value }}
.h-6.w-6.color-black.background-dark-grey.text-xxs.rounded.flex.items-center.justify-center(
v-if="collapsedDisplayCondition"
q-icon.network-icon(:name="contact?.icon", size="16px")
.text-xxs.cursor-default {{ contact?.value }}
.h-6.w-6.color-black.background-dark-grey.text-xxs.rounded.flex.items-center.justify-center.cursor-default(
v-if="collapsedDisplayCondition && contact"
) +1
span.text-xxs.self-end(v-if="record?.services.length && bodyClass?.['flex-col']") {{`${record?.services.length} услуг`}}
</template>
<script>
import * as moment from "moment/moment";
import {
recordingStatuses,
medicalСardStatuses,
statuses,
networks,
} from "@/pages/newCalendar/utils/calendarConfig.js";
import { trimName } from "@/pages/newCalendar/utils/calendarFunctions.js";
@@ -63,13 +64,27 @@ export default {
},
computed: {
contacts() {
let contactList = this.record?.member?.contacts
?.filter((elem) => elem.kind === "PHONE" || elem.kind === "EMAIL")
?.map((elem) => ({
kind: elem.kind,
icon: networks.find((item) => item.id === elem.kind)?.icon,
value: elem.value,
}));
let contactList = [];
this.record?.person?.contacts?.find((elem) => {
if (elem.category === "PHONE") {
contactList.push({
kind: elem?.category,
icon: networks?.find((item) => item.id === elem.category)?.icon,
value: elem?.value,
});
return true;
}
});
this.record?.person?.contacts?.find((elem) => {
if (elem.category === "EMAIL") {
contactList.push({
kind: elem?.category,
icon: networks?.find((item) => item.id === elem.category)?.icon,
value: elem?.value,
});
return true;
}
});
if (this.collapsedDisplayCondition) {
contactList.length = 1;
return contactList;
@@ -80,14 +95,10 @@ export default {
return !this.bodyClass?.["flex-col"] && !this.expandedType;
},
recordingStatus() {
return recordingStatuses.find(
const status = statuses?.[0]?.data?.find(
(elem) => elem.value === this.record?.status
);
},
medicalСardStatus() {
return medicalСardStatuses.find(
(elem) => elem.value === this.record?.medicalCard?.status
);
return status || statuses?.[0]?.data?.[0];
},
startTime() {
return moment.parseZone(this.record?.start);
@@ -199,4 +210,24 @@ export default {
.body
border-bottom-left-radius: 4px
border-bottom-right-radius: 4px
.network-icon :deep(path)
fill: var(--font-dark-blue-color-0)
.arrow-icon :deep(path)
fill: var(--font-dark-blue-color)
.time-icon :deep(path)
fill: var(--font-grey-color)
.recording-status
border-radius: 9999px
width: 17px
height: 17px
.not-accepted
border: 1.2px solid var(--font-grey-color)
.accepted
background-color: var(--system-color-green)
.rejected
background-color: var(--system-color-red)
.reception
background-color: var(--btn-blue-color)
span
cursor: default
</style>

View File

@@ -3,44 +3,46 @@
.header.flex.mb-6
.title.font-bold.text-xl.color-dark-blue Запись на {{ date }}, {{ time }}
.icons.flex.items-center.gap-x-3.-mt-5.-mr-4.p-1
q-icon.cursor-pointer(name="app:dots", size="18px", color="dark")
q-icon.cursor-pointer(name="app:cancel", size="18px", color="dark", @click="hidePreview")
q-icon.cursor-pointer.header-icon(name="app:dots", size="24px", color="dark")
q-icon.cursor-pointer.header-icon(name="app:cancel", size="24px", color="dark", @click="hidePreview")
.body.gap-y-4.text.text-sm
.flex.items-center.gap-x-3(v-for="field in previewConfig", :key="field?.title")
.field.color-grey.flex.items-center.justify-start.font-semibold {{ field?.title }}:
.info.flex-1.rounded.h-full.py-2.px-4.flex.items-center.gap-x-1.color-dark-blue(v-if="field?.data")
img.h-5.w-5(:src="field?.icon ? this[field?.icon] : ''", v-if="field?.icon")
//img.h-5.w-5(:src="field?.icon ? this[field?.icon] : ''", v-if="field?.icon")
span {{ field?.data ? this[field?.data] : "" }}
.flex.gap-x-1.flex-1(v-if="field?.title === 'Медкарта'")
.nameplate.rounded.px-4.pt-2.pb-1.flex.gap-x-2.info.flex-1
.flex.gap-x-1.flex-1(v-if="field?.title === 'Пациент'")
.nameplate.rounded.px-4.pt-2.pb-1.flex.gap-x-2.info.flex-1.items-center
q-avatar(size="40px")
img(:src="memberData?.photo")
img(:src="memberData?.photo ? memberData.photo : defaultImg")
.flex.flex-col.gap-y-2px
span.color-dark-blue {{ trimName(memberData?.last_name, memberData?.first_name, memberData?.patronymic) }}
span.color-grey {{ birthday }}
q-btn.flex-1(
color="primary",
no-caps,
label="Полная медкарта",
label="Медкарта",
:style="{'font-weight': 500}"
size="14px",
@click="openMedicalCard(memberData.id)"
)
q-icon.arrow(name="app:long-arrow", size="18px", right)
q-icon.arrow.ml-1(name="app:long-arrow", size="20px")
.flex.gap-x-1.flex-1.h-full(v-if="field?.title === 'Услуги'")
.rounded.h-full.services.flex.flex-wrap.gap-1.p-1
.py-2.px-4.color-dark-blue.rounded.h-7.relative(
v-for="chip in services.list",
:key="chip?.title",
:id="chip?.title",
:class="chipClass(chip?.title)"
:style="{'background-color': chip?.color}"
)
span {{chip?.title}}
.gradient.h-7.w-11.absolute.right-0(
:id="chip?.title+'gradient'",
:style="{background: `linear-gradient(270deg, ${chip?.color} 0%, rgba(255, 255, 255, 0.00) 100%)`}"
)
.info.color-dark-blue.rounded.h-7.px-4(v-if="services.remains > 0") +{{ services.remains }}
.rounded.info.color-grey.h-full.cost.flex.items-center.justify-center {{ services.cost }}
//.rounded.h-full.services.flex.flex-wrap.gap-1.p-1
// .py-2.px-4.color-dark-blue.rounded.h-7.relative(
// v-for="chip in services.list",
// :key="chip?.title",
// :id="chip?.title",
// :class="chipClass(chip?.title)"
// :style="{'background-color': chip?.color}"
// )
// span {{chip?.title}}
// .gradient.h-7.w-11.absolute.right-0(
// :id="chip?.title+'gradient'",
// :style="{background: `linear-gradient(270deg, ${chip?.color} 0%, rgba(255, 255, 255, 0.00) 100%)`}"
// )
// .info.color-dark-blue.rounded.h-7.px-4(v-if="services.remains > 0") +{{ services.remains }}
//.rounded.info.color-grey.h-full.cost.flex.items-center.justify-center {{ services.cost }} ₽
</template>
@@ -48,10 +50,11 @@
import * as moment from "moment/moment";
import { mapState } from "vuex";
import { trimName } from "@/pages/newCalendar/utils/calendarFunctions.js";
import { mapActions } from "vuex";
import defaultImg from "@/assets/images/person.png";
import {
recordList,
recordPreviewConfig,
recordingStatuses,
statuses,
} from "@/pages/newCalendar/utils/calendarConfig.js";
export default {
name: "CalendarRecordPreview",
@@ -60,6 +63,7 @@ export default {
},
data() {
return {
defaultImg,
previewConfig: recordPreviewConfig,
trimName: trimName,
};
@@ -75,9 +79,10 @@ export default {
},
...mapState({
selectedRecordId: (state) => state.calendar.selectedRecordId,
events: (state) => state.calendar.events || [],
}),
record() {
return recordList?.find((elem) => elem.id === this.selectedRecordId);
return this.events?.find((elem) => elem.id === this.selectedRecordId);
},
start() {
return moment.parseZone(this.record?.start);
@@ -92,34 +97,38 @@ export default {
return this.start?.format("HH:mm") + " " + this.end?.format("HH:mm");
},
statusLabel() {
return recordingStatuses.find(
(elem) => elem.value === this.record?.status
).label;
return statuses[0].data.find((elem) => elem.value === this.record?.status)
?.label;
},
statusIcon() {
return recordingStatuses.find(
(elem) => elem.value === this.record?.status
).icon;
return statuses[0].data.find((elem) => elem.value === this.record?.status)
?.icon;
},
memberData() {
return this.record?.member;
return this.record?.person;
},
birthday() {
return moment(this.memberData?.birth_date)?.format("MM.DD.YYYY");
},
services() {
let croppedServices = JSON.parse(JSON.stringify(this.record?.services));
let remains = this.record?.services?.length - 3;
if (remains > 0) croppedServices.length = 3;
else remains = 0;
return {
list: croppedServices,
remains: remains,
cost: this.record?.services?.reduce((acc, curr) => acc + curr.cost, 0),
};
},
// services() {
// let croppedServices = JSON.parse(JSON.stringify(this.record?.services));
// let remains = this.record?.services?.length - 3;
// if (remains > 0) croppedServices.length = 3;
// else remains = 0;
// return {
// list: croppedServices,
// remains: remains,
// cost: this.record?.services?.reduce((acc, curr) => acc + curr.cost, 0),
// };
// },
},
methods: {
openMedicalCard(id) {
this.getMedicalCardData({
personId: id,
successCallback: (id) => this.$router.push("medical-card/" + id),
});
},
hidePreview() {
this.internalPreview = false;
},
@@ -133,6 +142,9 @@ export default {
}
});
},
...mapActions({
getMedicalCardData: "getMedicalCardDataByPersonId",
}),
},
};
</script>
@@ -155,6 +167,8 @@ export default {
border-bottom: 4px solid var(--bg-aqua-blue)
.arrow
transform: rotate(180deg)
:deep(path)
fill: var(--default-white)
.cost
width: 82px
.services
@@ -172,4 +186,6 @@ export default {
white-space: nowrap
.gradient
display: none
.header-icon :deep(path)
fill: var(--font-dark-blue-color)
</style>

View File

@@ -1,25 +1,27 @@
<template lang="pug">
.sidebar.flex.flex-col.gap-y-1
.sidebar.flex.flex-col.gap-y-px
.button.flex.rounded-t
q-btn(
q-btn.button-open(
@click="openSidebar",
dense,
padding="8px",
style="color: var(--font-grey-color); background: var(--bg-light-grey)"
padding="8px"
)
img(:src="arrow")
.button.flex
base-button(width="40px", @click="createForm")
q-icon(name="app:plus", size="12px")
.button.flex.relative.btn-sidebar(v-for="svg in patientData.arrSvg")
q-btn.blue-hover(
v-click-outside="hideActive",
@click="()=>clickButton(svg.name)",
q-icon.plus(name="app:plus", size="24px")
.button.flex.relative.btn-sidebar.button-svg.cursor-pointer(
@click="()=>showActive(svg.name)",
v-for="svg in patientData.arrSvg"
v-click-outside="hideActive"
)
q-btn(
:class="{'active-btn': findActiveBtn(svg.name)}",
dense,
style="color: var(--font-grey-color); borderRadius: 50%",
style="borderRadius: 50%",
:padding="svg.name === 'group' ? '10.5px 7.5px' : '4px'"
)
calendar-sidebar-svg(:name-svg="svg.name", :active="svg.active")
calendar-sidebar-svg.svg(:name-svg="svg.name", :active="svg.active")
.separator.flex.absolute(v-show="allLeave")
.sidebar.flex-col.flex
.mark-top.flex.w-2.h-2
@@ -31,14 +33,13 @@
self="top right",
:style="{'margin-left': '8px !important'}"
)
.status-wrapper.flex.flex-col.gap-y-4.p-4
.font-bold.text-xm {{svg.text}}
.flex.flex-col.gap-2px
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7(
v-for="status in patientData.statuses",
v-close-popup
.modal-wrapper.flex.flex-col.gap-y-2
.font-bold.text-xm.px-2 {{svg.text}}
.flex.flex-col
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7.px-2(
v-for="status in patientData.statuses"
)
img(:src="status.icon")
.priority.rounded-full.flex.mr-1.5px(:class="choiceClass(status.id)")
span {{status.name}}
q-menu(
v-if="svg.name === 'medcard'",
@@ -46,16 +47,15 @@
self="top right",
:style="{'margin-left': '8px !important'}"
)
.fill-wrapper.flex.flex-col.gap-y-4.p-4
.font-bold.text-xm {{svg.text}}
.flex.flex-col.gap-2px
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7(
v-for="medical in medicalData",
v-close-popup
.modal-wrapper.flex.flex-col.gap-y-2
.font-bold.text-xm.px-2 {{svg.text}}
.flex.flex-col
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7.px-2(
v-for="medical in medicalData"
)
img(:src="medical.icon")
q-icon(:name="medical.icon", size="20px")
span {{medical.name}}
q-menu(
q-menu.overflow-hidden(
v-if="svg.name === 'group'",
anchor="center start",
self="top right",
@@ -63,37 +63,42 @@
)
.patient-wrapper.flex.flex-col.gap-y-4.px-4.pt-4
.font-bold.text-xm {{svg.text}}
.flex.flex-col.relative(:style="{height: '391px'}")
.flex.flex-col.relative(:style="{maxHeight: '391px'}")
.flex.flex-col.gap-y-2
.flex.h-8.w-full.items-center.justify-between
base-input(
base-input.input(
v-model="foundPerson",
debounce="10",
@keyup.enter="searchPerson",
@input="searchPerson",
id="input",
placeholder="Найти пациента...",
outlined,
:width="160",
iconLeft,
fontSize="12px",
lineHeight="16px",
textColor="var(--font-grey-color)"
:width="160"
size="S",
icon-left
)
q-icon(name="app:icon-search", size="16px", style="color: var(--font-grey-color)")
q-btn.btn.ml-2(
template(v-slot:iconLeft)
q-icon.input-icon(name="app:search", size="16px")
q-btn.ml-2(
@click="sortPerson(patientsData)",
style="color: var(--font-grey-color); background: var(--bg-light-grey)"
:style="{ width: '32px', height: '32px'}",
padding="0"
:style="{width: '32px', height: '32px', border: '1px solid var(--gray-secondary)'}",
padding="0",
:class="sortingClass"
)
img(:src="sort_word")
.flex.items-center.justify-between.font-medium.text-smm.h-10.py-2.cursor-pointer(
@click="checkAll(patientsData)"
calendar-sidebar-svg(name-svg="sort", :active="sort")
.flex.items-center.justify-between.font-medium.text-smm.h-55.py-2.cursor-pointer(
@click="checkAll(patientsData)",
v-if="!foundPerson"
)
span Все
.flex.items-center.gap-x-2
.all-icon.flex.items-center.justify-center
//- q-icon(name="app:patients")
calendar-sidebar-svg.p-6px(name-svg="group", active)
.flex.flex-col.font-medium
.text-smm Все
.grey-color.text.text-xsx {{ patientsData?.length + " пациентов" }}
img(v-if="selectAll(patientsData)", :src="icon_ok")
.person-wrapper.flex.flex-col
.person.items-center.flex.justify-between.py-2.cursor-pointer(
.person-wrapper.flex.flex-col(@scroll="scrollTo", id="persons")
.person.items-center.flex.justify-between.py-2.cursor-pointer.h-55(
v-for="(person, index) in choiceData(patientsData)",
@click="checkPerson(index, patientsData)"
)
@@ -101,21 +106,23 @@
img.h-10.w-10.object-cover.rounded-full(:src="person.avatar")
.flex.flex-col.font-medium
.text-smm {{trimOwnerName(person.last_name, person.first_name, person.patronymic)}}
.text.text-xsx {{person.birthday}}
.grey-color.text.text-xsx {{trimBirthday(person.birthday)}}
img.h-6.w-6(v-if="person.check", :src="icon_ok")
.gradient.flex.absolute
.gradient.flex.absolute(v-if="isGradient")
</template>
<script>
import * as moment from "moment";
import arrow from "@/assets/icons/double_left_arrow.svg";
import icon_ok from "@/assets/icons/icon_ok.svg";
import sort_word from "@/assets/icons/sort_word.svg";
import BaseInput from "@/components/base/BaseInput.vue";
import { patientData } from "@/pages/newCalendar/utils/calendarConfig.js";
import { patientList } from "@/pages/newCalendar/utils/calendarConfig.js";
import CalendarSidebarSvg from "@/pages/newCalendar/components/CalendarSidebarSvg.vue";
import { trimName } from "@/pages/newCalendar/utils/calendarFunctions.js";
import icon_patients from "@/assets/icons/person_group.svg";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "CalendarSidebar",
@@ -123,6 +130,7 @@ export default {
components: { BaseInput, CalendarSidebarSvg, BaseButton },
data() {
return {
icon_patients,
arrow,
icon_ok,
sort_word,
@@ -134,27 +142,52 @@ export default {
sortData: [],
sort: false,
trimOwnerName: trimName,
isGradient: true,
};
},
computed: {
allLeave() {
return this.patientData.arrSvg.find((e) => e.active)?.active
return this.patientData.arrSvg.find(({ active }) => active)?.active
? false
: true;
},
sortingClass() {
return this.sort
? {
"sort-icon-active": true,
}
: {
"sort-icon-default": true,
};
},
},
methods: {
findActiveBtn(value) {
return this.patientData.arrSvg.find(({ name }) => name === value)?.active
? true
: false;
},
hideActive() {
this.patientData.arrSvg.forEach((e) => {
if (e.active) e.active = false;
});
this.sortData = [];
this.foundPerson = "";
this.patientsData.forEach((e) => (e.check = false));
},
clickButton(name) {
this.patientData.arrSvg = this.patientData.arrSvg.map((e) => {
if (e.name === name) return { ...e, active: true };
return { ...e, active: false };
showActive(name) {
this.patientData.arrSvg.forEach((e) => {
if (e.name === name) e.active = !e.active;
});
},
choiceClass(priority) {
return {
"none-priority": !priority,
"red-color": priority === 1,
"blue-color": priority === 2,
"green-color": priority === 3,
};
},
checkPerson(index, arr) {
arr.map((e) => {
if (e.id === index) e.check = !e.check;
@@ -173,6 +206,9 @@ export default {
this.foundPerson.toLowerCase()
);
},
trimBirthday(birthday) {
return moment(birthday, "DD MM YYYY").format("DD MMMM YYYY");
},
choiceData(arr) {
return this.foundPerson ? this.sortData : arr;
},
@@ -185,6 +221,27 @@ export default {
arr.sort((a, b) => (b.last_name > a.last_name ? 1 : -1));
}
},
scrollTo(event) {
if (
Math.abs(
event.currentTarget.scrollHeight -
event.currentTarget.clientHeight -
event.currentTarget.scrollTop
) < 1
)
return (this.isGradient = false);
this.isGradient = true;
},
},
watch: {
foundPerson: {
immediate: true,
handler(val) {
if (val && document.getElementById("persons").offsetHeight < 296) {
this.isGradient = false;
}
},
},
},
};
</script>
@@ -199,56 +256,76 @@ export default {
background: var(--default-white)
align-items: center
justify-content: center
&:last-child
border-bottom-left-radius: 0.25rem
border-bottom-right-radius: 0.25rem
.btn-sidebar
&:hover
& .separator
display: flex
transition: 0.1s
opacity: 1
.status-wrapper
width: 232px
height: 188px
.fill-wrapper
height: 158px
.modal-wrapper
width: 232px
padding: 16px 8px 6px
.patient-wrapper
width: 232px
height: 445px
max-height: 445px
min-height: 102px
color: var(--font-dark-blue-color)
.h-55
height: 55px
.status
height: 28px
height: 40px
width: 100%
&:hover
height: 28px
background: var(--bg-light-grey)
height: 40px
background: var(--gray-thirdly)
cursor: pointer
.person-wrapper
overflow-y: auto
margin-right: -10px
max-height: 296px
&::-webkit-scrollbar
width: 4px
&::-webkit-scrollbar-track:vertical
margin-top: -48px
margin-bottom: 26px
margin-top: -40px
margin-bottom: 18px
.person
height: 56px
width: calc(100% - 10px)
border-bottom: 1px solid var(--bg-light-grey)
&:first-child
border-top: 1px solid var(--bg-light-grey)
.all-icon
height: 40px
width: 40px
border-radius: 50%
background: var(--surface-blue-big)
#input :deep(.q-field__control)
height: 32px
.q-field__prepend
height: 32px
.input :deep(.q-field__prepend)
padding-right: 4px
.input :deep(.q-field__append)
padding-left: 6px
.input-icon :deep(path)
fill: var(--font-grey-color)
.separator
display: none
transition: 0.1s
opacity: 0
z-index: 6
align-items: center
left: 72px
@@ -269,15 +346,67 @@ export default {
border-radius: 4px
color: var(--default-white)
// .q-btn .blue-hover
// transition: color 0.3s cubic-bezier(0.25,0.8,0.5,1), background-color 0.3s cubic-bezier(0.25,0.8,0.5,1)
// &:hover
// background: var(--bg-light-blue-color)
.gradient
width: 232px
height: 44px
right: 0px
bottom: 0px
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, var(--default-white) 100%)
.button-open
border: 1px solid var(--gray-secondary)
color: var(--font-grey-color)
background: var(--bg-light-grey)
.sort-icon-default
background-color: var(--bg-light-grey)
color: var(--font-grey-color)
border: 1px solid var(--gray-secondary)
.sort-icon-active
background-color: var(--btn-blue-color)
color: var(--default-white)
.active-btn
transition: background 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), opacity 0.4s cubic-bezier(0.25, 0.8, 0.5, 1)
background: var(--bg-light-blue-color)
.grey-color
color: var(--font-grey-color)
.q-btn :deep(.q-focus-helper)
display: none
.q-btn :deep(.q-ripple)
display: none
.plus :deep(path)
fill: var(--default-white)
.priority
height: 15px
width: 15px
.none-priority
border: 1.5px solid var(--font-grey-color)
.red-color
background: var(--system-color-red)
.blue-color
background: var(--btn-blue-color)
.green-color
background: var(--system-color-green)
.button-svg
&:hover
.svg :deep(.hover)
opacity: 1
transition: opacity 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), opacity 0.4s cubic-bezier(0.25, 0.8, 0.5, 1)
</style>
<style lang="sass">
.q-menu
box-shadow: -4px -4px 8px 0px rgba(9, 10, 21, 0.10), 4px 4px 8px 0px rgba(9, 10, 21, 0.10)
</style>

View File

@@ -1,17 +1,21 @@
<template lang="pug">
svg(:width="configSize[nameSvg].width" :height="configSize[nameSvg].height" :viewBox="`0 0 ${configSize[nameSvg].width} ${configSize[nameSvg].height}`" fill="none" xmlns="http://www.w3.org/2000/svg")
g(v-if="nameSvg === 'round'")
g.hover(v-if="nameSvg === 'round'", :opacity="active ? '1' : '0.6'")
path(opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M7.5 20C7.5 26.9036 13.0964 32.5 20 32.5C26.9036 32.5 32.5 26.9036 32.5 20C32.5 13.0964 26.9036 7.5 20 7.5C13.0964 7.5 7.5 13.0964 7.5 20ZM20 5C11.7157 5 5 11.7157 5 20C5 28.2843 11.7157 35 20 35C28.2843 35 35 28.2843 35 20C35 11.7157 28.2843 5 20 5Z" :fill="active ? '#4772F2' : '#9294A7'")
path(d="M10 20C10 14.4772 14.4772 10 20 10C25.5228 10 30 14.4772 30 20C30 25.5228 25.5228 30 20 30C14.4772 30 10 25.5228 10 20Z" :fill="active ? '#4772F2' : '#9294A7'")
g(v-if="nameSvg === 'medcard'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M14.221 7.30769C14.4088 6.00296 15.5381 5 16.9032 5H23.0968C24.4619 5 25.5912 6.00296 25.779 7.30769H29.2903C30.7868 7.30769 32 8.51308 32 10V32.3077C32 33.7946 30.7868 35 29.2903 35H10.7097C9.21316 35 8 33.7946 8 32.3077V10C8 8.51308 9.21316 7.30769 10.7097 7.30769H14.221ZM14.221 9.61538H10.7097C10.4959 9.61538 10.3226 9.78758 10.3226 10V32.3077C10.3226 32.5201 10.4959 32.6923 10.7097 32.6923H29.2903C29.5041 32.6923 29.6774 32.5201 29.6774 32.3077V10C29.6774 9.78758 29.5041 9.61538 29.2903 9.61538H25.779C25.5912 10.9201 24.4619 11.9231 23.0968 11.9231H16.9032C15.5381 11.9231 14.4088 10.9201 14.221 9.61538ZM16.9032 7.30769C16.6894 7.30769 16.5161 7.47989 16.5161 7.69231V9.23077C16.5161 9.44319 16.6894 9.61538 16.9032 9.61538H23.0968C23.3106 9.61538 23.4839 9.44319 23.4839 9.23077V7.69231C23.4839 7.47989 23.3106 7.30769 23.0968 7.30769H16.9032Z" :fill="active ? '#4772F2' : '#9294A7'")
path(d="M10.7097 9.61538H14.221C14.4088 10.9201 15.5381 11.9231 16.9032 11.9231H23.0968C24.4619 11.9231 25.5912 10.9201 25.779 9.61538H29.2903C29.5041 9.61538 29.6774 9.78758 29.6774 10V32.3077C29.6774 32.5201 29.5041 32.6923 29.2903 32.6923H10.7097C10.4959 32.6923 10.3226 32.5201 10.3226 32.3077V10C10.3226 9.78758 10.4959 9.61538 10.7097 9.61538Z" :fill="active ? '#4772F2' : '#9294A7'")
g(v-if="nameSvg === 'group'")
g.hover(v-if="nameSvg === 'medcard'", :opacity="active ? '1' : '0.6'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M14.221 7.30769C14.4088 6.00296 15.5381 5 16.9032 5H23.0968C24.4619 5 25.5912 6.00296 25.779 7.30769H29.2903C30.7868 7.30769 32 8.51308 32 10V32.3077C32 33.7946 30.7868 35 29.2903 35H10.7097C9.21317 35 8 33.7946 8 32.3077V10C8 8.51308 9.21316 7.30769 10.7097 7.30769H14.221ZM16.9032 7.30769C16.6894 7.30769 16.5161 7.47989 16.5161 7.69231V9.23077C16.5161 9.44319 16.6894 9.61538 16.9032 9.61538H23.0968C23.3106 9.61538 23.4839 9.44319 23.4839 9.23077V7.69231C23.4839 7.47989 23.3106 7.30769 23.0968 7.30769H16.9032Z" :fill="active ? '#4772F2' : '#9294A7'")
g.hover(v-if="nameSvg === 'group'", :opacity="active ? '1' : '0.6'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M0 23.6157C0 20.3869 2.6735 17.7695 5.97143 17.7695H16.0286C19.3265 17.7695 22 20.3869 22 23.6157V24.8464C22 26.036 21.015 27.0003 19.8 27.0003H2.2C0.984974 27.0003 0 26.036 0 24.8464V23.6157Z" :fill="active ? '#4772F2' : '#9294A7'")
path(d="M17.1272 8.68044C17.1272 12.0644 14.3839 14.8077 11 14.8077C7.616 14.8077 4.87275 12.0644 4.87275 8.68044C4.87275 5.29647 7.616 2.55322 11 2.55322C14.3839 2.55322 17.1272 5.29647 17.1272 8.68044Z" :fill="active ? '#4772F2' : '#9294A7'")
g(opacity="0.6")
path(d="M20.3457 12.077H27.66C30.0584 12.077 32.0028 14.04 32.0028 16.4616V17.3847C32.0028 18.2768 31.2865 19.0001 30.4028 19.0001H23.6888C22.357 16.8586 20.129 15.3317 17.5488 14.8961C18.2892 14.1192 18.8898 13.2091 19.3081 12.2029C19.6406 12.1206 19.9881 12.077 20.3457 12.077Z" :fill="active ? '#4772F2' : '#9294A7'")
path(d="M24.0677 9.83683C26.5477 9.83683 28.5582 7.82634 28.5582 5.34627C28.5582 2.8662 26.5477 0.855713 24.0677 0.855713C21.5876 0.855713 19.5771 2.8662 19.5771 5.34627C19.5771 7.82634 21.5876 9.83683 24.0677 9.83683Z" :fill="active ? '#4772F2' : '#9294A7'")
g(v-if="nameSvg === 'sort'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M5.76088 3.12494C6.10606 3.12494 6.38588 3.40476 6.38588 3.74994V14.5787L8.55012 12.0898C8.77662 11.8293 9.17139 11.8018 9.43186 12.0283C9.69233 12.2548 9.71988 12.6496 9.49338 12.91L6.23251 16.66C6.1138 16.7966 5.94178 16.8749 5.76088 16.8749C5.57998 16.8749 5.40795 16.7966 5.28925 16.66L2.02838 12.91C1.80188 12.6496 1.82942 12.2548 2.0899 12.0283C2.35037 11.8018 2.74514 11.8293 2.97164 12.0898L5.13588 14.5787V3.74994C5.13588 3.40476 5.4157 3.12494 5.76088 3.12494Z" :fill="active ? 'var(--default-white)' : '#9294A7'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M14.729 2.81763C14.9618 2.81763 15.1752 2.94695 15.283 3.15324L18.0222 8.39692C18.1821 8.70287 18.0636 9.08045 17.7577 9.24028C17.4517 9.4001 17.0741 9.28165 16.9143 8.9757L16.0583 7.33701H13.3998L12.5437 8.9757C12.3839 9.28165 12.0063 9.4001 11.7004 9.24028C11.3944 9.08045 11.276 8.70287 11.4358 8.39692L14.175 3.15324C14.2828 2.94695 14.4963 2.81763 14.729 2.81763ZM14.0528 6.08701H15.4053L14.729 4.79246L14.0528 6.08701Z" :fill="active ? 'var(--default-white)' : '#9294A7'")
path(fill-rule="evenodd" clip-rule="evenodd" d="M14.0513 10.2358C14.8116 10.071 15.6957 10.1295 16.3039 10.2174C16.6114 10.2619 16.8395 10.5254 16.8395 10.836V16.25C16.8395 16.5951 16.5597 16.875 16.2145 16.875C15.8693 16.875 15.5895 16.5951 15.5895 16.25V14.6599L12.9292 16.7421C12.6573 16.9549 12.2645 16.907 12.0518 16.6352C11.839 16.3634 11.8869 15.9705 12.1587 15.7578L14.3578 14.0366C14.2053 14.004 14.054 13.964 13.9078 13.9147C13.5445 13.7921 13.1658 13.5977 12.8743 13.2766C12.5702 12.9416 12.3977 12.5081 12.3977 11.9898C12.3977 11.4732 12.603 11.0528 12.9447 10.7511C13.2645 10.4687 13.6704 10.3184 14.0513 10.2358ZM15.5895 12.9233C15.1533 12.9047 14.6894 12.8591 14.3075 12.7303C14.0626 12.6476 13.8989 12.5455 13.7999 12.4365C13.7136 12.3414 13.6477 12.2111 13.6477 11.9898C13.6477 11.8351 13.6965 11.7548 13.772 11.6881C13.8695 11.6021 14.0441 11.5164 14.3162 11.4574C14.6968 11.3749 15.1581 11.3673 15.5895 11.3973V12.9233Z" :fill="active ? 'var(--default-white)' : '#9294A7'")
</template>
<script>
@@ -27,10 +31,9 @@ export default {
round: { width: 40, height: 40 },
medcard: { width: 40, height: 40 },
group: { width: 33, height: 27 },
sort: { width: 20, height: 20 },
},
};
},
};
</script>
<style lang="sass" scoped></style>

View File

@@ -1,291 +0,0 @@
<template lang="pug">
.schedule.flex-1.flex.flex-col.relative(
:style="{width: openSidebar ? 'calc(100vw - 320px)' : 'calc(100vw - 160px)'}"
)
calendar-header.w-full.mb-1(v-model="displayType")
.schedule-body.h-full.bg-white.w-full(:class="{rounded: !expandedDisplayType}")
.column-wrapper.flex.ml-20(:style="columnWrapperWidth")
calendar-column(
v-for="date in dateRange",
:key="date",
:date="date",
:style="columnHeight",
:expanded-display-type="expandedDisplayType",
:day-start-time="validateStartTime"
:day-end-time="validateEndTime"
)
.flex.relative(
:style="expandedDisplayType ? backgroundWrapperWidth : {}",
:class="{'border-bottom': expandedDisplayType}"
)
.time-coil-wrapper.left-0.-mt-12
calendar-clock-column(
:time-coil="timeCoil",
:current-time="currentTime",
:is-current-week="isCurrentWeek",
:day-end-time="validateEndTime"
)
.time-circle-indicator.left-74px.h-3.w-3.rounded-full.absolute(
v-if="isShownIndicator",
:style="circleIndicatorLocation"
)
span.time-line-indicator.block.left-20.absolute(
v-if="isShownIndicator",
:style="lineIndicatorLocation"
)
calendar-background.flex-1
.w-full.h-3.bg-white.footer(v-if="expandedDisplayType")
</template>
<script>
import CalendarHeader from "@/pages/newCalendar/components/CalendarHeader";
import CalendarBackground from "@/pages/newCalendar/components/CalendarBackground.vue";
import CalendarClockColumn from "@/pages/newCalendar/components/CalendarClockColumn.vue";
import CalendarColumn from "@/pages/newCalendar/components/CalendarColumn.vue";
import {
convertTime,
verifyTime,
} from "@/pages/newCalendar/utils/calendarFunctions.js";
import { mapState } from "vuex";
import * as moment from "moment/moment";
export default {
name: "CalendarWrapper",
components: {
CalendarHeader,
CalendarBackground,
CalendarClockColumn,
CalendarColumn,
},
props: {
openSidebar: Boolean,
},
data() {
return {
displayType: "expanded",
currentTime: "",
isCurrentWeek: true,
isShownIndicator: true,
timeCoil: [],
timer: null,
pixelsPerHour: 76,
};
},
computed: {
...mapState({
workingHours: (state) => state.calendar.workingHours,
selectedDates: (state) => state.calendar.selectedDates,
}),
hours() {
return convertTime(this.currentTime, 0, -6);
},
minutes() {
return convertTime(this.currentTime, 3, -3);
},
hoursMinutes() {
return this.currentTime.slice(0, -3);
},
pixelsPerMinute() {
return this.pixelsPerHour / 60;
},
backgroundHeight() {
return (
(this.validateEndTime - this.validateStartTime) * this.pixelsPerHour
);
},
expandedDisplayType() {
return this.displayType === "expanded";
},
dateRange() {
let diff = this.selectedDates?.to.diff(this.selectedDates?.from, "days");
let range = [];
for (let i = 0; i <= diff; i++) {
range.push(this.selectedDates?.from.clone().add(i, "day"));
}
return range;
},
validateStartTime() {
return verifyTime(this.workingHours.start);
},
validateEndTime() {
return verifyTime(this.workingHours.end);
},
columnHeight() {
return this.expandedDisplayType
? {
height: `${this.timeCoil.length * this.pixelsPerHour + 60}px`,
width: "380px",
}
: {
height: `${this.timeCoil.length * this.pixelsPerHour + 96}px`,
width: this.openSidebar
? `calc((100vw - 320px - 80px) / ${this.dateRange.length})`
: `calc((100vw - 160px - 80px) / ${this.dateRange.length})`,
};
},
columnWrapperWidth() {
return this.expandedDisplayType
? {
width: `${380 * this.dateRange.length}px`,
}
: {
width: this.openSidebar
? "calc(100vw - 320px - 80px)"
: "calc(100vw - 160px - 80px)",
};
},
backgroundWrapperWidth() {
return {
width: `${380 * this.dateRange.length + 80}px`,
};
},
lineIndicatorLocation() {
return {
top: `${this.calculateIndicatorLocation()}px`,
};
},
circleIndicatorLocation() {
return {
top: `${this.calculateIndicatorLocation() + 42}px`,
};
},
},
methods: {
changeCurrentTime() {
this.currentTime = moment().format("HH:mm:ss");
},
timeCoilInitialization() {
this.timeCoil = [];
for (let i = this.validateStartTime; i < this.validateEndTime; i++) {
if (
i === this.hours &&
this.hours !== this.validateEndTime &&
this.isCurrentWeek
) {
this.timeCoil.push(this.hoursMinutes);
} else this.timeCoil.push(`${i}:00`);
}
},
changeTimeCoil() {
this.timeCoil = this.timeCoil.map((elem) => {
if (convertTime(elem, 0, -3) === this.hours) {
return this.hoursMinutes;
}
return elem.slice(0, -3) + ":00";
});
},
startTimer() {
if (
this.hours >= this.validateStartTime &&
this.hours < this.validateEndTime
) {
this.timer = setInterval(() => {
this.changeCurrentTime();
this.changeTimeCoil();
}, 5000);
}
},
stopTimer() {
clearInterval(this.timer);
this.timer = null;
},
calculateIndicatorLocation() {
let newTime = this.currentTime
.split(":")
.map((elem) => parseInt(elem, 10));
let result =
(newTime[0] - this.validateStartTime) * this.pixelsPerHour +
newTime[1] * this.pixelsPerMinute;
if (result > this.backgroundHeight || result < 0) {
this.isShownIndicator = false;
return 0;
}
return result;
},
},
watch: {
currentTime() {
if (
this.hours === this.validateEndTime &&
this.minutes > 0 &&
this.timer
) {
this.stopTimer();
this.timeCoilInitialization();
}
},
selectedDates: {
deep: true,
handler(newValue) {
this.isCurrentWeek =
newValue?.from.isSame(moment().clone().startOf("week")) &&
newValue?.to.isSame(moment().clone().endOf("week"));
this.isShownIndicator = this.isCurrentWeek;
if (this.timer) {
this.stopTimer();
this.timeCoilInitialization();
}
if (this.isCurrentWeek) {
this.changeCurrentTime();
this.timeCoilInitialization();
this.startTimer();
}
},
},
},
mounted() {
this.changeCurrentTime();
this.timeCoilInitialization();
this.startTimer();
},
beforeUnmount() {
this.stopTimer();
},
};
</script>
<style lang="sass" scoped>
.schedule-body
overflow-x: auto
border-top-left-radius: 4px
border-top-right-radius: 4px
&::-webkit-scrollbar-track:horizontal
margin: 0 24px 0 24px
.background
background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)
.time-coil-wrapper
position: sticky
z-index: 5
background-color: var(--default-white)
padding-top: 38px
.column-wrapper
height: 60px
position: relative
background-color: var(--default-white)
.footer
border-bottom-left-radius: 4px
border-bottom-right-radius: 4px
.border-bottom
border-bottom: 4px solid var(--bg-ligth-blue-color)
.records-count
border-right: 1px solid var(--border-light-grey-color)
&:last-child
border-right: none
.border-top
border-top: 1px solid var(--border-light-grey-color)
.time-circle-indicator
background-color: var(--bg-event-red-color)
z-index: 5
.time-line-indicator
border-top: 1px solid var(--bg-event-red-color)
z-index: 4
width: calc(100% - 80px)
</style>

Some files were not shown because too many files have changed in this diff Show More