adata-ui 2.1.40-beta.1 → 2.1.40-beta.11

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 (56) hide show
  1. package/.claude/settings.local.json +19 -0
  2. package/components/elements/a-select-row/ASelectRowV2.vue +214 -0
  3. package/components/elements/button/AButtonV2.vue +112 -0
  4. package/components/elements/leave-note/ALeaveNote.vue +38 -17
  5. package/components/elements/segmented/ASegmentedV2.vue +58 -0
  6. package/components/elements/select/ASelectV2.vue +589 -0
  7. package/components/elements/show-more/AShowMoreV2.vue +26 -0
  8. package/components/elements/star-rating/AStarRating.vue +12 -4
  9. package/components/elements/status-badge-v2/StatusBadgeV2.vue +78 -0
  10. package/components/features/payment/process/PaymentKaspiQrSidePanel.vue +43 -27
  11. package/components/features/payment/process/PaymentKaspiRedirectSidePanel.vue +34 -23
  12. package/components/features/payment/process/PaymentMethodSidePanel.vue +61 -49
  13. package/components/features/payment/process/PaymentProcess.vue +6 -6
  14. package/components/features/payment/process/PaymentTopUpSidePanel.vue +44 -63
  15. package/components/forms/checkbox/ACheckboxV2.vue +229 -0
  16. package/components/forms/feedback-form/FeedbackForm.vue +8 -8
  17. package/components/forms/input/AInputV2.vue +542 -0
  18. package/components/forms/input/textarea/ATextareaV2.vue +248 -0
  19. package/components/forms/toggle/AToggleV2.vue +71 -0
  20. package/components/modals/AnotherDeviceModal.vue +22 -18
  21. package/components/modals/ApplicationAcceptedModal.vue +12 -15
  22. package/components/modals/ConnectingTariffModal.vue +13 -20
  23. package/components/modals/ContentNavigationModal.vue +77 -333
  24. package/components/modals/Insufficient-funds-modal.vue +18 -33
  25. package/components/modals/LimitReachedModal.vue +4 -3
  26. package/components/modals/NoAccessModal.vue +9 -11
  27. package/components/modals/PaymentMethodModal.vue +1 -1
  28. package/components/modals/ReportBugConfirmModal.vue +12 -10
  29. package/components/modals/ReportBugModal.vue +42 -36
  30. package/components/modals/Resend.vue +9 -10
  31. package/components/modals/SubmitApplicationModal.vue +27 -24
  32. package/components/modals/id/IdConfirmAccountOtpModal.vue +4 -9
  33. package/components/modals/id/IdLoginModal.vue +3 -8
  34. package/components/modals/id/IdModals.vue +23 -10
  35. package/components/modals/id/IdTwoFactorModal.vue +3 -8
  36. package/components/navigation/bottom-navigation/ABottomNavigation.vue +1 -1
  37. package/components/navigation/header/AHeader.vue +15 -19
  38. package/components/navigation/header/HeaderLink.vue +15 -21
  39. package/components/navigation/header/NavList.vue +8 -32
  40. package/components/navigation/header/ProductMenu.vue +52 -50
  41. package/components/navigation/pill-tabs/APillTabsV2.vue +134 -0
  42. package/components/overlays/modal/AModalV2.vue +391 -0
  43. package/composables/useAccessTokenCookie.ts +25 -0
  44. package/composables/useChipOverflow.ts +92 -0
  45. package/composables/useHeaderNavigationLinks.ts +53 -23
  46. package/icons/arrow/arrow-right.vue +14 -0
  47. package/icons/briefcase.vue +14 -0
  48. package/icons/car-side.vue +16 -0
  49. package/icons/cart.vue +15 -0
  50. package/icons/download-rounded.vue +15 -0
  51. package/icons/shield-verified.vue +14 -0
  52. package/lang/en.ts +35 -4
  53. package/lang/kk.ts +36 -5
  54. package/lang/ru.ts +37 -6
  55. package/package.json +1 -1
  56. package/shared/constans/pages.ts +8 -2
