@gudhub/ssg-web-components-library 1.0.78 → 1.0.80
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 +1 -1
- package/src/components/ai-image-generator/ai-image-compare/ai-image-compare.html +12 -0
- package/src/components/ai-image-generator/ai-image-compare/ai-image-compare.js +60 -0
- package/src/components/ai-image-generator/ai-image-compare/ai-image-compare.scss +21 -0
- package/src/components/ai-image-generator/ai-image-compare/config.js +6 -0
- package/src/components/ai-image-generator/ai-image-content/ai-image-content.html +29 -0
- package/src/components/ai-image-generator/ai-image-content/ai-image-content.js +18 -0
- package/src/components/ai-image-generator/ai-image-content/ai-image-content.scss +108 -0
- package/src/components/ai-image-generator/ai-image-content/config.js +6 -0
- package/src/components/ai-image-generator/ai-image-generator.html +43 -0
- package/src/components/ai-image-generator/ai-image-generator.js +143 -0
- package/src/components/ai-image-generator/ai-image-generator.scss +243 -0
- package/src/components/ai-image-generator/config.js +6 -0
- package/src/components/blog/blog-banner/blog-banner.js +8 -5
- package/src/components/blog/categories-list/categories-list.html +2 -2
- package/src/components/blog/categories-list/categories-list.js +1 -0
- package/src/components/blog/category-banner/category-banner.js +4 -4
- package/src/components/blog/comments/comments.js +1 -1
- package/src/config.js +3 -0
package/package.json
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import html from './ai-image-compare.html';
|
|
2
|
+
import './ai-image-compare.scss';
|
|
3
|
+
|
|
4
|
+
class AiImageCompare extends GHComponent {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async onServerRender() {
|
|
10
|
+
this.before = this.getAttribute('data-before') || '';
|
|
11
|
+
this.after = this.getAttribute('data-after') || '';
|
|
12
|
+
super.render(html);
|
|
13
|
+
await this.addScripts();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async onClientRender() {
|
|
17
|
+
this.initImageCompare();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
initImageCompare() {
|
|
21
|
+
const element = this.querySelector("div#image-compare");
|
|
22
|
+
if (!element || typeof window.ImageCompare === 'undefined') {
|
|
23
|
+
console.error("ImageCompare is not available or element not found.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
new window.ImageCompare(element).mount();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
addScripts() {
|
|
31
|
+
const head = document.querySelector('head');
|
|
32
|
+
|
|
33
|
+
const loadScript = () => {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
if (document.getElementById('img-compare-script')) return resolve();
|
|
36
|
+
|
|
37
|
+
const script = document.createElement('script');
|
|
38
|
+
script.id = 'img-compare-script';
|
|
39
|
+
script.src = 'https://unpkg.com/image-compare-viewer/dist/image-compare-viewer.min.js';
|
|
40
|
+
script.onload = resolve;
|
|
41
|
+
script.onerror = reject;
|
|
42
|
+
head.appendChild(script);
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const loadStyle = () => {
|
|
47
|
+
if (document.getElementById('img-compare-style')) return;
|
|
48
|
+
const link = document.createElement('link');
|
|
49
|
+
link.id = 'img-compare-style';
|
|
50
|
+
link.rel = 'stylesheet';
|
|
51
|
+
link.href = 'https://unpkg.com/image-compare-viewer/dist/image-compare-viewer.min.css';
|
|
52
|
+
head.appendChild(link);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
loadStyle();
|
|
56
|
+
return loadScript();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
window.customElements.define('ai-image-compare', AiImageCompare);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
ai-image-compare {
|
|
2
|
+
height: 100%;
|
|
3
|
+
width: fit-content;
|
|
4
|
+
position: relative;
|
|
5
|
+
|
|
6
|
+
#image-compare {
|
|
7
|
+
height: 100%;
|
|
8
|
+
max-height: 616px;
|
|
9
|
+
max-width: 920px;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&.generated {
|
|
13
|
+
#image-compare {
|
|
14
|
+
height: 100%;
|
|
15
|
+
max-height: 616px;
|
|
16
|
+
max-width: 1060px;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<section>
|
|
2
|
+
<div class="flex-wrapper">
|
|
3
|
+
<div class="content">
|
|
4
|
+
<div class="top">
|
|
5
|
+
<h1 class="title" gh-id="${ghId}.content.title"></h1>
|
|
6
|
+
${json.content.subtitle ? `
|
|
7
|
+
<div class="subtitle" gh-id="${ghId}.content.subtitle"></div>
|
|
8
|
+
` : ''}
|
|
9
|
+
</div>
|
|
10
|
+
<div class="bottom">
|
|
11
|
+
${json.content.button ? `
|
|
12
|
+
<button class="btn upload-image-button">
|
|
13
|
+
${json.content.button.text}
|
|
14
|
+
<svg width="26" height="27" viewBox="0 0 26 27" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
15
|
+
<path d="M12 19C12 19.5523 12.4477 20 13 20C13.5523 20 14 19.5523 14 19L12 19ZM13.7071 0.292894C13.3166 -0.0976315 12.6834 -0.0976314 12.2929 0.292892L5.92894 6.65685C5.53841 7.04738 5.53841 7.68054 5.92894 8.07107C6.31946 8.46159 6.95263 8.46159 7.34315 8.07107L13 2.41421L18.6569 8.07107C19.0474 8.46159 19.6805 8.46159 20.0711 8.07107C20.4616 7.68055 20.4616 7.04738 20.0711 6.65686L13.7071 0.292894ZM14 19L14 1L12 1L12 19L14 19Z" fill="white"/>
|
|
16
|
+
<path d="M1 18L1 24C1 25.1046 1.89543 26 3 26H23C24.1046 26 25 25.1046 25 24V18" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
|
17
|
+
</svg>
|
|
18
|
+
</button>
|
|
19
|
+
` : ''}
|
|
20
|
+
${json.content.formats ? `
|
|
21
|
+
<p class="formats">${json.content.formats}</p>
|
|
22
|
+
` : ''}
|
|
23
|
+
${json.content.noText ? `
|
|
24
|
+
<p class="no-text">${json.content.noText.sign} | ${json.content.noText.card}</p>
|
|
25
|
+
` : ''}
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</section>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import html from './ai-image-content.html';
|
|
2
|
+
import './ai-image-content.scss';
|
|
3
|
+
|
|
4
|
+
class AiImageContent extends GHComponent {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async onServerRender() {
|
|
10
|
+
this.ghId = this.getAttribute('data-gh-id') || null;
|
|
11
|
+
this.json = await super.getGhData(this.ghId);
|
|
12
|
+
|
|
13
|
+
super.render(html);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
window.customElements.define('ai-image-content', AiImageContent);
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
ai-image-content {
|
|
2
|
+
section {
|
|
3
|
+
padding: 0;
|
|
4
|
+
max-width: 622px;
|
|
5
|
+
font-family: Roboto, sans-serif;
|
|
6
|
+
|
|
7
|
+
.top {
|
|
8
|
+
h1 {
|
|
9
|
+
font-weight: 900;
|
|
10
|
+
font-size: 60px;
|
|
11
|
+
line-height: 100%;
|
|
12
|
+
color: #383838;
|
|
13
|
+
}
|
|
14
|
+
.subtitle {
|
|
15
|
+
font-size: 24px;
|
|
16
|
+
line-height: 140%;
|
|
17
|
+
color: #545454;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
.bottom {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
align-items: center;
|
|
24
|
+
max-width: 385px;
|
|
25
|
+
|
|
26
|
+
.btn {
|
|
27
|
+
background-color: #6CBE02;
|
|
28
|
+
border: 1px solid transparent;
|
|
29
|
+
padding: 18px 32px;
|
|
30
|
+
|
|
31
|
+
text-transform: uppercase;
|
|
32
|
+
font-size: 17px;
|
|
33
|
+
line-height: 100%;
|
|
34
|
+
font-weight: 500;
|
|
35
|
+
color: #fff;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
gap: 16px;
|
|
41
|
+
|
|
42
|
+
margin-bottom: 12px;
|
|
43
|
+
transition: all 0.2s ease;
|
|
44
|
+
|
|
45
|
+
&:hover {
|
|
46
|
+
background-color: #fff;
|
|
47
|
+
border-color: #6CBE02;
|
|
48
|
+
color: #6CBE02;
|
|
49
|
+
|
|
50
|
+
svg {
|
|
51
|
+
path {
|
|
52
|
+
stroke: #6CBE02;
|
|
53
|
+
fill: #6CBE02;
|
|
54
|
+
}
|
|
55
|
+
path[stroke-linecap] {
|
|
56
|
+
stroke: #6CBE02;
|
|
57
|
+
fill: transparent;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
.formats {
|
|
63
|
+
font-size: 16px;
|
|
64
|
+
font-weight: 300;
|
|
65
|
+
line-height: 100%;
|
|
66
|
+
color: #545454;
|
|
67
|
+
margin-bottom: 20px;
|
|
68
|
+
}
|
|
69
|
+
.no-text {
|
|
70
|
+
color: #6CBE02;
|
|
71
|
+
text-transform: uppercase;
|
|
72
|
+
font-weight: 500;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
@media screen and (max-width: 768px) {
|
|
78
|
+
ai-image-content section {
|
|
79
|
+
.content {
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-direction: column-reverse;
|
|
82
|
+
align-items: center;
|
|
83
|
+
gap: 15px;
|
|
84
|
+
}
|
|
85
|
+
.top {
|
|
86
|
+
h1 {
|
|
87
|
+
font-size: 31px;
|
|
88
|
+
}
|
|
89
|
+
.subtitle {
|
|
90
|
+
font-size: 18px;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
.bottom {
|
|
94
|
+
width: 100%;
|
|
95
|
+
max-width: 100%;
|
|
96
|
+
|
|
97
|
+
& > p {
|
|
98
|
+
display: none;
|
|
99
|
+
}
|
|
100
|
+
button {
|
|
101
|
+
display: flex;
|
|
102
|
+
justify-content: center;
|
|
103
|
+
width: 100%;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<section>
|
|
2
|
+
<div class="container">
|
|
3
|
+
<div class="flex-wrapper start">
|
|
4
|
+
<ai-image-content data-gh-id="${ghId}"></ai-image-content>
|
|
5
|
+
<ai-image-compare data-before="${json.compare.before}" data-after="${json.compare.after}"></ai-image-compare>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="result hidden">
|
|
8
|
+
<div class="images-wrapper">
|
|
9
|
+
<button class="btn download" onclick="downloadLatestBlobImage()">
|
|
10
|
+
${json.result.downloadButton}
|
|
11
|
+
<svg width="15" height="17" viewBox="0 0 15 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
12
|
+
<path d="M6.89435 1.29334C6.89435 0.989316 7.1408 0.74286 7.44482 0.742859C7.74884 0.742859 7.9953 0.989316 7.9953 1.29333L6.89435 1.29334ZM7.83407 11.5911C7.6191 11.8061 7.27056 11.8061 7.05558 11.5911L3.55238 8.08794C3.3374 7.87296 3.3374 7.52442 3.55238 7.30945C3.76735 7.09447 4.11589 7.09447 4.33087 7.30945L7.44483 10.4234L10.5588 7.30944C10.7738 7.09447 11.1223 7.09447 11.3373 7.30944C11.5523 7.52442 11.5523 7.87296 11.3373 8.08793L7.83407 11.5911ZM7.44482 1.29333L7.9953 1.29333L7.9953 11.2019L7.44483 11.2019L6.89435 11.2019L6.89435 1.29334L7.44482 1.29333Z" fill="#6CBE02"/>
|
|
13
|
+
<path d="M0.839355 11.2019L0.839355 14.5048C0.839355 15.1128 1.33227 15.6057 1.94031 15.6057H12.9498C13.5579 15.6057 14.0508 15.1128 14.0508 14.5048V11.2019" stroke="#6CBE02" stroke-width="1.10095" stroke-linecap="round"/>
|
|
14
|
+
</svg>
|
|
15
|
+
</button>
|
|
16
|
+
<ai-image-compare data class="generated hidden"></ai-image-compare>
|
|
17
|
+
<button-component data-placement="${json.result.popupButton.placement}" data-popup-id="${json.result.popupButton.popupId}">${json.result.popupButton.text}</button-component>
|
|
18
|
+
<img id="placeholder" src="" alt="placeholder" class="placeholder-image" />
|
|
19
|
+
<div id="loader" class="loader">
|
|
20
|
+
<div class="spinner-circle"></div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div class="actions-wrapper">
|
|
25
|
+
<div class="input-wrapper">
|
|
26
|
+
<textarea name="textarea" id="prompt">House, grass, trees, flowerbeds</textarea>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="flex-buttons">
|
|
29
|
+
<button class="btn primary regenerate-btn">${json.result.regenerate}</button>
|
|
30
|
+
<button class="btn empty upload-image-button">
|
|
31
|
+
${json.result.new}
|
|
32
|
+
<svg width="26" height="27" viewBox="0 0 26 27" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
33
|
+
<path d="M12 19C12 19.5523 12.4477 20 13 20C13.5523 20 14 19.5523 14 19L12 19ZM13.7071 0.292894C13.3166 -0.0976315 12.6834 -0.0976314 12.2929 0.292892L5.92894 6.65685C5.53841 7.04738 5.53841 7.68054 5.92894 8.07107C6.31946 8.46159 6.95263 8.46159 7.34315 8.07107L13 2.41421L18.6569 8.07107C19.0474 8.46159 19.6805 8.46159 20.0711 8.07107C20.4616 7.68055 20.4616 7.04738 20.0711 6.65686L13.7071 0.292894ZM14 19L14 1L12 1L12 19L14 19Z" fill="#0E1011"/>
|
|
34
|
+
<path d="M1 18L1 24C1 25.1046 1.89543 26 3 26H23C24.1046 26 25 25.1046 25 24V18" stroke="#0E1011" stroke-width="2" stroke-linecap="round"/>
|
|
35
|
+
</svg>
|
|
36
|
+
</button>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<input type="file" id="imageUpload" class="hidden" accept="image/*" />
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</section>
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import html from './ai-image-generator.html';
|
|
2
|
+
import './ai-image-generator.scss';
|
|
3
|
+
|
|
4
|
+
class AiImageGenerator extends GHComponent {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
this.startContainer = this.querySelector('.start');
|
|
8
|
+
this.resultContainer = this.querySelector('.result');
|
|
9
|
+
this.imageCompareGenerated = this.querySelector('ai-image-compare.generated');
|
|
10
|
+
this.imageBefore = this.querySelector('ai-image-compare.generated img#image-before');
|
|
11
|
+
this.imageAfter = this.querySelector('ai-image-compare.generated img#image-after');
|
|
12
|
+
this.placeholderImage = this.querySelector('.result img#placeholder');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async onServerRender() {
|
|
16
|
+
this.ghId = this.getAttribute('data-gh-id') || null;
|
|
17
|
+
this.json = await super.getGhData(this.ghId);
|
|
18
|
+
|
|
19
|
+
super.render(html);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async onClientRender() {
|
|
23
|
+
await this.uploadAndProcess();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async uploadAndProcess() {
|
|
27
|
+
const fileInput = document.getElementById("imageUpload");
|
|
28
|
+
const regenerateBtn = document.querySelector(".regenerate-btn");
|
|
29
|
+
const uploadButtons = document.querySelectorAll(".upload-image-button");
|
|
30
|
+
|
|
31
|
+
uploadButtons.forEach(button => {
|
|
32
|
+
button.addEventListener("click", () => {
|
|
33
|
+
fileInput.click();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
fileInput.addEventListener("change", async () => {
|
|
38
|
+
this.startContainer.classList.add("hidden");
|
|
39
|
+
this.resultContainer.classList.remove("hidden");
|
|
40
|
+
this.imageBefore.src = '';
|
|
41
|
+
|
|
42
|
+
const file = fileInput.files[0];
|
|
43
|
+
if (!file) return;
|
|
44
|
+
this.imageBefore.src = this.createBlobImageElement(file);
|
|
45
|
+
this.placeholderImage.src = this.createBlobImageElement(file);
|
|
46
|
+
|
|
47
|
+
this.lastFile = file;
|
|
48
|
+
const promptText = document.getElementById("prompt").value;
|
|
49
|
+
|
|
50
|
+
await this.sendToServer(file, promptText);
|
|
51
|
+
|
|
52
|
+
this.placeholderImage.classList.add("hidden");
|
|
53
|
+
this.imageCompareGenerated.classList.remove("hidden");
|
|
54
|
+
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
regenerateBtn.addEventListener("click", async () => {
|
|
58
|
+
if (!this.lastFile) {
|
|
59
|
+
console.warn("No image has been uploaded yet.");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const promptText = document.getElementById("prompt").value;
|
|
64
|
+
await this.sendToServer(this.lastFile, promptText);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async sendToServer(file, promptText) {
|
|
69
|
+
const loader = document.getElementById("loader");
|
|
70
|
+
const imageAfter = document.getElementById("image-after");
|
|
71
|
+
|
|
72
|
+
const formData = new FormData();
|
|
73
|
+
formData.append("image", file);
|
|
74
|
+
formData.append("prompt", promptText);
|
|
75
|
+
|
|
76
|
+
loader.classList.remove("hidden");
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const response = await fetch("https://ai.applet3d.com/api/image-upload", {
|
|
80
|
+
method: "POST",
|
|
81
|
+
body: formData,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (response.ok) {
|
|
85
|
+
const blob = await response.blob();
|
|
86
|
+
const objectURL = this.createBlobImageElement(blob);
|
|
87
|
+
this.imageAfter.src = objectURL;
|
|
88
|
+
|
|
89
|
+
const imgElement = document.createElement("img");
|
|
90
|
+
imgElement.src = objectURL;
|
|
91
|
+
imgElement.style.maxWidth = "1920px";
|
|
92
|
+
imgElement.dataset.blob = "true";
|
|
93
|
+
|
|
94
|
+
imageAfter.innerHTML = "";
|
|
95
|
+
imageAfter.appendChild(imgElement);
|
|
96
|
+
|
|
97
|
+
imgElement.onload = () => {
|
|
98
|
+
loader.classList.add("hidden");
|
|
99
|
+
};
|
|
100
|
+
} else {
|
|
101
|
+
console.error("Server error:", response.status);
|
|
102
|
+
loader.classList.add("hidden");
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error("Upload failed:", err);
|
|
106
|
+
loader.classList.add("hidden");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
downloadLatestBlobImage() {
|
|
111
|
+
const imageAfter = document.getElementById("image-after");
|
|
112
|
+
const imgElement = imageAfter.querySelector("img");
|
|
113
|
+
|
|
114
|
+
if (!imgElement || !imgElement.src.startsWith("blob:")) {
|
|
115
|
+
console.error("No blob image found to download.");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fetch(imgElement.src)
|
|
120
|
+
.then(response => response.blob())
|
|
121
|
+
.then(blob => {
|
|
122
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
123
|
+
|
|
124
|
+
const link = document.createElement("a");
|
|
125
|
+
link.href = objectUrl;
|
|
126
|
+
link.download = "downloaded-image.png";
|
|
127
|
+
document.body.appendChild(link);
|
|
128
|
+
link.click();
|
|
129
|
+
|
|
130
|
+
document.body.removeChild(link);
|
|
131
|
+
URL.revokeObjectURL(objectUrl);
|
|
132
|
+
})
|
|
133
|
+
.catch(err => {
|
|
134
|
+
console.error("Failed to download image:", err);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
createBlobImageElement(blob) {
|
|
139
|
+
return URL.createObjectURL(blob);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
window.customElements.define('ai-image-generator', AiImageGenerator);
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
ai-image-generator {
|
|
2
|
+
.flex-wrapper {
|
|
3
|
+
gap: 64px;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
align-items: center;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.result {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 30px;
|
|
13
|
+
|
|
14
|
+
.images-wrapper {
|
|
15
|
+
position: relative;
|
|
16
|
+
max-width: 1058px;
|
|
17
|
+
max-height: 566px;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
|
|
22
|
+
display: grid;
|
|
23
|
+
place-items: center;
|
|
24
|
+
|
|
25
|
+
img.placeholder-image {
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
max-width: 1058px;
|
|
29
|
+
max-height: 566px;
|
|
30
|
+
filter: blur(5px);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.btn {
|
|
34
|
+
position: absolute;
|
|
35
|
+
|
|
36
|
+
&.download {
|
|
37
|
+
top: 15px;
|
|
38
|
+
right: 15px;
|
|
39
|
+
z-index: 10;
|
|
40
|
+
display: flex;
|
|
41
|
+
gap: 8px;
|
|
42
|
+
padding: 12px 10px;
|
|
43
|
+
background: #00000099;
|
|
44
|
+
color: #6CBE02;
|
|
45
|
+
font-size: 14px;
|
|
46
|
+
text-transform: uppercase;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
button-component div.btn {
|
|
51
|
+
bottom: 15px;
|
|
52
|
+
left: 50%;
|
|
53
|
+
transform: translateX(-50%);
|
|
54
|
+
z-index: 10;
|
|
55
|
+
text-transform: uppercase;
|
|
56
|
+
border-color: #6CBE02;
|
|
57
|
+
background-color: #6CBE02;
|
|
58
|
+
color: #fff;
|
|
59
|
+
|
|
60
|
+
&:hover {
|
|
61
|
+
background-color: #fff;
|
|
62
|
+
color: #6CBE02;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.actions-wrapper {
|
|
68
|
+
display: flex;
|
|
69
|
+
gap: 16px;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
width: 100%;
|
|
73
|
+
|
|
74
|
+
.input-wrapper {
|
|
75
|
+
height: 52px;
|
|
76
|
+
max-width: 580px;
|
|
77
|
+
width: 100%;
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
textarea {
|
|
81
|
+
border-radius: 6px;
|
|
82
|
+
border: 1px solid #DADADA;
|
|
83
|
+
resize: none;
|
|
84
|
+
height: 52px;
|
|
85
|
+
width: 100%;
|
|
86
|
+
padding: 7px 16px;
|
|
87
|
+
color: #2B2B2B;
|
|
88
|
+
line-height: 100%;
|
|
89
|
+
font-size: 16px;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.flex-buttons {
|
|
94
|
+
display: flex;
|
|
95
|
+
gap: 16px;
|
|
96
|
+
|
|
97
|
+
.btn {
|
|
98
|
+
cursor: pointer;
|
|
99
|
+
padding: 14px 35px;
|
|
100
|
+
text-transform: uppercase;
|
|
101
|
+
display: flex;
|
|
102
|
+
gap: 6px;
|
|
103
|
+
align-items: center;
|
|
104
|
+
border: 1px solid transparent;
|
|
105
|
+
border-color: #0E1011;
|
|
106
|
+
transition: all 0.2s ease-in;
|
|
107
|
+
font-size: 20px;
|
|
108
|
+
max-height: 52px;
|
|
109
|
+
|
|
110
|
+
svg {
|
|
111
|
+
height: 24px;
|
|
112
|
+
|
|
113
|
+
path {
|
|
114
|
+
transition: all 0.2s ease-in;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
&.primary {
|
|
119
|
+
background-color: #0E1011;
|
|
120
|
+
color: #fff;
|
|
121
|
+
|
|
122
|
+
&:hover {
|
|
123
|
+
background-color: #fff;
|
|
124
|
+
color: #0E1011;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
&.empty {
|
|
129
|
+
background-color: #fff;
|
|
130
|
+
color: #0E1011;
|
|
131
|
+
|
|
132
|
+
&:hover {
|
|
133
|
+
background-color: #0E1011;
|
|
134
|
+
color: #fff;
|
|
135
|
+
|
|
136
|
+
svg {
|
|
137
|
+
path {
|
|
138
|
+
stroke: #fff;
|
|
139
|
+
fill: #fff;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
path[stroke-linecap] {
|
|
143
|
+
stroke: #fff;
|
|
144
|
+
fill: transparent;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&.disabled {
|
|
152
|
+
background-color: transparent;
|
|
153
|
+
border-color: #DADADA;
|
|
154
|
+
color: #DADADA;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.loader {
|
|
161
|
+
position: absolute;
|
|
162
|
+
top: 50%;
|
|
163
|
+
left: 50%;
|
|
164
|
+
transform: translate(-50%, -50%);
|
|
165
|
+
|
|
166
|
+
z-index: 100;
|
|
167
|
+
width: 140px;
|
|
168
|
+
height: 140px;
|
|
169
|
+
|
|
170
|
+
.spinner-circle {
|
|
171
|
+
width: 100%;
|
|
172
|
+
height: 100%;
|
|
173
|
+
border: 20px solid #DADADA;
|
|
174
|
+
border-top: 20px solid #6CBE02;
|
|
175
|
+
border-radius: 50%;
|
|
176
|
+
animation: spin 1s linear infinite;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
.hidden {
|
|
183
|
+
display: none;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@keyframes spin {
|
|
187
|
+
to {
|
|
188
|
+
transform: rotate(360deg);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@media (max-width: 1050px) {
|
|
194
|
+
ai-image-generator {
|
|
195
|
+
.flex-wrapper.start {
|
|
196
|
+
align-items: self-start;
|
|
197
|
+
flex-direction: column-reverse;
|
|
198
|
+
gap: 32px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.result {
|
|
202
|
+
.images-wrapper {
|
|
203
|
+
.btn.download {
|
|
204
|
+
top: 5px;
|
|
205
|
+
right: 5px;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
.actions-wrapper {
|
|
209
|
+
flex-direction: column;
|
|
210
|
+
|
|
211
|
+
.flex-buttons {
|
|
212
|
+
gap: 16px;
|
|
213
|
+
width: 100%;
|
|
214
|
+
|
|
215
|
+
.btn {
|
|
216
|
+
display: flex;
|
|
217
|
+
justify-content: center;
|
|
218
|
+
flex: 1;
|
|
219
|
+
padding: 14px;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
ai-image-content section {
|
|
226
|
+
max-width: 100%;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.loader {
|
|
230
|
+
width: 70px;
|
|
231
|
+
height: 70px;
|
|
232
|
+
.spinner-circle {
|
|
233
|
+
border: 8px solid #DADADA;
|
|
234
|
+
border-top: 8px solid #6CBE02;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
button-component div.btn {
|
|
239
|
+
padding: 9px;
|
|
240
|
+
font-size: 16px;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -7,10 +7,16 @@ class BlogBanner extends GHComponent {
|
|
|
7
7
|
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
|
+
const homepageAttr = this.getAttribute('data-homepage');
|
|
11
|
+
try {
|
|
12
|
+
this.homepageObj = homepageAttr && JSON.parse(homepageAttr);
|
|
13
|
+
} catch (e) {
|
|
14
|
+
console.warn('Invalid data-homepage JSON:', `data-homepage='{"title": "Головна", "link": "/"}'`);
|
|
15
|
+
this.homepageObj = { title: 'Головна', link: '/' };
|
|
16
|
+
}
|
|
10
17
|
}
|
|
11
18
|
|
|
12
19
|
async onServerRender() {
|
|
13
|
-
|
|
14
20
|
this.config = initBlogConfig(window.getConfig().componentsConfigs.blog_config[0]);
|
|
15
21
|
|
|
16
22
|
let url = new URL(window.location.href);
|
|
@@ -40,10 +46,7 @@ class BlogBanner extends GHComponent {
|
|
|
40
46
|
breadcrumbsTitle.innerHTML = this.json.title;
|
|
41
47
|
|
|
42
48
|
this.breadcrumbs = JSON.stringify([
|
|
43
|
-
|
|
44
|
-
title: 'Головна',
|
|
45
|
-
link: '/'
|
|
46
|
-
},
|
|
49
|
+
this.homepageObj,
|
|
47
50
|
{
|
|
48
51
|
title: breadcrumbsTitle.innerText
|
|
49
52
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<div class="button text" onclick="openList()">${config.general_settings.categories}</div>
|
|
3
3
|
<div class="list_wrapper">
|
|
4
4
|
<ul class="categories_list flex-wrapper">
|
|
5
|
-
<li ${url ==
|
|
6
|
-
<a href="
|
|
5
|
+
<li ${url == `${allArticlesButtonLink}` ? 'class="active"' : ''}>
|
|
6
|
+
<a href="${allArticlesButtonLink}" class="text btn empty">${config.general_settings.all_articles_button}</a>
|
|
7
7
|
</li>
|
|
8
8
|
${
|
|
9
9
|
categories.reduce((acc, category, index) => {
|
|
@@ -28,6 +28,7 @@ class CategoriesList extends GHComponent {
|
|
|
28
28
|
this.categories = this.categories.categories;
|
|
29
29
|
this.url = new URL (window.location.href);
|
|
30
30
|
this.url = this.url.searchParams.get('path');
|
|
31
|
+
this.allArticlesButtonLink = this.config.general_settings.all_articles_button_link || '/blog/'
|
|
31
32
|
super.render(html);
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -42,12 +42,12 @@ class CategoryBanner extends GHComponent {
|
|
|
42
42
|
|
|
43
43
|
this.breadcrumbs = JSON.stringify([
|
|
44
44
|
{
|
|
45
|
-
"title": "Головна",
|
|
46
|
-
"link": "/"
|
|
45
|
+
"title": this.config.breadcrumbs.homepage || "Головна",
|
|
46
|
+
"link": this.config.breadcrumbs.homepageLink || "/"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
|
-
"title": this.config.breadcrumbs.blog,
|
|
50
|
-
"link": "/blog/"
|
|
49
|
+
"title": this.config.breadcrumbs.blog || "Блог",
|
|
50
|
+
"link": this.config.breadcrumbs.blogLink || "/blog/"
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
"title": this.title
|
|
@@ -110,7 +110,7 @@ class CommentsComponent extends GHComponent {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
if (comment.name && comment.text) {
|
|
113
|
-
const { api_app_id } = window.getConfig().
|
|
113
|
+
const { api_app_id } = window.getConfig().chapters.blog;
|
|
114
114
|
const response = await fetch(`https://gudhub.com/api/services/prod/api/${api_app_id}/add-comment`, {
|
|
115
115
|
method: 'POST',
|
|
116
116
|
headers: {
|
package/src/config.js
CHANGED
|
@@ -66,6 +66,9 @@ export { PageBannerImageAndMenu } from './components/page-banner-image-and-menu/
|
|
|
66
66
|
export { GoogleAnalytics } from './components/google-analytics/config.js';
|
|
67
67
|
export { GoogleTag } from './components/google-tag/config.js';
|
|
68
68
|
export { cookiesPopup } from './components/cookies-popup/config.js';
|
|
69
|
+
export { AiImageGenerator } from './components/ai-image-generator/config.js';
|
|
70
|
+
export { AiImageContent } from './components/ai-image-generator/ai-image-content/config.js';
|
|
71
|
+
export { AiImageCompare } from './components/ai-image-generator/ai-image-compare/config.js';
|
|
69
72
|
|
|
70
73
|
// export { liqPayComponent } from './components/liqpay-component/config.js';
|
|
71
74
|
// export { htmlTextFromEditorJs } from './components/html-text-from-editor-js/config.js';
|