Add HL3D branding, Etsy Live/Draft paging and Projects lifecycle
Deploy HickLab3D Dashboard / Deploy to production (push) Failing after 23s

Replace the old touchmark/PNG identity with the supplied lockup and
monogram, segmented role-aware navigation, Live/Draft listing filters
with generation-based cache invalidation, and admin Projects covering
immutable file revisions, listing live pointers, and exact-decimal
filament/packaging/shipping costing. Additive schema only; no Etsy
publication. Isolated clone tests: 301 tests, 1162 assertions.
This commit is contained in:
2026-11-08 12:50:56 +00:00
parent c8c5822166
commit d4928789c4
83 changed files with 5808 additions and 84 deletions
+7 -6
View File
@@ -1,8 +1,8 @@
const chartBase = {
chart: {
background: 'transparent',
foreColor: '#b8bec4',
fontFamily: 'Inter, ui-sans-serif, system-ui, sans-serif',
foreColor: '#A7ADB5',
fontFamily: "'Avenir Next', 'Avenir', ui-sans-serif, system-ui, sans-serif",
toolbar: { show: false },
zoom: { enabled: false },
},
@@ -31,7 +31,7 @@ if (document.querySelector('[data-dashboard-chart]')) {
options = {
...chartBase,
chart: { ...chartBase.chart, type: 'area', height },
colors: ['#e3f504'],
colors: ['#E7FF00'],
series: [{ name: 'Awaiting dispatch', data: data.series }],
xaxis: { categories: data.labels, labels: { rotate: -45, hideOverlappingLabels: true } },
yaxis: { min: 0, forceNiceScale: true, labels: { formatter: (value) => Number.isInteger(value) ? value.toString() : '' } },
@@ -47,11 +47,11 @@ if (document.querySelector('[data-dashboard-chart]')) {
chart: { ...chartBase.chart, type: 'donut', height },
labels: data.map((item) => item.label),
series: data.map((item) => item.count),
colors: ['#e3f504', '#7dd3a3', '#f0a46b', '#f17fa5', '#8b9df0'],
legend: { position: 'bottom', fontSize: '12px', labels: { colors: '#b8bec4' } },
colors: ['#E7FF00', '#7dd3a3', '#f0a46b', '#f17fa5', '#8b9df0'],
legend: { position: 'bottom', fontSize: '12px', labels: { colors: '#A7ADB5' } },
plotOptions: { pie: { donut: { size: '68%', labels: { show: true, total: { show: true, label: 'Printers' } } } } },
dataLabels: { enabled: false },
stroke: { colors: ['#17191b'], width: 2 },
stroke: { colors: ['#1a1d21'], width: 2 },
};
}
@@ -63,3 +63,4 @@ if (document.querySelector('[data-dashboard-chart]')) {
}
import './notifications';
import './navigation';
+63
View File
@@ -0,0 +1,63 @@
const costLines = document.querySelector('[data-cost-lines]');
if (costLines) {
const template = costLines.firstElementChild.cloneNode(true);
let nextIndex = costLines.children.length;
document.querySelector('[data-add-cost-line]')?.addEventListener('click', () => {
if (costLines.children.length >= 50) { return; }
const line = template.cloneNode(true);
line.querySelector('legend').textContent = `Cost line ${nextIndex + 1}`;
line.querySelectorAll('[name]').forEach((input) => {
input.name = input.name.replace(/lines\[\d+\]/, `lines[${nextIndex}]`);
if (input.tagName === 'INPUT') { input.value = input.name.includes('units_per_parcel') ? '1' : input.name.includes('waste_quantity') ? '0' : ''; }
});
nextIndex += 1;
costLines.append(line);
line.querySelector('select').focus();
});
costLines.addEventListener('click', (event) => {
if (event.target.matches('[data-remove-cost-line]') && costLines.children.length > 1) { event.target.closest('[data-cost-line]').remove(); }
});
}
const sidebar = document.querySelector('[data-sidebar]');
const sidebarToggle = document.querySelector('[data-sidebar-toggle]');
if (sidebar && sidebarToggle) {
const collapsedKey = 'hl3d-sidebar-collapsed';
const applyCollapsed = (collapsed) => {
sidebar.classList.toggle('lg:w-20', collapsed);
sidebar.querySelectorAll('[data-sidebar-label]').forEach((label) => {
label.classList.toggle('hidden', collapsed);
});
sidebar.querySelectorAll('[data-sidebar-expanded-mark]').forEach((mark) => {
mark.classList.toggle('hidden', collapsed);
});
sidebar.querySelectorAll('[data-sidebar-collapsed-mark]').forEach((mark) => {
mark.classList.toggle('hidden', !collapsed);
});
sidebarToggle.setAttribute('aria-pressed', collapsed ? 'true' : 'false');
sidebarToggle.textContent = collapsed ? 'Expand' : 'Collapse';
};
applyCollapsed(localStorage.getItem(collapsedKey) === '1');
sidebarToggle.addEventListener('click', () => {
const collapsed = !sidebar.classList.contains('lg:w-20');
localStorage.setItem(collapsedKey, collapsed ? '1' : '0');
applyCollapsed(collapsed);
});
}
document.querySelectorAll('[data-nav-group]').forEach((details) => {
const storageKey = `hl3d-nav-group-${details.dataset.navGroup}`;
const stored = localStorage.getItem(storageKey);
if (stored !== null) {
details.open = stored === '1';
}
details.addEventListener('toggle', () => {
localStorage.setItem(storageKey, details.open ? '1' : '0');
});
});