import { Link, Links, Meta, Outlet, Scripts, ScrollRestoration, useLoaderData, useLocation, } from "@remix-run/react"; import { json, LoaderFunction } from "@remix-run/node"; import { useEffect, useState } from "react"; import type { Socket } from "socket.io-client"; import io from "socket.io-client"; import stylesheet from "./tailwind.css?url"; import { SocketProvider } from "./context"; import { l33tSerializer } from "../server/misc"; import { L33tMemDB } from "l33t-lib"; export const links = () => [ { rel: "stylesheet", href: stylesheet }, ]; export const loader: LoaderFunction = async ({ context }) => { return json(l33tSerializer(context)); }; export default function App() { const { memoryDB } = useLoaderData<{ memoryDB: L33tMemDB }>(); const [socket, setSocket] = useState(); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [showCheck, setShowCheck] = useState(false); const [selectedIds, setSelectedIds] = useState([]); const location = useLocation(); useEffect(() => { // Resetta lo stato quando cambia il percorso setShowCheck(false); setSelectedIds([]); }, [location.pathname]); useEffect(() => { const newSocket = io(); setSocket(newSocket); return () => { newSocket.close(); }; }, []); const toggleSelection = (id: string) => { setSelectedIds((prev) => prev.includes(id) ? prev.filter((itemId) => itemId !== id) : [...prev, id] ); }; const toggleDropdown = () => { setIsDropdownOpen(!isDropdownOpen); }; const handlePersist = () => { if (socket) { socket.emit("l33t_db_persist"); setIsDropdownOpen(false); } }; const handleBulkAction = (action: "start" | "stop" | "delete") => { if (!socket || selectedIds.length === 0) return; const entityType = location.pathname.startsWith("/streams") ? "streams" : location.pathname.startsWith("/plcs") ? "PLCs" : "tasks"; const confirmMessage = `Are you sure you want to ${action} ${selectedIds.length} ${entityType}?`; if (window.confirm(confirmMessage)) { selectedIds.forEach((id) => { switch (location.pathname) { case "/tasks": switch (action) { case "start": socket.emit("l33t_task_start", { taskId: id }); break; case "stop": console.log("emit stop") socket.emit("l33t_task_stop", { taskId: id }); break; case "delete": socket.emit("l33t_delete_task", { taskId: id }); break; } break; case "/streams": if (action === "delete") { socket.emit("l33t_delete_agent", { agentId: id }); } break; case "/plcs": if (action === "delete") { socket.emit("l33t_delete_plc", { plcId: id }); } break; } }); setSelectedIds([]); setShowCheck(false); } }; return (
    {[...Array(10)].map((_, i) => (
  • ))}
  • {isDropdownOpen && (
    )}
  • Streams
  • PLCs
  • Tasks
  • {/* Buttons aligned to the right, only on tasks page */}
    {selectedIds.length > 0 && ( <> {location.pathname.startsWith('/tasks') && ( <>
  • )}
  • )}
); }