adata-ui 2.1.40-beta.10 → 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.
@@ -0,0 +1,19 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "PowerShell(npm view *)",
5
+ "PowerShell(git rm *)",
6
+ "PowerShell(npx --yes @tailwindcss/upgrade@latest --force)",
7
+ "PowerShell(Out-File *)",
8
+ "PowerShell(pnpm install *)",
9
+ "PowerShell(Get-ChildItem node_modules\\\\eslint-plugin-tailwindcss\\\\lib\\\\rules | Select-Object -ExpandProperty Name; node -e \"const p=require\\('eslint-plugin-tailwindcss'\\); console.log\\(Object.keys\\(p.rules\\).join\\('\\\\n'\\)\\); console.log\\('CONFIGS:', Object.keys\\(p.configs\\).join\\(','\\)\\)\")",
10
+ "PowerShell(node -e \"const p=require\\('eslint-plugin-tailwindcss'\\); console.log\\(JSON.stringify\\(p.configs.recommended, \\(k,v\\)=> typeof v==='object'&&v!==null&&k==='plugins'?Object.keys\\(v\\):v, 2\\).substring\\(0,800\\)\\)\"; Select-String -Path node_modules\\\\eslint-plugin-tailwindcss\\\\README.md -Pattern 'entryPoint|settings' | Select-Object -First 10 | ForEach-Object Line)",
11
+ "PowerShell(Select-String -Path node_modules\\\\eslint-plugin-tailwindcss\\\\README.md -Pattern 'cssConfigPath|vue|\\\\.vue' -Context 2,4 | Select-Object -First 12 | ForEach-Object {$_.Context.PreContext + $_.Line + $_.Context.PostContext} | ForEach-Object {$_})",
12
+ "PowerShell(pnpm build *)",
13
+ "PowerShell($c = Get-Content .playground\\\\.output\\\\server\\\\chunks\\\\build\\\\entry-styles.B6sbRG45.mjs -Raw; foreach \\($m in '--color-deepblue-900','bg-gr-blue','heading-01','hover\\\\:bg-purple-900\\\\/20','a-container','--font-sans','outline-hidden','scrollbar-gutter'\\) { \"$m => $\\($c.Contains\\($m\\)\\)\" })",
14
+ "PowerShell(pnpm eslint *)",
15
+ "PowerShell(pnpm *)",
16
+ "PowerShell(Get-Content C:\\\\adata\\\\adata-ui\\\\app.vue; \"=== -error.vue \\(first 100\\) ===\"; Get-Content C:\\\\adata\\\\adata-ui\\\\-error.vue -TotalCount 100; \"=== .playground/app.vue ===\"; Get-Content C:\\\\adata\\\\adata-ui\\\\.playground\\\\app.vue -TotalCount 60)"
17
+ ]
18
+ }
19
+ }
@@ -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>
@@ -1,355 +1,99 @@
1
1
  <script setup lang="ts">
2
+ import type { Component } from 'vue'
3
+ import { useCurrentModule } from '#adata-ui/composables/projectState'
4
+ import { useHeaderNavigationLinks } from '#adata-ui/composables/useHeaderNavigationLinks'
2
5
 
