DmitrMakeev commited on
Commit
9849074
·
verified ·
1 Parent(s): 663b446

Update pages.html

Browse files
Files changed (1) hide show
  1. pages.html +472 -297
pages.html CHANGED
@@ -1,50 +1,232 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>GrapesJS Editor</title>
7
- <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">
8
- <style>
9
- .modal_1 {
10
- display: none;
11
- position: fixed;
12
- z-index: 1;
13
- left: 0;
14
- top: 0;
15
- width: 100%;
16
- height: 100%;
17
- overflow: auto;
18
- background-color: rgb(0,0,0);
19
- background-color: rgba(0,0,0,0.4);
20
- }
21
- .modal-content_1 {
22
- background-color: #fefefe;
23
- margin: 15% auto;
24
- padding: 20px;
25
- border: 1px solid #888;
26
- width: 80%;
27
- }
28
- .close_1 {
29
- color: #aaa;
30
- float: right;
31
- font-size: 28px;
32
- font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
- .close_1:hover,
35
- .close_1:focus {
36
- color: black;
37
- text-decoration: none;
38
- cursor: pointer;
39
  }
40
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  </head>
42
  <body>
 
 
 
 
 
 
 
43
  <button id="toggleAppBtn" style="position: absolute; top: 10px; left: 10px;">Показать/Скрыть приложение</button>
 
44
  <button id="myBtn" style="position: absolute; top: 30px; right: 10px;">Открыть модальное</button>
 
45
  <button id="testBtn" style="position: absolute; top: 70px; right: 32px;">Тестовая кнопка</button>
46
  <div id="gjs" style="height: 90vh;"></div>
 
47
  <div id="myModal_1" class="modal_1">
 
48
  <div class="modal-content_1">
49
  <div class="modal-header_1">
50
  <span class="close_1">&times;</span>
@@ -52,33 +234,26 @@
52
  </div>
53
  <div class="modal-body_1">
54
  <p>Некоторый текст в модальном теле</p>
55
- <div id="progressBarContainer">
56
- <div id="progressBar">0%</div>
57
- </div>
58
- <div id="imageUrl" onclick="copyToClipboard(this)">Кликните после загрузки, для получения ссылки на страницу.</div>
59
- <form id="uploadForm" enctype="multipart/form-data" method="post" action="/up_page">
60
- <input type="file" name="file" accept=".html">
61
- <input type="text" name="filename" placeholder="имя файла(маршрут)">
62
- <button type="submit">Загрузить</button>
63
- </form>
 
 
 
 
 
64
  </div>
65
  <div class="modal-footer_1">
66
  <h3>Добавление HTML файла с пользовательским маршрутом.</h3>
67
  </div>
68
  </div>
69
  </div>
70
-
71
- <script src="https://cdn.jsdelivr.net/npm/grapesjs"></script>
72
- <script src="https://cdn.jsdelivr.net/npm/grapesjs-blocks-basic"></script>
73
- <script src="https://cdn.jsdelivr.net/npm/grapesjs-component-countdown"></script>
74
- <script src="https://cdn.jsdelivr.net/npm/grapesjs-component-code-editor"></script>
75
- <script src="https://cdn.jsdelivr.net/npm/grapesjs-templates"></script>
76
- <script src="https://cdn.jsdelivr.net/npm/grapesjs-rte-extensions"></script>
77
- <script src="https://cdn.jsdelivr.net/npm/grapesjs-user-blocks"></script>
78
- <script src="https://cdn.jsdelivr.net/npm/@vkontakte/vk-bridge/dist/browser.min.js"></script>
79
- <script src="https://vk.com/js/api/openapi.js?169"></script>
80
- <script src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
81
-
82
  <script>
83
  // Инициализация GrapesJS редактора
84
  const editor = grapesjs.init({
@@ -154,7 +329,6 @@
154
  }
155
  },
156
  });
157
-
158
  // Добавление русского языка
159
  editor.I18n.addMessages({
160
  ru: {
@@ -210,16 +384,13 @@
210
  }
211
  }
212
  });
213
-
214
  // Установка русского языка по умолчанию
215
  editor.I18n.setLocale('ru');
216
-
217
  // Удаление ненужных блоков
218
  const unwantedBlocks = ['video', 'link', 'image'];
219
  unwantedBlocks.forEach(blockId => {
220
  editor.BlockManager.remove(blockId);
221
  });
222
-
223
  // Добавление блока адаптивной картинки
