feat: implement snapshot capture and storage for robot configurations
CI/CD / test-and-build (push) Has been cancelled
CI/CD / deploy (push) Has been cancelled

This commit is contained in:
Najjar\NajjarV02
2026-04-13 18:00:12 +04:00
parent 05b540997e
commit dc42aeb72a
5 changed files with 142 additions and 20 deletions
+50 -19
View File
@@ -418,14 +418,22 @@ function OrderRow({
formatDate: (ts: number) => string;
}) {
const [expanded, setExpanded] = useState(false);
const [snapshot, setSnapshot] = useState<string | null | 'loading'>(null);
const m = order.metadata;
const name = m.customerName || '—';
const email = m.customerEmail || '';
const phone = m.customerPhone || '';
const address = [m.customerAddress, m.customerCity, m.customerCountry, m.customerPostalCode]
.filter(Boolean).join(', ') || '';
const persona = m.persona || '';
const color = m.color || '';
const handleExpand = () => {
const next = !expanded;
setExpanded(next);
if (next && snapshot === null) {
setSnapshot('loading');
fetch(`/api/admin/snapshots/${order.id}/`)
.then((r) => (r.ok ? r.json() : null))
.then((data) => setSnapshot(data?.imageData ?? 'none'))
.catch(() => setSnapshot('none'));
}
};
return (
<div style={{ borderBottom: isLast ? 'none' : '1px solid rgba(0,0,0,0.04)' }}>
@@ -453,7 +461,7 @@ function OrderRow({
</div>
<div style={{ fontSize: '0.75rem', color: '#94a3b8' }}>{formatDate(order.created)}</div>
<button
onClick={() => setExpanded((v) => !v)}
onClick={handleExpand}
title={expanded ? 'Collapse' : 'Show details'}
style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#94a3b8', fontSize: '0.7rem', padding: '2px 4px', borderRadius: 4 }}
>
@@ -461,26 +469,49 @@ function OrderRow({
</button>
</div>
{/* Expanded customer details */}
{/* Expanded details */}
{expanded && (
<div style={{ padding: '0 1.25rem 0.875rem 1.25rem' }}>
<div style={{ background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', padding: '0.75rem 1rem', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0.5rem 1.5rem' }}>
<div style={{ padding: '0 1.25rem 1rem 1.25rem', display: 'grid', gridTemplateColumns: snapshot && snapshot !== 'loading' && snapshot !== 'none' ? '1fr 200px' : '1fr', gap: '1rem' }}>
{/* Customer info grid */}
<div style={{ background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', padding: '0.875rem 1rem', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0.625rem 1.5rem' }}>
{[
{ label: 'Full Name', value: m.customerName },
{ label: 'Email', value: m.customerEmail },
{ label: 'Phone', value: m.customerPhone },
{ label: 'Address', value: address },
{ label: 'Persona', value: persona },
{ label: 'Color', value: color },
].map(({ label, value }) =>
value ? (
<div key={label}>
<div style={{ fontSize: '0.65rem', fontWeight: 600, color: '#94a3b8', textTransform: 'uppercase', letterSpacing: '0.04em' }}>{label}</div>
<div style={{ fontSize: '0.8rem', color: '#374151', marginTop: '0.125rem', wordBreak: 'break-word' }}>{value}</div>
{ label: 'Address', value: m.customerAddress },
{ label: 'City', value: m.customerCity },
{ label: 'Country', value: m.customerCountry },
{ label: 'Postal Code', value: m.customerPostalCode },
{ label: 'Persona', value: m.persona },
{ label: 'Color', value: m.color },
].map(({ label, value }) => value ? (
<div key={label}>
<div style={{ fontSize: '0.63rem', fontWeight: 600, color: '#94a3b8', textTransform: 'uppercase', letterSpacing: '0.04em' }}>{label}</div>
<div style={{ fontSize: '0.8rem', color: '#374151', marginTop: '0.1rem', wordBreak: 'break-word', display: 'flex', alignItems: 'center', gap: '0.375rem' }}>
{label === 'Color' && (
<span style={{ display: 'inline-block', width: 12, height: 12, borderRadius: 3, backgroundColor: value, border: '1px solid rgba(0,0,0,0.12)', flexShrink: 0 }} />
)}
{value}
</div>
) : null
)}
</div>
) : null)}
</div>
{/* Robot snapshot */}
{snapshot === 'loading' && (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(248,248,246,0.8)', borderRadius: '0.5rem', minHeight: 120, fontSize: '0.75rem', color: '#94a3b8' }}>Loading image…</div>
)}
{snapshot && snapshot !== 'loading' && snapshot !== 'none' && (
<div>
<div style={{ fontSize: '0.63rem', fontWeight: 600, color: '#94a3b8', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '0.375rem' }}>Robot Configuration</div>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={snapshot}
alt="Robot configuration snapshot"
style={{ width: '100%', borderRadius: '0.5rem', border: '1px solid rgba(0,0,0,0.06)', display: 'block' }}
/>
</div>
)}
</div>
)}
</div>