@@ -0,0 +1,78 @@
1
+ <script lang="ts" setup>
2
+ import { twMerge } from 'tailwind-merge'
3
+
4
+ defineOptions({ name: 'StatusBadgeV2', inheritAttrs: false })
5
+
6
+ type BadgeType = 'primary' | 'success' | 'danger' | 'gray' | 'orange' | 'warning'
7
+ type BadgeView = 'default' | 'inverted' | 'transparent'
8
+ type BadgeSize = 'xs' | 'sm' | 'md' | 'lg'
9
+
10
+ interface Props {
11
+ type?: BadgeType
12
+ view?: BadgeView
13
+ size?: BadgeSize
14
+ }
15
+
16
+ const props = withDefaults(defineProps<Props>(), {
17
+ type: 'primary',
18
+ view: 'inverted',
19
+ size: 'sm',
20
+ })
21
+
22
+ const base
23
+ = 'inline-flex w-fit items-center justify-center gap-1.5 rounded-full font-semibold select-none'
24
+
25
+ const sizeClasses: Record<BadgeSize, string> = {
26
+ xs: 'px-2 py-0.5 text-[11px] leading-none',
27
+ sm: 'px-2.5 py-1 text-xs leading-none',
28
+ md: 'px-3 py-1.5 text-sm',
29
+ lg: 'px-4 py-2 text-base',
30
+ }
31
+
32
+ const typeClasses: Record<BadgeView, Partial<Record<BadgeType, string>>> = {
33
+ default: {
34
+ primary: 'bg-blue-700 text-white dark:bg-blue-500 dark:text-gray-900',
35
+ success: 'bg-green-500 text-white dark:bg-green-400 dark:text-gray-900',
36
+ danger: 'bg-red-500 text-white dark:text-gray-100',
37
+ warning: 'bg-yellow-400 text-white dark:text-gray-900',
38
+ gray: 'bg-deepblue-900 text-white dark:bg-gray-200/10 dark:text-gray-200',
39
+ orange: 'bg-orange-600 text-white dark:text-gray-100',
40
+ },
41
+ inverted: {
42
+ primary: 'bg-blue-700/10 text-blue-700 dark:bg-blue-500/10 dark:text-blue-500',
43
+ success: 'bg-green-500/15 text-green-600 dark:bg-green-400/15 dark:text-green-400',
44
+ danger: 'bg-red-500/10 text-red-500 dark:bg-red-400/10 dark:text-red-400',
45
+ warning: 'bg-yellow-400/15 text-yellow-500 dark:bg-yellow-400/15 dark:text-yellow-400',
46
+ gray: 'bg-deepblue-900/10 text-gray-600 dark:bg-gray-200/10 dark:text-gray-300',
47
+ orange: 'bg-orange-600/10 text-orange-600 dark:text-orange-500',
48
+ },
49
+ transparent: {
50
+ primary: 'bg-transparent text-blue-700 dark:text-blue-500',
51
+ success: 'bg-transparent text-green-600 dark:text-green-400',
52
+ danger: 'bg-transparent text-red-500 dark:text-red-400',
53
+ warning: 'bg-transparent text-yellow-500 dark:text-yellow-400',
54
+ gray: 'bg-transparent text-gray-600 dark:text-gray-300',
55
+ orange: 'bg-transparent text-orange-600 dark:text-orange-500',
56
+ },
57
+ }
58
+
59
+ const attrs = useAttrs()
60
+
61
+ // twMerge resolves Tailwind conflicts: any class passed via `class` wins over
62
+ // the defaults below, so padding / rounded / bg / text can all be overridden.
63
+ const classes = computed(() =>
64
+ twMerge(
65
+ base,
66
+ sizeClasses[props.size],
67
+ typeClasses[props.view][props.type],
68
+ attrs.class as string,
69
+ ),
70
+ )
71
+ </script>
72
+
73
+ <template>
74
+ <div :class="classes" v-bind="{ ...$attrs, class: undefined }">
75
+ <slot name="point" />
76
+ <slot />
77
+ </div>
78
+ </template>
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { toCanvas } from 'qrcode'
3
2
  import { removeTrailingSlash } from '#adata-ui/components/utils/removeTrailingSlash'
3
+ import { toCanvas } from 'qrcode'
4
4
 
