Changeset 0.28.7 (#193)
This commit is contained in:
17
packages/hello-dashboard/css/main.css
Normal file
17
packages/hello-dashboard/css/main.css
Normal file
@@ -0,0 +1,17 @@
|
||||
/* Hello Dashboard — sample extension surface styles.
|
||||
Uses CSS custom properties from the platform theme system (variables.css).
|
||||
See EXTENSION-SURFACES.md for the full property reference. */
|
||||
|
||||
.hello-dashboard { max-width: 720px; margin: 0 auto; padding: 40px 24px; }
|
||||
.hello-header { margin-bottom: 32px; }
|
||||
.hello-header h1 { font-size: 28px; font-weight: 700; color: var(--text); margin: 0 0 8px 0; }
|
||||
.hello-subtitle { font-size: 14px; color: var(--text-2); margin: 0; }
|
||||
.hello-subtitle code,
|
||||
.hello-card-value code { background: var(--bg-raised); padding: 2px 6px; border-radius: 4px; font-size: 13px; }
|
||||
.hello-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 24px; }
|
||||
.hello-card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px; }
|
||||
.hello-card-title { font-size: 12px; font-weight: 600; color: var(--text-2); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
|
||||
.hello-card-value { font-size: 20px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
|
||||
.hello-card-detail { font-size: 12px; color: var(--text-3); }
|
||||
.hello-actions { display: flex; gap: 12px; margin-bottom: 24px; }
|
||||
.hello-manifest { background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; font-size: 12px; color: var(--text-2); overflow-x: auto; white-space: pre-wrap; font-family: var(--mono); line-height: 1.5; }
|
||||
84
packages/hello-dashboard/js/main.js
Normal file
84
packages/hello-dashboard/js/main.js
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Hello Dashboard — sample extension surface.
|
||||
*
|
||||
* Platform contract:
|
||||
* - Mounts into #extension-mount
|
||||
* - window.__MANIFEST__ — surface manifest (json, lowercase keys)
|
||||
* - window.__USER__ — authenticated user {username, display_name, role}
|
||||
* - UI.toast(msg, type) — platform toast (success/error/info/warning)
|
||||
* - API._get(path) — authenticated fetch (returns parsed JSON)
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var mount = document.getElementById('extension-mount');
|
||||
if (!mount) return;
|
||||
|
||||
var manifest = window.__MANIFEST__ || {};
|
||||
var user = window.__USER__ || {};
|
||||
var isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||
var name = user.display_name || user.username || 'World';
|
||||
|
||||
mount.innerHTML =
|
||||
'<div class="hello-dashboard">' +
|
||||
'<div class="hello-header">' +
|
||||
'<h1>Hello, ' + esc(name) + '!</h1>' +
|
||||
'<p class="hello-subtitle">Extension surface <code>' + esc(manifest.id || 'unknown') + '</code> loaded successfully.</p>' +
|
||||
'</div>' +
|
||||
'<div class="hello-cards">' +
|
||||
card('Platform Access', (typeof UI !== 'undefined' ? '\u2713 Connected' : '\u2717 Unavailable'),
|
||||
'API, Theme, UI primitives available', 'var(--accent)') +
|
||||
card('Theme', isDark ? '\uD83C\uDF19 Dark' : '\u2600\uFE0F Light',
|
||||
'Reads from platform theme system', '') +
|
||||
card('Route', '<code>' + esc(manifest.route || '/s/hello-dashboard') + '</code>',
|
||||
'Registered via surface manifest', '') +
|
||||
'</div>' +
|
||||
'<div class="hello-actions">' +
|
||||
'<button class="btn-primary" id="helloToast">Show Toast</button>' +
|
||||
'<button class="btn-secondary" id="helloApi">Test API</button>' +
|
||||
'</div>' +
|
||||
'<pre class="hello-manifest">' + esc(JSON.stringify(manifest, null, 2)) + '</pre>' +
|
||||
'</div>';
|
||||
|
||||
// Wire toast button
|
||||
document.getElementById('helloToast').addEventListener('click', function() {
|
||||
if (typeof UI !== 'undefined' && UI.toast) {
|
||||
UI.toast('Extension surface is working!', 'success');
|
||||
} else {
|
||||
alert('Extension surface is working! (UI.toast not available)');
|
||||
}
|
||||
});
|
||||
|
||||
// Wire API test button
|
||||
document.getElementById('helloApi').addEventListener('click', function() {
|
||||
if (typeof API === 'undefined' || !API._get) {
|
||||
toast('API module not available', 'error');
|
||||
return;
|
||||
}
|
||||
API._get('/api/v1/surfaces').then(function(resp) {
|
||||
toast('API returned ' + (resp.surfaces || []).length + ' registered surfaces', 'info');
|
||||
}).catch(function(e) {
|
||||
toast('API error: ' + e.message, 'error');
|
||||
});
|
||||
});
|
||||
|
||||
function toast(msg, type) {
|
||||
if (typeof UI !== 'undefined' && UI.toast) UI.toast(msg, type);
|
||||
else alert(msg);
|
||||
}
|
||||
|
||||
function card(title, value, detail, color) {
|
||||
var style = color ? ' style="color:' + color + ';"' : '';
|
||||
return '<div class="hello-card">' +
|
||||
'<div class="hello-card-title">' + esc(title) + '</div>' +
|
||||
'<div class="hello-card-value"' + style + '>' + value + '</div>' +
|
||||
'<div class="hello-card-detail">' + esc(detail) + '</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
var el = document.createElement('span');
|
||||
el.textContent = s;
|
||||
return el.innerHTML;
|
||||
}
|
||||
})();
|
||||
11
packages/hello-dashboard/manifest.json
Normal file
11
packages/hello-dashboard/manifest.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "hello-dashboard",
|
||||
"title": "Hello Dashboard",
|
||||
"route": "/s/hello-dashboard",
|
||||
"auth": "authenticated",
|
||||
"layout": "single",
|
||||
"components": [],
|
||||
"hooks": ["surface"],
|
||||
"version": "0.1.0",
|
||||
"description": "Sample extension surface — verifies the /s/:slug pipeline works end-to-end."
|
||||
}
|
||||
Reference in New Issue
Block a user