feat(rschedule): add automation canvas link and workflow gallery to landing page
Adds "Automation Canvas" CTA button in hero and "Your Automations" section that fetches workflows from API and displays as grid cards or compact list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b3f335c7d4
commit
5ded81046c
|
|
@ -24,6 +24,11 @@ export function renderLanding(): string {
|
|||
onclick="document.querySelector('.rl-hero').closest('[data-space]')?.getAttribute('data-space') ? window.location.href='/' + document.querySelector('.rl-hero').closest('[data-space]').getAttribute('data-space') + '/rschedule' : void 0; return false;">
|
||||
Open Scheduler
|
||||
</a>
|
||||
<a href="#" class="rl-cta-primary" id="ml-automations"
|
||||
style="background:linear-gradient(to right,#8b5cf6,#6366f1);color:#fff"
|
||||
onclick="document.querySelector('.rl-hero').closest('[data-space]')?.getAttribute('data-space') ? window.location.href='/' + document.querySelector('.rl-hero').closest('[data-space]').getAttribute('data-space') + '/rschedule/reminders' : window.location.href='/demo/rschedule/reminders'; return false;">
|
||||
Automation Canvas
|
||||
</a>
|
||||
<a href="#features" class="rl-cta-secondary">Learn More</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -64,6 +69,147 @@ export function renderLanding(): string {
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Your Automations -->
|
||||
<section class="rl-section" id="automations">
|
||||
<div class="rl-container">
|
||||
<h2 style="text-align:center;font-size:1.5rem;margin-bottom:0.5rem;color:#e2e8f0">Your Automations</h2>
|
||||
<p style="text-align:center;color:rgba(148,163,184,0.7);margin-bottom:2rem;font-size:0.9rem">
|
||||
Visual workflows built on the automation canvas
|
||||
</p>
|
||||
<div id="rs-automations-list" style="min-height:120px">
|
||||
<p style="text-align:center;color:rgba(148,163,184,0.5);padding:2rem 0">Loading automations…</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var space = 'demo';
|
||||
var el = document.querySelector('.rl-hero');
|
||||
if (el) {
|
||||
var ds = el.closest('[data-space]');
|
||||
if (ds) space = ds.getAttribute('data-space') || 'demo';
|
||||
}
|
||||
var basePath = '/' + space + '/rschedule/';
|
||||
var container = document.getElementById('rs-automations-list');
|
||||
|
||||
fetch(basePath + 'api/workflows')
|
||||
.then(function(r) { return r.ok ? r.json() : { results: [] }; })
|
||||
.then(function(data) {
|
||||
var wfs = data.results || [];
|
||||
if (wfs.length === 0) {
|
||||
container.innerHTML =
|
||||
'<div style="text-align:center;padding:2.5rem 1rem">' +
|
||||
'<p style="color:rgba(148,163,184,0.6);margin-bottom:1.5rem">No automations yet.</p>' +
|
||||
'<a href="' + basePath + 'reminders" ' +
|
||||
'style="display:inline-block;padding:0.6rem 1.5rem;border-radius:8px;' +
|
||||
'background:linear-gradient(to right,#8b5cf6,#6366f1);color:#fff;text-decoration:none;font-weight:600;font-size:0.9rem">' +
|
||||
'+ Create your first automation</a>' +
|
||||
'</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
var viewMode = wfs.length > 6 ? 'list' : 'grid';
|
||||
var html = '';
|
||||
|
||||
if (viewMode === 'grid') {
|
||||
html += '<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:1rem">';
|
||||
for (var i = 0; i < wfs.length; i++) {
|
||||
var w = wfs[i];
|
||||
var nodeCount = (w.nodes || []).length;
|
||||
var edgeCount = (w.edges || []).length;
|
||||
var statusColor = w.enabled ? '#34d399' : '#64748b';
|
||||
var statusLabel = w.enabled ? 'Active' : 'Disabled';
|
||||
var lastRun = w.lastRunAt ? new Date(w.lastRunAt).toLocaleDateString() : 'Never';
|
||||
var runStatusIcon = w.lastRunStatus === 'success' ? '✓' : w.lastRunStatus === 'error' ? '✗' : '—';
|
||||
var runStatusColor = w.lastRunStatus === 'success' ? '#34d399' : w.lastRunStatus === 'error' ? '#ef4444' : '#64748b';
|
||||
|
||||
// Build a mini node-count summary
|
||||
var triggers = 0, conditions = 0, actions = 0;
|
||||
for (var n = 0; n < (w.nodes || []).length; n++) {
|
||||
var t = (w.nodes[n].type || '');
|
||||
if (t.indexOf('trigger') === 0) triggers++;
|
||||
else if (t.indexOf('condition') === 0) conditions++;
|
||||
else if (t.indexOf('action') === 0) actions++;
|
||||
}
|
||||
|
||||
html += '<a href="' + basePath + 'reminders?wf=' + w.id + '" ' +
|
||||
'style="display:block;text-decoration:none;border-radius:12px;' +
|
||||
'background:rgba(30,41,59,0.6);border:1px solid rgba(148,163,184,0.12);' +
|
||||
'padding:1.25rem;transition:border-color 0.2s,transform 0.15s;cursor:pointer" ' +
|
||||
'onmouseover="this.style.borderColor=\'rgba(139,92,246,0.4)\';this.style.transform=\'translateY(-2px)\'" ' +
|
||||
'onmouseout="this.style.borderColor=\'rgba(148,163,184,0.12)\';this.style.transform=\'none\'">' +
|
||||
|
||||
// Header row
|
||||
'<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:0.75rem">' +
|
||||
'<span style="font-weight:600;color:#e2e8f0;font-size:0.95rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + (w.name || 'Untitled') + '</span>' +
|
||||
'<span style="font-size:0.7rem;padding:2px 8px;border-radius:9999px;background:' + statusColor + '20;color:' + statusColor + ';font-weight:500;white-space:nowrap">' + statusLabel + '</span>' +
|
||||
'</div>' +
|
||||
|
||||
// Node summary
|
||||
'<div style="display:flex;gap:0.75rem;margin-bottom:0.6rem;font-size:0.8rem;color:rgba(148,163,184,0.7)">' +
|
||||
(triggers ? '<span style="color:#60a5fa">' + triggers + ' trigger' + (triggers > 1 ? 's' : '') + '</span>' : '') +
|
||||
(conditions ? '<span style="color:#fbbf24">' + conditions + ' condition' + (conditions > 1 ? 's' : '') + '</span>' : '') +
|
||||
(actions ? '<span style="color:#34d399">' + actions + ' action' + (actions > 1 ? 's' : '') + '</span>' : '') +
|
||||
(!nodeCount ? '<span>Empty workflow</span>' : '') +
|
||||
'</div>' +
|
||||
|
||||
// Footer
|
||||
'<div style="display:flex;align-items:center;justify-content:space-between;font-size:0.75rem;color:rgba(148,163,184,0.5)">' +
|
||||
'<span>Runs: ' + (w.runCount || 0) + '</span>' +
|
||||
'<span>Last: <span style="color:' + runStatusColor + '">' + runStatusIcon + '</span> ' + lastRun + '</span>' +
|
||||
'</div>' +
|
||||
'</a>';
|
||||
}
|
||||
html += '</div>';
|
||||
} else {
|
||||
// List view for many workflows
|
||||
html += '<div style="display:flex;flex-direction:column;gap:0.5rem">';
|
||||
for (var i = 0; i < wfs.length; i++) {
|
||||
var w = wfs[i];
|
||||
var nodeCount = (w.nodes || []).length;
|
||||
var statusColor = w.enabled ? '#34d399' : '#64748b';
|
||||
var statusLabel = w.enabled ? 'Active' : 'Disabled';
|
||||
var lastRun = w.lastRunAt ? new Date(w.lastRunAt).toLocaleDateString() : 'Never';
|
||||
var runStatusIcon = w.lastRunStatus === 'success' ? '✓' : w.lastRunStatus === 'error' ? '✗' : '—';
|
||||
var runStatusColor = w.lastRunStatus === 'success' ? '#34d399' : w.lastRunStatus === 'error' ? '#ef4444' : '#64748b';
|
||||
|
||||
html += '<a href="' + basePath + 'reminders?wf=' + w.id + '" ' +
|
||||
'style="display:flex;align-items:center;gap:1rem;text-decoration:none;border-radius:8px;' +
|
||||
'background:rgba(30,41,59,0.4);border:1px solid rgba(148,163,184,0.08);' +
|
||||
'padding:0.75rem 1rem;transition:border-color 0.2s" ' +
|
||||
'onmouseover="this.style.borderColor=\'rgba(139,92,246,0.4)\'" ' +
|
||||
'onmouseout="this.style.borderColor=\'rgba(148,163,184,0.08)\'">' +
|
||||
'<span style="width:8px;height:8px;border-radius:50%;background:' + statusColor + ';flex-shrink:0"></span>' +
|
||||
'<span style="flex:1;font-weight:500;color:#e2e8f0;font-size:0.9rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + (w.name || 'Untitled') + '</span>' +
|
||||
'<span style="font-size:0.75rem;color:rgba(148,163,184,0.5)">' + nodeCount + ' nodes</span>' +
|
||||
'<span style="font-size:0.75rem;color:rgba(148,163,184,0.5)">' + (w.runCount || 0) + ' runs</span>' +
|
||||
'<span style="font-size:0.75rem;color:' + runStatusColor + '">' + runStatusIcon + ' ' + lastRun + '</span>' +
|
||||
'</a>';
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
// Add "Open Canvas" link at the bottom
|
||||
html += '<div style="text-align:center;margin-top:1.5rem">' +
|
||||
'<a href="' + basePath + 'reminders" ' +
|
||||
'style="color:#8b5cf6;text-decoration:none;font-size:0.9rem;font-weight:500">' +
|
||||
'Open Automation Canvas →</a>' +
|
||||
'</div>';
|
||||
|
||||
container.innerHTML = html;
|
||||
})
|
||||
.catch(function() {
|
||||
container.innerHTML =
|
||||
'<div style="text-align:center;padding:2rem">' +
|
||||
'<p style="color:rgba(148,163,184,0.5)">Could not load automations.</p>' +
|
||||
'<a href="' + basePath + 'reminders" ' +
|
||||
'style="color:#8b5cf6;text-decoration:none;font-size:0.9rem">Open Automation Canvas →</a>' +
|
||||
'</div>';
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- How it works -->
|
||||
<section class="rl-section">
|
||||
<div class="rl-container">
|
||||
|
|
|
|||
Loading…
Reference in New Issue