mostly fixed layouts

This commit is contained in:
2026-03-13 18:31:21 -05:00
parent dfc4cccb56
commit c72da2fad5
5 changed files with 391 additions and 263 deletions
+46 -47
View File
@@ -7,6 +7,7 @@ import ItemRow from './ItemRow';
import SubScopeCard from './SubScopeCard';
import NoteEditor from './NoteEditor';
import LazyItem from './LazyItem';
import ScopeScaleWrapper from './ui/ScopeScaleWrapper';
interface ScopeCardProps {
scope: Scope;
@@ -200,49 +201,47 @@ const ScopeCard: Component<ScopeCardProps> = (props) => {
</div>
</Show>
<div
onClick={(e) => { if (e.target === e.currentTarget) props.onClearSelection(); }}
class="relative overflow-x-auto min-w-0"
>
<div class="p-6 space-y-4 min-w-full md:min-w-max flex flex-col items-stretch">
<Show when={scopeItems().length > 0}>
<div class="relative">
{/* Column Headers - Sticky, Square Top */}
<div class="sticky top-0 z-20 bg-background/95 backdrop-blur-sm border-b border-border py-2 mb-2 hidden md:flex items-center gap-4 text-[10px] font-bold text-muted-foreground uppercase tracking-wider px-3 rounded-none">
<div class="w-4 shrink-0"></div> {/* Grip space */}
<div class="flex-1 min-w-[200px]">Description</div>
<div class="w-20 shrink-0 text-right">Qty</div>
<div class="w-24 shrink-0 text-right">Price</div>
<div class="w-24 shrink-0 text-right">Subtotal</div>
<Show when={props.isSidebarCollapsed() || !props.hideColumns}>
<div class="w-32 shrink-0 text-center">Markup</div>
<div class="w-32 shrink-0 text-center">Contingency</div>
</Show>
<div class="w-28 shrink-0 text-right">Total</div>
<div class="w-16 shrink-0"></div> {/* Action space */}
</div>
<ScopeScaleWrapper>
{/* Sticky Column Headers */}
<div class="scope-sticky-header py-2 mb-2 hidden md:flex items-center gap-4 text-[10px] font-bold text-muted-foreground uppercase tracking-wider px-3">
<div class="w-4 shrink-0"></div> {/* Grip space */}
<div class="flex-1 min-w-[200px]">Description</div>
<div class="w-20 shrink-0 text-right">Qty</div>
<div class="w-24 shrink-0 text-right">Price</div>
<div class="w-24 shrink-0 text-right">Subtotal</div>
<Show when={props.isSidebarCollapsed() || !props.hideColumns}>
<div class="w-32 shrink-0 text-center">Markup</div>
<div class="w-32 shrink-0 text-center">Contingency</div>
</Show>
<div class="w-28 shrink-0 text-right">Total</div>
<div class="w-16 shrink-0"></div> {/* Action space */}
</div>
<div class="grid gap-2">
{/* Scope Level Items */}
<For each={props.items.filter(i => !i.subScopeId)}>
{(item) => (
<LazyItem estimatedHeight={60}>
<ItemRow
item={item}
onUpdate={props.onUpdateItem}
onDelete={props.onDeleteItem}
onDragStart={props.onDragStart}
onDuplicateItem={props.onDuplicateItem}
isSidebarCollapsed={props.isSidebarCollapsed}
isSelected={props.selectedIds.includes(item.id)}
anySelected={props.selectedIds.length > 0}
onToggleSelection={props.onToggleSelection}
hideColumns={props.hideColumns}
/>
</LazyItem>
)}
</For>
</div>
{/* Scope-level items */}
<div
onClick={(e) => { if (e.target === e.currentTarget) props.onClearSelection(); }}
class="px-3 pb-3 space-y-2"
>
<Show when={scopeItems().length > 0}>
<div class="grid gap-2">
<For each={props.items.filter(i => !i.subScopeId)}>
{(item) => (
<LazyItem estimatedHeight={60}>
<ItemRow
item={item}
onUpdate={props.onUpdateItem}
onDelete={props.onDeleteItem}
onDragStart={props.onDragStart}
onDuplicateItem={props.onDuplicateItem}
isSidebarCollapsed={props.isSidebarCollapsed}
isSelected={props.selectedIds.includes(item.id)}
anySelected={props.selectedIds.length > 0}
onToggleSelection={props.onToggleSelection}
hideColumns={props.hideColumns}
/>
</LazyItem>
)}
</For>
</div>
</Show>
@@ -252,11 +251,9 @@ const ScopeCard: Component<ScopeCardProps> = (props) => {
</div>
</Show>
</div>
</div>
<div class="p-6 pt-0 space-y-4 relative">
{/* Sub-scopes */}
<div class="space-y-6 pt-4">
{/* Sub-scopes — rendered inside the same scale wrapper so they zoom together */}
<div class="px-3 pb-3 space-y-4">
<For each={props.subScopes}>
{(subScope) => (
<SubScopeCard
@@ -281,9 +278,11 @@ const ScopeCard: Component<ScopeCardProps> = (props) => {
)}
</For>
</div>
</ScopeScaleWrapper>
<div class="p-6 pt-4 space-y-4">
{/* Scope Extras & Totals */}
<div class="mt-8 pt-6 border-t border-border space-y-3">
<div class="mt-4 pt-6 border-t border-border space-y-3">
{/* Management Line */}
<div class="flex items-center justify-between group">
<div class="flex items-center gap-3">