adata-ui 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/.editorconfig +12 -12
  2. package/.nuxtrc +1 -1
  3. package/.playground/app.config.ts +5 -5
  4. package/README.md +75 -75
  5. package/app.config.ts +4 -3
  6. package/app.vue +1 -0
  7. package/assets/styles/index.scss +104 -0
  8. package/assets/styles/modules/_base.scss +5 -0
  9. package/assets/styles/modules/_typography.scss +152 -0
  10. package/components/elements/README.md +1 -1
  11. package/components/elements/accordion/AAccordion.vue +13 -12
  12. package/components/elements/curve-block/ACurveBlock.vue +94 -19
  13. package/components/elements/feature-description/AFeatureDescription.vue +4 -4
  14. package/components/elements/illustrations/noAccess.vue +11 -2
  15. package/components/elements/photos-animation/APhotosAnimation.vue +3 -1
  16. package/components/elements/select/ASelect.vue +65 -9
  17. package/components/features/lang-switcher/lang-switcher.vue +8 -1
  18. package/components/features/payment/banner/BasicPlusLimitBanner.vue +104 -0
  19. package/components/features/payment/banner/PaymentBanner.vue +108 -0
  20. package/components/features/payment/process/PaymentKaspiQrSidePanel.vue +158 -0
  21. package/components/features/payment/process/PaymentKaspiRedirectSidePanel.vue +112 -0
  22. package/components/features/payment/process/PaymentMethodSidePanel.vue +121 -0
  23. package/components/features/payment/process/PaymentProcess.vue +138 -0
  24. package/components/features/payment/process/PaymentTopUpSidePanel.vue +130 -0
  25. package/components/features/pk-mobile-services/APkMobileServices.vue +21 -2
  26. package/components/forms/README.md +1 -1
  27. package/components/forms/checkbox/ACheckbox.vue +0 -2
  28. package/components/forms/radio-button/ARadioButton.vue +21 -13
  29. package/components/forms/request-demo/ARequestDemo.vue +21 -7
  30. package/components/modals/AConfirmationEmail.vue +40 -0
  31. package/components/modals/AnotherDeviceModal.vue +3 -2
  32. package/components/modals/ConnectingTariffModal.vue +0 -1
  33. package/components/modals/ContentNavigationModal.vue +148 -75
  34. package/components/modals/Insufficient-funds-modal.vue +5 -2
  35. package/components/modals/LimitReachedModal.vue +4 -3
  36. package/components/modals/ReportBugModal.vue +3 -3
  37. package/components/modals/Resend.vue +82 -0
  38. package/components/modals/SubmitApplicationModal.vue +4 -0
  39. package/components/modals/id/AuthModal.vue +78 -0
  40. package/components/modals/id/IdAutoLogoutModal.vue +45 -0
  41. package/components/modals/id/IdBanner.vue +58 -0
  42. package/components/modals/id/IdConfirmAccountOtpModal.vue +186 -0
  43. package/components/modals/id/IdConfirmSuccessfulModal.vue +41 -0
  44. package/components/modals/id/IdLoginModal.vue +316 -0
  45. package/components/modals/id/IdModals.vue +114 -0
  46. package/components/modals/id/IdNewPasswordModal.vue +129 -0
  47. package/components/modals/id/IdOtpInput.vue +155 -0
  48. package/components/modals/id/IdPasswordSuccessfulModal.vue +25 -0
  49. package/components/modals/id/IdRecoveryModal.vue +117 -0
  50. package/components/modals/id/IdRegistrationModal.vue +215 -0
  51. package/components/modals/id/IdResetPasswordOtpModal.vue +158 -0
  52. package/components/modals/id/IdTwoFactorModal.vue +130 -0
  53. package/components/navigation/README.md +1 -1
  54. package/components/navigation/bottom-navigation/ABottomNavigation.vue +34 -29
  55. package/components/navigation/footer/AFooter.vue +210 -57
  56. package/components/navigation/footer/ui/{new-footer-accordion.vue → a-footer-accordion.vue} +2 -4
  57. package/components/navigation/header/AHeader.vue +59 -51
  58. package/components/navigation/header/AlmatyContacts.vue +16 -14
  59. package/components/navigation/header/AstanaContacts.vue +13 -11
  60. package/components/navigation/header/CardGallery.vue +5 -4
  61. package/components/navigation/header/HeaderLink.vue +16 -8
  62. package/components/navigation/header/NavList.vue +21 -5
  63. package/components/navigation/header/ProductMenu.vue +8 -78
  64. package/components/navigation/header/ProfileMenu.vue +10 -5
  65. package/components/navigation/header/TopHeader.vue +2 -2
  66. package/components/navigation/mobile-navigation/AMobileNavigation.vue +3 -3
  67. package/components/navigation/pill-tabs/APillTabs.vue +18 -4
  68. package/components/navigation/pill-tabs/types.ts +1 -0
  69. package/components/navigation/side-navigation/ASideNavigation.vue +23 -21
  70. package/components/overlays/README.md +1 -1
  71. package/components/overlays/side-panel/ASidePanel.vue +439 -0
  72. package/components/overlays/tooltip/ATooltip.vue +149 -154
  73. package/components/utils/removeTrailingSlash.ts +7 -0
  74. package/composables/useBuyTariffs.ts +91 -0
  75. package/composables/useHeaderNavigationLinks.ts +174 -297
  76. package/composables/useIdModals.ts +36 -0
  77. package/composables/usePayment.ts +74 -0
  78. package/composables/useUrls.ts +21 -0
  79. package/eslint.config.mjs +45 -0
  80. package/icons/adata-logo.vue +1 -1
  81. package/icons/ai-assistant.vue +13 -0
  82. package/icons/akimat.vue +20 -0
  83. package/icons/arrow/arrow-bottom-left-on-square.vue +1 -1
  84. package/icons/arrow/arrow-circle-reset.vue +1 -1
  85. package/icons/arrow/arrow-corner.vue +1 -1
  86. package/icons/arrow/arrow-graph-down.vue +1 -1
  87. package/icons/arrow/arrow-graph-up.vue +1 -1
  88. package/icons/arrow/arrow-square-down.vue +1 -1
  89. package/icons/arrow/arrow-top-right-on-square.vue +1 -1
  90. package/icons/arrow-currency-gray.vue +1 -1
  91. package/icons/arrow-currency-green.vue +1 -1
  92. package/icons/arrow-currency-red.vue +1 -1
  93. package/icons/avatar.vue +1 -1
  94. package/icons/bank.vue +5 -0
  95. package/icons/block.vue +1 -1
  96. package/icons/bookmark/bookmark-filled.vue +1 -1
  97. package/icons/bookmark/bookmark.vue +1 -1
  98. package/icons/browsers/browser-duck.vue +1 -1
  99. package/icons/browsers/browser-google.vue +7 -1
  100. package/icons/browsers/browser-yandex.vue +1 -1
  101. package/icons/building-vector.vue +1 -1
  102. package/icons/calculator.vue +1 -1
  103. package/icons/calendar.vue +1 -1
  104. package/icons/car.vue +1 -1
  105. package/icons/chart-bar.vue +5 -0
  106. package/icons/chart-pie.vue +16 -0
  107. package/icons/check/check-circle.vue +1 -1
  108. package/icons/check/check.vue +1 -1
  109. package/icons/check/checkmark-circle.vue +1 -1
  110. package/icons/check-sb.vue +7 -0
  111. package/icons/checkbox/checkbox-active.vue +1 -1
  112. package/icons/checkbox/checkbox-empty.vue +1 -1
  113. package/icons/checkbox/checkbox-intermediate.vue +1 -1
  114. package/icons/chevron/chevron-down.vue +1 -1
  115. package/icons/chevron/chevron-left.vue +1 -1
  116. package/icons/chevron/chevron-right.vue +1 -1
  117. package/icons/chevron/chevron-up.vue +1 -1
  118. package/icons/chevron/double-chevron-right.vue +1 -1
  119. package/icons/clipboard-text.vue +1 -1
  120. package/icons/clock.vue +1 -1
  121. package/icons/company/company-bazis.vue +3 -3
  122. package/icons/company/company-bereke.vue +13 -13
  123. package/icons/company/company-bigroup.vue +5 -5
  124. package/icons/company/company-erg.vue +6 -6
  125. package/icons/company/company-forte.vue +11 -11
  126. package/icons/company/company-halyk.vue +4 -4
  127. package/icons/company/company-jusan.vue +20 -3
  128. package/icons/company/company-kaspi.vue +3 -3
  129. package/icons/company/company-mycar.vue +2 -2
  130. package/icons/company/company-samruk.vue +9 -9
  131. package/icons/company-egov-small.vue +1 -1
  132. package/icons/company.vue +1 -1
  133. package/icons/copy.vue +1 -1
  134. package/icons/currency/currency-dollar.vue +1 -1
  135. package/icons/currency/currency-down.vue +1 -1
  136. package/icons/currency/currency-eur.vue +1 -1
  137. package/icons/currency/currency-rub.vue +1 -1
  138. package/icons/currency/currency-tenge.vue +9 -0
  139. package/icons/currency/currency-usd.vue +1 -1
  140. package/icons/currency/currency-yuan.vue +1 -1
  141. package/icons/delete.vue +1 -1
  142. package/icons/document.vue +1 -1
  143. package/icons/download.vue +1 -1
  144. package/icons/edit.vue +1 -1
  145. package/icons/education.vue +1 -1
  146. package/icons/egov-small.vue +1 -1
  147. package/icons/excel-icon.vue +14 -0
  148. package/icons/expand-window.vue +1 -1
  149. package/icons/eye-closed.vue +1 -1
  150. package/icons/eye-open.vue +1 -1
  151. package/icons/eye-opened.vue +1 -1
  152. package/icons/file/file.vue +1 -1
  153. package/icons/filter.vue +1 -1
  154. package/icons/flag.vue +1 -1
  155. package/icons/gift.vue +1 -1
  156. package/icons/globe.vue +1 -1
  157. package/icons/google.vue +41 -0
  158. package/icons/hand/hand-thumb-up-filled.vue +1 -1
  159. package/icons/hand/hand-thumb-up.vue +1 -1
  160. package/icons/hand-with-phone/hand-with-phone-dark.vue +1 -1
  161. package/icons/hand-with-phone/hand-with-phone-light.vue +1 -1
  162. package/icons/handshake.vue +1 -1
  163. package/icons/hcheck.vue +1 -1
  164. package/icons/hdocument.vue +1 -1
  165. package/icons/history.vue +1 -1
  166. package/icons/horizontal-more.vue +1 -1
  167. package/icons/hot-line.vue +6 -0
  168. package/icons/hummer.vue +1 -1
  169. package/icons/info/info-circle.vue +1 -1
  170. package/icons/invoice.vue +1 -1
  171. package/icons/kaspi-qr.vue +13 -0
  172. package/icons/link-chain.vue +1 -1
  173. package/icons/link.vue +1 -1
  174. package/icons/linkedin.vue +24 -24
  175. package/icons/loader-circle.vue +1 -1
  176. package/icons/location.vue +1 -1
  177. package/icons/lock.vue +1 -1
  178. package/icons/logo.vue +1 -1
  179. package/icons/logout.vue +1 -1
  180. package/icons/magnify/magnifying-glass-minus.vue +1 -1
  181. package/icons/magnify/magnifying-glass-plus.vue +1 -1
  182. package/icons/magnify/magnifying-glass.vue +1 -1
  183. package/icons/mail.vue +1 -1
  184. package/icons/mailru.vue +34 -0
  185. package/icons/main-filter.vue +1 -1
  186. package/icons/map/map-pin-filled.vue +1 -1
  187. package/icons/map/map-pin-rect.vue +1 -1
  188. package/icons/map/map-pin.vue +1 -1
  189. package/icons/map-marker-start.vue +1 -1
  190. package/icons/medal.vue +1 -1
  191. package/icons/menu-filled.vue +1 -1
  192. package/icons/menu.vue +1 -1
  193. package/icons/message/message.vue +1 -1
  194. package/icons/minus/minus-circle.vue +1 -1
  195. package/icons/money.vue +1 -1
  196. package/icons/monitoring.vue +1 -1
  197. package/icons/moon.vue +1 -1
  198. package/icons/more.vue +1 -1
  199. package/icons/notification.vue +1 -1
  200. package/icons/paperclip.vue +1 -1
  201. package/icons/payment/payment-card.vue +1 -1
  202. package/icons/payment/payment-kaspi.vue +1 -1
  203. package/icons/person-vector.vue +1 -1
  204. package/icons/person-with-briefcase.vue +1 -1
  205. package/icons/phone-filled.vue +1 -1
  206. package/icons/phone.vue +1 -1
  207. package/icons/plus/plus-circle.vue +1 -1
  208. package/icons/plus/plus.vue +1 -1
  209. package/icons/profile.vue +1 -1
  210. package/icons/radio/radio-check.vue +1 -1
  211. package/icons/radio/radio-empty.vue +1 -1
  212. package/icons/receipt.vue +1 -1
  213. package/icons/sanctions.vue +8 -0
  214. package/icons/scales/scale.vue +1 -1
  215. package/icons/scales/scales.vue +1 -1
  216. package/icons/scales/standing-scales.vue +1 -1
  217. package/icons/search.vue +1 -1
  218. package/icons/share/share-alt.vue +1 -1
  219. package/icons/share/share.vue +1 -1
  220. package/icons/socials/face-book.vue +1 -1
  221. package/icons/socials/instagram.vue +1 -1
  222. package/icons/socials/telegram.vue +1 -1
  223. package/icons/socials/tik-tok.vue +1 -1
  224. package/icons/socials/youtube.vue +1 -1
  225. package/icons/sort/sort-asc.vue +1 -1
  226. package/icons/sort/sort-desc.vue +1 -1
  227. package/icons/splitting-arrows.vue +1 -1
  228. package/icons/star/star-filled.vue +1 -1
  229. package/icons/star/star-half-filled.vue +1 -1
  230. package/icons/star/star.vue +1 -1
  231. package/icons/sun.vue +14 -14
  232. package/icons/sviazi.vue +1 -1
  233. package/icons/tag.vue +1 -1
  234. package/icons/tasks.vue +10 -0
  235. package/icons/tender-search.vue +1 -1
  236. package/icons/toasts/check-circle-toast.vue +1 -1
  237. package/icons/toasts/warning-triangle-toast.vue +1 -1
  238. package/icons/trash.vue +1 -1
  239. package/icons/triangle.vue +1 -1
  240. package/icons/truck.vue +1 -1
  241. package/icons/user.vue +1 -1
  242. package/icons/users-focus.vue +1 -1
  243. package/icons/users.vue +1 -1
  244. package/icons/warning/warning-circle.vue +1 -1
  245. package/icons/warning/warning-triangle-filled.vue +1 -1
  246. package/icons/warning/warning-triangle.vue +1 -1
  247. package/icons/whatsapp.vue +1 -1
  248. package/icons/work-bag.vue +1 -1
  249. package/icons/work-case.vue +9 -0
  250. package/icons/work-search.vue +1 -1
  251. package/icons/work.vue +1 -1
  252. package/icons/x-mark.vue +1 -1
  253. package/icons/yandex.vue +28 -0
  254. package/illustrations/address-location.vue +1 -1
  255. package/illustrations/ball-with-chain.vue +1 -1
  256. package/illustrations/bill.vue +1 -1
  257. package/illustrations/buildings.vue +1 -1
  258. package/illustrations/calendar.vue +1 -1
  259. package/illustrations/chains.vue +1 -1
  260. package/illustrations/coin-percent.vue +1 -1
  261. package/illustrations/coins-stack.vue +1 -1
  262. package/illustrations/delete-dark.vue +1 -1
  263. package/illustrations/delete.vue +1 -1
  264. package/illustrations/doc-with-stamp.vue +1 -1
  265. package/illustrations/document.vue +1 -1
  266. package/illustrations/door.vue +1 -1
  267. package/illustrations/empty-box.vue +1 -1
  268. package/illustrations/empty-wallet.vue +1 -1
  269. package/illustrations/graph-in-coin.vue +1 -1
  270. package/illustrations/hammer.vue +1 -1
  271. package/illustrations/hand-cash.vue +1 -1
  272. package/illustrations/info.vue +1 -1
  273. package/illustrations/mail.vue +1 -1
  274. package/illustrations/ok.vue +1 -1
  275. package/illustrations/people-group.vue +1 -1
  276. package/illustrations/person-with-phone.vue +1 -1
  277. package/illustrations/person.vue +1 -1
  278. package/illustrations/phone-check.vue +1 -1
  279. package/illustrations/phone-payment-method.vue +1 -1
  280. package/illustrations/stop-hand.vue +1 -1
  281. package/illustrations/stop-sign.vue +1 -1
  282. package/illustrations/suit.vue +1 -1
  283. package/illustrations/suitcase.vue +1 -1
  284. package/illustrations/terminal-dark.vue +1 -1
  285. package/illustrations/terminal.vue +1 -1
  286. package/illustrations/trash-can.vue +1 -1
  287. package/illustrations/turn-on-tariff.vue +1 -1
  288. package/illustrations/two-persons.vue +1 -1
  289. package/lang/en.ts +475 -270
  290. package/lang/kk.ts +476 -271
  291. package/lang/ru.ts +315 -107
  292. package/layouts/default.vue +13 -13
  293. package/nuxt.config.ts +42 -14
  294. package/package.json +69 -53
  295. package/public/kaspi/logo.svg +4 -0
  296. package/shared/constans/pages.ts +17 -2
  297. package/tailwind.config.ts +163 -0
  298. package/vitest.config.ts +14 -0
  299. package/.eslintrc.cjs +0 -4
  300. package/.playground/app.vue +0 -9
  301. package/.playground/pages/index.vue +0 -13
  302. package/.prettierignore +0 -24
  303. package/.prettierrc +0 -10
  304. package/assets/styles/index.css +0 -226
  305. package/components/modals/AuthModal.vue +0 -50
  306. package/components/navigation/footer/NewFooter.vue +0 -276
  307. package/components/navigation/footer/ui/footer-acccordion.vue +0 -119
