4b86b2a660
- server-dev start/stop/deploy 및 Gitea push 자동 배포 - local-dev 로컬 개발 환경 Co-authored-by: Cursor <cursoragent@cursor.com>
245 lines
9.3 KiB
HTML
245 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<title>국민참여로 - 국민과 함께, 열린 도로, 열린 소통</title>
|
|
<meta name="description" content="한국도로공사 국민참여로 샘플 — AI 검색 배너 iframe 연동" />
|
|
<link rel="stylesheet" href="/chatbot/sample/css/partcptn-sample.css" />
|
|
</head>
|
|
<body>
|
|
<div class="partcptn-page">
|
|
<header class="partcptn-header">
|
|
<div class="partcptn-logo" aria-label="ex 국민참여로">
|
|
<span class="partcptn-logo-ex">ex</span>
|
|
<span class="partcptn-logo-text">국민참여로</span>
|
|
</div>
|
|
<button type="button" class="partcptn-menu-btn" aria-label="전체메뉴">
|
|
<span class="partcptn-menu-icon" aria-hidden="true">
|
|
<span></span><span></span><span></span>
|
|
</span>
|
|
전체메뉴
|
|
</button>
|
|
</header>
|
|
|
|
<main class="partcptn-hero">
|
|
<div class="partcptn-hero-bg" aria-hidden="true"></div>
|
|
|
|
<div class="partcptn-hero-content">
|
|
<h1 class="partcptn-hero-title">국민과 함께, 열린 도로, 열린 소통</h1>
|
|
<p class="partcptn-hero-sub">
|
|
국민의 작은 목소리도 정책의 시작이 됩니다.<br />
|
|
소통하고, 함께 만들어가는 스마트 국민 소통 플랫폼
|
|
</p>
|
|
|
|
<div class="partcptn-search-slot" id="partcptn-search-slot">
|
|
<iframe
|
|
id="chatbot-banner-frame"
|
|
src="/chatbot/banner/?embed=1&theme=partcptn&minwonUrl=%2Fchatbot%2Fsample%2Fminwon%2F&placeholder=%EA%B2%80%EC%83%89%EC%96%B4%EB%A5%BC%20%EC%9E%85%EB%A0%A5%ED%95%B4%20%EC%A3%BC%EC%84%B8%EC%9A%94"
|
|
title="AI 검색"
|
|
loading="lazy"
|
|
allowtransparency="true"
|
|
style="height: 48px"
|
|
></iframe>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<nav class="partcptn-bottom-dock" aria-label="챗봇 바로가기">
|
|
<button
|
|
type="button"
|
|
class="partcptn-dock-item"
|
|
data-chatbot-url="/chatbot/app/"
|
|
data-chatbot-title="카톡챗봇"
|
|
>
|
|
<span class="partcptn-dock-icon" aria-hidden="true">
|
|
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path
|
|
d="M14 10h20a4 4 0 0 1 4 4v10a4 4 0 0 1-4 4H20l-6 4v-4h-4a4 4 0 0 1-4-4V14a4 4 0 0 1 4-4z"
|
|
stroke="currentColor"
|
|
stroke-width="1.6"
|
|
stroke-linejoin="round"
|
|
/>
|
|
<circle cx="18" cy="19" r="1.2" fill="currentColor" />
|
|
<circle cx="24" cy="19" r="1.2" fill="currentColor" />
|
|
<circle cx="30" cy="19" r="1.2" fill="currentColor" />
|
|
</svg>
|
|
</span>
|
|
<span class="partcptn-dock-label">카톡챗봇</span>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="partcptn-dock-item"
|
|
data-chatbot-url="/chatbot/ai/"
|
|
data-chatbot-title="AI챗봇"
|
|
>
|
|
<span class="partcptn-dock-icon" aria-hidden="true">
|
|
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<rect x="12" y="14" width="24" height="20" rx="3" stroke="currentColor" stroke-width="1.6" />
|
|
<path d="M20 22h8M20 26h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
<path d="M18 10h12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
<circle cx="18" cy="10" r="1.5" fill="currentColor" />
|
|
<circle cx="30" cy="10" r="1.5" fill="currentColor" />
|
|
<path d="M16 38h16" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
</svg>
|
|
</span>
|
|
<span class="partcptn-dock-label">AI챗봇</span>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="partcptn-dock-item"
|
|
data-chatbot-url="/chatbot/voicebot/"
|
|
data-chatbot-title="음성챗봇"
|
|
>
|
|
<span class="partcptn-dock-icon" aria-hidden="true">
|
|
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<rect x="20" y="12" width="8" height="14" rx="4" stroke="currentColor" stroke-width="1.6" />
|
|
<path
|
|
d="M16 24a8 8 0 0 0 16 0"
|
|
stroke="currentColor"
|
|
stroke-width="1.6"
|
|
stroke-linecap="round"
|
|
/>
|
|
<path d="M24 32v4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
<path d="M20 36h8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
</svg>
|
|
</span>
|
|
<span class="partcptn-dock-label">음성챗봇</span>
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
|
|
<div
|
|
id="sample-chat-overlay"
|
|
class="sample-chat-overlay"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-hidden="true"
|
|
aria-label="챗봇"
|
|
>
|
|
<div class="sample-chat-panel">
|
|
<iframe
|
|
id="sample-chat-frame"
|
|
title="챗봇"
|
|
src="about:blank"
|
|
allow="microphone *; autoplay *"
|
|
></iframe>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function () {
|
|
var iframe = document.getElementById("chatbot-banner-frame");
|
|
var searchSlot = document.getElementById("partcptn-search-slot");
|
|
var page = document.querySelector(".partcptn-page");
|
|
if (iframe) {
|
|
var minH = 48;
|
|
function maxH() {
|
|
return Math.min(Math.round(window.innerHeight * 0.72), 640);
|
|
}
|
|
window.addEventListener("message", function (ev) {
|
|
if (!ev.data || ev.data.type !== "ex-chatbot-banner-resize") return;
|
|
if (ev.source !== iframe.contentWindow) return;
|
|
var h = Number(ev.data.height);
|
|
if (h > 0) {
|
|
var next = Math.min(Math.max(h, minH), maxH());
|
|
iframe.style.height = next + "px";
|
|
var expanded = next > minH + 8;
|
|
if (searchSlot) {
|
|
searchSlot.classList.toggle("is-expanded", expanded);
|
|
}
|
|
if (page) {
|
|
page.classList.toggle("partcptn-page--search-open", expanded);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
var overlay = document.getElementById("sample-chat-overlay");
|
|
var chatFrame = document.getElementById("sample-chat-frame");
|
|
|
|
function withEmbed(url) {
|
|
if (!url) return url;
|
|
return url + (url.indexOf("?") >= 0 ? "&" : "?") + "embed=1";
|
|
}
|
|
|
|
function openChatbot(url, title) {
|
|
if (!overlay || !chatFrame) return;
|
|
var isVoicebot = url.indexOf("/voicebot") !== -1;
|
|
var frameUrl = withEmbed(url);
|
|
|
|
function showFrame() {
|
|
chatFrame.src = frameUrl;
|
|
chatFrame.title = title || "챗봇";
|
|
overlay.classList.add("is-open");
|
|
overlay.setAttribute("aria-hidden", "false");
|
|
document.body.style.overflow = "hidden";
|
|
|
|
if (isVoicebot) {
|
|
chatFrame.onload = function () {
|
|
try {
|
|
chatFrame.contentWindow.postMessage(
|
|
{ type: "ex-voicebot-autostart" },
|
|
window.location.origin
|
|
);
|
|
} catch (_) {}
|
|
};
|
|
} else {
|
|
chatFrame.onload = null;
|
|
}
|
|
}
|
|
|
|
if (isVoicebot && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
|
navigator.mediaDevices
|
|
.getUserMedia({ audio: true, video: false })
|
|
.then(function (stream) {
|
|
stream.getTracks().forEach(function (track) {
|
|
track.stop();
|
|
});
|
|
showFrame();
|
|
})
|
|
.catch(function () {
|
|
showFrame();
|
|
});
|
|
return;
|
|
}
|
|
|
|
showFrame();
|
|
}
|
|
|
|
function closeChatbot() {
|
|
if (!overlay || !chatFrame) return;
|
|
overlay.classList.remove("is-open");
|
|
overlay.setAttribute("aria-hidden", "true");
|
|
chatFrame.src = "about:blank";
|
|
document.body.style.overflow = "";
|
|
}
|
|
|
|
document.querySelectorAll("[data-chatbot-url]").forEach(function (btn) {
|
|
btn.addEventListener("click", function () {
|
|
openChatbot(btn.getAttribute("data-chatbot-url"), btn.getAttribute("data-chatbot-title"));
|
|
});
|
|
});
|
|
|
|
window.addEventListener("message", function (ev) {
|
|
if (!ev.data || ev.data.type !== "ex-chatbot-close") return;
|
|
if (chatFrame && ev.source === chatFrame.contentWindow) {
|
|
closeChatbot();
|
|
}
|
|
});
|
|
|
|
if (overlay) {
|
|
overlay.addEventListener("click", function (e) {
|
|
if (e.target === overlay) closeChatbot();
|
|
});
|
|
}
|
|
document.addEventListener("keydown", function (e) {
|
|
if (e.key === "Escape" && overlay && overlay.classList.contains("is-open")) {
|
|
closeChatbot();
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|