224
  editor.BlockManager.add('responsive-image', {
225
  label: editor.I18n.t('blockManager.labels.responsive-image'),
@@ -240,7 +411,6 @@
240
  class: 'fa fa-image'
241
  }
242
  });
243
-
244
  // Добавление блока центрированного текста
245
  editor.BlockManager.add('centered-text', {
246
  label: editor.I18n.t('blockManager.labels.centered-text'),
@@ -255,154 +425,159 @@
255
  class: 'fa fa-align-center'
256
  }
257
  });
258
-
259
- // Создаем новый тип компонента для формы
260
- editor.Components.addType('custom-form', {
261
- model: {
262
- defaults: {
263
- // HTML-код формы
264
- content: `
265
- <div class="container">
266
- <form id="contactForm">
267
- <h4>КЛУБ-ПРАКТИК. 255 техник для психолога - 2024</h4>
268
- <div class="form-group">
269
- <label for="name">Имя</label>
270
- <input type="text" id="name" required>
271
- </div>
272
- <div class="form-group">
273
- <label for="email">Почта</label>
274
- <input type="email" id="email" required>
275
- </div>
276
- <div class="form-group">
277
- <label for="phone">Телефон</label>
278
- <input type="tel" id="phone" required>
279
- </div>
280
- <div class="form-group">
281
- <label for="options">Выберите тариф</label>
282
- <select id="options" required>
283
- <option value="" disabled selected>Тариф</option>
284
- <option>БИЗНЕС - 69 970р.</option>
285
- <option>PREMIUM - 89 970р.</option>
286
- <option>VIP - 149 990р.</option>
287
- </select>
288
- </div>
289
- <div class="form-check">
290
- <input type="checkbox" id="newsletter" required>
291
- <label for="newsletter">Согласие на email рассылку</label>
292
- </div>
293
- <div class="form-group">
294
- <a href="#" id="privacyPolicyLink">Политика конфиденциальности</a>
295
- </div>
296
- <button type="submit" class="btn-primary">ПЕРЕЙТИ К ОПЛАТЕ</button>
297
- </form>
298
- <div id="privacyModal" class="modal">
299
- <div class="modal-content">
300
- <span class="close">&times;</span>
301
- <iframe src="https://riverpsy.com/policy" frameborder="0"></iframe>
302
- </div>
303
- </div>
304
  </div>
305
- `,
306
- // Скрипт для обработки отправки формы
307
- script: function(props) {
308
- const form = this.querySelector('#contactForm');
309
- form.addEventListener('submit', function(event) {
310
- event.preventDefault();
311
- const data = new URLSearchParams();
312
- data.append('name', document.getElementById('name').value);
313
- data.append('email', document.getElementById('email').value);
314
- data.append('phone', document.getElementById('phone').value);
315
- data.append('options', document.getElementById('options').value);
316
- data.append('newsletter', document.getElementById('newsletter').checked);
317
- // Добавляем данные VK API
318
- if (sid_user) {
319
- data.append('vk_user_id', sid_user);
320
- }
321
- if (!props.submitUrl) {
322
- console.error('Submit URL is not defined');
323
- return;
324
- }
325
- console.log('Form Data:', data.toString()); // Выводим данные формы в консоль
326
- console.log('Submit URL:', props.submitUrl); // Выводим URL в консоль
327
- fetch(props.submitUrl + '&api=1&uid=' + sid_user, {
328
- method: 'POST',
329
- headers: {
330
- 'Content-Type': 'application/x-www-form-urlencoded'
331
- },
332
- body: data.toString()
333
- })
334
- .then(response => {
335
- console.log('Ответ сервера:', response); // Проверка ответа сервера
336
- if (!response.ok) {
337
- throw new Error('Ошибка HTTP: ' + response.status);
338
- }
339
- return response.json();
340
- })
341
- .then(data => {
342
- console.log('Данные от сервера:', data); // Вывод ответа сервера в консоль
343
- if (data.redirect) {
344
- window.location.href = data.redirect;
345
- }
346
- })
347
- .catch(error => {
348
- console.error('Error:', error);
349
- });
350
- });
351
- },
352
- // Свойства, которые будут передаваться в скрипт
353
- 'script-props': ['submitUrl'],
354
- // Настройки для изменения URL отправки
355
- traits: [
356
- {
357
- type: 'text',
358
- name: 'submitUrl',
359
- label: 'Submit URL',
360
- changeProp: true
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  }
362
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  }
 
 
 
365
  });
366
-
367
- // Создаем блок для компонента формы
368
- editor.Blocks.add('custom-form-block', {
369
- label: 'Custom Form',
370
- content: { type: 'custom-form' },
371
- });
372
-
373
- // Добавляем скрипты для интеграции с VK API
374
- editor.on('load', function() {
375
- vkBridge.send('VKWebAppInit');
376
- vkBridge.send("VKWebAppAllowMessagesFromGroup", {"group_id": 168704660, "key": "cc964fabb0e1d70924a92e4e8b513dbff7cc10a9"})
377
- .then(data => {
378
- console.log(data);
379
- if (data.result == true) {
380
- // Действия, если подписка подтверждена
381
- } else {
382
- window.location.href = "https://riverpsy.com/courses";
383
- }
384
- })
385
- .catch(error => {
386
- window.location.href = "https://riverpsy.com/courses";
387
- });
388
- vkBridge.send('VKWebAppGetUserInfo')
389
- .then(data => {
390
- console.log(data.id);
391
- console.log(data.first_name);
392
- console.log(data.last_name);
393
- console.log(data);
394
- sid_user = (data.id);
395
- vk_ides = (data.id);
396
- vk_photos1 = (data.photo_100);
397
- hashs = (location.hash);
398
- console.log(location.hash);
399
- console.log(vk_photos1);
400
- })
401
- .catch(error => {
402
- console.error('Error:', error);
403
- });
404
  });
405
-
 
 
406
  // Добавление кнопки для открытия редактора кода
407
  const pn = editor.Panels;
408
  const panelViews = pn.addPanel({
@@ -420,7 +595,6 @@
420
  id: "open-code",
421
  },
422
  ]);
423
-
424
  // Добавление команды для импорта HTML и CSS
425
  editor.Commands.add('gjs-open-import-webpage', {
426
  run(editor, sender) {
@@ -459,7 +633,6 @@
459
  modal.open();
460
  }
461
  });
462
-
463
  // Добавление кнопки для импорта в панель
464
  pn.addButton('options', {
465
  id: 'gjs-open-import-webpage',
@@ -470,7 +643,6 @@
470
  'data-tooltip-pos': 'bottom',
471
  },
472
  });