@@ -24,6 +24,7 @@ import IconMedal from "#adata-ui/icons/medal.vue";
24
24
 
25
25
  import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'
26
26
  import {PAGES} from "#adata-ui/shared/constans/pages";
27
+ import { useUrls } from '#adata-ui/composables/useUrls'
27
28
 
28
29
  type Modules = 'counterparty' | 'work' | 'tender' | 'fines' | 'analytics'
29
30
 
@@ -43,6 +44,7 @@ const props = withDefaults(defineProps<Props>(), {
43
44
  zIndex: 'auto'
44
45
  })
45
46
  const { myLayer }: any = useAppConfig()
47
+ const urls = useUrls()
46
48
 
47
49
  const activeModule = ref<Modules | null>(null)
48
50
  const bottom = ref<HTMLElement | null>(null)
@@ -98,37 +100,37 @@ const sideLinks = {
98
100
  {
99
101
  icon: IconSearch,
100
102
  label: "Проверка контрагентов",
101
- link: myLayer.pkUrl + PAGES.pk.main
103
+ link: urls.pk + PAGES.pk.main
102
104
  },
103
105
  {
104
106
  icon: IconScales,
105
107
  label: "Сравнение контрагентов",
106
- link: myLayer.counterParty ? myLayer.pkUrl + myLayer.counterParty + PAGES.pk.compare : myLayer.pkUrl + PAGES.pk.compare
108
+ link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.compare : urls.pk + PAGES.pk.compare
107
109
  },
108
110
  {
109
111
  icon: IconLink,
110
112
  label: "Косвенные связи",
111
- link: myLayer.counterParty ? myLayer.pkUrl + myLayer.counterParty + '/search-connections/check' : myLayer.pkUrl + PAGES.pk.connections
113
+ link: myLayer.counterParty ? urls.pk + myLayer.counterParty + '/search-connections/check' : urls.pk + PAGES.pk.connections
112
114
  },
113
115
  {
114
116
  icon: IconUsers,
115
117
  label: "Массовая проверка",
116
- link: myLayer.counterParty ? myLayer.pkUrl + myLayer.counterParty + PAGES.pk.employees : myLayer.pkUrl + PAGES.pk.employees
118
+ link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.employees : urls.pk + PAGES.pk.employees
117
119
  },
118
120
  {
119
121
  icon: IconGlobe,
120
122
  label: "Зарубежные контрагенты",
121
- link: myLayer.pkUrl + PAGES.pk.foreign
123
+ link: urls.pk + PAGES.pk.foreign
122
124
  },
123
125
  {
124
126
  icon: IconBlock,
125
127
  label: "Санкции",
126
- link: myLayer.counterParty ? myLayer.pkUrl + myLayer.counterParty + PAGES.pk.sanctions : myLayer.pkUrl + PAGES.pk.sanctions
128
+ link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.sanctions : urls.pk + PAGES.pk.sanctions
127
129
  },
128
130
  {
129
131
  icon: IconDollar,
130
132
  label: "Офшоры",
131
- link: myLayer.counterParty ? myLayer.pkUrl + myLayer.counterParty + PAGES.pk.offshore : myLayer.pkUrl + PAGES.pk.offshore
133
+ link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.offshore : urls.pk + PAGES.pk.offshore
132
134
  },
133
135
  {
134
136
  icon: IconDocument,
@@ -138,80 +140,80 @@ const sideLinks = {
138
140
  {
139
141
  icon: IconArrowCircle,
140
142
  label: "Выгрузка данных",
141
- link: myLayer.pkUrl + PAGES.pk.unload
143
+ link: urls.pk + PAGES.pk.unload
142
144
  }
143
145
  ],
144
146
  work: [
145
147
  {
146
148
  icon: IconWork,
147
149
  label: "Вакансии",
148
- link: myLayer.workUrl + PAGES.work.vacancy
150
+ link: urls.work + PAGES.work.vacancy
149
151
  },
150
152
  {
151
153
  icon: IconDocument,
152
154
  label: "Резюме",
153
- link: myLayer.workUrl + PAGES.work.summary
155
+ link: urls.work + PAGES.work.summary
154
156
  },
155
157
  ],
156
158
  tender: [
157
159
  {
158
160
  icon: IconSearch,
159
161
  label: "Поиск тендеров",
160
- link: myLayer.tenderUrl + PAGES.tender.main
162
+ link: urls.tender + PAGES.tender.main
161
163
  },
162
164
  {
163
165
  icon: IconFile,
164
166
  label: "Поиск договоров",
165
- link: myLayer.tenderUrl + PAGES.tender.contracts
167
+ link: urls.tender + PAGES.tender.contracts
166
168
  },
167
169
  {
168
170
  icon: IconCheck,
169
171
  label: "Планы закупок",
170
- link: myLayer.tenderUrl + PAGES.tender.plans
172
+ link: urls.tender + PAGES.tender.plans
171
173
  }
172
174
  ],
173
175
  fines: [
174
176
  {
175
177
  icon: IconCheckCircle,
176
178
  label: "Проверка штрафов",
177
- link: myLayer.avtoUrl + PAGES.fines.main
179
+ link: urls.avto + PAGES.fines.main
178
180
  },
179
181
  {
180
182
  icon: IconCar,
181
183
  label: "Проверка авто",
182
- link: myLayer.avtoUrl + PAGES.fines.avto
184
+ link: urls.avto + PAGES.fines.avto
183
185
  },
184
186
  {
185
187
  icon: IconTruck,
186
188
  label: "Массовая проверка авто",
187
- link: myLayer.avtoUrl + PAGES.fines.bulk
189
+ link: urls.avto + PAGES.fines.bulk
188
190
  }
189
191
  ],
190
192
  analytics: [
191
193
  {
192
194
  icon: IconSearch,
193
195
  label: "Поиск клиентов",
194
- link: myLayer.analyticsUrl + PAGES.analytics.clients
196
+ link: urls.analytics + PAGES.analytics.clients
195
197
  },
196
198
  {
197
199
  icon: IconCheck,
198
200
  label: "Анализ закупок",
199
- link: myLayer.analyticsUrl + PAGES.analytics.analysis
201
+ link: urls.analytics + PAGES.analytics.analysis
200
202
  },
201
203
  {
202
204
  icon: IconArrowGraph,
203
205
  label: "Индекс деловой активности",
204
- link: myLayer.analyticsUrl + PAGES.analytics.index
206
+ link: urls.analytics + PAGES.analytics.index
205
207
  },
206
208
  {
207
209
  icon: IconCompany,
208
210
  label: "Субьекты бизнеса",
209
- link: myLayer.analyticsUrl + PAGES.analytics.business
211
+ link: urls.analytics + PAGES.analytics.business
210
212
  },
211
213
  {
212
214
  icon: IconMedal,
213
215
  label: "Рейтинг налогоплательщиков",
214
- link: myLayer.analyticsUrl + PAGES.analytics.rating
216
+ link: urls.analytics + PAGES.analytics.rating
215
217
  }
216
218
  ],
217
219
  }
@@ -1 +1 @@
1
- # tooltip, popover, slide over, modal, context menu
1
+ # tooltip, popover, slide over, modal, context menu
@@ -0,0 +1,439 @@
1
+ <script setup lang="ts">
2
+ import {disableBodyScroll, enableBodyScroll} from 'body-scroll-lock';
3
+ import {useAdaptive} from "~/composables/useAdaptive";
4
+
5
+ type Side = 'top' | 'right' | 'bottom' | 'left'
6
+ const props = withDefaults(defineProps<{
7
+ idName?: string
8
+ hideCloseBtn?: boolean
9
+ noClose?: boolean
10
+ side?: Side
11
+ rerender?: boolean
12
+ zIndex?: number | 'auto'
13
+ width?: string
14
+ height?: string
15
+ lockScroll?: boolean
16
+ lockScrollHtml?: boolean
17
+ hideScrollbar?: boolean
18
+ overlayColor?: string
19
+ overlayOpacity?: number
20
+ overlayDuration?: number
21
+ panelColor?: string
22
+ panelDuration?: number
23
+ transitionName?: string
24
+ headerClass?: string
25
+ bodyClass?: string
26
+ footerClass?: string
27
+ }>(), {
28
+ idName: "vsp-container",
29
+ side: "right",
30
+ zIndex: "auto",
31
+ width: "auto",
32
+ height: "auto",
33
+ lockScroll: true,
34
+ hideScrollbar: false,
35
+ overlayColor: "black",
36
+ overlayOpacity: 0.5,
37
+ overlayDuration: 500,
38
+ panelColor: "bg-white dark:bg-gray-900",
39
+ panelDuration: 300
40
+ })
41
+
42
+ defineEmits<{
43
+ (e: 'opened'): void
44
+ (e: 'closed'): void
45
+ }>()
46
+ const modelValue = defineModel()
47
+
48
+ let teleportContainer: HTMLDivElement | undefined = undefined
49
+ const panel = ref<HTMLElement | null>(null)
50
+ const overlay = ref<HTMLElement | null>(null)
51
+ const footer = ref<HTMLElement | null>(null)
52
+ const header = ref<HTMLElement | null>(null)
53
+ const body = ref<HTMLElement | null>(null)
54
+ const panelSide = ref<Side>(props.side)
55
+
56
+
57
+ const device = useAdaptive()
58
+
59
+ const zIndex = ref<number>();
60
+ const isBodyAlreadyLocked = ref(false);
61
+
62
+ const attrs = useAttrs()
63
+
64
+ const closePanel = () => modelValue.value = false
65
+
66
+ const lockUnlockBodyScroll = (elem: HTMLElement, lock: boolean) => {
67
+ if (lock) {
68
+ setTimeout(() => {
69
+ disableBodyScroll(elem, {
70
+ reserveScrollBarGap: true,
71
+ allowTouchMove: elem && elem !== document.body
72
+ })
73
+ disableBodyScroll(elem, {reserveScrollBarGap: true})
74
+ if (props.lockScrollHtml) document.documentElement.style.overflow = 'hidden'
75
+ }, 0)
76
+ return
77
+ }
78
+ enableBodyScroll(elem)
79
+ if (props.lockScrollHtml) document.documentElement.style.removeProperty('overflow')
80
+ }
81
+
82
+ const getMaxZIndex = () =>
83
+ Math.max(
84
+ ...Array.from(document.querySelectorAll('body *'), (el) =>
85
+ parseFloat(window.getComputedStyle(el).zIndex),
86
+ ).filter((zIndex) => !Number.isNaN(zIndex)),
87
+ 0,
88
+ );
89
+
90
+ onMounted(() => {
91
+ zIndex.value = props.zIndex === 'auto' ? getMaxZIndex() : props.zIndex
92
+
93
+ const alreadyCreatedTarget = document.getElementById(props.idName)
94
+ if (!!alreadyCreatedTarget) return
95
+ teleportContainer = document.createElement('div')
96
+ teleportContainer.setAttribute('id', props.idName)
97
+ document.body.appendChild(teleportContainer)
98
+ })
99
+
100
+ onBeforeUnmount(() => {
101
+ if (props.lockScroll && panel.value && modelValue.value) lockUnlockBodyScroll(panel.value, false)
102
+ if (teleportContainer) document.body.removeChild(teleportContainer)
103
+ })
104
+
105
+ watch(() => device.value, () => {
106
+ panelSide.value = device.value.isTablet || device.value.isSmallTablet ? 'bottom': props.side
107
+ }, { immediate: true })
108
+
109
+ watch(() => [modelValue.value, panel.value], (newP, oldP) => {
110
+ const wasShown = oldP ? (oldP[0] as boolean) : false
111
+ const [isShown, panelEl] = newP
112
+ const isOpening = isShown
113
+ const isClosing = wasShown && !isShown
114
+ if (!panelEl) return
115
+ // if (isOpening) isBodyAlreadyLocked.value = !!document.body.style.overflow
116
+
117
+ if (isShown) {
118
+ if (props.lockScroll) lockUnlockBodyScroll(panelEl, true)
119
+ return;
120
+ }
121
+
122
+ if (!props.lockScroll || !isClosing || isBodyAlreadyLocked.value) return;
123
+
124
+ setTimeout(() => {
125
+ if (panelEl) lockUnlockBodyScroll(panelEl, false)
126
+ }, props.panelDuration)
127
+ }, {immediate: true})
128
+
129
+ const roundedClass = computed(() => {
130
+ const classes = {
131
+ left: "rounded-r-xl",
132
+ right: "rounded-l-xl",
133
+ top: "rounded-b-xl",
134
+ bottom: "rounded-t-xl",
135
+ }
136
+
137
+ return classes[panelSide.value]
138
+ })
139
+
140
+ const overlayStyles = computed(() => ({
141
+ zIndex: zIndex.value,
142
+ animationDuration: `${props.overlayDuration}ms`,
143
+ '--overlay-opacity': props.overlayOpacity,
144
+ opacity: modelValue.value ? props.overlayOpacity : 0,
145
+ backgroundColor: props.overlayColor,
146
+ pointerEvents: !modelValue.value ? 'none' : 'all',
147
+ }));
148
+
149
+ const panelStyles = computed(() => ({
150
+ width: ['left', 'right'].includes(panelSide.value) ? props.width : undefined,
151
+ maxWidth: '100%',
152
+
153
+ ...(['top', 'bottom'].includes(panelSide.value)
154
+ ? {
155
+ height: device.value.isSmallTablet || device.value.isTablet ? '100%' : props.height,
156
+ maxHeight: device.value.isMobile ? '90%': '100%',
157
+ }
158
+ : {}),
159
+
160
+ zIndex: zIndex.value,
161
+ animationDuration: `${props.panelDuration}ms`,
162
+
163
+ ...Object.assign({}, attrs.style),
164
+ }));
165
+ // Mobile swipe
166
+ const positionStart = ref<number>(0)
167
+ const isClose = ref<boolean>(false)
168
+ const modalHeight = ref(0)
169
+
170
+ const touchstart = (event: TouchEvent) => {
171
+ isClose.value = false
172
+ positionStart.value = event.touches[0].clientY
173
+ modalHeight.value = panel.value?.offsetHeight || 0 // Запоминаем текущую высоту модалки
174
+ }
175
+
176
+ const touchmove = (event: TouchEvent) => {
177
+ if (!device.value.isSmallTablet && !device.value.isTablet) return
178
+ event.preventDefault();
179
+ const touchPosition = event.touches[0].clientY
180
+ const step = touchPosition - positionStart.value
181
+
182
+ if (step < 0) return // предотвратить движение вверх
183
+
184
+ const newHeight = modalHeight.value - step
185
+ panel.value.style.height = `${newHeight}px`
186
+ isClose.value = step > 65
187
+ }
188
+
189
+ const touchend = () => {
190
+ if (isClose.value) {
191
+ closePanel()
192
+ } else {
193
+ panel.value.style.height = `${modalHeight.value}px`
194
+ }
195
+ }
196
+ </script>
197
+
198
+ <template>
199
+ <client-only>
200
+ <Teleport :to="`#${idName}`">
201
+ <div class="vsp-wrapper" :class="[modelValue && 'vsp-wrapper--active']">
202
+ <Transition name="overlay">
203
+ <div
204
+ v-show="modelValue"
205
+ ref="overlay"
206
+ class="vsp-overlay fixed top-0 left-0 w-full h-full"
207
+ :style="overlayStyles"
208
+ @click="() => (noClose ? undefined: closePanel())"
209
+ />
210
+ </Transition>
211
+ <Transition
212
+ :name="transitionName || `slide-${panelSide}`"
213
+ @after-enter="$emit('opened')"
214
+ @after-leave="$emit('closed')">
215
+ <div
216
+ v-if="rerender ? modelValue : true"
217
+ v-show="rerender ? true: modelValue"
218
+ ref="panel"
219
+ class="vsp fixed flex flex-col"
220
+ :class="[`vsp--${panelSide}-side`, $attrs.class, roundedClass, panelColor]"
221
+ :style="panelStyles"
222
+ >
223
+ <div
224
+ class="w-full flex justify-center items-center mt-1 lg:hidden"
225
+ @touchmove="touchmove"
226
+ @touchstart="touchstart"
227
+ @touchend="touchend"
228
+ >
229
+ <div class="h-1 w-10 bg-[#D9D9D9] rounded m-1" />
230
+ </div>
231
+ <div
232
+ :class="roundedClass"
233
+ class="absolute w-8 px-2 py-4 bg-blue-700 text-white -left-8 top-8 cursor-pointer lg:block hidden"
234
+ v-if="!hideCloseBtn"
235
+ @click="closePanel"
236
+ >
237
+ <a-icon-x-mark />
238
+ </div>
239
+ <div v-if="!!$slots.header" ref="header"
240
+ @touchmove="touchmove"
241
+ @touchstart="touchstart"
242
+ @touchend="touchend"
243
+ :class="[headerClass, 'vsp__header border-b border-deepblue-100 dark:border-[#E3E5E80D] lg:px-8 p-4']">
244
+ <slot name="header" :close="closePanel"/>
245
+ </div>
246
+ <div
247
+ ref="body"
248
+ :class="[
249
+ bodyClass,
250
+ 'vsp__body overflow-y-auto relative flex-grow-1 h-full lg:px-8 p-4',
251
+ hideScrollbar ? 'vsp__body--hide-scroll' : '',
252
+ ]"
253
+ >
254
+ <slot name="default" :close="closePanel"/>
255
+ </div>
256
+ <div v-if="!!$slots.footer" ref="footer"
257
+ :class="[footerClass, 'vsp__footer border-t border-deepblue-100 dark:border-[#E3E5E80D] lg:px-8 p-4']">
258
+ <slot name="footer"/>
259
+ </div>
260
+ </div>
261
+ </Transition>
262
+ </div>
263
+ </Teleport>
264
+ </client-only>
265
+ </template>
266
+
267
+ <style scoped lang="scss">
268
+ .vsp-wrapper {
269
+ .vsp {
270
+ &--right-side,
271
+ &--left-side {
272
+ top: 0;
273
+ height: 100%;
274
+ }
275
+
276
+ &--right-side {
277
+ right: 0;
278
+ left: unset;
279
+ }
280
+
281
+ &--left-side {
282
+ right: unset;
283
+ left: 0;
284
+ }
285
+
286
+ &--bottom-side,
287
+ &--top-side {
288
+ left: 0;
289
+ width: 100%;
290
+ }
291
+
292
+ &--bottom-side {
293
+ bottom: 0;
294
+ }
295
+
296
+ &--top-side {
297
+ top: 0;
298
+ }
299
+
300
+ &__body {
301
+ &.overflow-y-auto::-webkit-scrollbar {
302
+ width: 8px;
303
+ }
304
+
305
+ &.overflow-y-auto::-webkit-scrollbar-thumb {
306
+ background: #2C3E5033;
307
+ border-radius: 6px;
308
+ }
309
+
310
+ &.vsp__body--hide-scroll {
311
+ scrollbar-width: none;
312
+
313
+ &::-webkit-scrollbar {
314
+ width: 0;
315
+ height: 0;
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ .overlay-enter-active,
322
+ .overlay-leave-active {
323
+ animation: overlay-transition;
324
+ }
325
+
326
+ .overlay-leave-active {
327
+ animation-direction: reverse;
328
+ }
329
+
330
+ .slide-right-enter-active,
331
+ .slide-right-leave-active {
332
+ animation: slide-right;
333
+ }
334
+
335
+ .slide-right-leave-active {
336
+ animation-direction: reverse;
337
+ }
338
+
339
+ .slide-left-enter-active,
340
+ .slide-left-leave-active {
341
+ animation: slide-left;
342
+ }
343
+
344
+ .slide-left-leave-active {
345
+ animation-direction: reverse;
346
+ }
347
+
348
+ .slide-top-enter-active,
349
+ .slide-top-leave-active {
350
+ animation: slide-left;
351
+ }
352
+
353
+ .slide-top-leave-active {
354
+ animation-direction: reverse;
355
+ }
356
+
357
+ .slide-top-enter-active,
358
+ .slide-top-leave-active {
359
+ animation: slide-top;
360
+ }
361
+
362
+ .slide-top-leave-active {
363
+ animation-direction: reverse;
364
+ }
365
+
366
+ .slide-bottom-enter-active,
367
+ .slide-bottom-leave-active {
368
+ animation: slide-bottom;
369
+ }
370
+
371
+ .slide-bottom-leave-active {
372
+ animation-direction: reverse;
373
+ }
374
+
375
+ @keyframes slide-right {
376
+ 0% {
377
+ transform: translateX(100%);
378
+ opacity: 0;
379
+ }
380
+ 100% {
381
+ transform: translateX(0);
382
+ opacity: 1;
383
+ }
384
+ }
385
+
386
+ @keyframes slide-left {
387
+ 0% {
388
+ transform: translateX(-100%);
389
+ opacity: 0;
390
+ }
391
+ 100% {
392
+ transform: translateX(0);
393
+ opacity: 1;
394
+ }
395
+ }
396
+
397
+ @keyframes slide-bottom {
398
+ 0% {
399
+ transform: translateY(100%);
400
+ opacity: 0;
401
+ }
402
+ 100% {
403
+ transform: translateY(0);
404
+ opacity: 1;
405
+ }
406
+ }
407
+
408
+ @keyframes slide-top {
409
+ 0% {
410
+ transform: translateY(-100%);
411
+ opacity: 0;
412
+ }
413
+ 100% {
414
+ transform: translateY(0);
415
+ opacity: 1;
416
+ }
417
+ }
418
+
419
+ @keyframes slide-top {
420
+ 0% {
421
+ transform: translateY(-100%);
422
+ opacity: 0;
423
+ }
424
+ 100% {
425
+ transform: translateY(0);
426
+ opacity: 1;
427
+ }
428
+ }
429
+
430
+ @keyframes overlay-transition {
431
+ 0% {
432
+ opacity: 0;
433
+ }
434
+ 100% {
435
+ opacity: var(--overlay-opacity);
436
+ }
437
+ }
438
+ }
439
+ </style>