vibespot 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -5
- package/assets/blog-rules.md +251 -0
- package/assets/email-rules.md +390 -0
- package/assets/humanify-guide.md +300 -101
- package/assets/plan-templates/blog-content-hub.md +18 -9
- package/assets/plan-templates/email-announcement.md +41 -0
- package/assets/plan-templates/email-event-invite.md +43 -0
- package/assets/plan-templates/email-newsletter.md +41 -0
- package/assets/plan-templates/email-re-engagement.md +42 -0
- package/assets/plan-templates/email-welcome.md +41 -0
- package/dist/index.js +1460 -387
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/starters/06-blog-content-hub.json +75 -0
- package/starters/06-email-welcome.json +60 -0
- package/starters/07-email-announcement.json +60 -0
- package/starters/08-email-newsletter.json +52 -0
- package/ui/chat.js +777 -63
- package/ui/code-editor.js +49 -7
- package/ui/dashboard.js +379 -93
- package/ui/docs/docs.css +29 -0
- package/ui/docs/index.html +416 -119
- package/ui/docs/screenshots/asset-type-cards.png +0 -0
- package/ui/docs/screenshots/brand-kit-preview.png +0 -0
- package/ui/docs/screenshots/content-type-dropdown.png +0 -0
- package/ui/docs/screenshots/deploy-progress.png +0 -0
- package/ui/docs/screenshots/editor-full-layout.png +0 -0
- package/ui/docs/screenshots/email-client-preview.png +0 -0
- package/ui/docs/screenshots/inline-wysiwyg-editing.png +0 -0
- package/ui/docs/screenshots/module-overview-slideout.png +0 -0
- package/ui/docs/screenshots/multi-page-tree.png +0 -0
- package/ui/docs/screenshots/onboarding-walkthrough.png +0 -0
- package/ui/docs/screenshots/pipeline-progress.png +0 -0
- package/ui/docs/screenshots/project-overview-table.png +0 -0
- package/ui/docs/screenshots/split-pane-view.png +0 -0
- package/ui/docs/screenshots/visual-controls-toolbar.png +0 -0
- package/ui/docs/screenshots/workspace-tabs.png +0 -0
- package/ui/email-preview.js +109 -0
- package/ui/field-editor.js +72 -1
- package/ui/icons.js +120 -0
- package/ui/index.html +877 -629
- package/ui/inline-edit.js +710 -0
- package/ui/plan.js +0 -0
- package/ui/preview.js +101 -198
- package/ui/section-controls.js +628 -0
- package/ui/settings.js +58 -16
- package/ui/setup.js +750 -140
- package/ui/styles.css +3430 -952
- package/ui/upload-panel.js +47 -20
package/ui/upload-panel.js
CHANGED
|
@@ -8,6 +8,7 @@ let lastUploadErrors = [];
|
|
|
8
8
|
let lastUploadPortalId = "";
|
|
9
9
|
let lastUploadDataCenter = "na1";
|
|
10
10
|
let lastUploadThemeName = "";
|
|
11
|
+
let lastUploadContentMode = "page";
|
|
11
12
|
const MAX_UPLOAD_ATTEMPTS = 3;
|
|
12
13
|
|
|
13
14
|
async function startUpload() {
|
|
@@ -249,7 +250,7 @@ function confirmUpload(portalName, portalId) {
|
|
|
249
250
|
let html = '<div style="display:flex;flex-direction:column;gap:6px">';
|
|
250
251
|
for (const acct of accounts) {
|
|
251
252
|
const isActive = acct.portalId === activeId;
|
|
252
|
-
html += `<button class="btn btn--${isActive ? "primary" : "secondary"} confirm-acct-btn" data-portal="${esc(acct.portalId)}" style="text-align:left;padding:6px 12px;font-size:13px">${esc(acct.portalName || acct.portalId)} (${esc(acct.portalId)})${isActive ? "
|
|
253
|
+
html += `<button class="btn btn--${isActive ? "primary" : "secondary"} confirm-acct-btn" data-portal="${esc(acct.portalId)}" style="text-align:left;padding:6px 12px;font-size:13px">${esc(acct.portalName || acct.portalId)} (${esc(acct.portalId)})${isActive ? ' <span class="vs-icon-inline">' + vsIcon("check", {size: "sm"}) + '</span>' : ""}</button>`;
|
|
253
254
|
}
|
|
254
255
|
html += `<button class="btn btn--secondary confirm-acct-btn" data-portal="__new" style="text-align:left;padding:6px 12px;font-size:13px">+ Add another account</button>`;
|
|
255
256
|
html += '</div>';
|
|
@@ -326,10 +327,10 @@ function setUploadState(state, data) {
|
|
|
326
327
|
|
|
327
328
|
case "success":
|
|
328
329
|
panel.classList.add("upload-panel--success");
|
|
329
|
-
statusEl.innerHTML = '<span class="upload-status-icon"
|
|
330
|
+
statusEl.innerHTML = '<span class="upload-status-icon">' + vsIcon("check-circle", {size: "sm"}) + '</span> Upload complete!';
|
|
330
331
|
if (uploadBtn) {
|
|
331
332
|
uploadBtn.textContent = "Deploy";
|
|
332
|
-
uploadBtn.disabled =
|
|
333
|
+
uploadBtn.disabled = true;
|
|
333
334
|
}
|
|
334
335
|
const dismissBtn = document.createElement("button");
|
|
335
336
|
dismissBtn.className = "upload-action-btn";
|
|
@@ -337,13 +338,16 @@ function setUploadState(state, data) {
|
|
|
337
338
|
dismissBtn.addEventListener("click", () => setUploadState("idle"));
|
|
338
339
|
actions.appendChild(dismissBtn);
|
|
339
340
|
|
|
340
|
-
// Show the Create Page button
|
|
341
341
|
if (lastUploadPortalId) {
|
|
342
|
+
const isEmail = lastUploadContentMode === "email";
|
|
342
343
|
const createBtn = document.createElement("button");
|
|
343
344
|
createBtn.className = "upload-action-btn upload-action-btn--primary";
|
|
344
|
-
createBtn.textContent = "Create Page in HubSpot";
|
|
345
|
+
createBtn.textContent = isEmail ? "Create Email in HubSpot" : "Create Page in HubSpot";
|
|
345
346
|
createBtn.addEventListener("click", () => {
|
|
346
|
-
|
|
347
|
+
const url = isEmail
|
|
348
|
+
? buildHubSpotEmailUrl(lastUploadPortalId, lastUploadDataCenter)
|
|
349
|
+
: buildHubSpotPagesUrl(lastUploadPortalId, lastUploadDataCenter);
|
|
350
|
+
window.open(url, "_blank");
|
|
347
351
|
});
|
|
348
352
|
actions.insertBefore(createBtn, dismissBtn);
|
|
349
353
|
}
|
|
@@ -351,10 +355,10 @@ function setUploadState(state, data) {
|
|
|
351
355
|
|
|
352
356
|
case "failed":
|
|
353
357
|
panel.classList.add("upload-panel--error");
|
|
354
|
-
statusEl.innerHTML = '<span class="upload-status-icon"
|
|
358
|
+
statusEl.innerHTML = '<span class="upload-status-icon">' + vsIcon("x-circle", {size: "sm"}) + '</span> Upload failed';
|
|
355
359
|
if (uploadBtn) {
|
|
356
360
|
uploadBtn.textContent = "Deploy";
|
|
357
|
-
uploadBtn.disabled =
|
|
361
|
+
uploadBtn.disabled = true;
|
|
358
362
|
}
|
|
359
363
|
|
|
360
364
|
const retryBtn = document.createElement("button");
|
|
@@ -387,10 +391,10 @@ function setUploadState(state, data) {
|
|
|
387
391
|
|
|
388
392
|
case "fix_done":
|
|
389
393
|
panel.classList.add("upload-panel--fixing");
|
|
390
|
-
statusEl.innerHTML = '<span class="upload-status-icon"
|
|
394
|
+
statusEl.innerHTML = '<span class="upload-status-icon">' + vsIcon("check-circle", {size: "sm"}) + '</span> AI fixes applied';
|
|
391
395
|
if (uploadBtn) {
|
|
392
396
|
uploadBtn.textContent = "Deploy";
|
|
393
|
-
uploadBtn.disabled =
|
|
397
|
+
uploadBtn.disabled = true;
|
|
394
398
|
}
|
|
395
399
|
|
|
396
400
|
const redeployBtn = document.createElement("button");
|
|
@@ -490,12 +494,13 @@ function handleUploadWsMessage(msg) {
|
|
|
490
494
|
break;
|
|
491
495
|
|
|
492
496
|
case "upload_complete":
|
|
497
|
+
lastUploadContentMode = msg.contentMode || "page";
|
|
493
498
|
setUploadState("success");
|
|
494
499
|
// Update status bar
|
|
495
500
|
const statusText = document.getElementById("status-text");
|
|
496
501
|
if (statusText) statusText.textContent = "Upload complete!";
|
|
497
502
|
// Show celebration popup
|
|
498
|
-
showDeploySuccessPopup(msg.portalId, msg.dataCenter || "na1", msg.themeName);
|
|
503
|
+
showDeploySuccessPopup(msg.portalId, msg.dataCenter || "na1", msg.themeName, lastUploadContentMode);
|
|
499
504
|
break;
|
|
500
505
|
|
|
501
506
|
case "upload_failed":
|
|
@@ -538,32 +543,54 @@ function buildHubSpotPagesUrl(portalId, dataCenter) {
|
|
|
538
543
|
return `https://${host}/page-ui/${portalId}/management/pages/landing`;
|
|
539
544
|
}
|
|
540
545
|
|
|
541
|
-
function
|
|
546
|
+
function buildHubSpotEmailUrl(portalId, dataCenter) {
|
|
547
|
+
const host = dataCenter === "eu1" ? "app-eu1.hubspot.com" : "app.hubspot.com";
|
|
548
|
+
return `https://${host}/email/${portalId}`;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function showDeploySuccessPopup(portalId, dataCenter, themeName, contentMode) {
|
|
542
552
|
lastUploadPortalId = portalId || "";
|
|
543
553
|
lastUploadDataCenter = dataCenter || "na1";
|
|
544
554
|
lastUploadThemeName = themeName || "";
|
|
545
555
|
|
|
546
556
|
const name = themeName || "your theme";
|
|
547
|
-
const
|
|
548
|
-
const pagesUrl = portalId ? buildHubSpotPagesUrl(portalId, dataCenter) : "";
|
|
557
|
+
const isEmail = contentMode === "email";
|
|
549
558
|
|
|
550
559
|
// Spawn confetti
|
|
551
560
|
spawnConfetti();
|
|
552
561
|
|
|
562
|
+
let stepsHtml, actionUrl, actionLabel;
|
|
563
|
+
if (isEmail) {
|
|
564
|
+
actionUrl = portalId ? buildHubSpotEmailUrl(portalId, dataCenter) : "";
|
|
565
|
+
actionLabel = "Create Email in HubSpot";
|
|
566
|
+
stepsHtml = `
|
|
567
|
+
<div class="deploy-success__step"><span class="deploy-success__num">1</span> Go to <strong>Marketing → Email</strong></div>
|
|
568
|
+
<div class="deploy-success__step"><span class="deploy-success__num">2</span> Click <strong>"Create email"</strong></div>
|
|
569
|
+
<div class="deploy-success__step"><span class="deploy-success__num">3</span> Select your <strong>"${esc(name)}"</strong> template</div>
|
|
570
|
+
`;
|
|
571
|
+
} else {
|
|
572
|
+
const lpLabel = `${name} Landing Page`;
|
|
573
|
+
actionUrl = portalId ? buildHubSpotPagesUrl(portalId, dataCenter) : "";
|
|
574
|
+
actionLabel = "Create Page in HubSpot";
|
|
575
|
+
stepsHtml = `
|
|
576
|
+
<div class="deploy-success__step"><span class="deploy-success__num">1</span> Go to <strong>Content → Landing Pages</strong></div>
|
|
577
|
+
<div class="deploy-success__step"><span class="deploy-success__num">2</span> Click <strong>"Create" → "Landing page"</strong></div>
|
|
578
|
+
<div class="deploy-success__step"><span class="deploy-success__num">3</span> Select the <strong>"${esc(lpLabel)}"</strong> template</div>
|
|
579
|
+
`;
|
|
580
|
+
}
|
|
581
|
+
|
|
553
582
|
const overlay = document.createElement("div");
|
|
554
583
|
overlay.className = "confirm-overlay";
|
|
555
584
|
overlay.innerHTML = `
|
|
556
585
|
<div class="deploy-success">
|
|
557
|
-
<div class="deploy-success__icon"
|
|
558
|
-
<h2 class="deploy-success__title"
|
|
586
|
+
<div class="deploy-success__icon">${vsIcon("rocket", {size: "md"})}</div>
|
|
587
|
+
<h2 class="deploy-success__title">${isEmail ? "Email template deployed!" : "Theme deployed!"}</h2>
|
|
559
588
|
<p class="deploy-success__subtitle">"${esc(name)}" is now live on HubSpot.</p>
|
|
560
589
|
<div class="deploy-success__steps">
|
|
561
|
-
|
|
562
|
-
<div class="deploy-success__step"><span class="deploy-success__num">2</span> Click <strong>"Create" → "Landing page"</strong></div>
|
|
563
|
-
<div class="deploy-success__step"><span class="deploy-success__num">3</span> Select the <strong>"${esc(lpLabel)}"</strong> template</div>
|
|
590
|
+
${stepsHtml}
|
|
564
591
|
</div>
|
|
565
592
|
<div class="deploy-success__actions">
|
|
566
|
-
${
|
|
593
|
+
${actionUrl ? `<a href="${actionUrl}" target="_blank" class="btn btn--primary deploy-success__link">${actionLabel} →</a>` : ""}
|
|
567
594
|
<button class="btn btn--secondary" id="deploy-success-dismiss">Close</button>
|
|
568
595
|
</div>
|
|
569
596
|
</div>
|