473
-
474
  // Добавление кнопок для отмены и повтора действий
475
  pn.addButton('options', {
476
  id: 'undo',
@@ -490,7 +662,6 @@
490
  'data-tooltip-pos': 'bottom',
491
  },
492
  });
493
-
494
  // Добавление кнопки для очистки всего содержимого редактора
495
  pn.addButton('options', {
496
  id: 'clear-canvas',
@@ -535,40 +706,35 @@
535
  // Функция для показа/скрытия приложения
536
  document.addEventListener('DOMContentLoaded', () => {
537
  // Функция для тестовой кнопки
538
- document.getElementById('testBtn').addEventListener('click', function() {
539
- console.log('Тестовая кнопка работает!');
540
- // Получаем HTML-код из GrapesJS
541
- const editor = grapesjs.editors[0]; // Предполагается, что у вас есть только один редактор
542
- const htmlContent = editor.getHtml();
543
- const cssContent = editor.getCss();
544
- // Создаем полный HTML-документ
545
- const fullHtmlContent = `
546
- <!DOCTYPE html>
547
- <html lang="en">
548
- <head>
549
- <meta charset="UTF-8">
550
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
551
- <title>Скачанная HTML-страница</title>
552
- <style>${cssContent}</style>
553
- </head>
554
- <body>
555
- ${htmlContent}
556
- </body>
557
- </html>
558
- `;
559
- // Создаем Blob с HTML-кодом
560
- const blob = new Blob([fullHtmlContent], { type: 'text/html' });
561
- // Создаем ссылку для скачивания
562
- const link = document.createElement('a');
563
- link.href = URL.createObjectURL(blob);
564
- link.download = 'downloaded_page.html';
565
- // Добавляем ссылку в документ и программно кликаем по ней
566
- document.body.appendChild(link);
567
- link.click();
568
- // Удаляем ссылку из документа
569
- document.body.removeChild(link);
570
- });
571
-
572
  // Функция для показа/скрытия приложения
573
  document.getElementById('toggleAppBtn').addEventListener('click', function() {
574
  const app = document.getElementById('gjs');
@@ -581,62 +747,71 @@
581
  });
582
  </script>
583
 
584
- <script>
585
- document.getElementById('uploadForm').addEventListener('submit', function(event) {
586
- event.preventDefault();
587
- var formData = new FormData(this);
588
- var request = new XMLHttpRequest();
589
- request.open('POST', '/up_page');
590
- request.upload.addEventListener('progress', function(event) {
591
- if (event.lengthComputable) {
592
- var percentComplete = (event.loaded / event.total) * 100;
593
- document.getElementById('progressBar').style.width = percentComplete + '%';
594
- document.getElementById('progressBar').innerText = Math.round(percentComplete) + '%';
595
- }
596
- }, false);
597
- request.addEventListener('load', function(event) {
598
- var response = event.target.responseText;
599
- if (event.target.status === 200) {
600
- var fullUrl = response.split('saved to ')[1];
601
- document.getElementById('imageUrl').innerText = 'Click to copy URL';
602
- document.getElementById('imageUrl').setAttribute('data-url', fullUrl);
603
- Toastify({
604
- text: "File uploaded successfully",
605
- duration: 3000,
606
- gravity: "top",
607
- position: "center",
608
- backgroundColor: "#4CAF50",
609
- }).showToast();
610
- } else if (event.target.status === 409) {
611
- Toastify({
612
- text: "File with this name already exists",
613
- duration: 3000,
614
- gravity: "top",
615
- position: "center",
616
- backgroundColor: "#FF5733",
617
- }).showToast();
618
- }
619
- document.getElementById('progressBar').style.width = '0%';
620
- document.getElementById('progressBar').innerText = '0%';
621
- }, false);
622
- request.send(formData);
623
- });
624
 
625
- function copyToClipboard(element) {
626
- var tempInput = document.createElement("input");
627
- tempInput.value = element.getAttribute('data-url');
628
- document.body.appendChild(tempInput);
629
- tempInput.select();
630
- document.execCommand("copy");
631
- document.body.removeChild(tempInput);
632
- Toastify({
633
- text: "URL copied to clipboard",
634
- duration: 3000,
635
- gravity: "top",
636
- position: "center",
637
- backgroundColor: "#4CAF50",
638
- }).showToast();
639
- }
640
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
  </body>
642
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>File Upload</title>
7
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">
8
+
9
+
10
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
11
+ <script src="https://unpkg.com/@vkontakte/vk-bridge/dist/browser.min.js"></script>
12
+ <script type="text/javascript" src="https://vk.com/js/api/openapi.js?169"></script>
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
25
+ <title>GrapesJS Project</title>
26
+ <link href="https://unpkg.com/grapesjs/dist/css/grapes.min.css" rel="stylesheet" />
27
+ <link href="index.css" rel="stylesheet" />
28
+ <script src="https://unpkg.com/grapesjs"></script>
29
+ <script src="https://unpkg.com/grapesjs-blocks-basic"></script>
30
+ <script src="https://unpkg.com/grapesjs-component-countdown"></script>
31
+ <script src="https://unpkg.com/grapesjs-parser-postcss"></script>
32
+ <link href="https://unpkg.com/grapesjs-component-code-editor/dist/grapesjs-component-code-editor.min.css" rel="stylesheet" />
33
+ <script src="https://unpkg.com/grapesjs-component-code-editor"></script>
34
+ <script src="https://unpkg.com/grapesjs-templates"></script>
35
+ <link href="https://unpkg.com/grapesjs-rte-extensions/dist/grapesjs-rte-extensions.min.css" rel="stylesheet" />
36
+ <script src="https://unpkg.com/grapesjs-rte-extensions"></script>
37
+ <script src="https://unpkg.com/grapesjs-user-blocks"></script>
38
+
39
+
40
+
41
+
42
+
43
+ <style>
44
+ h1 {
45
+ background-color: #4CAF50;
46
+ color: white;
47
+ padding: 20px;
48
+ margin: 0;
49
+ border-bottom: 2px solid #388E3C;
50
+ }
51
+ button[type="submit"] {
52
+ color: white;
53
+ background-color: #4CAF50;
54
+ border: none;
55
+ cursor: pointer;
56
+ padding: 10px 20px;
57
+ font-size: 16px;
58
+ border-radius: 5px;
59
+ margin-top: 20px;
60
+ }
61
+ button[type="submit"]:hover {
62
+ background-color: #388E3C;
63
+ }
64
+ #imageUrl {
65
+ margin-top: 20px;
66
+ font-size: 16px;
67
+ color: #333;
68
+ cursor: pointer;
69
+ text-decoration: underline;
70
+ }
71
+ #progressBarContainer {
72
+ width: 80%;
73
+ margin: 20px auto;
74
+ background-color: #ddd;
75
+ border-radius: 13px;
76
+ padding: 3px;
77
+ }
78
+ #progressBar {
79
+ width: 0%;
80
+ height: 20px;
81
+ background-color: #4CAF50;
82
+ border-radius: 10px;
83
+ text-align: center;
84
+ line-height: 20px;
85
+ color: white;
86
+ }
87
+ </style>
88
+
89
+
90
+
91
+ <style>
92
+ body {
93
+ background-color: green;
94
+ display: flex;
95
+ justify-content: center;
96
+ align-items: center;
97
+ color: #ffffff;
98
+ height: 100vh;
99
+ }
100
+ #floating-element nav ul li a {
101
+ color: #fff; /* Белый цвет текста */
102
+ }
103
+ .responsive-image-container {
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: center;
107
+ width: 100%;
108
+ height: auto;
109
+ }
110
+ .responsive-image {
111
+ max-width: 100%;
112
+ height: auto;
113
+ object-fit: cover;
114
+ }
115
+ .centered-text {
116
+ text-align: center;
117
+ }
118
+ .gjs-one-bg {
119
+ background-color: green !important;
120
+ }
121
+ .countdown-timer {
122
+ text-align: center;
123
+ font-size: 24px;
124
+ color: #333;
125
+ }
126
+ @media (max-width: 768px) {
127
+ .responsive-image-container {
128
+ flex-direction: column;
129
  }
130
+ .responsive-image {
131
+ width: 100%;
132
+ margin-bottom: 20px;
 
 
133
  }
134
+ }
135
+ /* Модальный (фон) */
136
+ .modal_1 {
137
+ display: none; /* Скрыто по умолчанию */
138
+ position: fixed; /* Оставаться на месте */
139
+ z-index: 10; /* Сидеть на вершине */
140
+ padding-top: 100px; /* Расположение коробки */
141
+ left: 0;
142
+ top: 0;
143
+ width: 100%; /* Полная ширина */
144
+ height: 100%; /* Полная высот�� */
145
+ overflow: auto; /* Включите прокрутку, если это необходимо */
146
+ background-color: rgb(0,0,0); /* Цвет запасной вариант */
147
+ background-color: rgba(0,0,0,0.4); /*Черный с непрозрачностью */
148
+ }
149
+ /* Модальное содержание */
150
+ .modal-content_1 {
151
+ position: relative;
152
+ background-color: #fefefe;
153
+ margin: auto;
154
+ padding: 0;
155
+ border: 1px solid #888;
156
+ width: 60%;
157
+ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
158
+ -webkit-animation-name: animatetop_1;
159
+ -webkit-animation-duration: 0.4s;
160
+ animation-name: animatetop_1;
161
+ animation-duration: 0.4s
162
+ }
163
+ /* Добавить анимацию */
164
+ @-webkit-keyframes animatetop_1 {
165
+ from {top:-300px; opacity:0}
166
+ to {top:0; opacity:1}
167
+ }
168
+ @keyframes animatetop_1 {
169
+ from {top:-300px; opacity:0}
170
+ to {top:0; opacity:1}
171
+ }
172
+ /* Кнопка закрытия */
173
+ .close_1 {
174
+ color: white;
175
+ float: right;
176
+ font-size: 28px;
177
+ font-weight: bold;
178
+ }
179
+ .close_1:hover,
180
+ .close_1:focus {
181
+ color: #000;
182
+ text-decoration: none;
183
+ cursor: pointer;
184
+ }
185
+ .modal-header_1 {
186
+ padding: 2px 16px;
187
+ background-color: green;
188
+ color: white;
189
+ }
190
+ .modal-body_1 {padding: 2px 16px;}
191
+ .modal-footer_1 {
192
+ padding: 2px 16px;
193
+ background-color: green;
194
+ color: white;
195
+ }
196
+ #gjs {
197
+ position: absolute;
198
+ left: 0;
199
+ transition: left 0.3s ease;
200
+ }
201
+ #toggleAppBtn {
202
+ z-index: 1000; /* Убедитесь, что кнопка находится поверх других элементов */
203
+ }
204
+ </style>
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
  </head>
