סרגל הכפתורים הצף – מדריך טכני מלא
ניתוח מעמיק של הארכיטקטורה, הקוד, ה-AI, המטרה והפונקציונליות – כולל קוד מלא להעתקה למערכות אחרות
תוכן עניינים
הסרגל הצף (Floating Buttons Dock) הוא רכיב UI קבוע שצף מעל כל עמודי האפליקציה. הוא מספק גישה מהירה ל-4–5 כלים חיוניים:
עוזר אישי AI
צ'אט חכם מבוסס סוכן AI (OnboardingAssistant) שמלווה את המשתמש, עונה על שאלות ומכוון לפעולות. מחובר ל-base44 Agents SDK.
מצפן – מדריך המסע
מדריך אינטראקטיבי עם טיפים מותאמים לעמוד הנוכחי. כולל ניווט לעמודים רלוונטיים וסרטוני הסבר.
משוב ותמיכה
טופס משוב מורחב עם קטגוריות, דירוג כוכבים, צירוף קבצים, ותיעוד אוטומטי (עמוד, דפדפן, מכשיר). ניתוב למחלקות.
הגדרות נגישות
פאנל נגישות מתקדם עם 30+ הגדרות: פרופילים מוכנים (לקויי ראייה, ADHD, דיסלקציה...), גודל גופן, ניגודיות, צבעים, ניווט מקלדת, מדריך קריאה ועוד.
אונבורדינג מנהלים
כפתור שמופיע רק למנהלי מערכת. מקשר לתהליך האונבורדינג הייעודי למנהלים.
מטרת הסרגל: לאפשר לכל משתמש – חדש או ותיק – גישה מהירה לעזרה, נגישות ומשוב, מכל מקום באפליקציה, בלי לצאת מההקשר הנוכחי.
נקודת כניסה: הקומפוננטה FloatingButtonsContainer נטענת מ-Layout.js ומקבלת user ו-currentPageName.
המערכת מבוססת על React Context (DockProvider) שמנהל:
- dockedButtons – מערך מזהים של כפתורים שנמצאים בסרגל
- addToDock / removeFromDock – חיבור/הפרדת כפתור מהסרגל
- reorderDock – שינוי סדר כפתורים (drag & drop עם framer-motion Reorder)
- isInDock – בדיקה האם כפתור בתוך הסרגל
כל המצב נשמר ב-localStorage לפי אימייל המשתמש, כך שכל משתמש שומר את הסידור האישי שלו.
יכולות הסרגל:
- גרירה חופשית (drag handle) – למעלה/למטה/ימין/שמאל
- כיווץ לעיגול אחד / הרחבה חזרה
- מצב עריכה: סידור מחדש + הפרדת כפתורים
- כפתור שהופרד הופך לכפתור צף עצמאי עם ➕ לחיבור מחדש
- מדריך אינטראקטיבי (Tour) עם 4 צעדים ואנימציות
// Context for managing docked buttons
const DockContext = createContext(null);
export const useDock = () => useContext(DockContext);
export function DockProvider({ children, user }) {
const [dockedButtons, setDockedButtons] = useState(() => {
const saved = localStorage.getItem(`docked-buttons-${user?.email || 'guest'}`);
return saved ? JSON.parse(saved) : ['help', 'compass', 'feedback', 'accessibility'];
});
const addToDock = (buttonId) => {
setDockedButtons(prev => {
// ...פאנל עוזר אישי AI – צ'אט מלא עם הסוכן OnboardingAssistant.
- יוצר שיחה ב-
base44.agents.createConversation - מנוי real-time ב-
subscribeToConversation - הודעת הקשר ראשונית (hidden) עם סוג המשתמש וסטטוס
- דירוג תשובות (AssistantRating) עם 👍/👎
- streaming של תגובות
הסוכן מוגדר ב-agents/OnboardingAssistant.json ומשמש גם את העוזר הצף וגם את WhatsApp.
{
"name": "OnboardingAssistant",
"description": "AI assistant for OTnest onboarding",
"instructions": "You are an empathetic onboarding assistant for OTnest - the largest OT community in Israel...
USER TYPES: student, therapist, expert, parent
Personalize based on user_type, onboarding progress, club membership.
Respond in Hebrew. Be concise but helpful.",
"tool_configs": [
{ "entity_name": "User", "allowed_operations": ["read"] },
{ "entity_name": "DiscussionGroup", "allowed_operations": ["read"] },
{ "entity_name": "Course", "allowed_operations": ["read"] },
{ "entity_name": "Event", "allowed_operations": ["read"] }
// ...SDK Usage בקוד:
// Initialize conversation
let conversations = await base44.agents.listConversations({ agent_name: "OnboardingAssistant" });
let conv = conversations[0] || await base44.agents.createConversation({
agent_name: "OnboardingAssistant",
metadata: { userId: user.id, userEmail: user.email }
});
// Send hidden context message
await base44.agents.addMessage(conv, {
role: "user",
content: "context info...",
is_hidden: true
// ...גנרי – ניתן להעתקה ישירה
- ✅
DockableButtonsSystem.jsx– DockProvider + DraggableFloatingButton - ✅
FloatingButtonsDock.jsx– Reorder, minimize, drag, edit mode - ✅
FloatingButtonsBar.jsx– גרסה פשוטה (legacy) - ✅
FloatingButtonsTour.jsx– מדריך 4 שלבים - ✅
AccessibilityButton.jsx– דיאלוג נגישות פשוט - ✅
AdvancedAccessibilityPanel.jsx– פאנל נגישות מלא - ✅
QuickFeedbackWidget.jsx– טופס משוב בסיסי - ✅ לוגיקת drag (mouse + touch) – pattern מלא
- ✅ localStorage persistence per user
- ✅ CSS classes ב-globals.css (a11y-*)
ספציפי – דורש התאמה
- 🔧
FloatingButtonsContainer.jsx– הגדרת הכפתורים הספציפיים - 🔧 רשימת הכפתורים ותנאי ההצגה (
has_completed_onboarding,admin_roles) - 🔧 שם הסוכן (
OnboardingAssistant) - 🔧 הודעת ההקשר הראשונית (user_type, is_club_member)
- 🔧 טיפי המצפן ותוכנם
- 🔧
EnhancedFeedbackWidget.jsx– קטגוריות ומחלקות ספציפיות - 🔧
OnboardingAssistant.json– ה-instructions, tools, greeting - 🔧
FloatingSupportButton.jsx– מספרי WhatsApp, כתובת מייל - 🔧 פרופילי הנגישות (שמות, תיאורים, הגדרות ברירת מחדל)
- 🔧 צבעי gradient וסגנון (OTnest pink/purple theme)
להלן שלושת הקבצים המרכזיים המלאים. ניתן להעתיק ולהדביק במערכת אחרת.
import React, { useState, useRef, useEffect } from "react";
import { Link } from "react-router-dom";
import { createPageUrl } from "../../utils";
import { GripVertical, Compass, Accessibility, MessageSquarePlus, Sparkles, X, Send, Loader2, ArrowLeft, Star, Check, Shield } from "lucide-react";
import AdvancedAccessibilityPanel from "@/components/accessibility/AdvancedAccessibilityPanel";
import EnhancedFeedbackWidget from "@/components/feedback/EnhancedFeedbackWidget";
import { motion, AnimatePresence } from "framer-motion";
import { base44 } from "@/api/base44Client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent } from "@/components/ui/card";
import { ScrollArea } from "@/components/ui/scroll-area";
// ...import React, { useState, useEffect, useRef, createContext, useContext } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { GripVertical, Plus, X, Check } from "lucide-react";
import { cn } from "@/lib/utils";
const DockContext = createContext(null);
export const useDock = () => useContext(DockContext);
export function DraggableFloatingButton({ id, icon: Icon, label, gradient, glow, solid, onClick, isActive, children }) {
const { addToDock, isInDock } = useDock();
const [position, setPosition] = useState(() => {
const saved = localStorage.getItem(`floating-btn-pos-${id}`);
// ...import React, { useState, useRef, useEffect } from "react";
import { motion, AnimatePresence, Reorder } from "framer-motion";
import { GripVertical, ChevronsDown, ChevronsUp, Minus, HelpCircle } from "lucide-react";
import { useDock } from "./DockableButtonsSystem";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import FloatingButtonsTour from "./FloatingButtonsTour";
export default function FloatingButtonsDock({ buttons, activePanel, onButtonClick, children }) {
const { dockedButtons, removeFromDock, reorderDock, isInDock } = useDock();
const [position, setPosition] = useState(/* localStorage */);
const [isMinimized, setIsMinimized] = useState(/* localStorage */);
const [editMode, setEditMode] = useState(false);
// ...📋 סיכום
מערכת הסרגל הצף היא מודולרית לחלוטין. ה-DockProvider, FloatingButtonsDock ו-DraggableFloatingButton הם גנריים ב-100% – פשוט שנו את רשימת הכפתורים, הסוכן, והפאנלים כדי להתאים לכל מערכת. הגדרות הנגישות גנריות גם הן ומתאימות לכל אפליקציית web.