import React, { useEffect, useState } from 'react'; import styles from './MonitoringPage.module.css'; import { sendAPICall } from './MonitoringPageAPI'; // --- GESTURE COMPONENT --- export const GestureControls: React.FC = () => { const [selectedGesture, setSelectedGesture] = useState("animations/Stand/BodyTalk/Speaking/BodyTalk_1"); const gestures = [ { label: "Wave", value: "animations/Stand/Gestures/Hey_1" }, { label: "Think", value: "animations/Stand/Emotions/Neutral/Puzzled_1" }, { label: "Explain", value: "animations/Stand/Gestures/Explain_4" }, { label: "You", value: "animations/Stand/Gestures/You_1" }, { label: "Happy", value: "animations/Stand/Emotions/Positive/Happy_1" }, { label: "Laugh", value: "animations/Stand/Emotions/Positive/Laugh_2" }, { label: "Lonely", value: "animations/Stand/Emotions/Neutral/Lonely_1" }, { label: "Suprise", value: "animations/Stand/Emotions/Negative/Surprise_1" }, { label: "Hurt", value: "animations/Stand/Emotions/Negative/Hurt_2" }, { label: "Angry", value: "animations/Stand/Emotions/Negative/Angry_4" }, ]; return (

Gestures

); }; // --- PRESET SPEECH COMPONENT --- export const SpeechPresets: React.FC = () => { const phrases = [ { label: "Hello, I'm Pepper", text: "Hello, I'm Pepper" }, { label: "Repeat please", text: "Could you repeat that please" }, { label: "About yourself", text: "Tell me something about yourself" }, ]; return (

Speech Presets

); }; // --- DIRECT SPEECH (INPUT) COMPONENT --- export const DirectSpeechInput: React.FC = () => { const [text, setText] = useState(""); const handleSend = () => { if (!text.trim()) return; sendAPICall("speech", text); setText(""); // Clear after sending }; return (

Direct Pepper Speech

setText(e.target.value)} placeholder="Type message..." onKeyDown={(e) => e.key === 'Enter' && handleSend()} />
); }; // --- interface for goals/triggers/norms/conditional norms --- export type StatusItem = { id?: string | number; achieved?: boolean; description?: string; label?: string; norm?: string; name?: string; level?: number; }; interface StatusListProps { title: string; items: StatusItem[]; type: 'goal' | 'trigger' | 'norm'| 'cond_norm'; activeIds: Record; setActiveIds?: React.Dispatch>>; currentGoalIndex?: number; } // --- STATUS LIST COMPONENT --- export const StatusList: React.FC = ({ title, items, type, activeIds, setActiveIds, currentGoalIndex // Destructure this prop }) => { return (

{title}

    {items.map((item, idx) => { if (item.id === undefined) return null; const isActive = !!activeIds[item.id]; const showIndicator = type !== 'norm'; const isCurrentGoal = type === 'goal' && idx === currentGoalIndex; const canOverride = (showIndicator && !isActive) || (type === 'cond_norm' && isActive); const indentation = (item.level || 0) * 20; const handleOverrideClick = () => { if (!canOverride) return; if (type === 'cond_norm' && isActive){ {/* Unachieve conditional norm */} sendAPICall("override_unachieve", String(item.id)); } else { if(type === 'goal') if(setActiveIds) {setActiveIds(prev => ({ ...prev, [String(item.id)]: true }));} sendAPICall("override", String(item.id)); } }; return (
  • {showIndicator && ( {isActive ? "✔️" : "❌"} )} {item.name || item.norm} {isCurrentGoal && " (Current)"}
  • ); })}
); }; // --- Robot Connected --- export const RobotConnected = () => { /** * The current connection state: * - `true`: Robot is connected. * - `false`: Robot is not connected. * - `null`: Connection status is unknown (initial check in progress). */ const [connected, setConnected] = useState(null); useEffect(() => { // Open a Server-Sent Events (SSE) connection to receive live ping updates. // We're expecting a stream of data like that looks like this: `data = False` or `data = True` const eventSource = new EventSource("http://localhost:8000/robot/ping_stream"); eventSource.onmessage = (event) => { // Expecting messages in JSON format: `true` or `false` //commented out this log as it clutters console logs, but might be useful to debug //console.log("received message:", event.data); try { const data = JSON.parse(event.data); try { setConnected(data) } catch { console.log("couldnt extract connected from incoming ping data") } } catch { console.log("Ping message not in correct format:", event.data); } }; // Clean up the SSE connection when the component unmounts. return () => eventSource.close(); }, []); return (

Connection:

{connected ? "● Robot is connected" : "● Robot is disconnected"}

) }