adata-ui 3.1.50 → 3.1.51

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 (42) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +14 -1
  3. package/dist/runtime/components/SidePanel.vue +370 -0
  4. package/dist/runtime/components/SidePanel.vue.d.ts +68 -0
  5. package/dist/runtime/components/payment/process/PaymentKaspiQrSidePanel.vue +148 -0
  6. package/dist/runtime/components/payment/process/PaymentKaspiQrSidePanel.vue.d.ts +21 -0
  7. package/dist/runtime/components/payment/process/PaymentKaspiRedirectSidePanel.vue +97 -0
  8. package/dist/runtime/components/payment/process/PaymentKaspiRedirectSidePanel.vue.d.ts +20 -0
  9. package/dist/runtime/components/payment/process/PaymentMethodSidePanel.vue +106 -0
  10. package/dist/runtime/components/payment/process/PaymentMethodSidePanel.vue.d.ts +21 -0
  11. package/dist/runtime/components/payment/process/PaymentProcess.vue +112 -0
  12. package/dist/runtime/components/payment/process/PaymentProcess.vue.d.ts +2 -0
  13. package/dist/runtime/components/payment/process/PaymentTopUpSidePanel.vue +117 -0
  14. package/dist/runtime/components/payment/process/PaymentTopUpSidePanel.vue.d.ts +15 -0
  15. package/dist/runtime/composables/useAdaptive.d.ts +8 -0
  16. package/dist/runtime/composables/useAdaptive.js +27 -0
  17. package/dist/runtime/composables/usePayment.d.ts +8 -0
  18. package/dist/runtime/composables/usePayment.js +66 -0
  19. package/dist/runtime/i18n/i18n.config.d.ts +120 -0
  20. package/dist/runtime/icons/chevron/chevron-down.vue +16 -0
  21. package/dist/runtime/icons/chevron/chevron-down.vue.d.ts +2 -0
  22. package/dist/runtime/icons/chevron/chevron-left.vue +5 -0
  23. package/dist/runtime/icons/chevron/chevron-left.vue.d.ts +2 -0
  24. package/dist/runtime/icons/chevron/chevron-right.vue +5 -0
  25. package/dist/runtime/icons/chevron/chevron-right.vue.d.ts +2 -0
  26. package/dist/runtime/icons/chevron/chevron-up.vue +5 -0
  27. package/dist/runtime/icons/chevron/chevron-up.vue.d.ts +2 -0
  28. package/dist/runtime/icons/chevron/double-chevron-right.vue +12 -0
  29. package/dist/runtime/icons/chevron/double-chevron-right.vue.d.ts +2 -0
  30. package/dist/runtime/icons/kaspi-qr.vue +13 -0
  31. package/dist/runtime/icons/kaspi-qr.vue.d.ts +2 -0
  32. package/dist/runtime/icons/payment/payment-card.vue +6 -0
  33. package/dist/runtime/icons/payment/payment-card.vue.d.ts +2 -0
  34. package/dist/runtime/icons/payment/payment-kaspi.vue +11 -0
  35. package/dist/runtime/icons/payment/payment-kaspi.vue.d.ts +2 -0
  36. package/dist/runtime/lang/en.js +40 -0
  37. package/dist/runtime/lang/kk.js +40 -0
  38. package/dist/runtime/lang/ru.d.ts +40 -0
  39. package/dist/runtime/lang/ru.js +40 -0
  40. package/dist/runtime/plugins/toast.d.ts +24 -24
  41. package/dist/runtime/public/kaspi/logo.svg +4 -0
  42. package/package.json +4 -2
package/dist/module.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "nuxt": ">=3.16.0"
6
6
  },
7
7
  "failOnWarn": false,
8
- "version": "3.1.50",
8
+ "version": "3.1.51",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "1.0.1",
11
11
  "unbuild": "3.5.0"
package/dist/module.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { defu } from 'defu';
2
- import { defineNuxtModule, createResolver, addVitePlugin, addComponentsDir, addPlugin, installModule, addImportsDir, hasNuxtModule } from '@nuxt/kit';
2
+ import { defineNuxtModule, createResolver, addVitePlugin, addComponentsDir, addPlugin, installModule, addImportsDir, extendViteConfig, setGlobalHead, hasNuxtModule } from '@nuxt/kit';
3
3
 
