168 lines
5.1 KiB
JavaScript
168 lines
5.1 KiB
JavaScript
// Wrapping screens — phone frame with the grid at each density
|
||
|
||
const { IOSDevice } = window;
|
||
const { TABLES } = window;
|
||
const { Card1x1, Card2x1, Card2x2, Card4x1, Card4x2 } = window.TableCards;
|
||
const { DesignCanvas, DCSection, DCArtboard } = window;
|
||
|
||
// Density specs — each one has a column count, gap, and a card renderer.
|
||
// "1x1" means 4 columns of tiny squares; "4x2" means 1 large card per row.
|
||
//
|
||
// The naming reflects relative density: 1x1 = highest density (smallest cards),
|
||
// 4x2 = lowest density (biggest, most info).
|
||
const DENSITIES = {
|
||
'1x1': {
|
||
label: '1×1 — Highest density',
|
||
desc: 'Just the name. Status as color.',
|
||
cols: 4, gap: 8,
|
||
aspectW: 1, aspectH: 1,
|
||
Card: Card1x1,
|
||
},
|
||
'2x1': {
|
||
label: '2×1 — Compact',
|
||
desc: 'Name + status pill.',
|
||
cols: 2, gap: 10,
|
||
aspectW: 2, aspectH: 1,
|
||
Card: Card2x1,
|
||
},
|
||
'2x2': {
|
||
label: '2×2 — Balanced',
|
||
desc: 'Name, status, amount, waiters.',
|
||
cols: 2, gap: 12,
|
||
aspectW: 1, aspectH: 1,
|
||
Card: Card2x2,
|
||
},
|
||
'4x1': {
|
||
label: '4×1 — Wide row',
|
||
desc: 'Name, amount, status, waiters.',
|
||
cols: 1, gap: 10,
|
||
aspectW: 4, aspectH: 1,
|
||
Card: Card4x1,
|
||
},
|
||
'4x2': {
|
||
label: '4×2 — Full detail',
|
||
desc: 'Everything. Section, badges, waiter names.',
|
||
cols: 1, gap: 12,
|
||
aspectW: 2, aspectH: 1,
|
||
Card: Card4x2,
|
||
},
|
||
};
|
||
|
||
// Top filter bar
|
||
function FilterBar() {
|
||
const filters = [
|
||
{ label: 'All', active: true },
|
||
{ label: 'Mine' },
|
||
{ label: 'Free' },
|
||
{ label: 'Zone (2)' },
|
||
];
|
||
return (
|
||
<div style={{
|
||
padding: '10px 16px 14px',
|
||
background: 'white',
|
||
display: 'flex', gap: 8,
|
||
borderBottom: '1px solid #edeff1',
|
||
}}>
|
||
{filters.map(f => (
|
||
<button key={f.label} style={{
|
||
height: 38, padding: '0 16px',
|
||
borderRadius: 10,
|
||
background: f.active ? '#f5b740' : 'white',
|
||
border: '1.5px solid ' + (f.active ? '#f5b740' : '#dfe2e6'),
|
||
color: f.active ? '#3a2a05' : '#5a6169',
|
||
fontSize: 14, fontWeight: 700,
|
||
fontFamily: 'inherit',
|
||
cursor: 'pointer',
|
||
}}>{f.label}</button>
|
||
))}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function Header({ density }) {
|
||
return (
|
||
<div style={{
|
||
padding: '54px 16px 10px',
|
||
background: 'white',
|
||
display: 'flex', alignItems: 'center', gap: 10,
|
||
}}>
|
||
<div style={{ flex: 1, fontSize: 20, fontWeight: 700, color: '#111315' }}>Tables</div>
|
||
<button style={{
|
||
width: 38, height: 38,
|
||
borderRadius: 19, border: '1px solid #dfe2e6', background: 'white',
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
cursor: 'pointer',
|
||
}}>
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||
<path d="M12 22C13.1 22 14 21.1 14 20H10C10 21.1 10.9 22 12 22ZM18 16V11C18 7.9 16.4 5.4 13.5 4.7V4C13.5 3.2 12.8 2.5 12 2.5C11.2 2.5 10.5 3.2 10.5 4V4.7C7.6 5.4 6 7.9 6 11V16L4 18V19H20V18L18 16Z" stroke="#2b2f33" strokeWidth="1.6"/>
|
||
</svg>
|
||
</button>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 14, fontWeight: 600, color: '#2b2f33' }}>
|
||
dimitris
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6 9L12 15L18 9" stroke="#5a6169" strokeWidth="2"/></svg>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function DensityScreen({ densityKey }) {
|
||
const d = DENSITIES[densityKey];
|
||
// Compute card width: phone interior is ~370px wide, padding 12px each side
|
||
const padding = 12;
|
||
const innerW = 370 - padding * 2;
|
||
const cardW = (innerW - d.gap * (d.cols - 1)) / d.cols;
|
||
const cardH = cardW * (d.aspectH / d.aspectW);
|
||
|
||
return (
|
||
<div style={{
|
||
width: '100%', height: '100%',
|
||
background: '#f4f4f2',
|
||
display: 'flex', flexDirection: 'column',
|
||
overflow: 'hidden',
|
||
}}>
|
||
<Header density={d.label} />
|
||
<FilterBar />
|
||
<div style={{ flex: 1, overflowY: 'auto', padding: padding }}>
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: `repeat(${d.cols}, 1fr)`,
|
||
gap: d.gap,
|
||
}}>
|
||
{TABLES.map(t => (
|
||
<d.Card key={t.name} table={t} w={cardW} h={cardH} />
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function App() {
|
||
const order = ['1x1', '2x1', '2x2', '4x1', '4x2'];
|
||
return (
|
||
<DesignCanvas title="Table grid — 5 density options">
|
||
<DCSection id="densities" title="Density variants — selectable in user settings">
|
||
{order.map(k => {
|
||
const d = DENSITIES[k];
|
||
return (
|
||
<DCArtboard key={k} id={k} label={d.label + ' — ' + d.desc} width={460} height={920}>
|
||
<div style={{
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
width: '100%', height: '100%',
|
||
background: 'transparent',
|
||
}}>
|
||
<IOSDevice>
|
||
<DensityScreen densityKey={k} />
|
||
</IOSDevice>
|
||
</div>
|
||
</DCArtboard>
|
||
);
|
||
})}
|
||
</DCSection>
|
||
</DesignCanvas>
|
||
);
|
||
}
|
||
|
||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||
root.render(<App />);
|