3
- import {ref} from "vue";
4
- import IconSearch from "#adata-ui/icons/search.vue";
5
- import {PAGES} from '#adata-ui/shared/constans/pages'
6
- import IconScales from "#adata-ui/icons/scales/scale.vue";
7
- import IconLink from "#adata-ui/icons/link-chain.vue";
8
- import IconUsers from "#adata-ui/icons/users.vue";
9
- import IconGlobe from "#adata-ui/icons/globe.vue";
10
- import IconBlock from "#adata-ui/icons/block.vue";
11
- import IconDollar from "#adata-ui/icons/currency/currency-dollar.vue";
12
- import IconDocument from "#adata-ui/icons/hdocument.vue";
13
- import IconArrowCircle from "#adata-ui/icons/arrow/arrow-circle-down.vue";
14
- import IconWork from "#adata-ui/icons/work-bag.vue";
15
- import IconFile from "#adata-ui/icons/file/file.vue";
16
- import IconCheck from "#adata-ui/icons/hcheck.vue";
17
- import IconCheckCircle from "#adata-ui/icons/check/check-circle.vue";
18
- import IconCar from "#adata-ui/icons/car.vue";
19
- import IconTruck from "#adata-ui/icons/truck.vue";
20
- import IconArrowGraph from "#adata-ui/icons/arrow/arrow-graph-up.vue";
21
- import IconCompany from "#adata-ui/icons/company.vue";
22
- import IconMedal from "#adata-ui/icons/medal.vue";
23
- import IconProfile from "#adata-ui/icons/profile.vue";
24
- import Connections from "#adata-ui/icons/sviazi.vue";
25
- import {useCurrentModule} from "#adata-ui/composables/projectState";
26
- import IconCalc from '#adata-ui/icons/calculator.vue'
27
- import { buildLocalizedUrl } from '#adata-ui/utils/localizedNavigation'
28
- import {
29
- AIconAkimat,
30
- AIconCurrencyTenge,
31
- AIconExcelIcon,
32
- AIconFiles, AIconSearch,
33
- AIconUsers,
34
- AIconWarningTriangle
35
- } from '#components'
36
- import MapPinRect from '#adata-ui/icons/map/map-pin-rect.vue'
37
- import ChartBar from '#adata-ui/icons/chart-bar.vue'
38
- import Bank from '#adata-ui/icons/bank.vue'
39
- import { useUrls } from '#adata-ui/composables/useUrls'
40
- import MapPaper from '#adata-ui/icons/map-paper.vue'
41
- import AiAssistant from '#adata-ui/icons/ai-assistant.vue'
42
- import Tasks from '#adata-ui/icons/tasks.vue'
43
- import HotLine from '#adata-ui/icons/hot-line.vue'
44
- import Sanctions from '#adata-ui/icons/sanctions.vue'
45
- import CheckSb from '#adata-ui/icons/check-sb.vue'
46
- type Emits = {
47
- (e: 'pushMain'): void
6
+ interface NavItem {
7
+ title: string
8
+ icon: Component
9
+ to: string
48
10
  }
49
- const isOpen = ref(false)
50
- const tab = ref(useCurrentModule().value)
51
- const { myLayer }: any = useAppConfig()
52
- const urls = useUrls()
53
11
 
54
- const { t, locale } = useI18n()
12
+ interface Emits {
13
+ (e: 'pushMain'): void
14
+ }
55
15
  const emits = defineEmits<Emits>()
56
- const mode = myLayer.mode
57
-
58
- const tabOptions = [
59
- {
60
- name: 'header.products.counterparties.label',
61
- key: 'pk',
62
- },
63
- {
64
- name: 'header.products.fines.label',
65
- key: 'fines',
66
- },
67
- {
68
- name: 'header.products.jobs.label',
69
- key: 'work',
70
- },
71
- {
72
- name: 'header.products.fea.label',
73
- key: 'fea',
74
- },
75
- {
76
- name: 'header.products.tenders.label',
77
- key: 'tenders',
78
- },
79
- {
80
- name: 'header.products.edo.label',
81
- key: 'edo',
82
- },
83
- {
84
- name: 'header.products.compliance.label',
85
- key: 'compliance',
86
- },
87
16
 
88
- {
89
- name: 'header.products.analytics.label',
90
- key: 'analytics',
91
- },
17
+ const open = defineModel<boolean>({ default: false })
92
18
 
19
+ const { t } = useI18n()
20
+ const modules = useHeaderNavigationLinks()
93
21
 
22
+ const initialKey = useCurrentModule().value
23
+ const tab = ref<string>(
24
+ initialKey && modules.value.some(module => module.key === initialKey)
25
+ ? initialKey
26
+ : (modules.value[0]?.key ?? 'pk'),
27
+ )
94
28
 
95
- ]
96
- const sideLinks = <any>{
97
- edo: [
98
- {
99
- label: 'header.products.edo.label',
100
- icon: AIconFiles,
101
- link: urls.edo_docs,
102
- }
103
- ],
104
- pk: [
105
- {
106
- icon: IconSearch,
107
- label: 'header.products.counterparties.items.counterparty.title',
108
- link: urls.pk + PAGES.pk.main
109
- },
110
- {
111
- icon: IconScales,
112
- label: 'header.products.counterparties.items.compare.title',
113
- link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.compare : urls.pk + PAGES.pk.compare
114
- },
115
- {
116
- icon: IconLink,
117
- label: 'header.products.counterparties.items.networks.title',
118
- link: myLayer.counterParty ? urls.pk + myLayer.counterParty + '/search-connections/check' : urls.pk + PAGES.pk.connections
119
- },
120
- {
121
- icon: IconUsers,
122
- label: 'header.products.counterparties.items.wholesale.title',
123
- link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.employees : urls.pk + PAGES.pk.employees
124
- },
125
- {
126
- icon: IconGlobe,
127
- label: 'header.products.counterparties.items.foreign.title',
128
- link: urls.pk + PAGES.pk.foreign
129
- },
130
- {
131
- icon: IconBlock,
132
- label: 'header.products.counterparties.items.sanction.title',
133
- link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.sanctions : urls.pk + PAGES.pk.sanctions
134
- },
135
- {
136
- icon: IconDollar,
137
- label: 'header.products.counterparties.items.offshore.title',
138
- link: myLayer.counterParty ? urls.pk + myLayer.counterParty + PAGES.pk.offshore : urls.pk + PAGES.pk.offshore
139
- },
140
- // {
141
- // icon: IconDocument,
142
- // label: "Экспресс проверка",
143
- // link: "#"
144
- // },
145
- {
146
- icon: IconArrowCircle,
147
- label: 'header.products.counterparties.items.unloading.title',
148
- link: urls.pk + PAGES.pk.unload
149
- }
150
- ],
151
- work: [
152
- {
153
- icon: IconWork,
154
- label: 'header.products.jobs.items.vacancies.title',
155
- link: urls.work + PAGES.work.vacancy
156
- },
157
- {
158
- icon: IconDocument,
159
- label: 'header.products.jobs.items.resume.title',
160
- link: urls.work + PAGES.work.summary
161
- },
162
- ],
163
- tenders: [
164
- {
165
- icon: AIconUsers,
166
- label: t('header.products.tenders.items.customers.title'),
167
- link: urls.zakupki + PAGES.tender.customers,
168
- },
169
- {
170
- icon: AIconAkimat,
171
- label: t('header.products.tenders.items.akimat.title'),
172
- link: urls.zakupki + PAGES.tender.akimat,
173
- },
174
- {
175
- icon: AIconWarningTriangle,
176
- label: 'header.products.tenders.items.tru.title',
177
- link: urls.zakupki + PAGES.tender.tru
178
- },
179
- {
180
- icon: AIconCurrencyTenge,
181
- label: 'header.products.tenders.items.price.title',
182
- link: urls.zakupki + PAGES.tender.price
183
- },
184
- {
185
- icon: AIconExcelIcon,
186
- label: 'header.products.tenders.items.constructor.title',
187
- link: urls.zakupki + PAGES.tender.constructor
188
- },
189
- {
190
- icon: AIconSearch,
191
- label: 'header.products.tenders.items.monitoring.title',
192
- link: urls.tender
193
- }
194
- ],
195
- analytics: [
196
- // {
197
- // icon: IconSearch,
198
- // label: 'header.products.analytics.items.clients.title',
199
- // link: myLayer.analyticsUrl + PAGES.analytics.clients
200
- // },
201
- // {
202
- // icon: IconCheck,
203
- // label: 'header.products.analytics.items.procurement.title',
204
- // link: urls.analyticsNew + PAGES.analytics.main
205
- // },
206
- {
207
- icon: IconArrowGraph,
208
- label: 'header.products.analytics.items.activity.title',
209
- link: urls.analytics + PAGES.analytics.index
210
- },
211
- {
212
- icon: IconCompany,
213
- label: 'header.products.analytics.items.subjects.title',
214
- link: urls.analytics + PAGES.analytics.business
215
- },
216
- {
217
- icon: IconMedal,
218
- label: 'header.products.analytics.items.rate.title',
219
- link: urls.analytics + PAGES.analytics.rating
220
- }
221
- ],
222
- fines: [
223
- {
224
- icon: IconCheckCircle,
225
- label: 'header.products.fines.items.fines.title',
226
- link: urls.avto + PAGES.fines.main
227
- },
228
- {
229
- icon: IconCar,
230
- label: 'header.products.fines.items.auto.title',
231
- link: urls.avto + PAGES.fines.avto
232
- },
233
- // {
234
- // icon: IconTruck,
235
- // label: 'header.products.fines.items.wholesaleAuto.title',
236
- // link: myLayer.avtoUrl + PAGES.fines.bulk
237
- // }
238
- ],
239
- fea: [
240
- {
241
- label: 'header.products.fea.items.i.t',
242
- icon: IconSearch,
243
- link: `${urls.tnved}${PAGES.fea.t}`
244
- },
245
- {
246
- label: 'header.products.fea.items.o.t',
247
- icon: Connections,
248
- link: `${urls.tnved}${PAGES.fea.o}`
249
- },
250
- {
251
- label: 'header.products.fea.items.cp.t',
252
- icon: IconFile,
253
- link: `${urls.tnved}${PAGES.fea.cp}`
254
- },
255
- {
256
- label: 'header.products.fea.items.ca.t',
257
- icon: IconCalc,
258
- link: `${urls.tnved}${PAGES.fea.ca}`
259
- },
260
- {
261
- label: 'header.products.fea.items.tr.t',
262
- icon: IconGlobe,
263
- link: `${urls.tnved}${PAGES.fea.tr}`
264
- },
265
- {
266
- label: 'header.products.fea.items.importerMap.t',
267
- icon: MapPinRect,
268
- link: `${urls.tnved}${PAGES.fea.importerMap}`
269
- },
270
- {
271
- label: 'header.products.fea.items.containers.t',
272
- icon: MapPaper,
273
- link: `${urls.tnved}${PAGES.fea.containers}`
274
- }
275
- ],
276
- compliance: [
277
- {
278
- label: 'header.products.compliance.items.assistant.t',
279
- icon: AiAssistant,
280
- link: urls.compliancemain + PAGES.compliance.assistant
281
- },
282
- {
283
- label: 'header.products.compliance.items.assignments.t',
284
- icon: Tasks,
285
- link: urls.compliancemain + PAGES.compliance.assignments
286
- },
287
- {
288
- label: 'header.products.compliance.items.hotline.t',
289
- icon: HotLine,
290
- link: urls.compliancemain + PAGES.compliance.hotline
291
- },
292
- {
293
- label: 'header.products.compliance.items.sanctions.t',
294
- icon: Sanctions,
295
- link: urls.compliancemain + PAGES.compliance.sanctions
296
- },
297
- {
298
- label: 'header.products.compliance.items.suppliers.t',
299
- icon: IconProfile,
300
- link: urls.compliancemain + PAGES.compliance.suppliers
301
- },
302
- {
303
- label: 'header.products.compliance.items.sb.t',
304
- icon: CheckSb,
305
- link: urls.compliancemain + PAGES.compliance.sb
306
- }
307
- ]
308
- }
309
- const currentLinks = ref(sideLinks[tab.value])
29
+ const tabOptions = computed(() =>
30
+ modules.value.map(module => ({ key: module.key, name: module.name })),
31
+ )
310
32
 
311
- watch(tab, (e) => {
312
- if (e) {
313
- currentLinks.value = sideLinks[e]
314
- }
33
+ const currentLinks = computed<NavItem[]>(() => {
34
+ const module = modules.value.find(item => item.key === tab.value)
35
+ return (module?.items ?? []) as NavItem[]
315
36
  })
316
37
 
38
+ function onReturn() {
39
+ emits('pushMain')
40
+ }
317
41
  </script>
318
42
 
319
43
  <template>
320
- <a-modal v-model="isOpen" :title="t('modals.mobile_navigation.type_main')">
321
- <div class="flex flex-col gap-5">
322
- <div class="h-[1px] w-full bg-deepblue-900/5"/>
323
- <div>
324
- <a-pill-tabs v-model="tab" :options="tabOptions" view="gray"/>
325
- </div>
326
- <div class="h-[40vh] sm:h-[300px] overflow-auto no-scrollbar">
327
- <nuxt-link
328
- v-for="item in currentLinks"
329
- :key="item.label"
330
- :to="item.link"
331
- class="flex items-center gap-4 px-4 py-3 bg-gray-50 dark:bg-gray-800 mb-2 rounded"
332
- >
333
- <div class="bg-gradient-blue p-1 rounded-lg">
334
- <component
335
- :is="item.icon"
336
- class="w-5 h-5 text-white dark:text-gray-900"
337
- />
338
- </div>
339
- <span>{{ t(item.label) }}</span>
340
- </nuxt-link>
341
- </div>
342
- <div class="h-[1px] w-full bg-deepblue-900/5"/>
44
+ <a-modal-v2
45
+ v-model="open"
46
+ hide-close
47
+ content-class="bg-gray-50/60 dark:bg-gray-950/40"
48
+ >
49
+ <template #header>
50
+ <h2 class="w-full text-center text-base font-semibold text-gray-900 dark:text-gray-100">
51
+ {{ t('modals.mobile_navigation.type_main') }}
52
+ </h2>
53
+ </template>
54
+
55
+ <div class="px-4 py-3">
56
+ <a-pill-tabs-v2
57
+ v-model="tab"
58
+ :options="tabOptions"
59
+ size="md"
60
+ scroll-into-view
61
+ />
343
62
  </div>
63
+
64
+ <div class="no-scrollbar flex h-[50vh] flex-col gap-2 overflow-y-auto px-4 pb-4">
65
+ <nuxt-link
66
+ v-for="item in currentLinks"
67
+ :key="item.to"
68
+ :to="item.to"
69
+ class="group flex items-center gap-3 rounded-2xl border border-gray-100 bg-white px-3 py-2.5 transition-colors hover:border-blue-200 hover:bg-blue-50/50 dark:border-gray-800 dark:bg-gray-900 dark:hover:border-blue-500/30 dark:hover:bg-gray-800"
70
+ >
71
+ <span class="flex size-10 shrink-0 items-center justify-center rounded-xl bg-blue-50 text-blue-500 transition-colors group-hover:bg-blue-700 group-hover:text-white dark:bg-blue-500/10 dark:text-blue-500 dark:group-hover:bg-blue-500 dark:group-hover:text-white">
72
+ <component
73
+ :is="item.icon"
74
+ class="size-5"
75
+ />
76
+ </span>
77
+
78
+ <span class="min-w-0 flex-1 truncate text-sm font-semibold text-deepblue-900 dark:text-gray-100">
79
+ {{ item.title }}
80
+ </span>
81
+
82
+ <a-icon-chevron-right class="size-4 shrink-0 text-gray-300 transition-colors group-hover:text-blue-500 dark:text-gray-600" />
83
+ </nuxt-link>
84
+ </div>
85
+
344
86
  <template #footer>
345
- <nuxt-link to="/" @click="emits('pushMain')" class="flex items-center gap-4 px-4 py-3 bg-gray-50 rounded-md dark:bg-gray-800">
346
- <a-icon-menu/>
87
+ <nuxt-link
88
+ to="/"
89
+ class="flex items-center justify-center gap-2 rounded-2xl bg-gray-100 px-4 py-3 text-sm font-semibold text-deepblue-900 transition-colors hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-100 dark:hover:bg-gray-700"
90
+ @click="onReturn"
91
+ >
92
+ <a-icon-menu class="size-5" />
347
93
  {{ t('modals.mobile_navigation.return_button') }}
348
94
  </nuxt-link>
349
95
  </template>
350
- </a-modal>
96
+ </a-modal-v2>
351
97
  </template>
352
98
 
353
- <style scoped>
354
-
355
- </style>
99
+ <style scoped></style>
@@ -56,7 +56,7 @@ const profile: string = 'modals.mobile_navigation.type_profile'
56
56
  </script>
57
57
 
58
58
  <template>
59
- <header class="w-full border-t border-[#9DA3AC80] bg-white dark:bg-gray-900">
59
+ <header class="mx-3 mb-3 overflow-hidden rounded-full border border-deepblue-900/10 bg-gray-50/20 shadow-lg backdrop-blur-lg dark:border-gray-200/10 dark:bg-gray-900/30">
60
60
  <div class="grid w-full grid-cols-3 justify-items-center">
61
61
  <slot>
62
62
  <button
@@ -46,7 +46,7 @@ interface Props {
46
46
  oldVersion?: string
47
47
  }
48
48
 
49
- const { locale } = useI18n()
49
+ const { locale, t } = useI18n()
50
50
 
51
51
  useCurrentModule().value = props.module
52
52
  const { myLayer }: any = useAppConfig()
@@ -119,19 +119,15 @@ onMounted(() => {
119
119
  >
120
120
  <div
121
121
  v-if="mobileHeaderType === 'default'"
122
- class="flex justify-center"
122
+ class="text-deepblue dark:text-[#E3E5E8]"
123
+ @click="goToAnotherModule"
123
124
  >
124
- <div
125
- class="text-deepblue dark:text-[#E3E5E8]"
126
- @click="goToAnotherModule"
127
- >
128
- <span class="visually-hidden"> Сервисы Adata.kz</span>
125
+ <span class="visually-hidden"> Сервисы Adata.kz</span>
129
126
 
130
- <adata-logo
131
- :font-controlled="false"
132
- filled
133
- />
134
- </div>
127
+ <adata-logo
128
+ :font-controlled="false"
129
+ filled
130
+ />
135
131
  </div>
136
132
  <div
137
133
  v-else-if="mobileHeaderType === 'search'"
@@ -142,18 +138,18 @@ onMounted(() => {
142
138
  @click="goToAnotherModule"
143
139
  />
144
140
  <button
145
- class="flex w-full items-center gap-2 rounded-lg border border-gray-200 bg-white px-4 py-1.5 shadow-sm dark:border-gray-700 dark:bg-gray-900 dark:text-gray-400"
141
+ class="flex w-full items-center gap-2 rounded-full border border-gray-300/50 bg-white/30 px-4 py-1.5 backdrop-blur-sm dark:border-gray-600/50 dark:bg-white/5 dark:text-gray-300"
146
142
  @click="$emit('search')"
147
143
  >
148
144
  <a-icon-search class="text-gray-400 dark:text-gray-500" />
149
- <span class="body-400 text-gray-500 dark:text-gray-400">Найти</span>
145
+ <span class="body-400 text-gray-500 dark:text-gray-400">{{ t('header.search') }}</span>
150
146
  </button>
151
147
  </div>
152
148
  </section>
153
- <div class="lg:hidden">
149
+ <div class="flex items-center gap-1 lg:hidden">
150
+ <a-color-mode />
154
151
  <lang-switcher
155
152
  v-if="langIsOn || module === 'fea'"
156
- class="lg:hidden"
157
153
  is-mobile
158
154
  />
159
155
  </div>
@@ -2,10 +2,10 @@
2
2
  import NavList from '#adata-ui/components/navigation/header/NavList.vue'
3
3
  import { useActiveNavigation } from '#adata-ui/composables/useActiveNavigation'
4
4
  import { useHeaderNavigationLinks } from '#adata-ui/composables/useHeaderNavigationLinks'
5
- import { PAGES } from '#adata-ui/shared/constans/pages'
6
5
  import { useUrls } from '#adata-ui/composables/useUrls'
7
6
  import AIconArrowRight from '#adata-ui/icons/arrow/arrow-right.vue'
8
7
  import AIconDownloadRounded from '#adata-ui/icons/download-rounded.vue'
8
+ import { PAGES } from '#adata-ui/shared/constans/pages'
9
9
 
10
10
  defineProps<{ url?: string }>()
11
11
  defineEmits(['outerClick', 'mouseOver'])
@@ -38,7 +38,7 @@ function handleExportClick() {
38
38
  <div class="relative bg-white dark:bg-gray-950">
39
39
  <div class="a-container max-h-[calc(100dvh-4rem)] overflow-y-auto overscroll-contain py-8">
40
40
  <div class="flex justify-between gap-5">
41
- <div class="grid min-w-0 flex-1 grid-cols-5 gap-x-3 gap-y-3">
41
+ <div class="grid min-w-0 flex-1 grid-cols-5 gap-3">
42
42
  <div
43
43
  v-for="(column, index) in catalogColumns"
44
44
  :key="index"
@@ -62,10 +62,10 @@ function handleExportClick() {
62
62
  v-if="module.key === 'edo'"
63
63
  #bottom
64
64
  >
65
- <div class="mt-4 flex flex-col gap-4 rounded-xl bg-blue-700 dark:bg-blue-500 p-4 text-white normal-case">
65
+ <div class="mt-4 flex flex-col gap-4 rounded-xl bg-blue-700 p-4 normal-case text-white dark:bg-blue-500">
66
66
  <div class="flex items-center gap-3">
67
- <span class="p-[10px] bg-white rounded-[10px] dark:bg-gray-950">
68
- <AIconDownloadRounded class="size-5 text-blue-700 dark:text-blue-500" />
67
+ <span class="rounded-[10px] bg-white p-[10px] dark:bg-gray-950">
68
+ <a-icon-download-rounded class="size-5 text-blue-700 dark:text-blue-500" />
69
69
  </span>
70
70
  <span class="font-semibold text-white dark:text-gray-950">
71
71
  {{ t('header.products.exportCard.title') }}
@@ -78,14 +78,14 @@ function handleExportClick() {
78
78
 
79
79
  <a-button-v2
80
80
  view="soft"
81
- class="!h-9 w-fit !bg-white dark:!bg-gray-950 text-blue-700 dark:text-blue-500"
81
+ class="!h-9 w-fit !bg-white text-blue-700 dark:!bg-gray-950 dark:text-blue-500"
82
82
  size="sm"
83
83
  :icon="AIconArrowRight"
84
84
  icon-right
85
85
  @click="handleExportClick"
86
86
  >
87
87
  <span class="text-sm">
88
- {{ t('header.products.exportCard.receive') }}
88
+ {{ t('header.products.exportCard.receive') }}
89
89
  </span>
90
90
  </a-button-v2>
91
91
  </div>
@@ -18,15 +18,19 @@ const props = withDefaults(defineProps<{
18
18
  block?: boolean
19
19
  disabled?: boolean
20
20
  size?: 'sm' | 'md'
21
+ scrollIntoView?: boolean
21
22
  }>(), {
22
23
  showCount: false,
23
24
  block: false,
24
25
  disabled: false,
25
26
  size: 'sm',
27
+ scrollIntoView: false,
26
28
  })
27
29
 
28
30
  const emit = defineEmits<{ (e: 'update:modelValue', value: string): void }>()
29
31
 
32
+ const listRef = ref<HTMLElement | null>(null)
33
+
30
34
  const SIZE_CLASS: Record<'sm' | 'md', string> = {
31
35
  sm: 'text-xs',
32
36
  md: 'text-sm',
@@ -55,6 +59,17 @@ function select(option: PillTab) {
55
59
  if (isDisabled(option)) return
56
60
  emit('update:modelValue', option.key)
57
61
  }
62
+
63
+ function scrollActiveIntoView() {
64
+ if (!props.scrollIntoView) return
65
+ nextTick(() => {
66
+ const active = listRef.value?.querySelector<HTMLElement>('[aria-selected="true"]')
67
+ active?.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' })
68
+ })
69
+ }
70
+
71
+ watch(() => props.modelValue, scrollActiveIntoView)
72
+ onMounted(scrollActiveIntoView)
58
73
  </script>
59
74
 
60
75
  <template>
@@ -67,6 +82,7 @@ function select(option: PillTab) {
67
82
  :aria-disabled="disabled || undefined"
68
83
  >
69
84
  <div
85
+ ref="listRef"
70
86
  role="tablist"
71
87
  :aria-label="ariaLabel"
72
88
  class="pill-tabs-v2__list flex w-full flex-nowrap items-center gap-1 overflow-x-auto"
@@ -86,7 +102,7 @@ function select(option: PillTab) {
86
102
  isDisabled(option)
87
103
  ? 'cursor-not-allowed text-gray-300 dark:text-gray-600'
88
104
  : modelValue === option.key
89
- ? 'text-deepblue-900 bg-white shadow-sm dark:bg-gray-700 dark:text-gray-100 dark:shadow-none dark:ring-1 dark:ring-inset dark:ring-white/10'
105
+ ? 'bg-white text-deepblue-900 shadow-sm dark:bg-gray-700 dark:text-gray-100 dark:shadow-none dark:ring-1 dark:ring-inset dark:ring-white/10'
90
106
  : 'text-gray-700 hover:bg-white/70 hover:text-gray-900 dark:text-gray-200 dark:hover:bg-white/[0.06] dark:hover:text-gray-100',
91
107
  block ? 'flex-1 basis-0 justify-center' : 'shrink-0',
92
108
  ]"
@@ -14,6 +14,7 @@ const props = withDefaults(defineProps<{
14
14
  transition?: boolean
15
15
  contentClass?: string
16
16
  hideHeader?: boolean
17
+ hideClose?: boolean
17
18
  blur?: boolean | 'sm' | 'md' | 'lg' | 'xl'
18
19
  mobileSheet?: boolean
19
20
  swipeToClose?: boolean
@@ -27,6 +28,7 @@ const props = withDefaults(defineProps<{
27
28
  persistent: false,
28
29
  transition: true,
29
30
  hideHeader: false,
31
+ hideClose: false,
30
32
  blur: false,
31
33
  mobileSheet: true,
32
34
  swipeToClose: true,
@@ -311,6 +313,7 @@ function onTouchEnd() {
311
313
  </h2>
312
314
  </slot>
313
315
  <button
316
+ v-if="!hideClose"
314
317
  type="button"
315
318
  class="ml-auto rounded-md p-1 transition hover:bg-gray-100 dark:hover:bg-gray-800 dark:hover:text-gray-200"
316
319
  @click="closeIfAllowed"
package/lang/en.ts CHANGED
@@ -380,6 +380,7 @@ const EnLocale: RuLocale = {
380
380
  toContacts: 'Go to Contacts page',
381
381
  },
382
382
  login: 'Login',
383
+ search: 'Search',
383
384
  oldVersion: 'Old version of the site',
384
385
  notifications: {
385
386
  title: 'Notifications',
package/lang/kk.ts CHANGED
@@ -381,6 +381,7 @@ const KkLocale: RuLocale = {
381
381
  toContacts: 'Байланыс бетіне өту',
382
382
  },
383
383
  login: 'Кіру',
384
+ search: 'Іздеу',
384
385
  oldVersion: 'Сайттың ескі нұсқасы',
385
386
  notifications: {
386
387
  title: 'Хабарландырулар',
package/lang/ru.ts CHANGED
@@ -380,6 +380,7 @@ const RuLocale = {
380
380
  toContacts: 'На страницу Контакты',
381
381
  },
382
382
  login: 'Войти',
383
+ search: 'Найти',
383
384
  oldVersion: 'Старая версия сайта',
384
385
  notifications: {
385
386
  title: 'Уведомления',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "adata-ui",
3
3
  "type": "module",
4
- "version": "2.1.40-beta.10",
4
+ "version": "2.1.40-beta.11",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "dev": "nuxi dev .playground",