4
4
  const module = defineNuxtModule({
5
5
  meta: {
@@ -73,6 +73,19 @@ const module = defineNuxtModule({
73
73
  });
74
74
  addPlugin(resolver.resolve("./runtime/i18n"));
75
75
  addImportsDir(resolver.resolve("./runtime/composables"));
76
+ extendViteConfig((config) => {
77
+ config.optimizeDeps.include ||= ["qrcode"];
78
+ });
79
+ setGlobalHead({
80
+ script: [
81
+ {
82
+ src: "https://widget.tiptoppay.kz/bundles/widget.js",
83
+ defer: true,
84
+ async: true,
85
+ onerror: `console.error("Failed to load script: https://widget.tiptoppay.kz/bundles/widget.js");`
86
+ }
87
+ ]
88
+ });
76
89
  }
77
90
  });
78
91
 
@@ -0,0 +1,370 @@
1
+ <script setup>
2
+ import { disableBodyScroll, enableBodyScroll } from "body-scroll-lock";
3
+ import { useAdaptive } from "#adata-ui/composables/useAdaptive";
4
+ import { ref, useAttrs, onMounted, onBeforeUnmount, watch, computed } from "#imports";
5
+ const props = defineProps({
6
+ idName: { type: String, required: false, default: "vsp-container" },
7
+ hideCloseBtn: { type: Boolean, required: false },
8
+ noClose: { type: Boolean, required: false },
9
+ side: { type: String, required: false, default: "right" },
10
+ rerender: { type: Boolean, required: false },
11
+ zIndex: { type: [Number, String], required: false, default: "auto" },
12
+ width: { type: String, required: false, default: "auto" },
13
+ height: { type: String, required: false, default: "auto" },
14
+ lockScroll: { type: Boolean, required: false, default: true },
15
+ lockScrollHtml: { type: Boolean, required: false },
16
+ hideScrollbar: { type: Boolean, required: false, default: false },
17
+ overlayColor: { type: String, required: false, default: "black" },
18
+ overlayOpacity: { type: Number, required: false, default: 0.5 },
19
+ overlayDuration: { type: Number, required: false, default: 500 },
20
+ panelColor: { type: String, required: false, default: "bg-white dark:bg-gray-900" },
21
+ panelDuration: { type: Number, required: false, default: 300 },
22
+ transitionName: { type: String, required: false },
23
+ headerClass: { type: String, required: false },
24
+ bodyClass: { type: String, required: false },
25
+ footerClass: { type: String, required: false }
26
+ });
27
+ defineEmits(["opened", "closed"]);
28
+ const modelValue = defineModel();
29
+ let teleportContainer = void 0;
30
+ const panel = ref(null);
31
+ const overlay = ref(null);
32
+ const footer = ref(null);
33
+ const header = ref(null);
34
+ const body = ref(null);
35
+ const panelSide = ref(props.side);
36
+ const device = useAdaptive();
37
+ const zIndex = ref();
38
+ const isBodyAlreadyLocked = ref(false);
39
+ const attrs = useAttrs();
40
+ const closePanel = () => modelValue.value = false;
41
+ const lockUnlockBodyScroll = (elem, lock) => {
42
+ if (lock) {
43
+ setTimeout(() => {
44
+ disableBodyScroll(elem, {
45
+ reserveScrollBarGap: true,
46
+ allowTouchMove: elem && elem !== document.body
47
+ });
48
+ disableBodyScroll(elem, { reserveScrollBarGap: true });
49
+ if (props.lockScrollHtml) document.documentElement.style.overflow = "hidden";
50
+ }, 0);
51
+ return;
52
+ }
53
+ enableBodyScroll(elem);
54
+ if (props.lockScrollHtml) document.documentElement.style.removeProperty("overflow");
55
+ };
56
+ const getMaxZIndex = () => Math.max(
57
+ ...Array.from(
58
+ document.querySelectorAll("body *"),
59
+ (el) => Number.parseFloat(window.getComputedStyle(el).zIndex)
60
+ ).filter((zIndex2) => !Number.isNaN(zIndex2)),
61
+ 0
62
+ );
63
+ onMounted(() => {
64
+ zIndex.value = props.zIndex === "auto" ? getMaxZIndex() : props.zIndex;
65
+ const alreadyCreatedTarget = document.getElementById(props.idName);
66
+ if (alreadyCreatedTarget) return;
67
+ teleportContainer = document.createElement("div");
68
+ teleportContainer.setAttribute("id", props.idName);
69
+ document.body.appendChild(teleportContainer);
70
+ });
71
+ onBeforeUnmount(() => {
72
+ if (props.lockScroll && panel.value && modelValue.value) lockUnlockBodyScroll(panel.value, false);
73
+ if (teleportContainer) document.body.removeChild(teleportContainer);
74
+ });
75
+ watch(() => device.value, () => {
76
+ panelSide.value = device.value.isTablet || device.value.isSmallTablet ? "bottom" : props.side;
77
+ }, { immediate: true });
78
+ watch(() => [modelValue.value, panel.value], (newP, oldP) => {
79
+ const wasShown = oldP ? oldP[0] : false;
80
+ const [isShown, panelEl] = newP;
81
+ const isOpening = isShown;
82
+ const isClosing = wasShown && !isShown;
83
+ if (!panelEl) return;
84
+ if (isShown) {
85
+ if (props.lockScroll) lockUnlockBodyScroll(panelEl, true);
86
+ return;
87
+ }
88
+ if (!props.lockScroll || !isClosing || isBodyAlreadyLocked.value) return;
89
+ setTimeout(() => {
90
+ if (panelEl) lockUnlockBodyScroll(panelEl, false);
91
+ }, props.panelDuration);
92
+ }, { immediate: true });
93
+ const roundedClass = computed(() => {
94
+ const classes = {
95
+ left: "rounded-r-xl",
96
+ right: "rounded-l-xl",
97
+ top: "rounded-b-xl",
98
+ bottom: "rounded-t-xl"
99
+ };
100
+ return classes[panelSide.value];
101
+ });
102
+ const overlayStyles = computed(() => ({
103
+ "zIndex": zIndex.value,
104
+ "animationDuration": `${props.overlayDuration}ms`,
105
+ "--overlay-opacity": props.overlayOpacity,
106
+ "opacity": modelValue.value ? props.overlayOpacity : 0,
107
+ "backgroundColor": props.overlayColor,
108
+ "pointerEvents": !modelValue.value ? "none" : "all"
109
+ }));
110
+ const panelStyles = computed(() => ({
111
+ width: ["left", "right"].includes(panelSide.value) ? props.width : void 0,
112
+ maxWidth: "100%",
113
+ ...["top", "bottom"].includes(panelSide.value) ? {
114
+ height: device.value.isSmallTablet || device.value.isTablet ? "100%" : props.height,
115
+ maxHeight: device.value.isMobile ? "90%" : "100%"
116
+ } : {},
117
+ zIndex: zIndex.value,
118
+ animationDuration: `${props.panelDuration}ms`,
119
+ ...Object.assign({}, attrs.style)
120
+ }));
121
+ const positionStart = ref(0);
122
+ const isClose = ref(false);
123
+ const modalHeight = ref(0);
124
+ const touchstart = (event) => {
125
+ isClose.value = false;
126
+ positionStart.value = event.touches[0].clientY;
127
+ modalHeight.value = panel.value?.offsetHeight || 0;
128
+ };
129
+ const touchmove = (event) => {
130
+ if (!device.value.isSmallTablet && !device.value.isTablet) return;
131
+ event.preventDefault();
132
+ const touchPosition = event.touches[0].clientY;
133
+ const step = touchPosition - positionStart.value;
134
+ if (step < 0) return;
135
+ const newHeight = modalHeight.value - step;
136
+ panel.value.style.height = `${newHeight}px`;
137
+ isClose.value = step > 65;
138
+ };
139
+ const touchend = () => {
140
+ if (isClose.value) {
141
+ closePanel();
142
+ } else {
143
+ panel.value.style.height = `${modalHeight.value}px`;
144
+ }
145
+ };
146
+ </script>
147
+
148
+ <template>
149
+ <client-only>
150
+ <Teleport :to="`#${idName}`">
151
+ <div
152
+ class="vsp-wrapper"
153
+ :class="[modelValue && 'vsp-wrapper--active']"
154
+ >
155
+ <Transition name="overlay">
156
+ <div
157
+ v-show="modelValue"
158
+ ref="overlay"
159
+ class="vsp-overlay fixed top-0 left-0 w-full h-full"
160
+ :style="overlayStyles"
161
+ @click="() => noClose ? void 0 : closePanel()"
162
+ />
163
+ </Transition>
164
+ <Transition
165
+ :name="transitionName || `slide-${panelSide}`"
166
+ @after-enter="$emit('opened')"
167
+ @after-leave="$emit('closed')"
168
+ >
169
+ <div
170
+ v-if="rerender ? modelValue : true"
171
+ v-show="rerender ? true : modelValue"
172
+ ref="panel"
173
+ class="vsp fixed flex flex-col"
174
+ :class="[`vsp--${panelSide}-side`, $attrs.class, roundedClass, panelColor]"
175
+ :style="panelStyles"
176
+ >
177
+ <div
178
+ class="w-full flex justify-center items-center mt-1 lg:hidden"
179
+ @touchmove="touchmove"
180
+ @touchstart="touchstart"
181
+ @touchend="touchend"
182
+ >
183
+ <div class="h-1 w-10 bg-[#D9D9D9] rounded m-1" />
184
+ </div>
185
+ <div
186
+ v-if="!hideCloseBtn"
187
+ :class="roundedClass"
188
+ class="absolute w-8 px-2 py-4 bg-blue-700 text-white -left-8 top-8 cursor-pointer lg:block hidden"
189
+ @click="closePanel"
190
+ >
191
+ <i-x-mark />
192
+ </div>
193
+ <div
194
+ v-if="!!$slots.header"
195
+ ref="header"
196
+ :class="[headerClass, 'vsp__header border-b border-deepblue-100 dark:border-[#E3E5E80D] lg:px-8 p-4']"
197
+ @touchmove="touchmove"
198
+ @touchstart="touchstart"
199
+ @touchend="touchend"
200
+ >
201
+ <slot
202
+ name="header"
203
+ :close="closePanel"
204
+ />
205
+ </div>
206
+ <div
207
+ ref="body"
208
+ :class="[
209
+ bodyClass,
210
+ 'vsp__body overflow-y-auto relative flex-grow-1 h-full lg:px-8 p-4',
211
+ hideScrollbar ? 'vsp__body--hide-scroll' : ''
212
+ ]"
213
+ >
214
+ <slot
215
+ name="default"
216
+ :close="closePanel"
217
+ />
218
+ </div>
219
+ <div
220
+ v-if="!!$slots.footer"
221
+ ref="footer"
222
+ :class="[footerClass, 'vsp__footer border-t border-deepblue-100 dark:border-[#E3E5E80D] lg:px-8 p-4']"
223
+ >
224
+ <slot name="footer" />
225
+ </div>
226
+ </div>
227
+ </Transition>
228
+ </div>
229
+ </Teleport>
230
+ </client-only>
231
+ </template>
232
+
233
+ <style scoped>
234
+ .vsp-wrapper .vsp--right-side, .vsp-wrapper .vsp--left-side {
235
+ top: 0;
236
+ height: 100%;
237
+ }
238
+ .vsp-wrapper .vsp--right-side {
239
+ right: 0;
240
+ left: unset;
241
+ }
242
+ .vsp-wrapper .vsp--left-side {
243
+ right: unset;
244
+ left: 0;
245
+ }
246
+ .vsp-wrapper .vsp--bottom-side, .vsp-wrapper .vsp--top-side {
247
+ left: 0;
248
+ width: 100%;
249
+ }
250
+ .vsp-wrapper .vsp--bottom-side {
251
+ bottom: 0;
252
+ }
253
+ .vsp-wrapper .vsp--top-side {
254
+ top: 0;
255
+ }
256
+ .vsp-wrapper .vsp__body.overflow-y-auto::-webkit-scrollbar {
257
+ width: 8px;
258
+ }
259
+ .vsp-wrapper .vsp__body.overflow-y-auto::-webkit-scrollbar-thumb {
260
+ background: rgba(44, 62, 80, 0.2);
261
+ border-radius: 6px;
262
+ }
263
+ .vsp-wrapper .vsp__body.vsp__body--hide-scroll {
264
+ scrollbar-width: none;
265
+ }
266
+ .vsp-wrapper .vsp__body.vsp__body--hide-scroll::-webkit-scrollbar {
267
+ width: 0;
268
+ height: 0;
269
+ }
270
+ .vsp-wrapper .overlay-enter-active,
271
+ .vsp-wrapper .overlay-leave-active {
272
+ animation: overlay-transition;
273
+ }
274
+ .vsp-wrapper .overlay-leave-active {
275
+ animation-direction: reverse;
276
+ }
277
+ .vsp-wrapper .slide-right-enter-active,
278
+ .vsp-wrapper .slide-right-leave-active {
279
+ animation: slide-right;
280
+ }
281
+ .vsp-wrapper .slide-right-leave-active {
282
+ animation-direction: reverse;
283
+ }
284
+ .vsp-wrapper .slide-left-enter-active,
285
+ .vsp-wrapper .slide-left-leave-active {
286
+ animation: slide-left;
287
+ }
288
+ .vsp-wrapper .slide-left-leave-active {
289
+ animation-direction: reverse;
290
+ }
291
+ .vsp-wrapper .slide-top-enter-active,
292
+ .vsp-wrapper .slide-top-leave-active {
293
+ animation: slide-left;
294
+ }
295
+ .vsp-wrapper .slide-top-leave-active {
296
+ animation-direction: reverse;
297
+ }
298
+ .vsp-wrapper .slide-top-enter-active,
299
+ .vsp-wrapper .slide-top-leave-active {
300
+ animation: slide-top;
301
+ }
302
+ .vsp-wrapper .slide-top-leave-active {
303
+ animation-direction: reverse;
304
+ }
305
+ .vsp-wrapper .slide-bottom-enter-active,
306
+ .vsp-wrapper .slide-bottom-leave-active {
307
+ animation: slide-bottom;
308
+ }
309
+ .vsp-wrapper .slide-bottom-leave-active {
310
+ animation-direction: reverse;
311
+ }
312
+ @keyframes slide-right {
313
+ 0% {
314
+ transform: translateX(100%);
315
+ opacity: 0;
316
+ }
317
+ 100% {
318
+ transform: translateX(0);
319
+ opacity: 1;
320
+ }
321
+ }
322
+ @keyframes slide-left {
323
+ 0% {
324
+ transform: translateX(-100%);
325
+ opacity: 0;
326
+ }
327
+ 100% {
328
+ transform: translateX(0);
329
+ opacity: 1;
330
+ }
331
+ }
332
+ @keyframes slide-bottom {
333
+ 0% {
334
+ transform: translateY(100%);
335
+ opacity: 0;
336
+ }
337
+ 100% {
338
+ transform: translateY(0);
339
+ opacity: 1;
340
+ }
341
+ }
342
+ @keyframes slide-top {
343
+ 0% {
344
+ transform: translateY(-100%);
345
+ opacity: 0;
346
+ }
347
+ 100% {
348
+ transform: translateY(0);
349
+ opacity: 1;
350
+ }
351
+ }
352
+ @keyframes slide-top {
353
+ 0% {
354
+ transform: translateY(-100%);
355
+ opacity: 0;
356
+ }
357
+ 100% {
358
+ transform: translateY(0);
359
+ opacity: 1;
360
+ }
361
+ }
362
+ @keyframes overlay-transition {
363
+ 0% {
364
+ opacity: 0;
365
+ }
366
+ 100% {
367
+ opacity: var(--overlay-opacity);
368
+ }
369
+ }
370
+ </style>
@@ -0,0 +1,68 @@
1
+ type Side = 'top' | 'right' | 'bottom' | 'left';
2
+ type __VLS_Props = {
3
+ idName?: string;
4
+ hideCloseBtn?: boolean;
5
+ noClose?: boolean;
6
+ side?: Side;
7
+ rerender?: boolean;
8
+ zIndex?: number | 'auto';
9
+ width?: string;
10
+ height?: string;
11
+ lockScroll?: boolean;
12
+ lockScrollHtml?: boolean;
13
+ hideScrollbar?: boolean;
14
+ overlayColor?: string;
15
+ overlayOpacity?: number;
16
+ overlayDuration?: number;
17
+ panelColor?: string;
18
+ panelDuration?: number;
19
+ transitionName?: string;
20
+ headerClass?: string;
21
+ bodyClass?: string;
22
+ footerClass?: string;
23
+ };
24
+ type __VLS_PublicProps = __VLS_Props & {
25
+ modelValue?: any;
26
+ };
27
+ declare var __VLS_27: {
28
+ close: any;
29
+ }, __VLS_29: {
30
+ close: any;
31
+ }, __VLS_31: {};
32
+ type __VLS_Slots = {} & {
33
+ header?: (props: typeof __VLS_27) => any;
34
+ } & {
35
+ default?: (props: typeof __VLS_29) => any;
36
+ } & {
37
+ footer?: (props: typeof __VLS_31) => any;
38
+ };
39
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
40
+ "update:modelValue": (value: any) => any;
41
+ } & {
42
+ opened: () => any;
43
+ closed: () => any;
44
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
45
+ "onUpdate:modelValue"?: ((value: any) => any) | undefined;
46
+ onOpened?: (() => any) | undefined;
47
+ onClosed?: (() => any) | undefined;
48
+ }>, {
49
+ side: Side;
50
+ width: string;
51
+ idName: string;
52
+ zIndex: number | "auto";
53
+ height: string;
54
+ lockScroll: boolean;
55
+ hideScrollbar: boolean;
56
+ overlayColor: string;
57
+ overlayOpacity: number;
58
+ overlayDuration: number;
59
+ panelColor: string;
60
+ panelDuration: number;
61
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
62
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
63
+ export default _default;
64
+ type __VLS_WithSlots<T, S> = T & {
65
+ new (): {
66
+ $slots: S;
67
+ };
68
+ };
@@ -0,0 +1,148 @@
1
+ <script setup>
2
+ import { toCanvas } from "qrcode";
3
+ import { removeTrailingSlash } from "#adata-ui/utils/removeTrailingSlash";
4
+ import { watch, ref, nextTick } from "vue";
5
+ import { useAppConfig, useColorMode, useCookie, useI18n } from "#imports";
6
+ const props = defineProps({
7
+ requestUrl: { type: String, required: true },
8
+ requestId: { type: Number, required: true }
9
+ });
10
+ const emit = defineEmits(["back", "updateUserRate"]);
11
+ const isOpen = defineModel({ default: false });
12
+ const { t, locale } = useI18n();
13
+ const { commonAuth } = useAppConfig();
14
+ const accessToken = useCookie("accessToken");
15
+ const colorMode = useColorMode();
16
+ const userApiURL = commonAuth.userApiURL;
17
+ const paymentSuccess = ref(false);
18
+ let intervalId = null;
19
+ function onBack() {
20
+ emit("back", "kaspi");
21
+ }
22
+ async function checkPayment() {
23
+ try {
24
+ const { data } = await $fetch(`${removeTrailingSlash(userApiURL)}/user/kaspi-balance/invoice-status`, {
25
+ method: "GET",
26
+ credentials: "include",
27
+ headers: {
28
+ Authorization: `Bearer ${accessToken.value}`,
29
+ lang: locale.value
30
+ },
31
+ params: {
32
+ request_id: props.requestId,
33
+ initial: 0
34
+ }
35
+ });
36
+ if (data.status === "completed") {
37
+ paymentSuccess.value = true;
38
+ }
39
+ } catch (e) {
40
+ console.error(e);
41
+ }
42
+ }
43
+ watch(isOpen, async (value) => {
44
+ if (!value) {
45
+ if (intervalId) {
46
+ clearInterval(intervalId);
47
+ }
48
+ return;
49
+ }
50
+ await nextTick();
51
+ const canvas = document.getElementById("kaspiQr");
52
+ if (!canvas) return;
53
+ toCanvas(
54
+ canvas,
55
+ props.requestUrl,
56
+ {
57
+ errorCorrectionLevel: "H",
58
+ width: 300,
59
+ margin: 0,
60
+ color: {
61
+ dark: colorMode.value === "dark" ? "#FFFFFF" : "#000000",
62
+ // квадраты
63
+ light: colorMode.value === "dark" ? "#000000" : "#FFFFFF"
64
+ // фон
65
+ }
66
+ },
67
+ (error) => {
68
+ if (error) {
69
+ console.error(error);
70
+ return;
71
+ }
72
+ const ctx = canvas.getContext("2d");
73
+ if (!ctx) return;
74
+ const logo = new Image();
75
+ logo.src = "/adata-ui/kaspi/logo.svg";
76
+ logo.onload = () => {
77
+ const size = canvas.width * 0.2;
78
+ const x = (canvas.width - size) / 2;
79
+ const y = (canvas.height - size) / 2;
80
+ ctx.fillStyle = colorMode.value === "dark" ? "#000000" : "#fff";
81
+ ctx.fillRect(x - 6, y - 6, size + 12, size + 12);
82
+ ctx.drawImage(logo, x, y, size, size);
83
+ };
84
+ }
85
+ );
86
+ intervalId = setInterval(() => {
87
+ if (paymentSuccess.value && intervalId) {
88
+ clearInterval(intervalId);
89
+ emit("updateUserRate");
90
+ return;
91
+ }
92
+ checkPayment();
93
+ }, 1e3);
94
+ });
95
+ </script>
96
+
97
+ <template>
98
+ <adt-side-panel
99
+ v-model="isOpen"
100
+ width="484px"
101
+ >
102
+ <template #header>
103
+ <div class="flex items-center gap-2">
104
+ <button @click="onBack">
105
+ <i-chevron-left class="size-6" />
106
+ </button>
107
+ <p class="text-xl font-semibold">
108
+ {{ t("payment.kaspi.title") }}
109
+ </p>
110
+ </div>
111
+ </template>
112
+
113
+ <div class="flex flex-col gap-6">
114
+ <div class="flex flex-col items-center text-center text-black dark:text-white">
115
+ <p class="mb-4 font-semibold text-sm">
116
+ {{ t("payment.kaspi.description") }}
117
+ </p>
118
+
119
+ <div class="flex gap-3 items-center">
120
+ <i-kaspi-qr class="size-16" />
121
+ <span class="font-bold text-[44px]">
122
+ {{ t("payment.kaspi.qr") }}
123
+ </span>
124
+ </div>
125
+
126
+ <p class="mt-5 font-bold text-2xl">
127
+ {{ t("payment.kaspi.scan") }}
128
+ </p>
129
+
130
+ <canvas
131
+ id="kaspiQr"
132
+ class="mt-5"
133
+ />
134
+
135
+ <p class="mt-10 text-lg">
136
+ {{ t("payment.kaspi.adata") }}
137
+ </p>
138
+ </div>
139
+
140
+ <adt-button
141
+ view="outline"
142
+ @click="onBack"
143
+ >
144
+ {{ t("payment.kaspi.changeMethod") }}
145
+ </adt-button>
146
+ </div>
147
+ </adt-side-panel>
148
+ </template>
@@ -0,0 +1,21 @@
1
+ type __VLS_Props = {
2
+ requestUrl: string;
3
+ requestId: number;
4
+ };
5
+ declare const __VLS_defaults: {
6
+ modelValue: boolean;
7
+ };
8
+ type __VLS_PublicProps = __VLS_Props & {
9
+ modelValue?: typeof __VLS_defaults['modelValue'];
10
+ };
11
+ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
+ "update:modelValue": (value: boolean) => any;
13
+ } & {
14
+ back: (type: "kaspi") => any;
15
+ updateUserRate: () => any;
16
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
17
+ "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
18
+ onBack?: ((type: "kaspi") => any) | undefined;
19
+ onUpdateUserRate?: (() => any) | undefined;
20
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ export default _default;