@coopenomics/desktop 2025.11.11-alpha-1 → 2025.11.13-alpha-1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coopenomics/desktop",
3
- "version": "2025.11.11-alpha-1",
3
+ "version": "2025.11.13-alpha-1",
4
4
  "description": "A Desktop Project",
5
5
  "productName": "Desktop App",
6
6
  "author": "Alex Ant <dacom.dark.sun@gmail.com>",
@@ -25,9 +25,9 @@
25
25
  "start": "node -r ./alias-resolver.js dist/ssr/index.js"
26
26
  },
27
27
  "dependencies": {
28
- "@coopenomics/controller": "2025.11.11-alpha-1",
29
- "@coopenomics/notifications": "2025.11.11-alpha-1",
30
- "@coopenomics/sdk": "2025.11.11-alpha-1",
28
+ "@coopenomics/controller": "2025.11.13-alpha-1",
29
+ "@coopenomics/notifications": "2025.11.13-alpha-1",
30
+ "@coopenomics/sdk": "2025.11.13-alpha-1",
31
31
  "@dicebear/collection": "^9.0.1",
32
32
  "@dicebear/core": "^9.0.1",
33
33
  "@editorjs/code": "^2.9.3",
@@ -59,7 +59,7 @@
59
59
  "@wharfkit/wallet-plugin-privatekey": "^1.1.0",
60
60
  "axios": "^1.2.1",
61
61
  "compression": "^1.7.4",
62
- "cooptypes": "2025.11.11-alpha-1",
62
+ "cooptypes": "2025.11.13-alpha-1",
63
63
  "dompurify": "^3.1.7",
64
64
  "dotenv": "^16.4.5",
65
65
  "email-regex": "^5.0.0",
@@ -123,5 +123,5 @@
123
123
  "npm": ">= 6.13.4",
124
124
  "yarn": ">= 1.21.1"
125
125
  },
126
- "gitHead": "5b3c9c90552b081e0a4532048329454c0e43132a"
126
+ "gitHead": "d0f73c32bb68d8f7451ecef3989bdff4629d71c4"
127
127
  }
@@ -0,0 +1,26 @@
1
+ import { client } from 'src/shared/api/client';
2
+ import { Queries } from '@coopenomics/sdk';
3
+
4
+ /**
5
+ * Тип текущего инстанса из GraphQL API
6
+ */
7
+ export type CurrentInstance = Queries.System.GetCurrentInstance.IOutput[typeof Queries.System.GetCurrentInstance.name];
8
+
9
+ /**
10
+ * Получить текущий инстанс авторизованного пользователя
11
+ */
12
+ export async function getCurrentInstance(): Promise<CurrentInstance | null> {
13
+ try {
14
+ const { [Queries.System.GetCurrentInstance.name]: instance } =
15
+ await client.Query(Queries.System.GetCurrentInstance.query);
16
+
17
+ return instance;
18
+ } catch (error) {
19
+ console.error('Ошибка при получении текущего инстанса:', error);
20
+ return null;
21
+ }
22
+ }
23
+
24
+ export const api = {
25
+ getCurrentInstance
26
+ };
@@ -1 +1,2 @@
1
+ export * from './api'
1
2
  export * from './model'
@@ -3,6 +3,7 @@ import { ref } from 'vue'
3
3
  import { DigitalDocument } from 'src/shared/lib/document'
4
4
  import { useSessionStore } from 'src/entities/Session'
5
5
  import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives'
6
+ import { getCurrentInstance, type CurrentInstance } from '../api'
6
7
  import type { ITariff, IConnectionAgreementState, ICooperativeFormData } from './types'
7
8
 
8
9
 
@@ -15,6 +16,10 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
15
16
  const isInitialized = ref<boolean>(false)
16
17
  const document = ref<any>(null)
17
18
  const signedDocument = ref<any>(null)
