IframeDirect.tsx
· 1.3 KiB · TypeScript
Raw
export default function IframeDirect() {
return (
<div style={{ width: '100%', display: 'flex', flexDirection: 'column', height: '100%' }}>
<div style={{ background: 'white', borderRadius: '20px 20px 0 0', padding: '24px 32px', border: '1px solid #f1f5f9', borderBottom: 'none', display: 'flex', alignItems: 'center', gap: 20 }}>
<div style={{ width: 48, height: 48, background: '#f0fdfa', color: '#14b8a6', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20, flexShrink: 0 }}>⚡</div>
<div>
<h1 style={{ fontSize: '1.25rem', color: '#0f172a', marginBottom: 2, fontWeight: 700 }}>Direct Iframe Embed</h1>
<p style={{ fontSize: '0.875rem', color: '#64748b' }}>Chatbot dimuat langsung di dalam halaman tanpa modal.</p>
</div>
</div>
<div style={{ flex: 1, background: 'white', border: '1px solid #f1f5f9', borderRadius: '0 0 20px 20px', overflow: 'hidden', boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.05)' }}>
<iframe
src="https://ai-studio.bliv.bangunindo.io/chatbot/4eFb0BunqZYEZlg7"
style={{ width: '100%', height: '100%', border: 'none', display: 'block' }}
allow="microphone"
title="Chatbot Direct"
/>
</div>
</div>
)
}
| 1 | export default function IframeDirect() { |
| 2 | return ( |
| 3 | <div style={{ width: '100%', display: 'flex', flexDirection: 'column', height: '100%' }}> |
| 4 | <div style={{ background: 'white', borderRadius: '20px 20px 0 0', padding: '24px 32px', border: '1px solid #f1f5f9', borderBottom: 'none', display: 'flex', alignItems: 'center', gap: 20 }}> |
| 5 | <div style={{ width: 48, height: 48, background: '#f0fdfa', color: '#14b8a6', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20, flexShrink: 0 }}>⚡</div> |
| 6 | <div> |
| 7 | <h1 style={{ fontSize: '1.25rem', color: '#0f172a', marginBottom: 2, fontWeight: 700 }}>Direct Iframe Embed</h1> |
| 8 | <p style={{ fontSize: '0.875rem', color: '#64748b' }}>Chatbot dimuat langsung di dalam halaman tanpa modal.</p> |
| 9 | </div> |
| 10 | </div> |
| 11 | <div style={{ flex: 1, background: 'white', border: '1px solid #f1f5f9', borderRadius: '0 0 20px 20px', overflow: 'hidden', boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.05)' }}> |
| 12 | <iframe |
| 13 | src="https://ai-studio.bliv.bangunindo.io/chatbot/4eFb0BunqZYEZlg7" |
| 14 | style={{ width: '100%', height: '100%', border: 'none', display: 'block' }} |
| 15 | allow="microphone" |
| 16 | title="Chatbot Direct" |
| 17 | /> |
| 18 | </div> |
| 19 | </div> |
| 20 | ) |
| 21 | } |
| 22 |
IframeWithModal.tsx
· 5.1 KiB · TypeScript
Raw
import { useState } from 'react';
export default function IframeWithModal() {
const [isOpen, setIsOpen] = useState(false);
const appCode = "4eFb0BunqZYEZlg7";
const baseUrl = "https://ai-studio.bliv.bangunindo.io";
const iframeSrc = `${baseUrl}/chatbot-auth/${appCode}/history`;
const toggleModal = (val: boolean) => {
setIsOpen(val);
document.body.style.overflow = val ? 'hidden' : '';
};
return (
<div style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
<div style={{ background: 'white', borderRadius: 24, boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.1)', width: '100%', maxWidth: 480, overflow: 'hidden', border: '1px solid #f1f5f9' }}>
<div style={{ padding: 32, textAlign: 'center', borderBottom: '1px solid #f1f5f9' }}>
<div style={{ width: 64, height: 64, background: '#e0e7ff', color: '#4f46e5', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 28, margin: '0 auto 16px' }}>🔐</div>
<h1 style={{ fontSize: '1.5rem', color: '#0f172a', marginBottom: 4, fontWeight: 700 }}>Chatbot Modal Demo</h1>
<p style={{ fontSize: '0.875rem', color: '#64748b' }}>Authenticated • With History • Iframe Modal</p>
</div>
<div style={{ padding: '24px 32px 32px' }}>
<div style={{ fontSize: '0.7rem', fontWeight: 700, textTransform: 'uppercase', color: '#94a3b8', marginBottom: 12 }}>Configuration</div>
<div style={{ display: 'flex', gap: 8, marginBottom: 20, flexWrap: 'wrap' }}>
<span style={{ fontSize: '0.7rem', padding: '6px 12px', background: '#e0f2f1', borderRadius: 99, display: 'flex', alignItems: 'center', gap: 6, color: '#14b8a6', fontWeight: 600 }}>
<span style={{ width: 6, height: 6, background: '#14b8a6', borderRadius: '50%' }} /> Auth Enabled
</span>
<span style={{ fontSize: '0.7rem', padding: '6px 12px', background: '#dbeafe', borderRadius: 99, display: 'flex', alignItems: 'center', gap: 6, color: '#1e40af', fontWeight: 600 }}>
<span style={{ width: 6, height: 6, background: '#1e40af', borderRadius: '50%' }} /> History On
</span>
</div>
<div style={{ background: '#f8fafc', borderRadius: 16, padding: 16, marginBottom: 24, border: '1px solid #f1f5f9' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.8rem', padding: '6px 0', borderBottom: '1px solid #f1f5f9' }}>
<span style={{ color: '#64748b' }}>Authentication</span>
<span style={{ fontWeight: 600, color: '#0f172a' }}>Required</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.8rem', padding: '6px 0' }}>
<span style={{ color: '#64748b' }}>Mechanism</span>
<span style={{ fontWeight: 600, color: '#0f172a' }}>Iframe Modal</span>
</div>
</div>
<button
onClick={() => toggleModal(true)}
style={{ width: '100%', background: '#4f46e5', color: 'white', border: 'none', padding: '14px 24px', fontSize: '0.95rem', fontWeight: 600, borderRadius: 12, cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="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>
{isOpen && (
<div
onClick={() => toggleModal(false)}
style={{ position: 'fixed', inset: 0, background: 'rgba(0, 0, 0, 0.4)', backdropFilter: 'blur(8px)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }}
>
<div
onClick={(e) => e.stopPropagation()}
style={{ background: 'white', borderRadius: 24, width: '100%', maxWidth: 800, height: '80vh', maxHeight: 600, display: 'flex', flexDirection: 'column', overflow: 'hidden', boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)' }}
>
<div style={{ padding: '16px 24px', background: '#f8fafc', borderBottom: '1px solid #f1f5f9', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<h3 style={{ fontSize: '1rem', color: '#0f172a' }}>Bliv AI Chatbot</h3>
<button
onClick={() => toggleModal(false)}
style={{ background: '#f1f5f9', border: 'none', width: 32, height: 32, borderRadius: 8, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.25rem', color: '#64748b' }}
>
×
</button>
</div>
<div style={{ flex: 1, minHeight: 0 }}>
<iframe src={iframeSrc} allow="microphone" title="Chatbot" style={{ width: '100%', height: '100%', border: 'none' }} />
</div>
</div>
</div>
)}
</div>
);
}
| 1 | import { useState } from 'react'; |
| 2 | |
| 3 | export default function IframeWithModal() { |
| 4 | const [isOpen, setIsOpen] = useState(false); |
| 5 | const appCode = "4eFb0BunqZYEZlg7"; |
| 6 | const baseUrl = "https://ai-studio.bliv.bangunindo.io"; |
| 7 | const iframeSrc = `${baseUrl}/chatbot-auth/${appCode}/history`; |
| 8 | |
| 9 | const toggleModal = (val: boolean) => { |
| 10 | setIsOpen(val); |
| 11 | document.body.style.overflow = val ? 'hidden' : ''; |
| 12 | }; |
| 13 | |
| 14 | return ( |
| 15 | <div style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}> |
| 16 | <div style={{ background: 'white', borderRadius: 24, boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.1)', width: '100%', maxWidth: 480, overflow: 'hidden', border: '1px solid #f1f5f9' }}> |
| 17 | <div style={{ padding: 32, textAlign: 'center', borderBottom: '1px solid #f1f5f9' }}> |
| 18 | <div style={{ width: 64, height: 64, background: '#e0e7ff', color: '#4f46e5', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 28, margin: '0 auto 16px' }}>🔐</div> |
| 19 | <h1 style={{ fontSize: '1.5rem', color: '#0f172a', marginBottom: 4, fontWeight: 700 }}>Chatbot Modal Demo</h1> |
| 20 | <p style={{ fontSize: '0.875rem', color: '#64748b' }}>Authenticated • With History • Iframe Modal</p> |
| 21 | </div> |
| 22 | <div style={{ padding: '24px 32px 32px' }}> |
| 23 | <div style={{ fontSize: '0.7rem', fontWeight: 700, textTransform: 'uppercase', color: '#94a3b8', marginBottom: 12 }}>Configuration</div> |
| 24 | <div style={{ display: 'flex', gap: 8, marginBottom: 20, flexWrap: 'wrap' }}> |
| 25 | <span style={{ fontSize: '0.7rem', padding: '6px 12px', background: '#e0f2f1', borderRadius: 99, display: 'flex', alignItems: 'center', gap: 6, color: '#14b8a6', fontWeight: 600 }}> |
| 26 | <span style={{ width: 6, height: 6, background: '#14b8a6', borderRadius: '50%' }} /> Auth Enabled |
| 27 | </span> |
| 28 | <span style={{ fontSize: '0.7rem', padding: '6px 12px', background: '#dbeafe', borderRadius: 99, display: 'flex', alignItems: 'center', gap: 6, color: '#1e40af', fontWeight: 600 }}> |
| 29 | <span style={{ width: 6, height: 6, background: '#1e40af', borderRadius: '50%' }} /> History On |
| 30 | </span> |
| 31 | </div> |
| 32 | <div style={{ background: '#f8fafc', borderRadius: 16, padding: 16, marginBottom: 24, border: '1px solid #f1f5f9' }}> |
| 33 | <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.8rem', padding: '6px 0', borderBottom: '1px solid #f1f5f9' }}> |
| 34 | <span style={{ color: '#64748b' }}>Authentication</span> |
| 35 | <span style={{ fontWeight: 600, color: '#0f172a' }}>Required</span> |
| 36 | </div> |
| 37 | <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.8rem', padding: '6px 0' }}> |
| 38 | <span style={{ color: '#64748b' }}>Mechanism</span> |
| 39 | <span style={{ fontWeight: 600, color: '#0f172a' }}>Iframe Modal</span> |
| 40 | </div> |
| 41 | </div> |
| 42 | <button |
| 43 | onClick={() => toggleModal(true)} |
| 44 | style={{ width: '100%', background: '#4f46e5', color: 'white', border: 'none', padding: '14px 24px', fontSize: '0.95rem', fontWeight: 600, borderRadius: 12, cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8 }} |
| 45 | > |
| 46 | <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="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> |
| 47 | Mulai Percakapan |
| 48 | </button> |
| 49 | </div> |
| 50 | </div> |
| 51 | |
| 52 | {isOpen && ( |
| 53 | <div |
| 54 | onClick={() => toggleModal(false)} |
| 55 | style={{ position: 'fixed', inset: 0, background: 'rgba(0, 0, 0, 0.4)', backdropFilter: 'blur(8px)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }} |
| 56 | > |
| 57 | <div |
| 58 | onClick={(e) => e.stopPropagation()} |
| 59 | style={{ background: 'white', borderRadius: 24, width: '100%', maxWidth: 800, height: '80vh', maxHeight: 600, display: 'flex', flexDirection: 'column', overflow: 'hidden', boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)' }} |
| 60 | > |
| 61 | <div style={{ padding: '16px 24px', background: '#f8fafc', borderBottom: '1px solid #f1f5f9', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> |
| 62 | <h3 style={{ fontSize: '1rem', color: '#0f172a' }}>Bliv AI Chatbot</h3> |
| 63 | <button |
| 64 | onClick={() => toggleModal(false)} |
| 65 | style={{ background: '#f1f5f9', border: 'none', width: 32, height: 32, borderRadius: 8, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.25rem', color: '#64748b' }} |
| 66 | > |
| 67 | × |
| 68 | </button> |
| 69 | </div> |
| 70 | <div style={{ flex: 1, minHeight: 0 }}> |
| 71 | <iframe src={iframeSrc} allow="microphone" title="Chatbot" style={{ width: '100%', height: '100%', border: 'none' }} /> |
| 72 | </div> |
| 73 | </div> |
| 74 | </div> |
| 75 | )} |
| 76 | </div> |
| 77 | ); |
| 78 | } |
| 79 |
ScriptDirect.tsx
· 2.5 KiB · TypeScript
Raw
import { useEffect } from 'react';
declare global {
interface Window {
blivChatbotConfig: Record<string, unknown>;
}
}
export default function ScriptDirect() {
const baseUrl = "https://ai-studio.bliv.bangunindo.io";
useEffect(() => {
const config = {
token: "4eFb0BunqZYEZlg7",
baseUrl: baseUrl,
isDev: true,
login: false,
history: false,
draggable: true,
dragAxis: "both",
dynamicScript: true,
systemVariables: {},
userVariables: {},
};
window.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);
return () => {
const existingScript = document.getElementById("bliv-embed-script");
if (existingScript) existingScript.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());
});
// @ts-expect-error: delete not allowed on window properties
delete window.blivChatbotConfig;
};
}, []);
return (
<div style={{ width: '100%', padding: 24 }}>
<div style={{ marginBottom: 24, fontWeight: 600, color: '#374151' }}>Direct Script Embed</div>
<div style={{ background: 'white', padding: 48, borderRadius: 24, textAlign: 'center', maxWidth: 480, margin: '60px auto', boxShadow: '0 4px 20px -5px rgba(0, 0, 0, 0.1)', border: '1px solid #f1f5f9' }}>
<div style={{ width: 64, height: 64, background: '#e0f2f1', color: '#14b8a6', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 28, margin: '0 auto 24px' }}>⚡</div>
<h1 style={{ fontSize: '1.5rem', marginBottom: 12, color: '#0f172a', fontWeight: 700 }}>Widget Aktif</h1>
<p style={{ color: '#475569', marginBottom: 24, lineHeight: 1.6 }}>
Script chatbot Bliv AI telah dimuat secara langsung pada halaman ini.
</p>
<small style={{ color: '#94a3b8', fontWeight: 500 }}>
Periksa sudut kanan bawah layar Anda untuk memulai chat.
</small>
</div>
</div>
);
}
| 1 | import { useEffect } from 'react'; |
| 2 | |
| 3 | declare global { |
| 4 | interface Window { |
| 5 | blivChatbotConfig: Record<string, unknown>; |
| 6 | } |
| 7 | } |
| 8 | |
| 9 | |
| 10 | |
| 11 | export default function ScriptDirect() { |
| 12 | const baseUrl = "https://ai-studio.bliv.bangunindo.io"; |
| 13 | |
| 14 | useEffect(() => { |
| 15 | const config = { |
| 16 | token: "4eFb0BunqZYEZlg7", |
| 17 | baseUrl: baseUrl, |
| 18 | isDev: true, |
| 19 | login: false, |
| 20 | history: false, |
| 21 | draggable: true, |
| 22 | dragAxis: "both", |
| 23 | dynamicScript: true, |
| 24 | systemVariables: {}, |
| 25 | userVariables: {}, |
| 26 | }; |
| 27 | window.blivChatbotConfig = config; |
| 28 | |
| 29 | |
| 30 | |
| 31 | const script = document.createElement("script"); |
| 32 | script.id = "bliv-embed-script"; |
| 33 | script.src = `${baseUrl}/embed.min.js`; |
| 34 | script.async = true; |
| 35 | document.body.appendChild(script); |
| 36 | |
| 37 | return () => { |
| 38 | const existingScript = document.getElementById("bliv-embed-script"); |
| 39 | if (existingScript) existingScript.remove(); |
| 40 | |
| 41 | const selectors = [ |
| 42 | "#bliv-chatbot-widget", |
| 43 | "#bliv-chatbot-bubble", |
| 44 | "#bliv-chatbot-container", |
| 45 | "#bliv-chatbot-iframe", |
| 46 | ".bliv-chatbot-widget", |
| 47 | ".bliv-chatbot-bubble", |
| 48 | ".bliv-chatbot-container", |
| 49 | 'iframe[src*="ai-studio.bliv.bangunindo.io"]', |
| 50 | ]; |
| 51 | |
| 52 | selectors.forEach((sel) => { |
| 53 | document.querySelectorAll(sel).forEach((el) => el.remove()); |
| 54 | }); |
| 55 | |
| 56 | // @ts-expect-error: delete not allowed on window properties |
| 57 | delete window.blivChatbotConfig; |
| 58 | |
| 59 | |
| 60 | |
| 61 | |
| 62 | }; |
| 63 | }, []); |
| 64 | |
| 65 | return ( |
| 66 | <div style={{ width: '100%', padding: 24 }}> |
| 67 | <div style={{ marginBottom: 24, fontWeight: 600, color: '#374151' }}>Direct Script Embed</div> |
| 68 | <div style={{ background: 'white', padding: 48, borderRadius: 24, textAlign: 'center', maxWidth: 480, margin: '60px auto', boxShadow: '0 4px 20px -5px rgba(0, 0, 0, 0.1)', border: '1px solid #f1f5f9' }}> |
| 69 | <div style={{ width: 64, height: 64, background: '#e0f2f1', color: '#14b8a6', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 28, margin: '0 auto 24px' }}>⚡</div> |
| 70 | <h1 style={{ fontSize: '1.5rem', marginBottom: 12, color: '#0f172a', fontWeight: 700 }}>Widget Aktif</h1> |
| 71 | <p style={{ color: '#475569', marginBottom: 24, lineHeight: 1.6 }}> |
| 72 | Script chatbot Bliv AI telah dimuat secara langsung pada halaman ini. |
| 73 | </p> |
| 74 | <small style={{ color: '#94a3b8', fontWeight: 500 }}> |
| 75 | Periksa sudut kanan bawah layar Anda untuk memulai chat. |
| 76 | </small> |
| 77 | </div> |
| 78 | </div> |
| 79 | ); |
| 80 | } |
| 81 |