Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions src/_includes/components/expert-dock.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{# ============================================================
FLOATING FLOWFUSE EXPERT DOCK (use case pages only)
A fixed, floating widget that hovers above the page content with a
margin from the left/right/bottom edges, rounded corners and a drop
shadow (it does not span edge to edge). It reuses the EXISTING AI
Expert experience: the bar contains the same entry point used on
/ai/ (the "Describe your workflow" textarea + #tell-me-how-btn), and
includes the shared ai-expert-modal component. No chat engine is
duplicated here.

The outer wrapper is transparent and click-through (pointer-events-none)
so the gutters either side of the floating card never block the page;
the inner card re-enables pointer events.
============================================================ #}
{% set dockSlug = page.fileSlug %}

<div id="expert-dock"
role="region"
aria-label="Ask the FlowFuse Expert"
class="fixed inset-x-4 bottom-4 sm:bottom-6 z-40 pointer-events-none">
<div class="max-w-screen-xl mx-auto pointer-events-auto rounded-2xl border border-indigo-100 bg-white/95 backdrop-blur shadow-[0_12px_40px_-10px_rgba(49,46,129,0.45)] px-4 sm:px-6 py-3 flex items-center gap-3">
<div class="hidden sm:flex items-center gap-2 flex-shrink-0">
<div class="w-24 h-6">{% include "components/flowfuse-wordmark.njk" %}</div>
<span class="text-sm font-semibold text-gray-700">Expert</span>
</div>
<div class="textarea-wrapper relative flex-1 min-w-0">
<textarea
aria-label="Describe your workflow"
rows="1"
placeholder="Ask the FlowFuse Expert about {{ title }}..."
class="w-full resize-none bg-gray-50 border border-gray-300 rounded-full py-2.5 px-4 pr-4 text-sm text-gray-700 placeholder-gray-400 focus:outline-none focus:border-indigo-500 h-11 leading-6 overflow-hidden"></textarea>
</div>
<button id="tell-me-how-btn"
class="ff-btn ff-btn--highlight uppercase whitespace-nowrap px-5 py-2.5 flex-shrink-0"
onclick="if(typeof capture === 'function') capture('cta-expert-dock', {'usecase': '{{ dockSlug }}'})">
Ask
</button>
<button id="expert-dock-dismiss"
type="button"
aria-label="Dismiss the FlowFuse Expert"
class="flex-shrink-0 w-9 h-9 flex items-center justify-center rounded-full text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors">
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
</div>

{# Shared AI Expert modal (same entry point as /ai/). #}
{% include "components/ai-expert-modal.njk" %}

<script>
(function () {
var dock = document.getElementById('expert-dock');
var dismiss = document.getElementById('expert-dock-dismiss');
if (!dock || !dismiss) return;

function hideDock() {
dock.style.display = 'none';
// Return focus to the body in a predictable place for keyboard users.
var main = document.getElementById('main-content');
if (main) {
main.setAttribute('tabindex', '-1');
main.focus();
}
}

dismiss.addEventListener('click', hideDock);

// ESC dismisses the dock only when the Expert modal is not open
// (the modal handles its own ESC/focus-trap behaviour).
document.addEventListener('keydown', function (e) {
if (e.key !== 'Escape') return;
var modal = document.getElementById('ai-expert-modal');
var modalOpen = modal && !modal.classList.contains('hidden');
if (!modalOpen && dock.style.display !== 'none') {
hideDock();
}
});
})();
</script>
9 changes: 8 additions & 1 deletion src/_includes/layouts/use-case.njk
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,12 @@ sitemapPriority: 0.7
{% set relatedTag = "usecase:" + page.fileSlug %}
{% include "components/related-resources.njk" %}

<!-- spacer so sticky dock never overlaps the final content -->
<!-- spacer so the floating expert dock never overlaps the final content -->
<div class="w-full h-28"></div>

</div>

<!-- ============================================================
FLOATING FLOWFUSE EXPERT DOCK (use case pages only)
============================================================ -->
{% include "components/expert-dock.njk" %}