132 lines
6.1 KiB
JavaScript
132 lines
6.1 KiB
JavaScript
/**
|
||
* WijiBoard – Home Section
|
||
* web/js/sections/home.js
|
||
*
|
||
* A minimal placeholder home section.
|
||
*/
|
||
|
||
import BLE from '../ble.js';
|
||
|
||
const HomeSection = {
|
||
_cleanup: [],
|
||
|
||
mount(container) {
|
||
container.innerHTML = `
|
||
<div class="section-page fade-in">
|
||
<div class="section-header">
|
||
<h2>WijiBoard</h2>
|
||
<p>WiFi Spirit Board — SCARA arm controller. Select a section from the sidebar to get started.</p>
|
||
</div>
|
||
|
||
<div class="grid-2" style="margin-bottom:16px">
|
||
<!-- Status card -->
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span class="card-title">Connection</span>
|
||
</div>
|
||
<div class="status-row" style="margin-bottom:10px">
|
||
<span class="status-label">BLE</span>
|
||
<span class="status-value" id="home-ble-status">
|
||
${BLE.isConnected() ? `✓ ${BLE.getDeviceName()}` : 'Not connected'}
|
||
</span>
|
||
</div>
|
||
<p style="font-size:0.8rem;color:var(--text-muted)">
|
||
Use the <strong style="color:var(--text-secondary)">Connect</strong> button
|
||
in the top bar to pair with the WijiBoard via Bluetooth.
|
||
The device name is <code style="color:var(--accent-blue)">WijiBoard</code>.
|
||
</p>
|
||
</div>
|
||
|
||
<!-- About card -->
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span class="card-title">About</span>
|
||
</div>
|
||
<p style="font-size:0.82rem;line-height:1.8;color:var(--text-secondary)">
|
||
This dashboard controls a two-arm SCARA robot that moves a planchette
|
||
across a spirit board. It uses <strong style="color:var(--text-primary)">Web Bluetooth</strong>
|
||
to communicate with an ESP32-C3 running two 28BYJ-48 stepper motors
|
||
with AccelStepper.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Sections overview -->
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<span class="card-title">Sections</span>
|
||
</div>
|
||
<div class="grid-2">
|
||
<button class="sidebar-nav-item" data-route="board-control"
|
||
onclick="document.getElementById('nav-board-control').click()"
|
||
style="padding:14px 16px;background:var(--surface-2);text-align:left;border:none;cursor:pointer;width:100%;">
|
||
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M12 20h9M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
|
||
</svg>
|
||
<div>
|
||
<div style="font-weight:600;font-size:0.875rem;color:var(--text-primary)">Board Control</div>
|
||
<div style="font-size:0.75rem;color:var(--text-muted);margin-top:2px">Interactive map navigation</div>
|
||
</div>
|
||
</button>
|
||
|
||
<button class="sidebar-nav-item" data-route="input-text"
|
||
onclick="document.getElementById('nav-input-text').click()"
|
||
style="padding:14px 16px;background:var(--surface-2);text-align:left;border:none;cursor:pointer;width:100%;">
|
||
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
|
||
</svg>
|
||
<div>
|
||
<div style="font-weight:600;font-size:0.875rem;color:var(--text-primary)">Input Text</div>
|
||
<div style="font-size:0.75rem;color:var(--text-muted);margin-top:2px">Spell out words automatically</div>
|
||
</div>
|
||
</button>
|
||
|
||
<button class="sidebar-nav-item" data-route="sequence-editor"
|
||
onclick="document.getElementById('nav-sequence-editor').click()"
|
||
style="padding:14px 16px;background:var(--surface-2);text-align:left;border:none;cursor:pointer;width:100%;">
|
||
<svg class="nav-icon"><use href="web/assets/icons.svg#icon-sequence"></use></svg>
|
||
<div>
|
||
<div style="font-weight:600;font-size:0.875rem;color:var(--text-primary)">Sequence Editor</div>
|
||
<div style="font-size:0.75rem;color:var(--text-muted);margin-top:2px">Build and test custom sequences</div>
|
||
</div>
|
||
</button>
|
||
|
||
<button class="sidebar-nav-item" data-route="stepper-test"
|
||
onclick="document.getElementById('nav-stepper-test').click()"
|
||
style="padding:14px 16px;background:var(--surface-2);text-align:left;border:none;cursor:pointer;width:100%;">
|
||
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="3"/><path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/>
|
||
</svg>
|
||
<div>
|
||
<div style="font-weight:600;font-size:0.875rem;color:var(--text-primary)">Stepper Test</div>
|
||
<div style="font-size:0.75rem;color:var(--text-muted);margin-top:2px">Manually jog each motor, visualize arm position</div>
|
||
</div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
// Keep home BLE status label in sync
|
||
const statusEl = container.querySelector('#home-ble-status');
|
||
const update = () => {
|
||
if (statusEl) statusEl.textContent = BLE.isConnected()
|
||
? `✓ ${BLE.getDeviceName()}`
|
||
: 'Not connected';
|
||
};
|
||
BLE.on('connected', update);
|
||
BLE.on('disconnected', update);
|
||
this._cleanup = [
|
||
() => BLE.off('connected', update),
|
||
() => BLE.off('disconnected', update),
|
||
];
|
||
},
|
||
|
||
unmount() {
|
||
this._cleanup.forEach(fn => fn());
|
||
this._cleanup = [];
|
||
},
|
||
};
|
||
|
||
export default HomeSection;
|