IframeImplementation.vue
· 659 B · vue
Raw
<template>
<div class="direct-iframe-wrapper">
<div class="direct-iframe-title">Direct Iframe Embed</div>
<iframe
src="https://ai-studio.bliv.bangunindo.io/chatbot/4eFb0BunqZYEZlg7"
class="direct-iframe"
allow="microphone"
title="Chatbot Direct"
/>
</div>
</template>
<style scoped>
.direct-iframe-wrapper {
width: 100%;
height: calc(100vh - 48px);
display: flex;
flex-direction: column;
}
.direct-iframe-title {
margin-bottom: 16px;
font-weight: 600;
color: #374151;
}
.direct-iframe {
width: 100%;
flex: 1;
min-height: 700px;
border: none;
border-radius: 16px;
background: #fff;
}
</style>
| 1 | <template> |
| 2 | <div class="direct-iframe-wrapper"> |
| 3 | <div class="direct-iframe-title">Direct Iframe Embed</div> |
| 4 | <iframe |
| 5 | src="https://ai-studio.bliv.bangunindo.io/chatbot/4eFb0BunqZYEZlg7" |
| 6 | class="direct-iframe" |
| 7 | allow="microphone" |
| 8 | title="Chatbot Direct" |
| 9 | /> |
| 10 | </div> |
| 11 | </template> |
| 12 | |
| 13 | <style scoped> |
| 14 | .direct-iframe-wrapper { |
| 15 | width: 100%; |
| 16 | height: calc(100vh - 48px); |
| 17 | display: flex; |
| 18 | flex-direction: column; |
| 19 | } |
| 20 | .direct-iframe-title { |
| 21 | margin-bottom: 16px; |
| 22 | font-weight: 600; |
| 23 | color: #374151; |
| 24 | } |
| 25 | .direct-iframe { |
| 26 | width: 100%; |
| 27 | flex: 1; |
| 28 | min-height: 700px; |
| 29 | border: none; |
| 30 | border-radius: 16px; |
| 31 | background: #fff; |
| 32 | } |
| 33 | </style> |
| 34 |
IframeWithModalImplementation.vue
· 5.5 KiB · vue
Raw
<template>
<div class="embed-wrapper">
<div class="card">
<div class="card-header">
<div class="icon-circle">🔐</div>
<h1>Chatbot Modal Demo</h1>
<p>Authenticated • With History • Iframe Modal</p>
</div>
<div class="card-body">
<div class="section-title">Configuration</div>
<div class="badges">
<span class="badge badge-auth"><span class="badge-dot"></span>Auth Enabled</span>
<span class="badge badge-history"><span class="badge-dot"></span>History On</span>
<span class="badge badge-mode"><span class="badge-dot"></span>Modal Mode</span>
</div>
<div class="details">
<div class="detail-row">
<span class="detail-label">Mechanism</span>
<span class="detail-value">Iframe in Modal</span>
</div>
<div class="detail-row">
<span class="detail-label">Authentication</span>
<span class="detail-value">Required</span>
</div>
<div class="detail-row">
<span class="detail-label">Base URL</span>
<span class="detail-value" style="font-size: 0.7rem">ai-studio.bliv.bangunindo.io</span>
</div>
</div>
<button class="btn-primary" @click="isOpen = true">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
Mulai Percakapan
</button>
</div>
</div>
<!-- Modal Implementation -->
<div class="modal" :class="{ active: isOpen }" @click.self="isOpen = false">
<div class="modal-content">
<div class="modal-header">
<h3>Bliv AI Chatbot</h3>
<button class="close-btn" @click="isOpen = false">×</button>
</div>
<div class="modal-body">
<iframe
v-if="isOpen"
:src="iframeSrc"
allow="microphone"
title="Chatbot"
/>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const isOpen = ref(false);
const appCode = "4eFb0BunqZYEZlg7";
const baseUrl = "https://ai-studio.bliv.bangunindo.io";
const iframeSrc = `${baseUrl}/chatbot-auth/${appCode}/history`;
</script>
<style scoped>
.embed-wrapper {
width: 100%;
display: flex;
align-items: center; justify-content: center;
padding: 24px;
}
.card {
background: white; border-radius: 24px; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1); width: 100%; max-width: 480px; overflow: hidden; border: 1px solid #f1f5f9;
}
.card-header { padding: 32px; text-align: center; border-bottom: 1px solid #f1f5f9; }
.icon-circle { width: 64px; height: 64px; background: #e0e7ff; color: #4f46e5; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 28px; margin: 0 auto 16px; }
.card-header h1 { font-size: 1.5rem; color: #0f172a; margin-bottom: 4px; font-weight: 700; }
.card-header p { font-size: 0.875rem; color: #64748b; }
.card-body { padding: 24px 32px 32px; }
.section-title { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; color: #94a3b8; margin-bottom: 12px; }
.badges { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
.badge { font-size: 0.7rem; padding: 6px 12px; background: #f1f5f9; border-radius: 99px; display: flex; align-items: center; gap: 6px; color: #475569; font-weight: 600; }
.badge-dot { width: 6px; height: 6px; background: #64748b; border-radius: 50%; }
.badge-auth { background: #e0f2f1; color: #14b8a6; }
.badge-auth .badge-dot { background: #14b8a6; }
.badge-history { background: #dbeafe; color: #1e40af; }
.badge-history .badge-dot { background: #1e40af; }
.details { background: #f8fafc; border-radius: 16px; padding: 16px; margin-bottom: 24px; border: 1px solid #f1f5f9; }
.detail-row { display: flex; justify-content: space-between; font-size: 0.8rem; padding: 6px 0; border-bottom: 1px solid #f1f5f9; }
.detail-row:last-child { border-bottom: none; }
.detail-label { color: #64748b; }
.detail-value { font-weight: 600; font-family: ui-monospace, monospace; color: #0f172a; }
.btn-primary {
width: 100%; background: #4f46e5; color: white; border: none; padding: 14px 24px; font-size: 0.95rem; font-weight: 600; border-radius: 12px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: all 0.2s;
}
.btn-primary:hover { transform: translateY(-2px); filter: brightness(1.1); }
/* Modal Styles */
.modal {
display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(8px); z-index: 1000; align-items: center; justify-content: center; padding: 20px;
}
.modal.active { display: flex; }
.modal-content {
background: white; border-radius: 24px; width: 100%; max-width: 800px; height: 80vh; max-height: 600px; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}
.modal-header { padding: 16px 24px; background: #f8fafc; border-bottom: 1px solid #f1f5f9; display: flex; justify-content: space-between; align-items: center; }
.modal-header h3 { font-size: 1rem; color: #0f172a; }
.close-btn { background: #f1f5f9; border: none; width: 32px; height: 32px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; color: #64748b; }
.modal-body { flex: 1; min-height: 0; }
iframe { width: 100%; height: 100%; border: none; }
</style>
| 1 | <template> |
| 2 | <div class="embed-wrapper"> |
| 3 | <div class="card"> |
| 4 | <div class="card-header"> |
| 5 | <div class="icon-circle">🔐</div> |
| 6 | <h1>Chatbot Modal Demo</h1> |
| 7 | <p>Authenticated • With History • Iframe Modal</p> |
| 8 | </div> |
| 9 | <div class="card-body"> |
| 10 | <div class="section-title">Configuration</div> |
| 11 | <div class="badges"> |
| 12 | <span class="badge badge-auth"><span class="badge-dot"></span>Auth Enabled</span> |
| 13 | <span class="badge badge-history"><span class="badge-dot"></span>History On</span> |
| 14 | <span class="badge badge-mode"><span class="badge-dot"></span>Modal Mode</span> |
| 15 | </div> |
| 16 | <div class="details"> |
| 17 | <div class="detail-row"> |
| 18 | <span class="detail-label">Mechanism</span> |
| 19 | <span class="detail-value">Iframe in Modal</span> |
| 20 | </div> |
| 21 | <div class="detail-row"> |
| 22 | <span class="detail-label">Authentication</span> |
| 23 | <span class="detail-value">Required</span> |
| 24 | </div> |
| 25 | <div class="detail-row"> |
| 26 | <span class="detail-label">Base URL</span> |
| 27 | <span class="detail-value" style="font-size: 0.7rem">ai-studio.bliv.bangunindo.io</span> |
| 28 | </div> |
| 29 | </div> |
| 30 | <button class="btn-primary" @click="isOpen = true"> |
| 31 | <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> |
| 32 | Mulai Percakapan |
| 33 | </button> |
| 34 | </div> |
| 35 | </div> |
| 36 | |
| 37 | <!-- Modal Implementation --> |
| 38 | <div class="modal" :class="{ active: isOpen }" @click.self="isOpen = false"> |
| 39 | <div class="modal-content"> |
| 40 | <div class="modal-header"> |
| 41 | <h3>Bliv AI Chatbot</h3> |
| 42 | <button class="close-btn" @click="isOpen = false">×</button> |
| 43 | </div> |
| 44 | <div class="modal-body"> |
| 45 | <iframe |
| 46 | v-if="isOpen" |
| 47 | :src="iframeSrc" |
| 48 | allow="microphone" |
| 49 | title="Chatbot" |
| 50 | /> |
| 51 | </div> |
| 52 | </div> |
| 53 | </div> |
| 54 | </div> |
| 55 | </template> |
| 56 | |
| 57 | <script setup lang="ts"> |
| 58 | import { ref } from 'vue'; |
| 59 | |
| 60 | const isOpen = ref(false); |
| 61 | const appCode = "4eFb0BunqZYEZlg7"; |
| 62 | const baseUrl = "https://ai-studio.bliv.bangunindo.io"; |
| 63 | const iframeSrc = `${baseUrl}/chatbot-auth/${appCode}/history`; |
| 64 | </script> |
| 65 | |
| 66 | <style scoped> |
| 67 | .embed-wrapper { |
| 68 | width: 100%; |
| 69 | display: flex; |
| 70 | align-items: center; justify-content: center; |
| 71 | padding: 24px; |
| 72 | } |
| 73 | .card { |
| 74 | background: white; border-radius: 24px; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1); width: 100%; max-width: 480px; overflow: hidden; border: 1px solid #f1f5f9; |
| 75 | } |
| 76 | .card-header { padding: 32px; text-align: center; border-bottom: 1px solid #f1f5f9; } |
| 77 | .icon-circle { width: 64px; height: 64px; background: #e0e7ff; color: #4f46e5; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 28px; margin: 0 auto 16px; } |
| 78 | .card-header h1 { font-size: 1.5rem; color: #0f172a; margin-bottom: 4px; font-weight: 700; } |
| 79 | .card-header p { font-size: 0.875rem; color: #64748b; } |
| 80 | .card-body { padding: 24px 32px 32px; } |
| 81 | .section-title { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; color: #94a3b8; margin-bottom: 12px; } |
| 82 | .badges { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; } |
| 83 | .badge { font-size: 0.7rem; padding: 6px 12px; background: #f1f5f9; border-radius: 99px; display: flex; align-items: center; gap: 6px; color: #475569; font-weight: 600; } |
| 84 | .badge-dot { width: 6px; height: 6px; background: #64748b; border-radius: 50%; } |
| 85 | .badge-auth { background: #e0f2f1; color: #14b8a6; } |
| 86 | .badge-auth .badge-dot { background: #14b8a6; } |
| 87 | .badge-history { background: #dbeafe; color: #1e40af; } |
| 88 | .badge-history .badge-dot { background: #1e40af; } |
| 89 | |
| 90 | .details { background: #f8fafc; border-radius: 16px; padding: 16px; margin-bottom: 24px; border: 1px solid #f1f5f9; } |
| 91 | .detail-row { display: flex; justify-content: space-between; font-size: 0.8rem; padding: 6px 0; border-bottom: 1px solid #f1f5f9; } |
| 92 | .detail-row:last-child { border-bottom: none; } |
| 93 | .detail-label { color: #64748b; } |
| 94 | .detail-value { font-weight: 600; font-family: ui-monospace, monospace; color: #0f172a; } |
| 95 | |
| 96 | .btn-primary { |
| 97 | width: 100%; background: #4f46e5; color: white; border: none; padding: 14px 24px; font-size: 0.95rem; font-weight: 600; border-radius: 12px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: all 0.2s; |
| 98 | } |
| 99 | .btn-primary:hover { transform: translateY(-2px); filter: brightness(1.1); } |
| 100 | |
| 101 | /* Modal Styles */ |
| 102 | .modal { |
| 103 | display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(8px); z-index: 1000; align-items: center; justify-content: center; padding: 20px; |
| 104 | } |
| 105 | .modal.active { display: flex; } |
| 106 | .modal-content { |
| 107 | background: white; border-radius: 24px; width: 100%; max-width: 800px; height: 80vh; max-height: 600px; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); |
| 108 | } |
| 109 | .modal-header { padding: 16px 24px; background: #f8fafc; border-bottom: 1px solid #f1f5f9; display: flex; justify-content: space-between; align-items: center; } |
| 110 | .modal-header h3 { font-size: 1rem; color: #0f172a; } |
| 111 | .close-btn { background: #f1f5f9; border: none; width: 32px; height: 32px; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; color: #64748b; } |
| 112 | .modal-body { flex: 1; min-height: 0; } |
| 113 | iframe { width: 100%; height: 100%; border: none; } |
| 114 | </style> |
| 115 |
ScriptImplementation.vue
· 2.4 KiB · vue
Raw
<template>
<div class="direct-script-wrapper">
<div class="direct-script-title">Direct Script Embed</div>
<div class="direct-script-card">
<div class="icon-circle">⚡</div>
<h1>Widget Aktif</h1>
<p>
Script chatbot Bliv AI telah dimuat secara langsung pada halaman ini.
</p>
<small>Periksa sudut kanan bawah layar Anda untuk memulai chat.</small>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted } from "vue";
const baseUrl = "https://ai-studio.bliv.bangunindo.io";
onMounted(() => {
const config = {
token: "4eFb0BunqZYEZlg7",
baseUrl: baseUrl,
isDev: true,
login: false,
history: false,
draggable: true,
dragAxis: "both",
dynamicScript: true,
systemVariables: {},
userVariables: {},
};
(window as any).blivChatbotConfig = config;
const script = document.createElement("script");
script.id = "bliv-embed-script";
script.src = `${baseUrl}/embed.min.js`;
script.async = true;
document.body.appendChild(script);
});
onUnmounted(() => {
const script = document.getElementById("bliv-embed-script");
if (script) script.remove();
const selectors = [
"#bliv-chatbot-widget",
"#bliv-chatbot-bubble",
"#bliv-chatbot-container",
"#bliv-chatbot-iframe",
".bliv-chatbot-widget",
".bliv-chatbot-bubble",
".bliv-chatbot-container",
'iframe[src*="ai-studio.bliv.bangunindo.io"]',
];
selectors.forEach((sel) => {
document.querySelectorAll(sel).forEach((el) => el.remove());
});
delete (window as any).blivChatbotConfig;
});
</script>
<style scoped>
.direct-script-wrapper {
width: 100%;
padding: 24px;
}
.direct-script-title {
margin-bottom: 24px;
font-weight: 600;
color: #374151;
}
.direct-script-card {
background: white;
padding: 48px;
border-radius: 24px;
text-align: center;
max-width: 480px;
margin: 60px auto;
box-shadow: 0 4px 20px -5px rgba(0, 0, 0, 0.1);
border: 1px solid #f1f5f9;
}
.icon-circle {
width: 64px;
height: 64px;
background: #e0f2f1;
color: #14b8a6;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
margin: 0 auto 24px;
}
h1 {
font-size: 1.5rem;
margin-bottom: 12px;
color: #0f172a;
font-weight: 700;
}
p {
color: #475569;
margin-bottom: 24px;
line-height: 1.6;
}
small {
color: #94a3b8;
font-weight: 500;
}
</style>
| 1 | <template> |
| 2 | <div class="direct-script-wrapper"> |
| 3 | <div class="direct-script-title">Direct Script Embed</div> |
| 4 | <div class="direct-script-card"> |
| 5 | <div class="icon-circle">⚡</div> |
| 6 | <h1>Widget Aktif</h1> |
| 7 | <p> |
| 8 | Script chatbot Bliv AI telah dimuat secara langsung pada halaman ini. |
| 9 | </p> |
| 10 | <small>Periksa sudut kanan bawah layar Anda untuk memulai chat.</small> |
| 11 | </div> |
| 12 | </div> |
| 13 | </template> |
| 14 | |
| 15 | <script setup lang="ts"> |
| 16 | import { onMounted, onUnmounted } from "vue"; |
| 17 | |
| 18 | const baseUrl = "https://ai-studio.bliv.bangunindo.io"; |
| 19 | |
| 20 | onMounted(() => { |
| 21 | const config = { |
| 22 | token: "4eFb0BunqZYEZlg7", |
| 23 | baseUrl: baseUrl, |
| 24 | isDev: true, |
| 25 | login: false, |
| 26 | history: false, |
| 27 | draggable: true, |
| 28 | dragAxis: "both", |
| 29 | dynamicScript: true, |
| 30 | systemVariables: {}, |
| 31 | userVariables: {}, |
| 32 | }; |
| 33 | (window as any).blivChatbotConfig = config; |
| 34 | |
| 35 | const script = document.createElement("script"); |
| 36 | script.id = "bliv-embed-script"; |
| 37 | script.src = `${baseUrl}/embed.min.js`; |
| 38 | script.async = true; |
| 39 | document.body.appendChild(script); |
| 40 | }); |
| 41 | |
| 42 | onUnmounted(() => { |
| 43 | const script = document.getElementById("bliv-embed-script"); |
| 44 | if (script) script.remove(); |
| 45 | |
| 46 | const selectors = [ |
| 47 | "#bliv-chatbot-widget", |
| 48 | "#bliv-chatbot-bubble", |
| 49 | "#bliv-chatbot-container", |
| 50 | "#bliv-chatbot-iframe", |
| 51 | ".bliv-chatbot-widget", |
| 52 | ".bliv-chatbot-bubble", |
| 53 | ".bliv-chatbot-container", |
| 54 | 'iframe[src*="ai-studio.bliv.bangunindo.io"]', |
| 55 | ]; |
| 56 | |
| 57 | selectors.forEach((sel) => { |
| 58 | document.querySelectorAll(sel).forEach((el) => el.remove()); |
| 59 | }); |
| 60 | |
| 61 | delete (window as any).blivChatbotConfig; |
| 62 | }); |
| 63 | </script> |
| 64 | |
| 65 | <style scoped> |
| 66 | .direct-script-wrapper { |
| 67 | width: 100%; |
| 68 | padding: 24px; |
| 69 | } |
| 70 | .direct-script-title { |
| 71 | margin-bottom: 24px; |
| 72 | font-weight: 600; |
| 73 | color: #374151; |
| 74 | } |
| 75 | .direct-script-card { |
| 76 | background: white; |
| 77 | padding: 48px; |
| 78 | border-radius: 24px; |
| 79 | text-align: center; |
| 80 | max-width: 480px; |
| 81 | margin: 60px auto; |
| 82 | box-shadow: 0 4px 20px -5px rgba(0, 0, 0, 0.1); |
| 83 | border: 1px solid #f1f5f9; |
| 84 | } |
| 85 | .icon-circle { |
| 86 | width: 64px; |
| 87 | height: 64px; |
| 88 | background: #e0f2f1; |
| 89 | color: #14b8a6; |
| 90 | border-radius: 50%; |
| 91 | display: flex; |
| 92 | align-items: center; |
| 93 | justify-content: center; |
| 94 | font-size: 28px; |
| 95 | margin: 0 auto 24px; |
| 96 | } |
| 97 | h1 { |
| 98 | font-size: 1.5rem; |
| 99 | margin-bottom: 12px; |
| 100 | color: #0f172a; |
| 101 | font-weight: 700; |
| 102 | } |
| 103 | p { |
| 104 | color: #475569; |
| 105 | margin-bottom: 24px; |
| 106 | line-height: 1.6; |
| 107 | } |
| 108 | small { |
| 109 | color: #94a3b8; |
| 110 | font-weight: 500; |
| 111 | } |
| 112 | </style> |
| 113 |