213
  <body>
214
+ <script>
215
+ vkBridge.send('VKWebAppInit');
216
+ </script>
217
+
218
+
219
+
220
+ <!-- Кнопка для показа/скрытия приложения -->
221
  <button id="toggleAppBtn" style="position: absolute; top: 10px; left: 10px;">Показать/Скрыть приложение</button>
222
+ <!-- Кнопка для открытия модального окна -->
223
  <button id="myBtn" style="position: absolute; top: 30px; right: 10px;">Открыть модальное</button>
224
+ <!-- Кнопка для проверки работы -->
225
  <button id="testBtn" style="position: absolute; top: 70px; right: 32px;">Тестовая кнопка</button>
226
  <div id="gjs" style="height: 90vh;"></div>
227
+ <!-- The Modal -->
228
  <div id="myModal_1" class="modal_1">
229
+ <!-- Модальное содержание -->
230
  <div class="modal-content_1">
231
  <div class="modal-header_1">
232
  <span class="close_1">&times;</span>
 
234
  </div>
235
  <div class="modal-body_1">
236
  <p>Некоторый текст в модальном теле</p>
237
+
238
+
239
+ <div id="progressBarContainer">
240
+ <div id="progressBar">0%</div>
241
+ </div>
242
+ <div id="imageUrl" onclick="copyToClipboard(this)">Кликните после загрузки, для получения ссылки на страницу.</div>
243
+ <form id="uploadForm" enctype="multipart/form-data" method="post" action="/up_page">
244
+ <input type="file" name="file" accept=".html">
245
+ <input type="text" name="filename" placeholder="имя файла(маршрут)">
246
+ <button type="submit">Загрузить</button>
247
+ </form>
248
+
249
+
250
+ <br><br><br>
251
  </div>