5
5
  const props = defineProps<{
6
6
  requestUrl: string
@@ -9,7 +9,7 @@ const props = defineProps<{
9
9
 
10
10
  const emit = defineEmits<{
11
11
  (e: 'back', type: 'kaspi'): void
12
- (e: 'updateUserRate'): void
12
+ (e: 'updateUserRate'): void
13
13
  }>()
14
14
 
15
15
  const isOpen = defineModel({ default: false })
@@ -74,11 +74,10 @@ watch(isOpen, async (value) => {
74
74
  margin: 0,
75
75
  color: {
76
76
  dark: colorMode.value === 'dark' ? '#FFFFFF' : '#000000', // квадраты
77
- light: colorMode.value === 'dark' ? '#000000' : '#FFFFFF' // фон
78
- }
77
+ light: colorMode.value === 'dark' ? '#000000' : '#FFFFFF', // фон
78
+ },
79
79
  },
80
80
  (error) => {
81
-
82
81
  if (error) {
83
82
  console.error(error)
84
83
  return
@@ -99,7 +98,8 @@ watch(isOpen, async (value) => {
99
98
 
100
99
  ctx.drawImage(logo, x, y, size, size)
101
100
  }
102
- })
101
+ },
102
+ )
103
103
 
104
104
  intervalId = setInterval(() => {
105
105
  if (paymentSuccess.value && intervalId) {
@@ -110,7 +110,6 @@ watch(isOpen, async (value) => {
110
110
  checkPayment()
111
111
  }, 1000)
112
112
  })
113
-
114
113
  </script>
115
114
 
116
115
  <template>
@@ -120,42 +119,59 @@ watch(isOpen, async (value) => {
120
119
  >
121
120
  <template #header>
122
121
  <div class="flex items-center gap-2">
123
- <button @click="onBack">
122
+ <button
123
+ type="button"
124
+ class="rounded-lg p-1 transition-colors hover:bg-gray-100 dark:hover:bg-white/[0.06]"
125
+ @click="onBack"
126
+ >
124
127
  <a-icon-chevron-left class="size-6" />
125
128
  </button>
126
- <p class="text-xl font-semibold">
129
+ <p class="text-xl font-semibold text-deepblue-900 dark:text-gray-100">
127
130
  {{ t('payment.kaspi.title') }}
128
131
  </p>
129
132
  </div>
130
133
  </template>
131
134
 
132
135
  <div class="flex flex-col gap-6">
133
- <div class="flex flex-col items-center text-center text-black dark:text-white">
134
- <p class="mb-4 font-semibold text-sm">
135
- {{ t('payment.kaspi.description') }}
136
- </p>
137
-
138
- <div class="flex gap-3 items-center">
139
- <a-icon-kaspi-qr class="size-16" />
140
- <span class="font-bold text-[44px]">
141
- {{ t('payment.kaspi.qr') }}
136
+ <p class="text-center text-sm font-medium text-gray-600 dark:text-gray-300">
137
+ {{ t('payment.kaspi.description') }}
138
+ </p>
139
+
140
+ <div class="flex flex-col items-center gap-5 rounded-2xl border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-900">
141
+ <div class="flex items-center gap-3">
142
+ <a-icon-kaspi-qr class="size-14" />
143
+ <span class="text-[40px] font-bold leading-none text-deepblue-900 dark:text-white">
144
+ {{ t('payment.kaspi.qr') }}
142
145
  </span>
143
146
  </div>
144
147
 
145
- <p class="mt-5 font-bold text-2xl">{{ t('payment.kaspi.scan') }}</p>
148
+ <p class="text-center text-xl font-bold text-deepblue-900 dark:text-white">
149
+ {{ t('payment.kaspi.scan') }}
150
+ </p>
146
151
 
147
- <canvas class="mt-5" id="kaspiQr"></canvas>
152
+ <canvas
153
+ id="kaspiQr"
154
+ class="rounded-lg"
155
+ />
148
156
 
149
- <p class="mt-10 text-lg">{{ t('payment.kaspi.adata') }}</p>
157
+ <p class="text-center text-base text-gray-600 dark:text-gray-300">
158
+ {{ t('payment.kaspi.adata') }}
159
+ </p>
150
160
  </div>
161
+ </div>
151
162
 
152
- <a-button @click="onBack" view="outline">
163
+ <template #footer>
164
+ <a-button-v2
165
+ view="outline"
166
+ color="gray"
167
+ size="lg"
168
+ block
169
+ @click="onBack"
170
+ >
153
171
  {{ t('payment.kaspi.changeMethod') }}
154
- </a-button>
155
- </div>
172
+ </a-button-v2>
173
+ </template>
156
174
  </a-side-panel>
157
175
  </template>
158
176
 
159
- <style scoped>
160
-
161
- </style>
177
+ <style scoped></style>
@@ -2,12 +2,12 @@
2
2
  import { removeTrailingSlash } from '#adata-ui/components/utils/removeTrailingSlash'
3
3
 
4
4
  const props = defineProps<{
5
- requestId: number
5
+ requestId: number
6
6
  }>()
7
7
 
8
8
  const emit = defineEmits<{
9
9
  (e: 'back', type: 'kaspi'): void
10
- (e: 'updateUserRate'): void
10
+ (e: 'updateUserRate'): void
11
11
  }>()
12
12
 
13
13
  const isOpen = defineModel({ default: false })
@@ -78,35 +78,46 @@ watch(isOpen, async (value) => {
78
78
  v-model="isOpen"
79
79
  width="484px"
80
80
  >
81
- <div class="flex flex-col gap-5">
82
- <p class="text-center text-2xl font-bold whitespace-pre-wrap">
81
+ <div class="flex flex-col gap-6">
82
+ <p class="whitespace-pre-wrap text-center text-xl font-bold text-deepblue-900 dark:text-gray-100">
83
83
  {{ t('payment.redirect.title') }}
84
84
  </p>
85
- <a-button block @click="goKaspi">
86
- {{ t('payment.redirect.goKaspi') }}
87
- </a-button>
88
- <div class="flex flex-col gap-2">
89
- <p class="text-center text-sm">
85
+
86
+ <div class="flex flex-col items-center gap-1 rounded-2xl bg-gray-50 p-5 text-center dark:bg-white/[0.03]">
87
+ <span class="text-xs text-gray-500 dark:text-gray-400">
90
88
  {{ t('payment.redirect.paymentId') }}
91
- </p>
92
- <p class="text-center text-xl font-semibold">
89
+ </span>
90
+ <span class="text-2xl font-bold text-deepblue-900 dark:text-gray-100">
93
91
  {{ requestId }}
94
- </p>
92
+ </span>
95
93
  </div>
96
- <p class="text-center text-sm">
94
+
95
+ <p class="text-center text-sm text-gray-600 dark:text-gray-300">
97
96
  {{ t('payment.redirect.description') }}
98
97
  </p>
99
- <a-button
100
- view="outline"
101
- block
102
- @click="onBack"
103
- >
104
- {{ t('payment.redirect.changeMethod') }}
105
- </a-button>
106
98
  </div>
99
+
100
+ <template #footer>
101
+ <div class="flex flex-col gap-2">
102
+ <a-button-v2
103
+ size="lg"
104
+ block
105
+ @click="goKaspi"
106
+ >
107
+ {{ t('payment.redirect.goKaspi') }}
108
+ </a-button-v2>
109
+ <a-button-v2
110
+ view="outline"
111
+ color="gray"
112
+ size="lg"
113
+ block
114
+ @click="onBack"
115
+ >
116
+ {{ t('payment.redirect.changeMethod') }}
117
+ </a-button-v2>
118
+ </div>
119
+ </template>
107
120
  </a-side-panel>
108
121
  </template>
109
122
 
110
- <style scoped>
111
-
112
- </style>
123
+ <style scoped></style>
@@ -16,24 +16,16 @@ const isOpen = defineModel({ default: false })
16
16
 
17
17
  const { t } = useI18n()
18
18
 
19
- const checkbox = ref<IBank>('kaspi')
19
+ const selected = ref<IBank>('kaspi')
20
20
  const cards = [
21
- {
22
- id: 'kaspi',
23
- name: 'payment.method.kaspi',
24
- sum: 10000,
25
- img: AIconPaymentKaspi,
26
- },
27
- {
28
- id: 'other',
29
- name: 'payment.method.other',
30
- sum: 10000,
31
- img: AIconPaymentCard,
32
- },
33
- ]
21
+ { id: 'kaspi', name: 'payment.method.kaspi', img: AIconPaymentKaspi },
22
+ { id: 'other', name: 'payment.method.other', img: AIconPaymentCard },
23
+ ] as const
24
+
25
+ const formattedSum = computed(() => Math.round(props.sum).toLocaleString('ru-RU'))
34
26
 
35
27
  function confirm() {
36
- emit('nextBank', checkbox.value, props.sum)
28
+ emit('nextBank', selected.value, props.sum)
37
29
  }
38
30
 
39
31
  function cancel() {
@@ -52,70 +44,90 @@ function onBack() {
52
44
  >
53
45
  <template #header>
54
46
  <div class="flex items-center gap-2">
55
- <button @click="onBack">
47
+ <button
48
+ type="button"
49
+ class="rounded-lg p-1 transition-colors hover:bg-gray-100 dark:hover:bg-white/[0.06]"
50
+ @click="onBack"
51
+ >
56
52
  <a-icon-chevron-left class="size-6" />
57
53
  </button>
58
- <p class="text-xl font-semibold">
54
+ <p class="text-xl font-semibold text-deepblue-900 dark:text-gray-100">
59
55
  {{ t('payment.method.title') }}
60
56
  </p>
61
57
  </div>
62
58
  </template>
63
59
 
64
60
  <div class="flex flex-col gap-6">
65
- <div class="flex flex-col items-center gap-4">
61
+ <div class="flex flex-col items-center gap-4 rounded-2xl bg-gray-50 p-6 text-center dark:bg-white/[0.03]">
66
62
  <a-ill-phone-check class="size-[120px]" />
67
- <p class="text-center text-sm font-semibold">
63
+ <p class="text-sm font-medium text-gray-600 dark:text-gray-300">
68
64
  {{ t('payment.method.description') }}
69
65
  </p>
70
66
  </div>
71
67
 
72
- <div class="font-semibold">
73
- {{ t('payment.method.note') }}
74
- </div>
75
-
76
68
  <div class="flex flex-col gap-2">
77
- <a-radio-button
78
- v-for="(item) in cards"
69
+ <p class="text-sm font-semibold text-deepblue-900 dark:text-gray-100">
70
+ {{ t('payment.method.note') }}
71
+ </p>
72
+
73
+ <button
74
+ v-for="item in cards"
79
75
  :key="item.id"
80
- v-model="checkbox"
81
- :name="`${item.name}`"
82
- side="right"
83
- size="lg"
84
- :value="item.id"
85
- class="flex items-center justify-between gap-2 rounded-md bg-gray-50 p-[10px_16px] dark:bg-[#393D40]"
76
+ type="button"
77
+ class="flex items-center gap-3 rounded-2xl border p-4 text-left transition-colors"
78
+ :class="selected === item.id
79
+ ? 'border-blue-500 bg-blue-50/60 dark:border-blue-400 dark:bg-blue-950/30'
80
+ : 'border-gray-200 bg-white hover:border-gray-300 hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-900 dark:hover:bg-gray-800'"
81
+ @click="selected = item.id"
86
82
  >
87
- <div class="flex w-full items-center gap-2">
88
- <component :is="item.img" />
89
- <div class="flex w-full items-center justify-between">
83
+ <component
84
+ :is="item.img"
85
+ class="h-7 w-auto shrink-0"
86
+ />
87
+ <div class="flex min-w-0 flex-1 items-center justify-between gap-2">
88
+ <span class="text-sm font-semibold text-deepblue-900 dark:text-gray-100">
90
89
  {{ t(item.name) }}
91
- <p class="body-600">
92
- {{ Math.round(sum).toLocaleString('RU-ru') }} ₸
93
- </p>
94
- </div>
90
+ </span>
91
+ <span class="text-sm font-semibold text-gray-600 dark:text-gray-300">
92
+ {{ formattedSum }} ₸
93
+ </span>
95
94
  </div>
96
- </a-radio-button>
95
+ <span
96
+ class="flex size-5 shrink-0 items-center justify-center rounded-full border-2 transition-colors"
97
+ :class="selected === item.id
98
+ ? 'border-blue-600 dark:border-blue-400'
99
+ : 'border-gray-300 dark:border-gray-600'"
100
+ >
101
+ <span
102
+ v-if="selected === item.id"
103
+ class="size-2.5 rounded-full bg-blue-600 dark:bg-blue-400"
104
+ />
105
+ </span>
106
+ </button>
97
107
  </div>
108
+ </div>
98
109
 
99
- <div class="flex flex-col gap-2 ">
100
- <a-button
101
- :disabled="!checkbox"
110
+ <template #footer>
111
+ <div class="flex flex-col gap-2">
112
+ <a-button-v2
113
+ size="lg"
102
114
  block
103
115
  @click="confirm"
104
116
  >
105
117
  {{ t('actions.topUp') }}
106
- </a-button>
107
- <a-button
118
+ </a-button-v2>
119
+ <a-button-v2
108
120
  view="outline"
121
+ color="gray"
122
+ size="lg"
109
123
  block
110
124
  @click="cancel"
111
125
  >
112
126
  {{ t('actions.close') }}
113
- </a-button>
127
+ </a-button-v2>
114
128
  </div>
115
- </div>
129
+ </template>
116
130
  </a-side-panel>
117
131
  </template>
118
132
 
119
- <style scoped>
120
-
121
- </style>
133
+ <style scoped></style>
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
- import PaymentTopUpSidePanel from '#adata-ui/components/features/payment/process/PaymentTopUpSidePanel.vue'
3
- import PaymentMethodSidePanel from '#adata-ui/components/features/payment/process/PaymentMethodSidePanel.vue'
4
2
  import PaymentKaspiQrSidePanel from '#adata-ui/components/features/payment/process/PaymentKaspiQrSidePanel.vue'
5
3
  import PaymentKaspiRedirectSidePanel from '#adata-ui/components/features/payment/process/PaymentKaspiRedirectSidePanel.vue'
4
+ import PaymentMethodSidePanel from '#adata-ui/components/features/payment/process/PaymentMethodSidePanel.vue'
5
+ import PaymentTopUpSidePanel from '#adata-ui/components/features/payment/process/PaymentTopUpSidePanel.vue'
6
6
  import { removeTrailingSlash } from '#adata-ui/components/utils/removeTrailingSlash'
7
7
 
8
8
  const { $toast } = useNuxtApp()
@@ -16,7 +16,7 @@ const {
16
16
  methodSidePanel,
17
17
  kaspiQRSidePanel,
18
18
  kaspiRedirectSidePanel,
19
- payByCard
19
+ payByCard,
20
20
  } = usePayment()
21
21
 
22
22
  const userApiURL = commonAuth.userApiURL
@@ -132,23 +132,23 @@ async function updateUserRate() {
132
132
 
133
133
  <payment-method-side-panel
134
134
  v-model="methodSidePanel"
135
- @back="onBack"
136
135
  :sum="paymentSum"
136
+ @back="onBack"
137
137
  @next-bank="directionsBanks"
138
138
  />
139
139
 
140
140
  <payment-kaspi-qr-side-panel
141
141
  v-model="kaspiQRSidePanel"
142
- @back="onBack"
143
142
  :request-url="requestUrl"
144
143
  :request-id="requestId as number"
144
+ @back="onBack"
145
145
  @update-user-rate="updateUserRate"
146
146
  />
147
147
 
148
148
  <payment-kaspi-redirect-side-panel
149
149
  v-model="kaspiRedirectSidePanel"
150
- @back="onBack"
151
150
  :request-id="requestId as number"
151
+ @back="onBack"
152
152
  @update-user-rate="updateUserRate"
153
153
  />
154
154
  </template>
@@ -1,6 +1,4 @@
1
1
  <script setup lang="ts">
2
- import ASidePanel from "#adata-ui/components/overlays/side-panel/ASidePanel.vue";
3
-
4
2
  const emit = defineEmits<{
5
3
  (e: 'next', sum: number): void
6
4
  }>()
@@ -9,35 +7,18 @@ const isOpen = defineModel({ default: false })
9
7
 
10
8
  const { t } = useI18n()
11
9
 
12
- const money = ref(0)
10
+ const money = ref<number | string>(0)
13
11
  const errorAlert = ref(false)
14
12
 
15
- const sumArr = ref([
16
- {
17
- id: 1,
18
- value: 2000,
19
- label: '2 000 ₸',
20
- },
21
- {
22
- id: 2,
23
- value: 5000,
24
- label: '5 000 ₸',
25
- },
26
- {
27
- id: 3,
28
- value: 10000,
29
- label: '10 000 ₸',
30
- },
31
- {
32
- id: 4,
33
- value: 20000,
34
- label: '20 000 ₸',
35
- },
36
- ])
13
+ const sumArr = [
14
+ { id: 1, value: 2000, label: '2 000 ₸' },
15
+ { id: 2, value: 5000, label: '5 000 ₸' },
16
+ { id: 3, value: 10000, label: '10 000 ₸' },
17
+ { id: 4, value: 20000, label: '20 000 ₸' },
18
+ ]
37
19
 
38
- const filterMoney = computed(() => {
39
- return money.value >= 1
40
- })
20
+ const amount = computed(() => Number(money.value) || 0)
21
+ const filterMoney = computed(() => amount.value >= 1)
41
22
 
42
23
  function onSelectAmount(value: number) {
43
24
  money.value = value
@@ -50,10 +31,11 @@ function onClose() {
50
31
  }
51
32
 
52
33
  function handlePayment() {
53
- if (money.value <= 1000000) {
54
- emit('next', money.value)
34
+ if (amount.value <= 1000000) {
35
+ emit('next', amount.value)
55
36
  errorAlert.value = false
56
- } else {
37
+ }
38
+ else {
57
39
  errorAlert.value = true
58
40
  }
59
41
  }
@@ -65,69 +47,68 @@ function handlePayment() {
65
47
  width="484px"
66
48
  >
67
49
  <template #header>
68
- <div class="text-xl font-semibold">
50
+ <div class="text-xl font-semibold text-deepblue-900 dark:text-gray-100">
69
51
  {{ t('payment.topUp.title') }}
70
52
  </div>
71
53
  </template>
72
54
 
73
55
  <div class="flex flex-col gap-6">
74
- <div class="flex flex-col items-center gap-4 ">
56
+ <div class="flex flex-col items-center gap-4 rounded-2xl bg-gray-50 p-6 text-center dark:bg-white/[0.03]">
75
57
  <a-ill-bill class="size-[120px]" />
76
- <p class="text-center text-sm font-semibold">
58
+ <p class="text-sm font-medium text-gray-600 dark:text-gray-300">
77
59
  {{ t('payment.topUp.info') }}
78
60
  </p>
79
61
  </div>
80
62
 
81
- <div class="flex flex-col gap-4">
82
- <a-input-standard
63
+ <div class="flex flex-col gap-3">
64
+ <a-input-v2
83
65
  v-model="money"
84
- :label="`${t('payment.topUp.enterAmount')}`"
66
+ :label="t('payment.topUp.enterAmount')"
85
67
  type="number"
86
- pattern="[0-9]*"
68
+ size="md"
87
69
  clearable
70
+ :error="errorAlert ? t('modals.replenish_modal.error') : undefined"
88
71
  />
89
- <a-alert
90
- v-if="errorAlert"
91
- color="red"
92
- >
93
- {{ t('modals.replenish_modal.error') }}
94
- </a-alert>
95
- <div class="flex gap-4">
96
- <a-chips
72
+
73
+ <div class="grid grid-cols-2 gap-2 sm:grid-cols-4">
74
+ <button
97
75
  v-for="item in sumArr"
98
76
  :key="item.id"
99
- view="standard"
100
- size="lg"
101
- :class="[
102
- money === item.value
103
- ? 'bg-blue-700 text-white hover:bg-blue-700 dark:border-blue-500 dark:bg-transparent dark:text-blue-500 dark:hover:bg-transparent'
104
- : '',
105
- ]"
77
+ type="button"
78
+ class="rounded-xl border px-3 py-2.5 text-sm font-semibold transition-colors"
79
+ :class="amount === item.value
80
+ ? 'border-blue-500 bg-blue-50 text-blue-700 dark:border-blue-400 dark:bg-blue-950/40 dark:text-blue-300'
81
+ : 'border-gray-200 bg-white text-deepblue-900 hover:border-gray-300 hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:hover:bg-gray-800'"
106
82
  @click.stop="onSelectAmount(item.value)"
107
83
  >
108
- <span>{{ item.label }}</span>
109
- </a-chips>
84
+ {{ item.label }}
85
+ </button>
110
86
  </div>
111
87
  </div>
88
+ </div>
112
89
 
90
+ <template #footer>
113
91
  <div class="flex flex-col gap-2">
114
- <a-button
92
+ <a-button-v2
93
+ size="lg"
94
+ block
115
95
  :disabled="!filterMoney"
116
96
  @click="handlePayment"
117
97
  >
118
98
  {{ t('actions.topUp') }}
119
- </a-button>
120
- <a-button
99
+ </a-button-v2>
100
+ <a-button-v2
121
101
  view="outline"
102
+ color="gray"
103
+ size="lg"
104
+ block
122
105
  @click="onClose"
123
106
  >
124
107
  {{ t('actions.back') }}
125
- </a-button>
108
+ </a-button-v2>
126
109
  </div>
127
- </div>
110
+ </template>
128
111
  </a-side-panel>
129
112
  </template>
130
113
 
131
- <style scoped>
132
-
133
- </style>
114
+ <style scoped></style>