19
+ const currentInstance = ref<CurrentInstance | null>(null)
20
+ const currentInstanceLoading = ref<boolean>(false)
21
+ const currentInstanceError = ref<string | null>(null)
22
+ const coop = ref<any>(null)
18
23
  const formData = ref<ICooperativeFormData>({
19
24
  announce: '',
20
25
  initial: '',
@@ -44,6 +49,10 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
44
49
  signedDocument.value = doc
45
50
  }
46
51
 
52
+ const setCoop = (coopData: any) => {
53
+ coop.value = coopData
54
+ }
55
+
47
56
  const setFormData = (data: ICooperativeFormData) => {
48
57
  formData.value = data
49
58
  }
@@ -113,20 +122,54 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
113
122
  const session = useSessionStore()
114
123
 
115
124
  try {
116
- const coop = await loadOneCooperative(session.username)
117
- return coop
125
+ const coopData = await loadOneCooperative(session.username)
126
+ coop.value = coopData
127
+ return coopData
118
128
  } catch (error) {
119
129
  console.error('Ошибка при перезагрузке кооператива:', error)
120
130
  throw error
121
131
  }
122
132
  }
123
133
 
134
+ const loadCurrentInstance = async () => {
135
+ try {
136
+ currentInstanceLoading.value = true
137
+ currentInstanceError.value = null
138
+ currentInstance.value = await getCurrentInstance()
139
+ console.log('Текущий инстанс загружен:', currentInstance.value)
140
+ } catch (error: any) {
141
+ currentInstanceError.value = error.message || 'Ошибка загрузки инстанса'
142
+ // Очищаем старые данные при ошибке - они больше не актуальны
143
+ currentInstance.value = null
144
+ console.error('Ошибка при загрузке текущего инстанса:', error)
145
+ } finally {
146
+ currentInstanceLoading.value = false
147
+ }
148
+ }
149
+
150
+ const startInstanceAutoRefresh = (intervalMs = 30000) => { // 30 секунд по умолчанию
151
+ loadCurrentInstance() // Первая загрузка
152
+
153
+ const interval = setInterval(() => {
154
+ loadCurrentInstance()
155
+ }, intervalMs)
156
+
157
+ // Функция для остановки автообновления
158
+ const stop = () => clearInterval(interval)
159
+
160
+ return stop
161
+ }
162
+
124
163
  const reset = () => {
125
164
  currentStep.value = 1
126
165
  selectedTariff.value = null
127
166
  isInitialized.value = false
128
167
  document.value = null
129
168
  signedDocument.value = null
169
+ currentInstance.value = null
170
+ currentInstanceLoading.value = false
171
+ currentInstanceError.value = null
172
+ coop.value = null
130
173
  formData.value = {
131
174
  announce: '',
132
175
  initial: '',
@@ -152,6 +195,9 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
152
195
  if (state.signedDocument !== undefined) {
153
196
  signedDocument.value = state.signedDocument
154
197
  }
198
+ if (state.coop !== undefined) {
199
+ coop.value = state.coop
200
+ }
155
201
  if (state.formData !== undefined && state.formData !== null) {
156
202
  formData.value = state.formData
157
203
  }
@@ -164,6 +210,10 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
164
210
  isInitialized,
165
211
  document,
166
212
  signedDocument,
213
+ currentInstance,
214
+ currentInstanceLoading,
215
+ currentInstanceError,
216
+ coop,
167
217
  formData,
168
218
 
169
219
  // Methods
@@ -172,6 +222,7 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
172
222
  setInitialized,
173
223
  setDocument,
174
224
  setSignedDocument,
225
+ setCoop,
175
226
  setFormData,
176
227
  reset,
177
228
  initialize,
@@ -180,7 +231,9 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
180
231
  generateDocument,
181
232
  signDocument,
182
233
  clearSignedDocument,
183
- reloadCooperative
234
+ reloadCooperative,
235
+ loadCurrentInstance,
236
+ startInstanceAutoRefresh
184
237
  }
185
238
  }, {
186
239
  persist: true
@@ -21,5 +21,6 @@ export interface IConnectionAgreementState {
21
21
  isInitialized: boolean
22
22
  document?: any
23
23
  signedDocument?: any
24
+ coop?: any
24
25
  formData?: ICooperativeFormData
25
26
  }
@@ -59,6 +59,7 @@ export function useProviderSubscriptions() {
59
59
  */
60
60
  const loadSubscriptions = async () => {
61
61
  // Проверяем доступность провайдера
62
+ console.log('system.info', system.info);
62
63
  if (!system.info.is_providered) {
63
64
  error.value = 'Функционал провайдера не доступен';
64
65
  return;
@@ -68,6 +69,7 @@ export function useProviderSubscriptions() {
68
69
  isLoading.value = true;
69
70
  error.value = null;
70
71
  subscriptions.value = await loadProviderSubscriptions();
72
+ console.log('subscriptions', subscriptions.value);
71
73
  } catch (err: any) {
72
74
  error.value = err.message || 'Ошибка загрузки подписок';
73
75
  console.error('Error loading provider subscriptions:', err);
@@ -1,44 +1,69 @@
1
1
  <template lang="pug">
2
2
  div
3
3
  Form(:handler-submit="saveData" :showCancel="false" :button-cancel-txt="'Отменить'" :button-submit-txt="'Продолжить'" @cancel="clear").q-gutter-md
4
- q-input(standout="bg-teal text-white" hint="domovoy.com или coop.domovoy.com" label="Домен или поддомен для запуска" v-model="connectionAgreement.formData.announce" :rules="[val => notEmpty(val), val => isDomain(val)]")
4
+ q-input(standout="bg-teal text-white" hint="domovoy.com или coop.domovoy.com" label="Домен или поддомен для запуска" v-model="formData.announce" :rules="[val => notEmpty(val), val => isDomain(val)]")
5
5
 
6
- q-input(standout="bg-teal text-white" hint="100 RUB" label="Вступительный взнос для физлиц и ИП" v-model="connectionAgreement.formData.initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
6
+ q-input(standout="bg-teal text-white" placeholder="100" label="Вступительный взнос для физлиц и ИП" v-model="formData.initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
7
7
  template(#append)
8
8
  span.text-overline RUB
9
9
 
10
- q-input(standout="bg-teal text-white" label="Минимальный паевый взнос для физлиц и ИП" hint="300 RUB" v-model="connectionAgreement.formData.minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
10
+ q-input(standout="bg-teal text-white" label="Минимальный паевый взнос для физлиц и ИП" placeholder="300" v-model="formData.minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
11
11
  template(#append)
12
12
  span.text-overline RUB
13
13
 
14
- q-input(standout="bg-teal text-white" hint="1000 RUB" label="Вступительный взнос для организаций" v-model="connectionAgreement.formData.org_initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
14
+ q-input(standout="bg-teal text-white" placeholder="1000" label="Вступительный взнос для организаций" v-model="formData.org_initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
15
15
  template(#append)
16
16
  span.text-overline RUB
17
17
 
18
- q-input(standout="bg-teal text-white" hint="3000 RUB" label="Минимальный паевый взнос для организаций" v-model="connectionAgreement.formData.org_minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
18
+ q-input(standout="bg-teal text-white" placeholder="3000" label="Минимальный паевый взнос для организаций" v-model="formData.org_minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
19
19
  template(#append)
20
20
  span.text-overline RUB
21
21
  </template>
22
22
  <script lang="ts" setup>
23
+ import { ref, watch } from 'vue'
23
24
  import { Form } from 'src/shared/ui/Form';
24
25
  import { notEmpty, isDomain } from 'src/shared/lib/utils';
25
26
  import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement';
27
+ import type { ICooperativeFormData } from 'src/entities/ConnectionAgreement/model/types';
26
28
 
27
29
 
28
30
  const emit = defineEmits(['continue'])
29
31
 
30
32
  const connectionAgreement = useConnectionAgreementStore()
31
33
 
32
- // Данные напрямую из стора (уже инициализированы с дефолтными значениями)
34
+ // Локальное состояние формы для избежания проблем с реактивностью
35
+ const formData = ref<ICooperativeFormData>({
36
+ announce: connectionAgreement.formData.announce || '',
37
+ initial: connectionAgreement.formData.initial || '',
38
+ minimum: connectionAgreement.formData.minimum || '',
39
+ org_initial: connectionAgreement.formData.org_initial || '',
40
+ org_minimum: connectionAgreement.formData.org_minimum || ''
41
+ })
42
+
43
+ // Синхронизируем локальное состояние с изменениями в store
44
+ watch(() => connectionAgreement.formData, (newFormData) => {
45
+ formData.value = {
46
+ announce: newFormData.announce || '',
47
+ initial: newFormData.initial || '',
48
+ minimum: newFormData.minimum || '',
49
+ org_initial: newFormData.org_initial || '',
50
+ org_minimum: newFormData.org_minimum || ''
51
+ }
52
+ }, { deep: true })
53
+
54
+ // Синхронизируем локальное состояние с store при изменении
55
+ const syncFormData = () => {
56
+ connectionAgreement.setFormData(formData.value)
57
+ }
33
58
 
34
59
  const clear = () => {
35
60
  emit('continue')
36
61
  }
37
62
 
38
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
- const saveData = async (e?: Event) => {
40
- console.log('📤 CooperativeDataForm: Данные формы:', connectionAgreement.formData)
41
- // Данные уже сохранены в сторе напрямую
42
- emit('continue', connectionAgreement.formData)
63
+ const saveData = async () => {
64
+ console.log('📤 CooperativeDataForm: Данные формы:', formData.value)
65
+ // Синхронизируем данные с store перед отправкой
66
+ syncFormData()
67
+ emit('continue', formData.value)
43
68
  }
44
69
  </script>
@@ -2,15 +2,16 @@
2
2
  div.row.q-pa-md
3
3
  div.col-md-12.col-xs-12
4
4
  div(v-if="system.info.is_providered")
5
- ConnectionAgreementStepper(
6
- :coop="coop"
7
- :domain-valid="domainValid"
8
- :installation-progress="installationProgress"
9
- :instance-status="instanceStatus"
10
- :subscriptions-loading="subscriptionsLoading"
11
- :subscriptions-error="subscriptionsError"
5
+
6
+ //- Показываем дашборд если установка завершена
7
+ ConnectionDashboard(
8
+ v-if="isInstallationCompleted"
12
9
  )
13
10
 
11
+ //- Показываем степпер если установка не завершена
12
+ ConnectionAgreementStepper(v-else)
13
+
14
+
14
15
  div(v-else).row
15
16
  //- Заглушка для недоступного провайдера
16
17
  div.col-md-12.col-xs-12
@@ -28,44 +29,35 @@ div.row.q-pa-md
28
29
 
29
30
  </template>
30
31
  <script setup lang="ts">
31
- import { ref, onMounted, onUnmounted, watch } from 'vue';
32
- import { useSessionStore } from 'src/entities/Session';
32
+ import { computed, onMounted, onUnmounted, watch } from 'vue';
33
33
  import { useSystemStore } from 'src/entities/System/model';
34
34
  import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement';
35
- import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives';
36
- import { useProviderSubscriptions } from 'src/features/Provider';
37
35
  import { ConnectionAgreementStepper } from 'src/widgets/ConnectionAgreementStepper';
36
+ import { ConnectionDashboard } from 'src/widgets/ConnectionDashboard';
38
37
  import { ColorCard } from 'src/shared/ui';
38
+ import {Zeus} from '@coopenomics/sdk';
39
39
 
40
- const session = useSessionStore()
41
40
  const system = useSystemStore()
42
41
  const connectionAgreement = useConnectionAgreementStore()
43
- const { loadOneCooperative } = useLoadCooperatives()
44
- const {
45
- domainValid,
46
- installationProgress,
47
- instanceStatus,
48
- isLoading: subscriptionsLoading,
49
- error: subscriptionsError,
50
- startAutoRefresh
51
- } = useProviderSubscriptions()
52
-
53
- const coop = ref()
54
42
 
55
43
  // Остановка автообновления при размонтировании компонента
56
- let stopRefresh: (() => void) | null = null
44
+ let stopInstanceRefresh: (() => void) | null = null
45
+
46
+ // Проверка завершения установки
47
+ const isInstallationCompleted = computed(() => {
48
+ // Не показываем поздравление если идет загрузка или есть ошибка
49
+ if (connectionAgreement.currentInstanceLoading || connectionAgreement.currentInstanceError) {
50
+ return false
51
+ }
52
+
53
+ const instance = connectionAgreement.currentInstance
54
+ return instance?.progress === 100 && instance?.status === Zeus.InstanceStatus.ACTIVE
55
+ })
57
56
 
58
57
  const openProviderWebsite = () => {
59
58
  window.open('https://цифровой-кооператив.рф', '_blank')
60
59
  }
61
60
 
62
- // Загружаем кооператив
63
- const loadCooperative = async () => {
64
- if (system.info.is_providered) {
65
- coop.value = await loadOneCooperative(session.username)
66
- }
67
- }
68
-
69
61
  const init = async () => {
70
62
  // Инициализация имеет смысл только если провайдер доступен
71
63
  if (!system.info.is_providered) return
@@ -75,41 +67,63 @@ const init = async () => {
75
67
  connectionAgreement.setInitialized(true)
76
68
  }
77
69
 
78
- // Загружаем кооператив
79
- await loadCooperative()
80
-
81
- // Если кооператив существует, инициализируем данные формы из него
82
- if (coop.value) {
83
- const formData = {
84
- announce: coop.value.announce || '',
85
- initial: parseFloat(coop.value.initial || '0').toString(),
86
- minimum: parseFloat(coop.value.minimum || '0').toString(),
87
- org_initial: parseFloat(coop.value.org_initial || '0').toString(),
88
- org_minimum: parseFloat(coop.value.org_minimum || '0').toString()
89
- }
90
- connectionAgreement.setFormData(formData)
91
- }
92
- }
93
-
94
- const finish = () => {
95
- // Эта функция имеет смысл только если провайдер доступен
96
- if (!system.info.is_providered) return
97
70
 
98
- // Запускаем автообновление подписок каждую минуту
99
- if (!stopRefresh) {
100
- stopRefresh = startAutoRefresh(60000) // 1 минута
101
- }
71
+ // Загружаем текущий инстанс
72
+ await connectionAgreement.loadCurrentInstance()
102
73
 
103
- // Сбрасываем persistent состояние после завершения
104
- connectionAgreement.reset()
74
+ // Запускаем автообновление инстанса каждые 30 секунд
75
+ stopInstanceRefresh = connectionAgreement.startInstanceAutoRefresh(30000)
105
76
  }
106
77
 
107
- // Watch за изменением шага для автоматического завершения
108
- watch(() => connectionAgreement.currentStep, (newStep) => {
109
- if (newStep >= 5) {
110
- finish()
78
+ // Watch за изменением currentInstance для автоматического перехода между шагами
79
+ watch(() => connectionAgreement.currentInstance, (instance) => {
80
+ // Не обрабатываем изменения если идет загрузка или есть ошибка
81
+ if (connectionAgreement.currentInstanceLoading || connectionAgreement.currentInstanceError) {
82
+ return
111
83
  }
112
- })
84
+
85
+ if (!instance) return
86
+
87
+ const currentStep = connectionAgreement.currentStep
88
+
89
+ console.log('📊 Instance обновлен:', {
90
+ step: currentStep,
91
+ is_valid: instance.is_valid,
92
+ is_delegated: instance.is_delegated,
93
+ blockchain_status: instance.blockchain_status,
94
+ progress: instance.progress,
95
+ status: instance.status
96
+ })
97
+
98
+ // Логика автоматических переходов (только для шагов 4, 5, 6)
99
+ if (currentStep === 4) {
100
+ // Шаг 4: Проверка домена
101
+ if (instance.is_valid && instance.is_delegated) {
102
+ // Домен валиден и делегирован
103
+ if (instance.blockchain_status === 'active') {
104
+ // Можно переходить сразу к установке
105
+ console.log('✅ Домен готов и blockchain_status активен → переход к шагу 6')
106
+ connectionAgreement.setCurrentStep(6)
107
+ } else {
108
+ // Ожидаем подтверждения от союза
109
+ console.log('⏳ Домен готов, но ожидаем подтверждения → переход к шагу 5')
110
+ connectionAgreement.setCurrentStep(5)
111
+ }
112
+ }
113
+ } else if (currentStep === 5) {
114
+ // Шаг 5: Ожидание подтверждения от союза
115
+ if (instance.blockchain_status === 'active') {
116
+ console.log('✅ Подтверждение получено → переход к шагу 6')
117
+ connectionAgreement.setCurrentStep(6)
118
+ }
119
+ } else if (currentStep === 6) {
120
+ // Шаг 6: Установка
121
+ if (instance.progress === 100 && instance.status === Zeus.InstanceStatus.ACTIVE) {
122
+ console.log('🎉 Установка завершена!')
123
+ // Не переходим автоматически, просто покажется дашборд через computed
124
+ }
125
+ }
126
+ }, { deep: true })
113
127
 
114
128
  // Lifecycle хуки
115
129
  onMounted(() => {
@@ -121,16 +135,10 @@ onMounted(() => {
121
135
  })
122
136
 
123
137
  onUnmounted(() => {
124
- // Останавливаем автообновление при размонтировании компонента
125
- if (stopRefresh) {
126
- stopRefresh()
127
- stopRefresh = null
138
+ // Останавливаем автообновление инстанса при размонтировании компонента
139
+ if (stopInstanceRefresh) {
140
+ stopInstanceRefresh()
141
+ stopInstanceRefresh = null
128
142
  }
129
143
  })
130
-
131
- /**
132
- * Здесь необходимо получить соглашение для подключения и проверить заполнено ли оно.
133
- *
134
- *
135
- */
136
144
  </script>
@@ -4,6 +4,8 @@ import type { IStepProps } from '../model/types'
4
4
  import { DocumentHtmlReader } from 'src/shared/ui/DocumentHtmlReader'
5
5
  import { Loader } from 'src/shared/ui/Loader'
6
6
  import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
7
+ import { useAddCooperative } from 'src/features/Union/AddCooperative/model'
8
+ import { useSessionStore } from 'src/entities/Session'
7
9
 
8
10
  const props = withDefaults(defineProps<IStepProps & {
9
11
  html?: string
@@ -16,13 +18,52 @@ const isDone = computed(() => props.isDone)
16
18
 
17
19
  const handleSign = async () => {
18
20
  try {
21
+ console.log('📝 AgreementStep: Подписываем документ')
19
22
  await connectionAgreement.signDocument()
20
- // Переходим к следующему шагу после подписания
23
+
24
+ console.log('🔗 AgreementStep: Отправляем транзакцию registerCooperative в блокчейн')
25
+ const { addCooperative } = useAddCooperative()
26
+ const session = useSessionStore()
27
+
28
+ // Формируем данные для registerCooperative действия
29
+ const registerData = {
30
+ coopname: session.username,
31
+ params: {
32
+ is_cooperative: true,
33
+ coop_type: 'conscoop',
34
+ announce: connectionAgreement.formData.announce,
35
+ description: '',
36
+ initial: connectionAgreement.formData.initial,
37
+ minimum: connectionAgreement.formData.minimum,
38
+ org_initial: connectionAgreement.formData.org_initial,
39
+ org_minimum: connectionAgreement.formData.org_minimum
40
+ },
41
+ username: session.username,
42
+ document: connectionAgreement.signedDocument
43
+ }
44
+
45
+ // Отправляем данные формы в блокчейн
46
+ await addCooperative(registerData)
47
+
48
+ console.log('✅ AgreementStep: Транзакция успешно отправлена')
49
+
50
+ // Обновляем информацию о кооперативе из блокчейна
51
+ console.log('🔄 AgreementStep: Обновляем информацию о кооперативе')
52
+ await connectionAgreement.reloadCooperative()
53
+
54
+ // Обновляем информацию об инстансе
55
+ console.log('🔄 AgreementStep: Обновляем информацию об инстансе')
56
+ await connectionAgreement.loadCurrentInstance()
57
+
58
+ console.log('✅ AgreementStep: Информация обновлена')
59
+
60
+ // Переходим к следующему шагу после подписания и отправки в блокчейн
21
61
  if (connectionAgreement.currentStep < 5) {
22
62
  connectionAgreement.setCurrentStep(connectionAgreement.currentStep + 1)
23
63
  }
24
64
  } catch (error) {
25
- console.error('Ошибка подписания документа:', error)
65
+ console.error('Ошибка при подписании или отправке в блокчейн:', error)
66
+ throw error
26
67
  }
27
68
  }
28
69
 
@@ -0,0 +1,81 @@
1
+ <template lang="pug">
2
+ q-step(
3
+ :name="5"
4
+ title="Ожидание подтверждения"
5
+ icon="schedule"
6
+ :done="isDone"
7
+ )
8
+ .q-pa-md
9
+ //- Успех - готово к установке
10
+ .flex.column.items-center.q-pa-lg
11
+ q-icon(name="check_circle" color="positive" size="64px").q-mb-md
12
+ .text-h6.text-center.q-mb-md Техническая подготовка завершена
13
+ .text-body1.text-center.text-grey-7.q-mb-xl
14
+ | Ваш кооператив готов к установке
15
+
16
+ //- Информационная карточка
17
+ q-card(flat).q-mb-lg.bg-grey-1
18
+ q-card-section.q-pa-lg
19
+ .text-subtitle2.q-mb-md.text-weight-medium Ожидание подтверждения
20
+ .text-body2.text-grey-8.q-mb-lg
21
+ | Все готово к установке, но мы ожидаем поступления подтверждения от союза о вашем членстве.
22
+
23
+ .text-body2.text-grey-7.q-mb-md
24
+ | Как только союз подтвердит ваше членство, статус изменится автоматически и установка начнется.
25
+
26
+ .text-body2.text-grey-7
27
+ | Приблизительное время установки после получения подтверждения:
28
+ strong.text-primary 60 минут
29
+
30
+ //- Статус подтверждения
31
+ .flex.justify-center.q-mb-lg
32
+ q-chip(
33
+ :color="getBlockchainStatusColor"
34
+ text-color="white"
35
+ size="md"
36
+ :icon="instance?.blockchain_status === 'active' ? 'check_circle' : 'schedule'"
37
+ )
38
+ span {{ getBlockchainStatusText }}
39
+
40
+ //- Навигация
41
+ q-stepper-navigation.q-gutter-sm
42
+ q-btn(
43
+ color="grey-6"
44
+ flat
45
+ label="Назад"
46
+ @click="handleBack"
47
+ )
48
+ </template>
49
+
50
+ <script setup lang="ts">
51
+ import { computed, withDefaults } from 'vue'
52
+ import type { IStepProps } from '../model/types'
53
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
54
+
55
+ const props = withDefaults(defineProps<IStepProps>(), {})
56
+
57
+ const connectionAgreement = useConnectionAgreementStore()
58
+
59
+ // Получаем данные напрямую из store
60
+ const instance = computed(() => connectionAgreement.currentInstance)
61
+
62
+ const isDone = computed(() => props.isDone)
63
+
64
+ // Цвет статуса блокчейна
65
+ const getBlockchainStatusColor = computed(() => {
66
+ if (instance.value?.blockchain_status === 'active') return 'positive'
67
+ return 'info'
68
+ })
69
+
70
+ // Текст статуса блокчейна
71
+ const getBlockchainStatusText = computed(() => {
72
+ if (instance.value?.blockchain_status === 'active') return 'Подтверждено'
73
+ if (instance.value?.blockchain_status === 'pending') return 'Ожидание подтверждения'
74
+ return 'Не подтверждено'
75
+ })
76
+
77
+ const handleBack = () => {
78
+ connectionAgreement.setCurrentStep(2)
79
+ }
80
+ </script>
81
+