252
  <div class="modal-footer_1">
253
  <h3>Добавление HTML файла с пользовательским маршрутом.</h3>
254
  </div>
255
  </div>
256
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
257
  <script>
258
  // Инициализация GrapesJS редактора
259
  const editor = grapesjs.init({
 
329
  }
330
  },
331
  });
 
332
  // Добавление русского языка
333
  editor.I18n.addMessages({
334
  ru: {
 
384
  }
385
  }
386
  });
 
387
  // Установка русского языка по умолчанию
388
  editor.I18n.setLocale('ru');
 
389
  // Удаление ненужных блоков
390
  const unwantedBlocks = ['video', 'link', 'image'];
391
  unwantedBlocks.forEach(blockId => {
392
  editor.BlockManager.remove(blockId);
393
  });
 
394
  // Добавление блока адаптивной картинки
395
  editor.BlockManager.add('responsive-image', {
396
  label: editor.I18n.t('blockManager.labels.responsive-image'),
 
411
  class: 'fa fa-image'
412
  }
413
  });
 
414
  // Добавление блока центрированного текста
415
  editor.BlockManager.add('centered-text', {
416
  label: editor.I18n.t('blockManager.labels.centered-text'),
 
425
  class: 'fa fa-align-center'
426
  }
427
  });
428
+ // Создаем новый тип компонента для формы
429
+ editor.Components.addType('custom-form', {
430
+ model: {
431
+ defaults: {
432
+ // HTML-код формы
433
+ content: `
434
+ <div class="container">
435
+ <form id="contactForm">
436
+ <h4>КЛУБ-ПРАКТИК. 255 техник для психолога - 2024</h4>
437
+ <div class="form-group">
438
+ <label for="name">Имя</label>
439
+ <input type="text" id="name" required>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  </div>
441
+ <div class="form-group">
442
+ <label for="email">Почта</label>
443
+ <input type="email" id="email" required>
444
+ </div>
445
+ <div class="form-group">
446
+ <label for="phone">Телефон</label>
447
+ <input type="tel" id="phone" required>
448
+ </div>
449
+ <div class="form-group">
450
+ <label for="options">Выберите тариф</label>
451
+ <select id="options" required>
452
+ <option value="" disabled selected>Тариф</option>
453
+ <option>БИЗНЕС - 69 970р.</option>
454
+ <option>PREMIUM - 89 970р.</option>
455
+ <option>VIP - 149 990р.</option>
456
+ </select>
457
+ </div>
458
+ <div class="form-check">
459
+ <input type="checkbox" id="newsletter" required>
460
+ <label for="newsletter">Согласие на email рассылку</label>
461
+ </div>
462
+ <div class="form-group">
463
+ <a href="#" id="privacyPolicyLink">Политика конфиденциальности</a>
464
+ </div>
465
+ <button type="submit" class="btn-primary">ПЕРЕЙТИ К ОПЛАТЕ</button>
466
+ </form>
467
+ <div id="privacyModal" class="modal">
468
+ <div class="modal-content">
469
+ <span class="close">&times;</span>
470
+ <iframe src="https://riverpsy.com/policy" frameborder="0"></iframe>
471
+ </div>
472
+ </div>
473
+ </div>
474
+ `,
475
+ // Скрипт для обработки отправки формы
476
+ script: function(props) {
477
+ const form = this.querySelector('#contactForm');
478
+ form.addEventListener('submit', function(event) {
479
+ event.preventDefault();
480
+ const data = new URLSearchParams();
481
+ data.append('name', document.getElementById('name').value);
482
+ data.append('email', document.getElementById('email').value);
483
+ data.append('phone', document.getElementById('phone').value);
484
+ data.append('options', document.getElementById('options').value);
485
+ data.append('newsletter', document.getElementById('newsletter').checked);
486
+ // Добавляем данные VK API
487
+ if (sid_user) {
488
+ data.append('vk_user_id', sid_user);
489
+ }
490
+ if (!props.submitUrl) {
491
+ console.error('Submit URL is not defined');
492
+ return;
493
+ }
494
+ console.log('Form Data:', data.toString()); // Выводим данные формы в консоль
495
+ console.log('Submit URL:', props.submitUrl); // Выводим URL в консоль
496
+ fetch(props.submitUrl + '&api=1&uid=' + sid_user, {
497
+ method: 'POST',
498
+ headers: {
499
+ 'Content-Type': 'application/x-www-form-urlencoded'
500
+ },
501
+ body: data.toString()
502
+ })
503
+ .then(response => {
504
+ console.log('Ответ сервера:', response); // Проверка ответа сервера
505
+ if (!response.ok) {
506
+ throw new Error('Ошибка HTTP: ' + response.status);
507
+ }
508
+ return response.json();
509
+ })
510
+ .then(data => {
511
+ console.log('Данные от сервера:', data); // Вывод ответа сервера в консоль
512
+ if (data.redirect) {
513
+ window.location.href = data.redirect;
514
  }
515
+ })
516
+ .catch(error => {
517
+ console.error('Error:', error);
518
+ });
519
+ });
520
+ },
521
+ // Свойства, которые будут передаваться в скрипт
522
+ 'script-props': ['submitUrl'],
523
+ // Настройки для изменения URL отправки
524
+ traits: [
525
+ {
526
+ type: 'text',
527
+ name: 'submitUrl',
528
+ label: 'Submit URL',
529
+ changeProp: true
530
  }
531
+ ]
532
+ }
533
+ }
534
+ });
535
+ // Создаем блок для компонента формы
536
+ editor.Blocks.add('custom-form-block', {
537
+ label: 'Custom Form',
538
+ content: { type: 'custom-form' },
539
+ });
540
+ // Добавляем скрипты для интеграции с VK API
541
+ editor.on('load', function() {
542
+ const script1 = document.createElement('script');
543
+ script1.src = 'https://unpkg.com/@vkontakte/vk-bridge/dist/browser.min.js';
544
+ document.head.appendChild(script1);
545
+ const script2 = document.createElement('script');
546
+ script2.src = 'https://vk.com/js/api/openapi.js?169';
547
+ document.head.appendChild(script2);
548
+ script2.onload = function() {
549
+ vkBridge.send('VKWebAppInit');
550
+ vkBridge.send("VKWebAppAllowMessagesFromGroup", {"group_id": 168704660, "key": "cc964fabb0e1d70924a92e4e8b513dbff7cc10a9"})
551
+ .then(data => {
552
+ console.log(data);
553
+ if (data.result == true) {
554
+ // Действия, если подписка подтверждена
555
+ } else {
556
+ window.location.href = "https://riverpsy.com/courses";
557
  }
558
+ })
559
+ .catch(error => {
560
+ window.location.href = "https://riverpsy.com/courses";
561
  });
562
+ vkBridge.send('VKWebAppGetUserInfo')
563
+ .then(data => {
564
+ console.log(data.id);
565
+ console.log(data.first_name);
566
+ console.log(data.last_name);
567
+ console.log(data);
568
+ sid_user = (data.id);
569
+ vk_ides = (data.id);
570
+ vk_photos1 = (data.photo_100);
571
+ hashs = (location.hash);
572
+ console.log(location.hash);
573
+ console.log(vk_photos1);
574
+ })
575
+ .catch(error => {
576
+ console.error('Error:', error);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  });
578
+ };
579
+ });
580
+
581
  // Добавление кнопки для открытия редактора кода
