conversion astryx
This commit is contained in:
121
src/components/spike/ConsoleUiProbe.tsx
Normal file
121
src/components/spike/ConsoleUiProbe.tsx
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* PHASE 3 verification harness — THROWAWAY, delete with the spike folder.
|
||||
*
|
||||
* The ten screens that consume consoleUi sit behind a login, so this renders
|
||||
* the seven rewritten primitives directly with stand-in data. It imports them
|
||||
* by their original names through the original module path, which is the point:
|
||||
* if these render, the adapters are signature-compatible.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Card,
|
||||
FilterBar,
|
||||
TableShell,
|
||||
Skeleton,
|
||||
Tooltip,
|
||||
LiveStatus,
|
||||
SlideDrawer,
|
||||
Pill,
|
||||
StatusChip,
|
||||
MetricPill,
|
||||
StampCell,
|
||||
SearchPill,
|
||||
KpiStrip,
|
||||
ORDER_STATUS,
|
||||
DELIVERY_STATUS,
|
||||
statusColor,
|
||||
BRAND,
|
||||
} from '../consoleUi';
|
||||
import { Package } from 'lucide-react';
|
||||
import { ConfirmModal } from '../ConfirmModal';
|
||||
import { useNotify } from '../Toasts';
|
||||
|
||||
export default function ConsoleUiProbe() {
|
||||
const { notifyOk, notifyFail } = useNotify();
|
||||
const [confirm, setConfirm] = useState(false);
|
||||
const [drawer, setDrawer] = useState(false);
|
||||
const [q, setQ] = useState('');
|
||||
const [tab, setTab] = useState('pending');
|
||||
|
||||
return (
|
||||
<div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20 }}>
|
||||
<h2 className="text-xl font-extrabold">consoleUi — Phase 3 adapters</h2>
|
||||
|
||||
<KpiStrip
|
||||
items={[
|
||||
{ label: 'Orders', value: '1,248', color: BRAND, icon: <Package /> },
|
||||
{ label: 'Delivered', value: '1,102', color: '#10b981', icon: <Package />, badge: '88%' },
|
||||
{ label: 'Pending', value: '94', color: '#f59e0b', icon: <Package /> },
|
||||
{ label: 'Cancelled', value: '52', color: '#ef4444', icon: <Package /> },
|
||||
]}
|
||||
/>
|
||||
|
||||
<FilterBar>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<LiveStatus state="live" label="Live" />
|
||||
<LiveStatus state="loading" label="Syncing" />
|
||||
<LiveStatus state="error" label="Failed" />
|
||||
<div className="w-64"><SearchPill value={q} onChange={setQ} placeholder="Search orders…" /></div>
|
||||
{['pending', 'confirmed', 'delivered', 'cancelled'].map((s) => (
|
||||
<Pill key={s} active={tab === s} color={statusColor(ORDER_STATUS, s)} onClick={() => setTab(s)} count={12}>
|
||||
{s}
|
||||
</Pill>
|
||||
))}
|
||||
<Tooltip content="Astryx tooltip — now opens on keyboard focus too.">
|
||||
<span className="text-xs font-bold underline decoration-dotted">hover me</span>
|
||||
</Tooltip>
|
||||
<button className="text-xs font-bold underline" onClick={() => setDrawer(true)}>open drawer</button>
|
||||
</div>
|
||||
</FilterBar>
|
||||
|
||||
<TableShell head={['Order', 'Status', 'Distance', 'Amount', 'Placed']} minWidth={720}>
|
||||
{[
|
||||
{ id: '#1043', s: 'delivered', km: '4.2', amt: '₹248' },
|
||||
{ id: '#1041', s: 'cancelled', km: '1.1', amt: '₹89' },
|
||||
{ id: '#1040', s: 'pending', km: '7.8', amt: '₹156' },
|
||||
].map((r) => (
|
||||
<tr key={r.id}>
|
||||
<td className="px-4 py-3 font-bold">{r.id}</td>
|
||||
<td className="px-4 py-3"><StatusChip label={r.s} color={statusColor(ORDER_STATUS, r.s)} /></td>
|
||||
<td className="px-4 py-3 text-right"><MetricPill color={statusColor(DELIVERY_STATUS, 'active')}>{r.km} km</MetricPill></td>
|
||||
<td className="px-4 py-3 text-right font-mono font-bold">{r.amt}</td>
|
||||
<td className="px-4 py-3 text-right"><StampCell date="12 Aug" time="10:42" /></td>
|
||||
</tr>
|
||||
))}
|
||||
</TableShell>
|
||||
|
||||
<Card className="p-4">
|
||||
<div className="text-xs font-bold mb-2">Skeletons</div>
|
||||
<div className="flex gap-2">
|
||||
<Skeleton className="h-4 w-24" />
|
||||
<Skeleton className="h-4 w-40" />
|
||||
<Skeleton className="h-4 w-16" />
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="p-4">
|
||||
<div className="text-xs font-bold mb-2">Phase 5 — overlays & toasts</div>
|
||||
<div className="flex gap-3">
|
||||
<button className="text-xs font-bold underline" onClick={() => setConfirm(true)}>open confirm dialog</button>
|
||||
<button className="text-xs font-bold underline" onClick={() => notifyOk('Published to all outlets')}>toast: ok</button>
|
||||
<button className="text-xs font-bold underline" onClick={() => notifyFail(new Error('Set a price before publishing.'))}>toast: error</button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<ConfirmModal
|
||||
isOpen={confirm}
|
||||
title="Unpublish product"
|
||||
message="This removes it from every outlet under the tenant. Stock and history are kept."
|
||||
confirmText="Unpublish"
|
||||
isDestructive
|
||||
onConfirm={() => { setConfirm(false); notifyOk('Unpublished from 3 outlets'); }}
|
||||
onCancel={() => setConfirm(false)}
|
||||
/>
|
||||
|
||||
<SlideDrawer isOpen={drawer} onClose={() => setDrawer(false)} title="Order #1043">
|
||||
<p className="text-sm">Escape should close this, and focus should return to the button that opened it.</p>
|
||||
</SlideDrawer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user