@coopenomics/desktop 2025.11.13-alpha-1 → 2025.11.13-alpha-3
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/extensions/participant/install.ts +16 -1
- package/package.json +6 -6
- package/src/entities/ConnectionAgreement/model/store.ts +2 -2
- package/src/pages/Union/ConnectionAgreement/ConnectionAgreementPage.vue +136 -98
- package/src/pages/Union/ConnectionAgreement/InstallationCompletedPage.vue +221 -0
- package/src/pages/Union/ConnectionAgreement/index.ts +1 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/AgreementStep.vue +1 -1
- package/src/widgets/ConnectionAgreementStepper/Steps/ApprovalWaitingStep.vue +202 -50
- package/src/widgets/ConnectionAgreementStepper/Steps/DomainValidationStep.vue +4 -4
- package/src/widgets/ConnectionAgreementStepper/Steps/FormStep.vue +1 -1
- package/src/widgets/ConnectionAgreementStepper/Steps/InstallationStep.vue +23 -209
- package/src/widgets/ConnectionAgreementStepper/Steps/IntroStep.vue +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { markRaw } from 'vue';
|
|
2
2
|
import { ProfilePage } from 'src/pages/User/ProfilePage';
|
|
3
3
|
import { WalletPage } from 'src/pages/User/WalletPage';
|
|
4
|
-
import { ConnectionAgreementPage } from 'src/pages/Union/ConnectionAgreement';
|
|
4
|
+
import { ConnectionAgreementPage, InstallationCompletedPage } from 'src/pages/Union/ConnectionAgreement';
|
|
5
5
|
import { UserPaymentMethodsPage } from 'src/pages/User/PaymentMethodsPage';
|
|
6
6
|
import { ContactsPage } from 'src/pages/Contacts';
|
|
7
7
|
import { ListOfMeetsPage } from 'src/pages/Cooperative/ListOfMeets';
|
|
@@ -64,6 +64,21 @@ export default async function (): Promise<IWorkspaceConfig[]> {
|
|
|
64
64
|
path: '/:coopname/connect',
|
|
65
65
|
name: 'connect',
|
|
66
66
|
component: markRaw(ConnectionAgreementPage),
|
|
67
|
+
children: [
|
|
68
|
+
{
|
|
69
|
+
path: 'completed',
|
|
70
|
+
name: 'installation-completed',
|
|
71
|
+
component: markRaw(InstallationCompletedPage),
|
|
72
|
+
meta: {
|
|
73
|
+
title: 'Установка завершена',
|
|
74
|
+
icon: 'fas fa-check-circle',
|
|
75
|
+
roles: ['user'],
|
|
76
|
+
conditions: 'isCoop === true && coopname === "voskhod"',
|
|
77
|
+
requiresAuth: true,
|
|
78
|
+
hidden: true,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
],
|
|
67
82
|
},
|
|
68
83
|
{
|
|
69
84
|
meta: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coopenomics/desktop",
|
|
3
|
-
"version": "2025.11.13-alpha-
|
|
3
|
+
"version": "2025.11.13-alpha-3",
|
|
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.13-alpha-
|
|
29
|
-
"@coopenomics/notifications": "2025.11.13-alpha-
|
|
30
|
-
"@coopenomics/sdk": "2025.11.13-alpha-
|
|
28
|
+
"@coopenomics/controller": "2025.11.13-alpha-3",
|
|
29
|
+
"@coopenomics/notifications": "2025.11.13-alpha-3",
|
|
30
|
+
"@coopenomics/sdk": "2025.11.13-alpha-3",
|
|
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.13-alpha-
|
|
62
|
+
"cooptypes": "2025.11.13-alpha-3",
|
|
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": "
|
|
126
|
+
"gitHead": "dab94657557e501109b96a18e0e00db0c00d111e"
|
|
127
127
|
}
|
|
@@ -147,8 +147,8 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
const startInstanceAutoRefresh = (intervalMs = 30000) => { // 30 секунд по умолчанию
|
|
151
|
-
loadCurrentInstance() // Первая загрузка
|
|
150
|
+
const startInstanceAutoRefresh = async (intervalMs = 30000) => { // 30 секунд по умолчанию
|
|
151
|
+
await loadCurrentInstance() // Первая загрузка
|
|
152
152
|
|
|
153
153
|
const interval = setInterval(() => {
|
|
154
154
|
loadCurrentInstance()
|
|
@@ -1,144 +1,182 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
div.row.q-pa-md
|
|
3
3
|
div.col-md-12.col-xs-12
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
q-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
4
|
+
// Лоадер пока идет загрузка данных
|
|
5
|
+
WindowLoader(v-if="isLoading", text="Загрузка данных подключения...")
|
|
6
|
+
|
|
7
|
+
// Основной контент после загрузки
|
|
8
|
+
div(v-else)
|
|
9
|
+
div(v-if="system.info.is_providered")
|
|
10
|
+
//- Показываем дашборд если установка завершена и мы на основной странице
|
|
11
|
+
ConnectionDashboard(v-if="isInstallationCompleted && !isOnCompletionRoute")
|
|
12
|
+
|
|
13
|
+
//- Показываем степпер если идет процесс подключения
|
|
14
|
+
ConnectionAgreementStepper(v-else-if="!isOnCompletionRoute")
|
|
15
|
+
|
|
16
|
+
//- Router view для дочерних страниц (завершение установки) только на дочерних маршрутах
|
|
17
|
+
router-view(v-if="isOnCompletionRoute")
|
|
18
|
+
|
|
19
|
+
div(v-else).row
|
|
20
|
+
//- Заглушка для недоступного провайдера
|
|
21
|
+
div.col-md-12.col-xs-12
|
|
22
|
+
ColorCard(color="blue")
|
|
23
|
+
.text-center.q-pa-md
|
|
24
|
+
q-icon(name="fas fa-info-circle" size="2rem").q-mb-sm
|
|
25
|
+
.text-h6.q-mb-md Подключение к Кооперативной Экономике
|
|
26
|
+
p Для запуска вашего Цифрового Кооператива и подключения к платформе Кооперативной Экономики обратитесь в ПК ВОСХОД.
|
|
27
|
+
q-btn(
|
|
28
|
+
color="primary"
|
|
29
|
+
label="Перейти на сайт"
|
|
30
|
+
@click="openProviderWebsite"
|
|
31
|
+
size="md"
|
|
32
|
+
).q-mt-md
|
|
29
33
|
|
|
30
34
|
</template>
|
|
31
35
|
<script setup lang="ts">
|
|
32
|
-
import { computed, onMounted, onUnmounted, watch } from 'vue';
|
|
36
|
+
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
|
|
37
|
+
import { useRouter } from 'vue-router';
|
|
33
38
|
import { useSystemStore } from 'src/entities/System/model';
|
|
34
39
|
import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement';
|
|
35
40
|
import { ConnectionAgreementStepper } from 'src/widgets/ConnectionAgreementStepper';
|
|
36
41
|
import { ConnectionDashboard } from 'src/widgets/ConnectionDashboard';
|
|
37
42
|
import { ColorCard } from 'src/shared/ui';
|
|
38
|
-
import {
|
|
43
|
+
import { WindowLoader } from 'src/shared/ui/Loader';
|
|
44
|
+
import { Zeus } from '@coopenomics/sdk';
|
|
39
45
|
|
|
40
|
-
const
|
|
41
|
-
const
|
|
46
|
+
const router = useRouter();
|
|
47
|
+
const system = useSystemStore();
|
|
48
|
+
const connectionAgreement = useConnectionAgreementStore();
|
|
49
|
+
|
|
50
|
+
// Лоадер состояния
|
|
51
|
+
const isLoading = ref(true);
|
|
42
52
|
|
|
43
53
|
// Остановка автообновления при размонтировании компонента
|
|
44
|
-
let stopInstanceRefresh: (() => void) | null = null
|
|
54
|
+
let stopInstanceRefresh: (() => void) | null = null;
|
|
55
|
+
|
|
56
|
+
// Редирект теперь делает только InstallationStep.vue
|
|
45
57
|
|
|
46
58
|
// Проверка завершения установки
|
|
47
59
|
const isInstallationCompleted = computed(() => {
|
|
48
|
-
//
|
|
49
|
-
if (
|
|
50
|
-
|
|
60
|
+
// После загрузки данных проверяем статус установки
|
|
61
|
+
if (!isLoading.value) {
|
|
62
|
+
const instance = connectionAgreement.currentInstance;
|
|
63
|
+
return instance?.progress === 100 && instance?.status === Zeus.InstanceStatus.ACTIVE;
|
|
64
|
+
}
|
|
65
|
+
return false; // Во время загрузки считаем, что установка не завершена
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Проверка, находимся ли мы на маршруте завершения установки
|
|
69
|
+
const isOnCompletionRoute = computed(() => {
|
|
70
|
+
return router.currentRoute.value.name === 'installation-completed';
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Переменная для отслеживания предыдущего состояния завершения установки
|
|
74
|
+
let wasInstallationCompleted = false;
|
|
75
|
+
|
|
76
|
+
// Флаг для отслеживания, был ли уже показан степпер (означает, что пользователь видел процесс установки)
|
|
77
|
+
let hasShownStepper = false;
|
|
78
|
+
|
|
79
|
+
// Следим за завершением установки для редиректа
|
|
80
|
+
watch(isInstallationCompleted, (isCompleted) => {
|
|
81
|
+
// Редирект только при переходе из незавершенного состояния в завершенное
|
|
82
|
+
// и только если пользователь уже видел степпер (т.е. установка шла в реальном времени)
|
|
83
|
+
if (isCompleted && !wasInstallationCompleted && hasShownStepper && !isOnCompletionRoute.value) {
|
|
84
|
+
console.log('🎉 Установка завершена в реальном времени! → переадресация на страницу завершения')
|
|
85
|
+
router.push({ name: 'installation-completed' })
|
|
51
86
|
}
|
|
87
|
+
wasInstallationCompleted = isCompleted
|
|
88
|
+
})
|
|
52
89
|
|
|
53
|
-
|
|
54
|
-
|
|
90
|
+
// Следим за показом степпера
|
|
91
|
+
watch(() => !isInstallationCompleted.value && !isLoading.value && !isOnCompletionRoute.value, (isShowingStepper) => {
|
|
92
|
+
if (isShowingStepper) {
|
|
93
|
+
hasShownStepper = true
|
|
94
|
+
}
|
|
55
95
|
})
|
|
56
96
|
|
|
57
97
|
const openProviderWebsite = () => {
|
|
58
|
-
window.open('https://цифровой-кооператив.рф', '_blank')
|
|
59
|
-
}
|
|
98
|
+
window.open('https://цифровой-кооператив.рф', '_blank');
|
|
99
|
+
};
|
|
60
100
|
|
|
61
101
|
const init = async () => {
|
|
62
102
|
// Инициализация имеет смысл только если провайдер доступен
|
|
63
|
-
if (!system.info.is_providered)
|
|
103
|
+
if (!system.info.is_providered) {
|
|
104
|
+
isLoading.value = false;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
64
107
|
|
|
65
108
|
// Инициализируем persistent store если он еще не инициализирован
|
|
66
109
|
if (!connectionAgreement.isInitialized) {
|
|
67
|
-
connectionAgreement.setInitialized(true)
|
|
110
|
+
connectionAgreement.setInitialized(true);
|
|
68
111
|
}
|
|
69
112
|
|
|
113
|
+
// Запускаем автообновление инстанса каждые 30 секунд (включает начальную загрузку)
|
|
114
|
+
stopInstanceRefresh = await connectionAgreement.startInstanceAutoRefresh(30000);
|
|
70
115
|
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// Запускаем автообновление инстанса каждые 30 секунд
|
|
75
|
-
stopInstanceRefresh = connectionAgreement.startInstanceAutoRefresh(30000)
|
|
76
|
-
}
|
|
116
|
+
// Скрываем лоадер после загрузки данных
|
|
117
|
+
isLoading.value = false;
|
|
118
|
+
};
|
|
77
119
|
|
|
78
120
|
// Watch за изменением currentInstance для автоматического перехода между шагами
|
|
79
|
-
watch(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
})
|
|
121
|
+
watch(
|
|
122
|
+
() => connectionAgreement.currentInstance,
|
|
123
|
+
(instance) => {
|
|
124
|
+
// Не обрабатываем изменения если идет загрузка или есть ошибка
|
|
125
|
+
if (connectionAgreement.currentInstanceLoading || connectionAgreement.currentInstanceError) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
97
128
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
129
|
+
if (!instance) return;
|
|
130
|
+
|
|
131
|
+
const currentStep = connectionAgreement.currentStep;
|
|
132
|
+
|
|
133
|
+
console.log('📊 Instance обновлен:', {
|
|
134
|
+
step: currentStep,
|
|
135
|
+
is_valid: instance.is_valid,
|
|
136
|
+
is_delegated: instance.is_delegated,
|
|
137
|
+
blockchain_status: instance.blockchain_status,
|
|
138
|
+
progress: instance.progress,
|
|
139
|
+
status: instance.status,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Логика автоматических переходов (только для шагов 4, 5, 6)
|
|
143
|
+
if (currentStep === 4) {
|
|
144
|
+
// Шаг 4: Проверка домена
|
|
145
|
+
if (instance.is_valid && instance.is_delegated) {
|
|
146
|
+
// Домен валиден и делегирован
|
|
147
|
+
if (instance.blockchain_status === 'active') {
|
|
148
|
+
// Можно переходить сразу к установке
|
|
149
|
+
console.log('✅ Домен готов и blockchain_status активен → переход к шагу 6');
|
|
150
|
+
connectionAgreement.setCurrentStep(6);
|
|
151
|
+
} else {
|
|
152
|
+
// Ожидаем подтверждения от союза
|
|
153
|
+
console.log('⏳ Домен готов, но ожидаем подтверждения → переход к шагу 5');
|
|
154
|
+
connectionAgreement.setCurrentStep(5);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} else if (currentStep === 5) {
|
|
158
|
+
// Шаг 5: Ожидание подтверждения от союза
|
|
103
159
|
if (instance.blockchain_status === 'active') {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
connectionAgreement.setCurrentStep(6)
|
|
107
|
-
} else {
|
|
108
|
-
// Ожидаем подтверждения от союза
|
|
109
|
-
console.log('⏳ Домен готов, но ожидаем подтверждения → переход к шагу 5')
|
|
110
|
-
connectionAgreement.setCurrentStep(5)
|
|
160
|
+
console.log('✅ Подтверждение получено → переход к шагу 6');
|
|
161
|
+
connectionAgreement.setCurrentStep(6);
|
|
111
162
|
}
|
|
112
163
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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 })
|
|
164
|
+
// Редирект на страницу завершения теперь делает только InstallationStep.vue
|
|
165
|
+
},
|
|
166
|
+
{ deep: true }
|
|
167
|
+
);
|
|
127
168
|
|
|
128
169
|
// Lifecycle хуки
|
|
129
170
|
onMounted(() => {
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
// Если провайдер недоступен - ничего не делаем, показываем заглушку
|
|
135
|
-
})
|
|
171
|
+
// Делаем инициализацию при монтировании компонента
|
|
172
|
+
init();
|
|
173
|
+
});
|
|
136
174
|
|
|
137
175
|
onUnmounted(() => {
|
|
138
176
|
// Останавливаем автообновление инстанса при размонтировании компонента
|
|
139
177
|
if (stopInstanceRefresh) {
|
|
140
|
-
stopInstanceRefresh()
|
|
141
|
-
stopInstanceRefresh = null
|
|
178
|
+
stopInstanceRefresh();
|
|
179
|
+
stopInstanceRefresh = null;
|
|
142
180
|
}
|
|
143
|
-
})
|
|
181
|
+
});
|
|
144
182
|
</script>
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
div.row.q-pa-md
|
|
3
|
+
div.col-md-12.col-xs-12
|
|
4
|
+
.completion-container
|
|
5
|
+
.completion-card
|
|
6
|
+
.completion-header
|
|
7
|
+
.celebration-icon
|
|
8
|
+
q-icon(name="celebration" color="positive" size="80px")
|
|
9
|
+
.sparkle.sparkle-1
|
|
10
|
+
.sparkle.sparkle-2
|
|
11
|
+
.sparkle.sparkle-3
|
|
12
|
+
.completion-title.text-h5.text-positive.q-mt-lg Установка завершена!
|
|
13
|
+
.completion-subtitle.text-body1.text-grey-7.q-mt-sm
|
|
14
|
+
| Ваш Цифровой Кооператив успешно развернут и подключен к платформе
|
|
15
|
+
|
|
16
|
+
.completion-details.q-mt-xl
|
|
17
|
+
.detail-item
|
|
18
|
+
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
19
|
+
.detail-text
|
|
20
|
+
.text-body2.text-weight-medium Серверная инфраструктура
|
|
21
|
+
.text-caption.text-grey-6 Полностью настроена и оптимизирована
|
|
22
|
+
|
|
23
|
+
.detail-item.q-mt-md
|
|
24
|
+
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
25
|
+
.detail-text
|
|
26
|
+
.text-body2.text-weight-medium Блокчейн-узел
|
|
27
|
+
.text-caption.text-grey-6 Развернут, синхронизирован и подключен к сети
|
|
28
|
+
|
|
29
|
+
.detail-item.q-mt-md
|
|
30
|
+
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
31
|
+
.detail-text
|
|
32
|
+
.text-body2.text-weight-medium Базы данных
|
|
33
|
+
.text-caption.text-grey-6 Инициализированы и готовы к работе
|
|
34
|
+
|
|
35
|
+
.detail-item.q-mt-md
|
|
36
|
+
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
37
|
+
.detail-text
|
|
38
|
+
.text-body2.text-weight-medium Сервисы кооператива
|
|
39
|
+
.text-caption.text-grey-6 Запущены и функционируют
|
|
40
|
+
|
|
41
|
+
.next-steps.q-mt-xl
|
|
42
|
+
.text-subtitle2.text-weight-medium.q-mb-md Что дальше?
|
|
43
|
+
.text-body2.text-grey-8.q-mb-lg
|
|
44
|
+
| Для завершения настройки необходимо выполнить финальную конфигурацию на сайте вашего Цифрового Кооператива. Нажмите кнопку ниже, чтобы перейти к управлению подключением, где сможете просматривать статус подключения, управлять подписками и настраивать параметры платформы.
|
|
45
|
+
|
|
46
|
+
q-btn(
|
|
47
|
+
color="primary"
|
|
48
|
+
label="Перейти к управлению подключением"
|
|
49
|
+
@click="goToDashboard"
|
|
50
|
+
size="lg"
|
|
51
|
+
unelevated
|
|
52
|
+
no-caps
|
|
53
|
+
).q-mt-md
|
|
54
|
+
</template>
|
|
55
|
+
|
|
56
|
+
<script setup lang="ts">
|
|
57
|
+
import { useRouter } from 'vue-router'
|
|
58
|
+
|
|
59
|
+
const router = useRouter()
|
|
60
|
+
|
|
61
|
+
const goToDashboard = () => {
|
|
62
|
+
router.push({ name: 'connect' })
|
|
63
|
+
}
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<style scoped>
|
|
67
|
+
.completion-container {
|
|
68
|
+
display: flex;
|
|
69
|
+
justify-content: center;
|
|
70
|
+
align-items: center;
|
|
71
|
+
min-height: 80vh;
|
|
72
|
+
padding: 2rem 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.completion-card {
|
|
76
|
+
max-width: 600px;
|
|
77
|
+
width: 100%;
|
|
78
|
+
text-align: center;
|
|
79
|
+
padding: 3rem;
|
|
80
|
+
border-radius: 24px;
|
|
81
|
+
border: 1px solid rgba(76, 175, 80, 0.1);
|
|
82
|
+
box-shadow:
|
|
83
|
+
0 12px 40px rgba(0, 0, 0, 0.08),
|
|
84
|
+
0 4px 16px rgba(0, 0, 0, 0.04);
|
|
85
|
+
position: relative;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.completion-card::before {
|
|
90
|
+
content: '';
|
|
91
|
+
position: absolute;
|
|
92
|
+
top: 0;
|
|
93
|
+
left: 0;
|
|
94
|
+
right: 0;
|
|
95
|
+
height: 4px;
|
|
96
|
+
background: linear-gradient(90deg, var(--q-positive) 0%, #4CAF50 50%, var(--q-positive) 100%);
|
|
97
|
+
background-size: 200% 100%;
|
|
98
|
+
animation: completion-shimmer 3s cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@keyframes completion-shimmer {
|
|
102
|
+
0%, 100% { background-position: -100% 0; }
|
|
103
|
+
50% { background-position: 100% 0; }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.completion-header {
|
|
107
|
+
position: relative;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.celebration-icon {
|
|
111
|
+
position: relative;
|
|
112
|
+
display: inline-block;
|
|
113
|
+
margin-bottom: 1rem;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.sparkle {
|
|
117
|
+
position: absolute;
|
|
118
|
+
width: 8px;
|
|
119
|
+
height: 8px;
|
|
120
|
+
background: var(--q-positive);
|
|
121
|
+
border-radius: 50%;
|
|
122
|
+
animation: sparkle 2s infinite ease-in-out;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.sparkle-1 {
|
|
126
|
+
top: -10px;
|
|
127
|
+
right: -10px;
|
|
128
|
+
animation-delay: 0s;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.sparkle-2 {
|
|
132
|
+
top: 20px;
|
|
133
|
+
left: -15px;
|
|
134
|
+
animation-delay: 0.5s;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.sparkle-3 {
|
|
138
|
+
bottom: -5px;
|
|
139
|
+
right: 15px;
|
|
140
|
+
animation-delay: 1s;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@keyframes sparkle {
|
|
144
|
+
0%, 100% {
|
|
145
|
+
opacity: 0;
|
|
146
|
+
transform: scale(0);
|
|
147
|
+
}
|
|
148
|
+
50% {
|
|
149
|
+
opacity: 1;
|
|
150
|
+
transform: scale(1);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.completion-title {
|
|
155
|
+
font-weight: 700;
|
|
156
|
+
letter-spacing: -0.5px;
|
|
157
|
+
margin-bottom: 0.5rem;
|
|
158
|
+
background: linear-gradient(135deg, var(--q-positive) 0%, #4CAF50 100%);
|
|
159
|
+
-webkit-background-clip: text;
|
|
160
|
+
-webkit-text-fill-color: transparent;
|
|
161
|
+
background-clip: text;
|
|
162
|
+
text-shadow: 0 2px 4px rgba(76, 175, 80, 0.3);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.completion-details {
|
|
166
|
+
margin-top: 2rem;
|
|
167
|
+
text-align: left;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.detail-item {
|
|
171
|
+
display: flex;
|
|
172
|
+
align-items: center;
|
|
173
|
+
padding: 1rem;
|
|
174
|
+
background: rgba(76, 175, 80, 0.02);
|
|
175
|
+
border-radius: 12px;
|
|
176
|
+
border: 1px solid rgba(76, 175, 80, 0.1);
|
|
177
|
+
transition: all 0.3s ease;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.detail-item:hover {
|
|
181
|
+
transform: translateX(4px);
|
|
182
|
+
background: rgba(76, 175, 80, 0.05);
|
|
183
|
+
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.1);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.detail-text {
|
|
187
|
+
margin-left: 1rem;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.next-steps {
|
|
191
|
+
margin-top: 2rem;
|
|
192
|
+
text-align: left;
|
|
193
|
+
padding: 1.5rem;
|
|
194
|
+
background: rgba(0, 0, 0, 0.02);
|
|
195
|
+
border-radius: 12px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Адаптивность */
|
|
199
|
+
@media (max-width: 768px) {
|
|
200
|
+
.completion-card {
|
|
201
|
+
padding: 2rem;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.detail-item {
|
|
205
|
+
flex-direction: column;
|
|
206
|
+
text-align: center;
|
|
207
|
+
gap: 0.5rem;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.completion-container {
|
|
211
|
+
min-height: 70vh;
|
|
212
|
+
padding: 1rem 0;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@media (max-width: 480px) {
|
|
217
|
+
.completion-card {
|
|
218
|
+
padding: 1.5rem;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
</style>
|
|
@@ -5,46 +5,38 @@
|
|
|
5
5
|
icon="schedule"
|
|
6
6
|
:done="isDone"
|
|
7
7
|
)
|
|
8
|
-
.q-pa-md
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.text-
|
|
27
|
-
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//- Навигация
|
|
41
|
-
q-stepper-navigation.q-gutter-sm
|
|
42
|
-
q-btn(
|
|
43
|
-
color="grey-6"
|
|
44
|
-
flat
|
|
45
|
-
label="Назад"
|
|
46
|
-
@click="handleBack"
|
|
47
|
-
)
|
|
8
|
+
.approval-waiting-container.q-pa-md
|
|
9
|
+
|
|
10
|
+
//- Основная карточка ожидания
|
|
11
|
+
.waiting-card.bg-surface.q-mb-xl
|
|
12
|
+
.waiting-header
|
|
13
|
+
.waiting-icon-container
|
|
14
|
+
q-icon.waiting-icon(
|
|
15
|
+
:name="getWaitingIcon"
|
|
16
|
+
:color="getWaitingIconColor"
|
|
17
|
+
size="80px"
|
|
18
|
+
@click="refreshStatus"
|
|
19
|
+
clickable
|
|
20
|
+
)
|
|
21
|
+
.pulse-ring(v-if="instance?.blockchain_status !== 'active'")
|
|
22
|
+
.waiting-title.text-h5.text-weight-medium.text-primary Ожидание подтверждения союза
|
|
23
|
+
|
|
24
|
+
//- Статусная информация
|
|
25
|
+
.status-info.q-mt-lg
|
|
26
|
+
.status-description.text-body1.text-on-surface
|
|
27
|
+
| Все технические подготовки завершены. Ваш Цифровой Кооператив готов к установке и подключению к платформе Кооперативной Экономики.
|
|
28
|
+
br
|
|
29
|
+
| Теперь мы ожидаем официального подтверждения от союза кооперативов о вашем членстве.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
//- Навигация
|
|
33
|
+
q-stepper-navigation.q-gutter-sm
|
|
34
|
+
q-btn(
|
|
35
|
+
color="grey-6"
|
|
36
|
+
flat
|
|
37
|
+
label="Назад"
|
|
38
|
+
@click="handleBack"
|
|
39
|
+
)
|
|
48
40
|
</template>
|
|
49
41
|
|
|
50
42
|
<script setup lang="ts">
|
|
@@ -61,21 +53,181 @@ const instance = computed(() => connectionAgreement.currentInstance)
|
|
|
61
53
|
|
|
62
54
|
const isDone = computed(() => props.isDone)
|
|
63
55
|
|
|
64
|
-
//
|
|
65
|
-
const
|
|
66
|
-
if (instance.value?.blockchain_status === 'active') return '
|
|
67
|
-
return '
|
|
56
|
+
// Иконка ожидания
|
|
57
|
+
const getWaitingIcon = computed(() => {
|
|
58
|
+
if (instance.value?.blockchain_status === 'active') return 'check_circle'
|
|
59
|
+
return 'schedule'
|
|
68
60
|
})
|
|
69
61
|
|
|
70
|
-
//
|
|
71
|
-
const
|
|
72
|
-
if (instance.value?.blockchain_status === 'active') return '
|
|
73
|
-
|
|
74
|
-
return 'Не подтверждено'
|
|
62
|
+
// Цвет иконки ожидания
|
|
63
|
+
const getWaitingIconColor = computed(() => {
|
|
64
|
+
if (instance.value?.blockchain_status === 'active') return 'positive'
|
|
65
|
+
return 'warning'
|
|
75
66
|
})
|
|
76
67
|
|
|
68
|
+
// Функция обновления статуса
|
|
69
|
+
const refreshStatus = async () => {
|
|
70
|
+
try {
|
|
71
|
+
await connectionAgreement.loadCurrentInstance()
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('Ошибка обновления статуса:', error)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
77
|
const handleBack = () => {
|
|
78
|
-
connectionAgreement.setCurrentStep(
|
|
78
|
+
connectionAgreement.setCurrentStep(4)
|
|
79
79
|
}
|
|
80
80
|
</script>
|
|
81
81
|
|
|
82
|
+
<style scoped>
|
|
83
|
+
.approval-waiting-container {
|
|
84
|
+
max-width: 900px;
|
|
85
|
+
margin: 0 auto;
|
|
86
|
+
position: relative;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Основная карточка ожидания */
|
|
90
|
+
.waiting-card {
|
|
91
|
+
border-radius: 20px;
|
|
92
|
+
padding: 2.5rem;
|
|
93
|
+
box-shadow:
|
|
94
|
+
0 8px 32px rgba(0, 0, 0, 0.08),
|
|
95
|
+
0 2px 8px rgba(0, 0, 0, 0.04);
|
|
96
|
+
position: relative;
|
|
97
|
+
overflow: hidden;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.waiting-card::before {
|
|
101
|
+
content: '';
|
|
102
|
+
position: absolute;
|
|
103
|
+
top: 0;
|
|
104
|
+
left: 0;
|
|
105
|
+
right: 0;
|
|
106
|
+
height: 4px;
|
|
107
|
+
background: linear-gradient(90deg, var(--q-primary) 0%, var(--q-secondary) 50%, var(--q-primary) 100%);
|
|
108
|
+
background-size: 200% 100%;
|
|
109
|
+
animation: shimmer 4s cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@keyframes shimmer {
|
|
113
|
+
0% { background-position: -100% 0; }
|
|
114
|
+
100% { background-position: 100% 0; }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Заголовок карточки */
|
|
118
|
+
.waiting-header {
|
|
119
|
+
text-align: center;
|
|
120
|
+
margin-bottom: 2rem;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.waiting-icon-container {
|
|
124
|
+
position: relative;
|
|
125
|
+
display: inline-block;
|
|
126
|
+
margin-bottom: 1.5rem;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.waiting-icon {
|
|
130
|
+
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15));
|
|
131
|
+
animation: gentle-pulse 3s ease-in-out infinite;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
transition: all 0.3s ease;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.waiting-icon:hover {
|
|
137
|
+
transform: scale(1.1);
|
|
138
|
+
filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.25));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@keyframes gentle-pulse {
|
|
142
|
+
0%, 100% {
|
|
143
|
+
transform: scale(1);
|
|
144
|
+
opacity: 1;
|
|
145
|
+
}
|
|
146
|
+
50% {
|
|
147
|
+
transform: scale(1.05);
|
|
148
|
+
opacity: 0.9;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.pulse-ring {
|
|
153
|
+
position: absolute;
|
|
154
|
+
top: 50%;
|
|
155
|
+
left: 50%;
|
|
156
|
+
transform: translate(-50%, -50%);
|
|
157
|
+
width: 90px;
|
|
158
|
+
height: 90px;
|
|
159
|
+
border: 1px solid rgba(255, 152, 0, 0.2);
|
|
160
|
+
border-radius: 50%;
|
|
161
|
+
animation: pulse-ring 2s cubic-bezier(0.455, 0.03, 0.515, 0.955) infinite;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@keyframes pulse-ring {
|
|
165
|
+
0% {
|
|
166
|
+
transform: translate(-50%, -50%) scale(0.8);
|
|
167
|
+
opacity: 1;
|
|
168
|
+
}
|
|
169
|
+
100% {
|
|
170
|
+
transform: translate(-50%, -50%) scale(1.4);
|
|
171
|
+
opacity: 0;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.waiting-title {
|
|
176
|
+
font-weight: 700;
|
|
177
|
+
letter-spacing: -0.5px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Статусная информация */
|
|
181
|
+
.status-info {
|
|
182
|
+
padding: 1.5rem;
|
|
183
|
+
border-radius: 16px;
|
|
184
|
+
border: 1px solid rgba(255, 152, 0, 0.1);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.status-description {
|
|
188
|
+
line-height: 1.6;
|
|
189
|
+
text-align: center;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
/* Адаптивность */
|
|
196
|
+
@media (max-width: 768px) {
|
|
197
|
+
.waiting-card {
|
|
198
|
+
padding: 2rem;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
.pulse-ring {
|
|
204
|
+
width: 70px;
|
|
205
|
+
height: 70px;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@media (max-width: 480px) {
|
|
210
|
+
.approval-waiting-container {
|
|
211
|
+
padding: 1rem;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.waiting-card {
|
|
215
|
+
padding: 1.5rem;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.waiting-icon {
|
|
219
|
+
font-size: 60px;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.pulse-ring {
|
|
223
|
+
width: 60px;
|
|
224
|
+
height: 60px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.status-info {
|
|
228
|
+
padding: 1rem;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
}
|
|
232
|
+
</style>
|
|
233
|
+
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
span.q-ml-xs {{ instance?.is_delegated ? 'Делегирован' : 'Ожидаем делегирования' }}
|
|
56
56
|
|
|
57
57
|
.instruction-footer
|
|
58
|
-
| Платформа автоматически проверит домен и активирует подключение
|
|
58
|
+
| Платформа Кооперативной Экономики автоматически проверит домен и активирует подключение вашего Цифрового Кооператива
|
|
59
59
|
|
|
60
60
|
//- Навигация
|
|
61
61
|
q-stepper-navigation.q-gutter-sm
|
|
@@ -206,12 +206,12 @@ const copyIpAddress = async () => {
|
|
|
206
206
|
height: 3px;
|
|
207
207
|
background: linear-gradient(90deg, #2196F3 0%, #21CBF3 50%, #2196F3 100%);
|
|
208
208
|
background-size: 200% 100%;
|
|
209
|
-
animation: shimmer 3s
|
|
209
|
+
animation: shimmer 3s cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
@keyframes shimmer {
|
|
213
|
-
0% { background-position: -
|
|
214
|
-
100% { background-position:
|
|
213
|
+
0% { background-position: -100% 0; }
|
|
214
|
+
100% { background-position: 100% 0; }
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
.instruction-header {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
q-step(
|
|
3
3
|
:name="6"
|
|
4
|
-
title="Установка
|
|
4
|
+
title="Установка Цифрового Кооператива"
|
|
5
5
|
icon="cloud_download"
|
|
6
6
|
:done="isDone"
|
|
7
7
|
)
|
|
8
8
|
.installation-container.q-pa-md
|
|
9
9
|
|
|
10
10
|
//- Установка в процессе
|
|
11
|
-
div
|
|
12
|
-
|
|
11
|
+
div
|
|
13
12
|
//- Заголовок с градиентом
|
|
13
|
+
|
|
14
14
|
.installation-header
|
|
15
|
-
.text-h6.installation-title Установка
|
|
15
|
+
.text-h6.installation-title Установка Цифрового Кооператива
|
|
16
16
|
.subtitle.text-body2.text-grey-7.q-mt-sm
|
|
17
|
-
|
|
|
17
|
+
| Подключение к платформе Кооперативной Экономики
|
|
18
18
|
|
|
19
19
|
//- Основная карточка прогресса
|
|
20
20
|
.progress-card.q-mb-xl
|
|
@@ -48,49 +48,6 @@
|
|
|
48
48
|
.stage-description.text-body2.text-grey-7.q-mt-xs {{ currentStageDescription }}
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
//- Установка завершена
|
|
52
|
-
div(v-else)
|
|
53
|
-
.completion-container
|
|
54
|
-
.completion-card
|
|
55
|
-
.completion-header
|
|
56
|
-
.celebration-icon
|
|
57
|
-
q-icon(name="celebration" color="positive" size="80px")
|
|
58
|
-
.sparkle.sparkle-1
|
|
59
|
-
.sparkle.sparkle-2
|
|
60
|
-
.sparkle.sparkle-3
|
|
61
|
-
.completion-title.text-h5.text-positive.q-mt-lg Установка завершена!
|
|
62
|
-
.completion-subtitle.text-body1.text-grey-7.q-mt-sm
|
|
63
|
-
| Ваш кооператив успешно развернут и готов к работе
|
|
64
|
-
|
|
65
|
-
.completion-details.q-mt-xl
|
|
66
|
-
.detail-item
|
|
67
|
-
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
68
|
-
.detail-text
|
|
69
|
-
.text-body2.text-weight-medium Серверная инфраструктура
|
|
70
|
-
.text-caption.text-grey-6 Полностью настроена и оптимизирована
|
|
71
|
-
|
|
72
|
-
.detail-item.q-mt-md
|
|
73
|
-
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
74
|
-
.detail-text
|
|
75
|
-
.text-body2.text-weight-medium Блокчейн интеграция
|
|
76
|
-
.text-caption.text-grey-6 Подключена и протестирована
|
|
77
|
-
|
|
78
|
-
.detail-item.q-mt-md
|
|
79
|
-
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
80
|
-
.detail-text
|
|
81
|
-
.text-body2.text-weight-medium База данных
|
|
82
|
-
.text-caption.text-grey-6 Инициализирована и готова к работе
|
|
83
|
-
|
|
84
|
-
.detail-item.q-mt-md
|
|
85
|
-
q-icon(name="check_circle" color="positive" size="24px").q-mr-md
|
|
86
|
-
.detail-text
|
|
87
|
-
.text-body2.text-weight-medium Платформенные сервисы
|
|
88
|
-
.text-caption.text-grey-6 Запущены и функционируют
|
|
89
|
-
|
|
90
|
-
.next-steps.q-mt-xl
|
|
91
|
-
.text-subtitle2.text-weight-medium.q-mb-md Что дальше?
|
|
92
|
-
.text-body2.text-grey-8
|
|
93
|
-
| Дашборд подключения откроется автоматически через несколько секунд. Здесь вы сможете управлять подписками, просматривать баланс кошелька AXON и настраивать параметры платформы.
|
|
94
51
|
|
|
95
52
|
</template>
|
|
96
53
|
|
|
@@ -117,45 +74,50 @@ const currentStageInfo = computed(() => {
|
|
|
117
74
|
icon: 'settings',
|
|
118
75
|
color: 'primary',
|
|
119
76
|
title: 'Подготовка серверного окружения',
|
|
120
|
-
description: 'Настраиваем
|
|
77
|
+
description: 'Настраиваем инфраструктуру, разворачиваем серверные компоненты и настраиваем файервол'
|
|
121
78
|
}
|
|
122
79
|
} else if (progress < 40) {
|
|
123
80
|
return {
|
|
124
81
|
icon: 'download',
|
|
125
82
|
color: 'info',
|
|
126
|
-
title: 'Загрузка компонентов
|
|
127
|
-
description: 'Устанавливаем
|
|
83
|
+
title: 'Загрузка компонентов Цифрового Кооператива',
|
|
84
|
+
description: 'Устанавливаем программное обеспечение и зависимости для работы платформы'
|
|
128
85
|
}
|
|
129
86
|
} else if (progress < 60) {
|
|
130
87
|
return {
|
|
131
88
|
icon: 'storage',
|
|
132
89
|
color: 'warning',
|
|
133
|
-
title: 'Настройка
|
|
134
|
-
description: '
|
|
90
|
+
title: 'Настройка баз данных и хранилищ',
|
|
91
|
+
description: 'Разворачиваем базы данных, инициализируем структуры и настраиваем резервное копирование'
|
|
135
92
|
}
|
|
136
93
|
} else if (progress < 80) {
|
|
137
94
|
return {
|
|
138
95
|
icon: 'security',
|
|
139
96
|
color: 'secondary',
|
|
140
|
-
title: '
|
|
141
|
-
description: '
|
|
97
|
+
title: 'Запуск блокчейн-узла',
|
|
98
|
+
description: 'Разворачиваем и синхронизируем блокчейн-узел для подключения к Кооперативной Экономике'
|
|
142
99
|
}
|
|
143
100
|
} else {
|
|
144
101
|
return {
|
|
145
102
|
icon: 'check_circle',
|
|
146
103
|
color: 'positive',
|
|
147
104
|
title: 'Финализация установки',
|
|
148
|
-
description: 'Выполняем заключительные
|
|
105
|
+
description: 'Выполняем заключительные настройки, проверяем работоспособность всех компонентов'
|
|
149
106
|
}
|
|
150
107
|
}
|
|
151
108
|
})
|
|
152
109
|
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
153
111
|
const currentStageIcon = computed(() => currentStageInfo.value.icon)
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
154
113
|
const currentStageColor = computed(() => currentStageInfo.value.color)
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
155
115
|
const currentStageTitle = computed(() => currentStageInfo.value.title)
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
156
117
|
const currentStageDescription = computed(() => currentStageInfo.value.description)
|
|
157
118
|
|
|
158
119
|
// Расчет оставшегося времени (общая установка 100 минут)
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
159
121
|
const remainingTime = computed(() => {
|
|
160
122
|
const progress = instance.value?.progress || 0
|
|
161
123
|
const totalMinutes = 100
|
|
@@ -163,12 +125,8 @@ const remainingTime = computed(() => {
|
|
|
163
125
|
return Math.max(0, remaining) // Не показываем отрицательные значения
|
|
164
126
|
})
|
|
165
127
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
watch(() => instance.value?.progress, () => {
|
|
170
|
-
// Ничего не делаем, просто реактивно обновляем отображение
|
|
171
|
-
}, { immediate: true })
|
|
128
|
+
// Редирект теперь обрабатывается в ConnectionAgreementPage через реактивность
|
|
129
|
+
// Здесь только отображение прогресса
|
|
172
130
|
</script>
|
|
173
131
|
|
|
174
132
|
<style scoped>
|
|
@@ -198,7 +156,6 @@ watch(() => instance.value?.progress, () => {
|
|
|
198
156
|
.progress-card {
|
|
199
157
|
border-radius: 20px;
|
|
200
158
|
padding: 2.5rem;
|
|
201
|
-
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
|
202
159
|
border: 1px solid rgba(0, 0, 0, 0.05);
|
|
203
160
|
box-shadow:
|
|
204
161
|
0 8px 32px rgba(0, 0, 0, 0.08),
|
|
@@ -216,12 +173,12 @@ watch(() => instance.value?.progress, () => {
|
|
|
216
173
|
height: 4px;
|
|
217
174
|
background: linear-gradient(90deg, var(--q-primary) 0%, var(--q-secondary) 50%, var(--q-accent) 100%);
|
|
218
175
|
background-size: 200% 100%;
|
|
219
|
-
animation: shimmer 4s
|
|
176
|
+
animation: shimmer 4s cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
|
|
220
177
|
}
|
|
221
178
|
|
|
222
179
|
@keyframes shimmer {
|
|
223
|
-
0% { background-position:
|
|
224
|
-
100% { background-position:
|
|
180
|
+
0% { background-position: 100% 0; }
|
|
181
|
+
100% { background-position: -100% 0; }
|
|
225
182
|
}
|
|
226
183
|
|
|
227
184
|
.progress-header {
|
|
@@ -371,138 +328,6 @@ watch(() => instance.value?.progress, () => {
|
|
|
371
328
|
}
|
|
372
329
|
|
|
373
330
|
|
|
374
|
-
/* Экран завершения */
|
|
375
|
-
.completion-container {
|
|
376
|
-
display: flex;
|
|
377
|
-
justify-content: center;
|
|
378
|
-
align-items: center;
|
|
379
|
-
min-height: 500px;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
.completion-card {
|
|
383
|
-
max-width: 600px;
|
|
384
|
-
width: 100%;
|
|
385
|
-
text-align: center;
|
|
386
|
-
padding: 3rem;
|
|
387
|
-
border-radius: 24px;
|
|
388
|
-
background: linear-gradient(135deg, #ffffff 0%, #f8fff9 100%);
|
|
389
|
-
border: 1px solid rgba(76, 175, 80, 0.1);
|
|
390
|
-
box-shadow:
|
|
391
|
-
0 12px 40px rgba(0, 0, 0, 0.08),
|
|
392
|
-
0 4px 16px rgba(0, 0, 0, 0.04);
|
|
393
|
-
position: relative;
|
|
394
|
-
overflow: hidden;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.completion-card::before {
|
|
398
|
-
content: '';
|
|
399
|
-
position: absolute;
|
|
400
|
-
top: 0;
|
|
401
|
-
left: 0;
|
|
402
|
-
right: 0;
|
|
403
|
-
height: 4px;
|
|
404
|
-
background: linear-gradient(90deg, var(--q-positive) 0%, #4CAF50 50%, var(--q-positive) 100%);
|
|
405
|
-
background-size: 200% 100%;
|
|
406
|
-
animation: completion-shimmer 3s ease-in-out infinite;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
@keyframes completion-shimmer {
|
|
410
|
-
0%, 100% { background-position: -200% 0; }
|
|
411
|
-
50% { background-position: 200% 0; }
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
.completion-header {
|
|
415
|
-
position: relative;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
.celebration-icon {
|
|
419
|
-
position: relative;
|
|
420
|
-
display: inline-block;
|
|
421
|
-
margin-bottom: 1rem;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
.sparkle {
|
|
425
|
-
position: absolute;
|
|
426
|
-
width: 8px;
|
|
427
|
-
height: 8px;
|
|
428
|
-
background: var(--q-positive);
|
|
429
|
-
border-radius: 50%;
|
|
430
|
-
animation: sparkle 2s infinite ease-in-out;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
.sparkle-1 {
|
|
434
|
-
top: -10px;
|
|
435
|
-
right: -10px;
|
|
436
|
-
animation-delay: 0s;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
.sparkle-2 {
|
|
440
|
-
top: 20px;
|
|
441
|
-
left: -15px;
|
|
442
|
-
animation-delay: 0.5s;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
.sparkle-3 {
|
|
446
|
-
bottom: -5px;
|
|
447
|
-
right: 15px;
|
|
448
|
-
animation-delay: 1s;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
@keyframes sparkle {
|
|
452
|
-
0%, 100% {
|
|
453
|
-
opacity: 0;
|
|
454
|
-
transform: scale(0);
|
|
455
|
-
}
|
|
456
|
-
50% {
|
|
457
|
-
opacity: 1;
|
|
458
|
-
transform: scale(1);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
.completion-title {
|
|
463
|
-
font-weight: 700;
|
|
464
|
-
letter-spacing: -0.5px;
|
|
465
|
-
margin-bottom: 0.5rem;
|
|
466
|
-
background: linear-gradient(135deg, var(--q-positive) 0%, #4CAF50 100%);
|
|
467
|
-
-webkit-background-clip: text;
|
|
468
|
-
-webkit-text-fill-color: transparent;
|
|
469
|
-
background-clip: text;
|
|
470
|
-
text-shadow: 0 2px 4px rgba(76, 175, 80, 0.3);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
.completion-details {
|
|
474
|
-
margin-top: 2rem;
|
|
475
|
-
text-align: left;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
.detail-item {
|
|
479
|
-
display: flex;
|
|
480
|
-
align-items: center;
|
|
481
|
-
padding: 1rem;
|
|
482
|
-
background: rgba(76, 175, 80, 0.02);
|
|
483
|
-
border-radius: 12px;
|
|
484
|
-
border: 1px solid rgba(76, 175, 80, 0.1);
|
|
485
|
-
transition: all 0.3s ease;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
.detail-item:hover {
|
|
489
|
-
transform: translateX(4px);
|
|
490
|
-
background: rgba(76, 175, 80, 0.05);
|
|
491
|
-
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.1);
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
.detail-text {
|
|
495
|
-
margin-left: 1rem;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
.next-steps {
|
|
499
|
-
margin-top: 2rem;
|
|
500
|
-
text-align: left;
|
|
501
|
-
padding: 1.5rem;
|
|
502
|
-
background: rgba(0, 0, 0, 0.02);
|
|
503
|
-
border-radius: 12px;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
331
|
/* Адаптивность */
|
|
507
332
|
@media (max-width: 768px) {
|
|
508
333
|
.progress-card {
|
|
@@ -515,23 +340,12 @@ watch(() => instance.value?.progress, () => {
|
|
|
515
340
|
text-align: center;
|
|
516
341
|
}
|
|
517
342
|
|
|
518
|
-
|
|
519
343
|
.stage-info {
|
|
520
344
|
flex-direction: column;
|
|
521
345
|
text-align: center;
|
|
522
346
|
gap: 0.75rem;
|
|
523
347
|
}
|
|
524
348
|
|
|
525
|
-
.completion-card {
|
|
526
|
-
padding: 2rem;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
.detail-item {
|
|
530
|
-
flex-direction: column;
|
|
531
|
-
text-align: center;
|
|
532
|
-
gap: 0.5rem;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
349
|
.time-display {
|
|
536
350
|
padding: 0.5rem 1rem;
|
|
537
351
|
}
|