582
  const pn = editor.Panels;
583
  const panelViews = pn.addPanel({
 
595
  id: "open-code",
596
  },
597
  ]);
 
598
  // Добавление команды для импорта HTML и CSS
599
  editor.Commands.add('gjs-open-import-webpage', {
600
  run(editor, sender) {
 
633
  modal.open();
634
  }
635
  });
 
636
  // Добавление кнопки для импорта в панель
637
  pn.addButton('options', {
638
  id: 'gjs-open-import-webpage',
 
643
  'data-tooltip-pos': 'bottom',
644
  },
645
  });
 
646
  // Добавление кнопок для отмены и повтора действий
647
  pn.addButton('options', {
648
  id: 'undo',
 
662
  'data-tooltip-pos': 'bottom',
663
  },
664
  });
 
665
  // Добавление кнопки для очистки всего содержимого редактора
666
  pn.addButton('options', {
667
  id: 'clear-canvas',
 
706
  // Функция для показа/скрытия приложения
707
  document.addEventListener('DOMContentLoaded', () => {
708
  // Функция для тестовой кнопки
709
+ document.addEventListener('DOMContentLoaded', () => {
710
+ document.getElementById('testBtn').addEventListener('click', function() {
711
+ console.log('Тестовая кнопка работает!');
712
+ const editor = grapesjs.editors[0]; // Предполагается, что у вас есть только один редактор
713
+ const htmlContent = editor.getHtml();
714
+ const cssContent = editor.getCss();
715
+ const fullHtmlContent = `
716
+ <!DOCTYPE html>
717
+ <html lang="en">
718
+ <head>
719
+ <meta charset="UTF-8">
720
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
721
+ <title>Скачанная HTML-страница</title>
722
+ <style>${cssContent}</style>
723
+ </head>
724
+ <body>
725
+ ${htmlContent}
726
+ </body>
727
+ </html>
728
+ `;
729
+ const blob = new Blob([fullHtmlContent], { type: 'text/html' });
730
+ const link = document.createElement('a');
731
+ link.href = URL.createObjectURL(blob);
732
+ link.download = 'downloaded_page.html';
733
+ document.body.appendChild(link);
734
+ link.click();
735
+ document.body.removeChild(link);
736
+ });
737
+ });
 
 
 
 
 
738
  // Функция для показа/скрытия приложения
739
  document.getElementById('toggleAppBtn').addEventListener('click', function() {
740
  const app = document.getElementById('gjs');
 
747
  });
748
  </script>
749
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
750
 
751
+
752
+
753
+
754
+
755
+
756
+
757
+
758
+
759
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
760
+ <script>
761
+ document.getElementById('uploadForm').addEventListener('submit', function(event) {
762
+ event.preventDefault();
763
+ var formData = new FormData(this);
764
+ var request = new XMLHttpRequest();
765
+ request.open('POST', '/up_page');
766
+ request.upload.addEventListener('progress', function(event) {
767
+ if (event.lengthComputable) {
768
+ var percentComplete = (event.loaded / event.total) * 100;
769
+ document.getElementById('progressBar').style.width = percentComplete + '%';
770
+ document.getElementById('progressBar').innerText = Math.round(percentComplete) + '%';
771
+ }
772
+ }, false);
773
+ request.addEventListener('load', function(event) {
774
+ var response = event.target.responseText;
775
+ if (event.target.status === 200) {
776
+ var fullUrl = response.split('saved to ')[1];
777
+ document.getElementById('imageUrl').innerText = 'Click to copy URL';
778
+ document.getElementById('imageUrl').setAttribute('data-url', fullUrl);
779
+ Toastify({
780
+ text: "File uploaded successfully",
781
+ duration: 3000,
782
+ gravity: "top",
783
+ position: "center",
784
+ backgroundColor: "#4CAF50",
785
+ }).showToast();
786
+ } else if (event.target.status === 409) {
787
+ Toastify({
788
+ text: "File with this name already exists",
789
+ duration: 3000,
790
+ gravity: "top",
791
+ position: "center",
792
+ backgroundColor: "#FF5733",
793
+ }).showToast();
794
+ }
795
+ document.getElementById('progressBar').style.width = '0%';
796
+ document.getElementById('progressBar').innerText = '0%';
797
+ }, false);
798
+ request.send(formData);
799
+ });
800
+ function copyToClipboard(element) {
801
+ var tempInput = document.createElement("input");
802
+ tempInput.value = element.getAttribute('data-url');
803
+ document.body.appendChild(tempInput);
804
+ tempInput.select();
805
+ document.execCommand("copy");
806
+ document.body.removeChild(tempInput);
807
+ Toastify({
808
+ text: "URL copied to clipboard",
809
+ duration: 3000,
810
+ gravity: "top",
811
+ position: "center",
812
+ backgroundColor: "#4CAF50",
813
+ }).showToast();
814
+ }
815
+ </script>
816
  </body>
817
  </html>