Download index.html from BruceBanners/splitflap-commander-pro: direct link, hf CLI and curl.
- Browser
- Download file 28.2 kB
-
https://huggingface.co/spaces/BruceBanners/splitflap-commander-pro/resolve/main/index.html
- Command line
-
hf download hf://spaces/BruceBanners/splitflap-commander-pro/index.html
-
curl -L -o index.html https://huggingface.co/spaces/BruceBanners/splitflap-commander-pro/resolve/main/index.html
28.2 kB
| <html lang="no"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>Split-flap Admin – Canvas</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <style> | |
| :root { | |
| --primary: #3b82f6; | |
| --secondary: #1f2937; | |
| --accent: #10b981; | |
| --danger: #ef4444; | |
| --warning: #f59e0b; | |
| --dark: #0f1115; | |
| --darker: #0b0d12; | |
| --light: #e5e7eb; | |
| --border: #1f2330; | |
| } | |
| body { | |
| scrollbar-width: thin; | |
| scrollbar-color: var(--secondary) var(--darker); | |
| } | |
| body::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| body::-webkit-scrollbar-track { | |
| background: var(--darker); | |
| } | |
| body::-webkit-scrollbar-thumb { | |
| background: var(--secondary); | |
| border-radius: 4px; | |
| } | |
| .tile-handle { | |
| position: absolute; | |
| right: -4px; | |
| bottom: -4px; | |
| width: 12px; | |
| height: 12px; | |
| background: var(--primary); | |
| border-radius: 2px; | |
| cursor: nwse-resize; | |
| opacity: 0; | |
| transition: opacity 0.2s; | |
| } | |
| .tile:hover .tile-handle { | |
| opacity: 1; | |
| } | |
| .grid-bg { | |
| background-size: calc(100%/var(--cols)) calc(100%/var(--rows)); | |
| background-image: | |
| linear-gradient(#1a2333 1px, transparent 1px), | |
| linear-gradient(90deg, #1a2333 1px, transparent 1px); | |
| } | |
| .property-section { | |
| transition: all 0.3s ease; | |
| } | |
| .log-entry { | |
| animation: fadeIn 0.3s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(-5px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .status-indicator { | |
| transition: all 0.3s ease; | |
| } | |
| input:focus, select:focus, textarea:focus { | |
| outline: 2px solid var(--primary); | |
| outline-offset: -2px; | |
| } | |
| .btn { | |
| transition: all 0.2s ease; | |
| } | |
| .btn:hover { | |
| transform: translateY(-1px); | |
| } | |
| .btn:active { | |
| transform: translateY(1px); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-900 text-gray-100 font-sans min-h-screen"> | |
| <div class="flex flex-col md:flex-row h-screen overflow-hidden"> | |
| <!-- Sidebar --> | |
| <div class="w-full md:w-80 lg:w-96 bg-gray-800 border-r border-gray-700 overflow-y-auto p-4 space-y-6"> | |
| <!-- Header --> | |
| <div class="flex items-center justify-between"> | |
| <h1 class="text-xl font-bold text-white flex items-center"> | |
| <i data-feather="layout" class="mr-2"></i> | |
| SplitFlap Commander | |
| </h1> | |
| <span id="status" class="px-2 py-1 bg-green-500/20 text-green-400 text-xs rounded-full border border-green-500/30">Ready</span> | |
| </div> | |
| <!-- API Configuration --> | |
| <div class="bg-gray-750 rounded-lg p-4 border border-gray-700"> | |
| <h2 class="text-sm font-semibold text-gray-300 mb-3 flex items-center"> | |
| <i data-feather="settings" class="mr-2 w-4 h-4"></i> | |
| API Configuration | |
| </h2> | |
| <div class="space-y-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">API Endpoint</label> | |
| <input id="apiUrl" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm" value="/cb/api.php"> | |
| </div> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Room</label> | |
| <input id="room" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm" value="hallA"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Token</label> | |
| <input id="token" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm" value="BYTT-DETTE"> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-3 gap-2"> | |
| <button id="ping" class="btn bg-blue-600 hover:bg-blue-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="wifi" class="w-4 h-4"></i> | |
| </button> | |
| <button id="clear" class="btn bg-gray-600 hover:bg-gray-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="trash-2" class="w-4 h-4"></i> | |
| </button> | |
| <button id="pushScene" class="btn bg-green-600 hover:bg-green-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="send" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Grid Configuration --> | |
| <div class="bg-gray-750 rounded-lg p-4 border border-gray-700"> | |
| <h2 class="text-sm font-semibold text-gray-300 mb-3 flex items-center"> | |
| <i data-feather="grid" class="mr-2 w-4 h-4"></i> | |
| Grid Setup | |
| </h2> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Columns</label> | |
| <input id="cols" type="number" min="4" max="80" value="20" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Rows</label> | |
| <input id="rows" type="number" min="4" max="40" value="10" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Icons Configuration --> | |
| <div class="bg-gray-750 rounded-lg p-4 border border-gray-700"> | |
| <h2 class="text-sm font-semibold text-gray-300 mb-3 flex items-center"> | |
| <i data-feather="star" class="mr-2 w-4 h-4"></i> | |
| Icons | |
| </h2> | |
| <div class="grid grid-cols-3 gap-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Rail</label> | |
| <input id="icoRail" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm text-center" value="🚆"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Bus</label> | |
| <input id="icoBus" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm text-center" value="🚌"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Tram</label> | |
| <input id="icoTram" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm text-center" value="🚊"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Metro</label> | |
| <input id="icoMetro" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm text-center" value="🚇"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Water</label> | |
| <input id="icoWater" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm text-center" value="🛥️"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Air</label> | |
| <input id="icoAir" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm text-center" value="✈️"> | |
| </div> | |
| <div class="col-span-3"> | |
| <label class="block text-xs text-gray-400 mb-1">Other</label> | |
| <input id="icoOther" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm text-center" value="•"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Tile Management --> | |
| <div class="bg-gray-750 rounded-lg p-4 border border-gray-700"> | |
| <h2 class="text-sm font-semibold text-gray-300 mb-3 flex items-center"> | |
| <i data-feather="plus-square" class="mr-2 w-4 h-4"></i> | |
| Add Tiles | |
| </h2> | |
| <div class="grid grid-cols-2 gap-2"> | |
| <button id="addClock" class="btn bg-purple-600 hover:bg-purple-700 text-white py-2 px-3 rounded text-sm flex items-center justify-center"> | |
| <i data-feather="clock" class="w-4 h-4 mr-1"></i> Clock | |
| </button> | |
| <button id="addEntur" class="btn bg-indigo-600 hover:bg-indigo-700 text-white py-2 px-3 rounded text-sm flex items-center justify-center"> | |
| <i data-feather="list" class="w-4 h-4 mr-1"></i> Entur | |
| </button> | |
| <button id="addText" class="btn bg-blue-600 hover:bg-blue-700 text-white py-2 px-3 rounded text-sm flex items-center justify-center"> | |
| <i data-feather="type" class="w-4 h-4 mr-1"></i> Text | |
| </button> | |
| <div class="grid grid-cols-2 gap-2"> | |
| <button id="dupTile" class="btn bg-gray-600 hover:bg-gray-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="copy" class="w-4 h-4"></i> | |
| </button> | |
| <button id="delTile" class="btn bg-red-600 hover:bg-red-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="trash" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Properties Panel --> | |
| <div id="propsPanel" class="bg-gray-750 rounded-lg p-4 border border-gray-700"> | |
| <h2 class="text-sm font-semibold text-gray-300 mb-3 flex items-center"> | |
| <i data-feather="sliders" class="mr-2 w-4 h-4"></i> | |
| Properties | |
| </h2> | |
| <div id="props" class="space-y-4"> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">ID</label> | |
| <input id="p_id" readonly class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm font-mono"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Type</label> | |
| <input id="p_type" readonly class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm font-mono"> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-4 gap-2"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">X</label> | |
| <input id="p_x" type="number" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Y</label> | |
| <input id="p_y" type="number" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">W</label> | |
| <input id="p_w" type="number" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">H</label> | |
| <input id="p_h" type="number" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| </div> | |
| <!-- Clock Properties --> | |
| <div id="typeClock" class="property-section hidden space-y-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Time Format</label> | |
| <select id="clk_fmt" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| <option value="HH:mm">HH:mm</option> | |
| <option value="HH:mm:ss">HH:mm:ss</option> | |
| <option value="dd.MM HH:mm">dd.MM HH:mm</option> | |
| <option value="dd.MM">dd.MM</option> | |
| </select> | |
| </div> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Color</label> | |
| <input id="clk_color" type="color" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm h-9" value="#ffffff"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Update (ms)</label> | |
| <input id="clk_ms" type="number" min="200" value="1000" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Entur Properties --> | |
| <div id="typeEntur" class="property-section hidden space-y-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Stop Place ID</label> | |
| <input id="en_stop" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm font-mono" value="NSR:StopPlace:58287"> | |
| </div> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Mode</label> | |
| <select id="en_mode" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| <option value="departures">Departures</option> | |
| <option value="arrivals">Arrivals</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Limit</label> | |
| <input id="en_limit" type="number" min="1" max="20" value="6" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-2 gap-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Fetch (s)</label> | |
| <input id="en_fetch" type="number" min="5" value="30" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Lines</label> | |
| <input id="en_lines" type="number" min="1" max="20" value="6" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Template</label> | |
| <input id="en_tpl" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm font-mono" value="[{icon}] {time} {line|cut=6} {dest|cutEnd=12} Sp{quay|pad=2} {status} {delay}"> | |
| </div> | |
| <div class="grid grid-cols-3 gap-2"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Normal</label> | |
| <input id="en_c_norm" type="color" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm h-9" value="#ffffff"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Delayed</label> | |
| <input id="en_c_del" type="color" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm h-9" value="#ffe66d"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Cancelled</label> | |
| <input id="en_c_can" type="color" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm h-9" value="#ff5c5c"> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-5 gap-2 pt-2"> | |
| <label class="flex items-center space-x-1"> | |
| <input id="en_vy" type="checkbox" checked class="rounded border-gray-600 text-blue-600"> | |
| <span class="text-xs">Vy</span> | |
| </label> | |
| <label class="flex items-center space-x-1"> | |
| <input id="en_sj" type="checkbox" checked class="rounded border-gray-600 text-blue-600"> | |
| <span class="text-xs">SJ</span> | |
| </label> | |
| <label class="flex items-center space-x-1"> | |
| <input id="en_fly" type="checkbox" checked class="rounded border-gray-600 text-blue-600"> | |
| <span class="text-xs">Fly</span> | |
| </label> | |
| <label class="flex items-center space-x-1"> | |
| <input id="en_onlydel" type="checkbox" class="rounded border-gray-600 text-blue-600"> | |
| <span class="text-xs">Delayed</span> | |
| </label> | |
| <label class="flex items-center space-x-1"> | |
| <input id="en_onlycan" type="checkbox" class="rounded border-gray-600 text-blue-600"> | |
| <span class="text-xs">Canceled</span> | |
| </label> | |
| </div> | |
| <div class="grid grid-cols-2 gap-2 pt-2"> | |
| <button id="en_fetch_now" class="btn bg-blue-600 hover:bg-blue-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="refresh-cw" class="w-4 h-4 mr-1"></i> Fetch Now | |
| </button> | |
| <button id="en_preview" class="btn bg-gray-600 hover:bg-gray-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="eye" class="w-4 h-4 mr-1"></i> Preview | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Text Properties --> | |
| <div id="typeText" class="property-section hidden space-y-3"> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Text Content</label> | |
| <input id="tx_text" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm" value="Velkommen"> | |
| </div> | |
| <div> | |
| <label class="block text-xs text-gray-400 mb-1">Text Color</label> | |
| <input id="tx_color" type="color" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm h-9" value="#6daaff"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Auto Push --> | |
| <div class="bg-gray-750 rounded-lg p-4 border border-gray-700"> | |
| <h2 class="text-sm font-semibold text-gray-300 mb-3 flex items-center"> | |
| <i data-feather="repeat" class="mr-2 w-4 h-4"></i> | |
| Auto Push | |
| </h2> | |
| <div class="grid grid-cols-3 gap-3 items-end"> | |
| <div class="col-span-2"> | |
| <label class="block text-xs text-gray-400 mb-1">Interval (seconds)</label> | |
| <input id="scene_push" type="number" value="10" min="3" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm"> | |
| </div> | |
| <div class="grid grid-cols-2 gap-2"> | |
| <button id="startAuto" class="btn bg-green-600 hover:bg-green-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="play" class="w-4 h-4"></i> | |
| </button> | |
| <button id="stopAuto" class="btn bg-red-600 hover:bg-red-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="square" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Storage --> | |
| <div class="bg-gray-750 rounded-lg p-4 border border-gray-700"> | |
| <h2 class="text-sm font-semibold text-gray-300 mb-3 flex items-center"> | |
| <i data-feather="save" class="mr-2 w-4 h-4"></i> | |
| Storage | |
| </h2> | |
| <div class="grid grid-cols-3 gap-2"> | |
| <button id="save" class="btn bg-blue-600 hover:bg-blue-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="save" class="w-4 h-4"></i> | |
| </button> | |
| <button id="load" class="btn bg-gray-600 hover:bg-gray-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="folder" class="w-4 h-4"></i> | |
| </button> | |
| <button id="export" class="btn bg-green-600 hover:bg-green-700 text-white py-2 px-3 rounded text-sm"> | |
| <i data-feather="download" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <div class="mt-3"> | |
| <label class="block text-xs text-gray-400 mb-1">Import Configuration</label> | |
| <input id="importFile" type="file" accept="application/json" class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-sm file:mr-3 file:py-1 file:px-3 file:rounded file:border-0 file:text-xs file:font-medium file:bg-gray-600 file:text-white"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="flex-1 flex flex-col overflow-hidden"> | |
| <!-- Canvas Header --> | |
| <div class="bg-gray-800 border-b border-gray-700 p-4"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center space-x-4"> | |
| <h2 class="text-lg font-semibold text-white">Canvas</h2> | |
| <span id="dim" class="px-2 py-1 bg-gray-700 text-gray-300 text-xs rounded">20 × 10</span> | |
| </div> | |
| <div class="flex items-center space-x-2"> | |
| <button class="btn bg-gray-700 hover:bg-gray-600 text-gray-300 p-2 rounded" title="Zoom In"> | |
| <i data-feather="zoom-in" class="w-4 h-4"></i> | |
| </button> | |
| <button class="btn bg-gray-700 hover:bg-gray-600 text-gray-300 p-2 rounded" title="Zoom Out"> | |
| <i data-feather="zoom-out" class="w-4 h-4"></i> | |
| </button> | |
| <button class="btn bg-gray-700 hover:bg-gray-600 text-gray-300 p-2 rounded" title="Reset View"> | |
| <i data-feather="refresh-ccw" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Canvas Area --> | |
| <div class="flex-1 relative overflow-auto bg-gray-900 p-4"> | |
| <div id="canvas" class="relative w-full h-full min-h-[400px] bg-gray-850 border border-gray-700 rounded-lg overflow-hidden"> | |
| <div id="grid" class="absolute inset-0 grid-bg" style="--cols:20;--rows:10"></div> | |
| <!-- Tiles will be rendered here --> | |
| </div> | |
| </div> | |
| <!-- Log Area --> | |
| <div class="bg-gray-800 border-t border-gray-700"> | |
| <div class="flex items-center justify-between p-3 border-b border-gray-700"> | |
| <h3 class="text-sm font-semibold text-gray-300 flex items-center"> | |
| <i data-feather="activity" class="mr-2 w-4 h-4"></i> | |
| Log | |
| </h3> | |
| <button class="text-gray-400 hover:text-gray-300 p-1 rounded" title="Clear Log"> | |
| <i data-feather="trash-2" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <div id="log" class="h-32 overflow-y-auto bg-gray-900 text-xs font-mono p-3 space-y-1"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Your original JavaScript code remains mostly unchanged, but integrated with the new UI | |
| // Only minor adjustments for class names and selectors | |
| const S=id=>document.getElementById(id); | |
| const statusEl=S('status'); const logEl=S('log'); | |
| function setStatus(s, type = 'success') { | |
| statusEl.textContent = s; | |
| const colors = { | |
| success: 'bg-green-500/20 text-green-400 border-green-500/30', | |
| error: 'bg-red-500/20 text-red-400 border-red-500/30', | |
| warning: 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30', | |
| info: 'bg-blue-500/20 text-blue-400 border-blue-500/30' | |
| }; | |
| statusEl.className = `px-2 py-1 text-xs rounded-full border ${colors[type] || colors.success}`; | |
| } | |
| function log(m,d){ | |
| const t=new Date().toLocaleTimeString(); | |
| const line=`[${t}] ${m}${d? " "+JSON.stringify(d):""}`; | |
| const entry = document.createElement('div'); | |
| entry.className = 'log-entry text-gray-300'; | |
| entry.textContent = line; | |
| logEl.prepend(entry); | |
| console.log(m,d??""); | |
| } | |
| // The rest of your JavaScript code remains the same... | |
| // [Your original JavaScript code continues here with minimal adjustments for the new class names] | |
| // Initialize feather icons | |
| feather.replace(); | |
| </script> | |
| </body> | |
| </html> | |