Layout fixes
This commit is contained in:
@@ -10,7 +10,7 @@ const AppContainer: Component<AppContainerProps> = (props) => {
|
||||
<div class="min-h-screen bg-gray-50/50">
|
||||
{/* Top Navigation Bar */}
|
||||
<header class="bg-white border-b border-gray-200 sticky top-0 z-10 no-print">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-[1800px] w-full mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between h-16">
|
||||
<div class="flex items-center gap-8">
|
||||
<div class="flex-shrink-0 flex items-center">
|
||||
@@ -39,7 +39,7 @@ const AppContainer: Component<AppContainerProps> = (props) => {
|
||||
</header>
|
||||
|
||||
{/* Main Content Area */}
|
||||
<main class="max-w-6xl mx-auto p-4 sm:p-6 lg:p-8">
|
||||
<main class="max-w-[1800px] w-full mx-auto p-4 sm:p-6 lg:p-8">
|
||||
{props.children}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -212,7 +212,7 @@ const EstimateBuilder: Component<EstimateBuilderProps> = (props) => {
|
||||
onAddScope={addScope}
|
||||
/>
|
||||
|
||||
<main onClick={clearSelection} class="flex-1 p-8 bg-zinc-50/50 space-y-8 min-h-screen">
|
||||
<main onClick={clearSelection} class="flex-1 min-w-0 p-4 md:p-8 bg-zinc-50/50 space-y-8 min-h-screen">
|
||||
<ProjectDetailsForm />
|
||||
|
||||
<div class="bg-muted/30 border border-border rounded-3xl p-6 mb-8">
|
||||
|
||||
@@ -70,13 +70,13 @@ const ItemRow: Component<ItemRowProps> = (props) => {
|
||||
e.stopPropagation();
|
||||
props.onToggleSelection(props.item.id, e.metaKey || e.ctrlKey, e.shiftKey);
|
||||
}}
|
||||
class={`cursor-grab transition-colors shrink-0 w-4 mt-2 p-1 -m-1 rounded hover:bg-muted ${props.isSelected ? 'text-primary' : 'text-muted-foreground/30 hover:text-muted-foreground/60'}`}
|
||||
class={`cursor-grab transition-colors shrink-0 w-4 mt-2 p-1 rounded hover:bg-muted ${props.isSelected ? 'text-primary' : 'text-muted-foreground/30 hover:text-muted-foreground/60'}`}
|
||||
title="Drag to move or click to select"
|
||||
>
|
||||
<GripVertical class="w-4 h-4" />
|
||||
</div>
|
||||
|
||||
<div class="flex-1 relative">
|
||||
<div class="flex-1 relative min-w-[200px]">
|
||||
|
||||
<textarea
|
||||
ref={descriptionRef}
|
||||
|
||||
@@ -203,19 +203,21 @@ const ScopeCard: Component<ScopeCardProps> = (props) => {
|
||||
onClick={(e) => { if (e.target === e.currentTarget) props.onClearSelection(); }}
|
||||
class="p-6 space-y-4 relative"
|
||||
>
|
||||
<div class="overflow-x-auto w-full pb-4 -mx-6 px-6">
|
||||
<div class="min-w-[768px]">
|
||||
{/* Column Headers - Sticky, Square Top */}
|
||||
<div class="sticky top-header 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"></div> {/* Grip space */}
|
||||
<div class="flex-1">Description</div>
|
||||
<div class="w-20 text-right">Qty</div>
|
||||
<div class="w-24 text-right">Price</div>
|
||||
<div class="w-24 text-right">Subtotal</div>
|
||||
<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 text-center">Markup</div>
|
||||
<div class="w-32 text-center">Contingency</div>
|
||||
<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 text-right px-2">Total</div>
|
||||
<div class="w-16"></div> {/* Action space */}
|
||||
<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">
|
||||
@@ -244,6 +246,8 @@ const ScopeCard: Component<ScopeCardProps> = (props) => {
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sub-scopes */}
|
||||
<div class="space-y-6 pt-4">
|
||||
|
||||
@@ -164,6 +164,8 @@ const SubScopeCard: Component<SubScopeCardProps> = (props) => {
|
||||
</div>
|
||||
|
||||
<Show when={!isCollapsed()}>
|
||||
<div class="overflow-x-auto w-full pb-2 -mx-2 px-2">
|
||||
<div class="min-w-[768px]">
|
||||
<div
|
||||
onClick={(e) => { if (e.target === e.currentTarget) props.onClearSelection(); }}
|
||||
class="p-2 space-y-1.5"
|
||||
@@ -192,6 +194,8 @@ const SubScopeCard: Component<SubScopeCardProps> = (props) => {
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ export const BuilderHeader: Component<BuilderHeaderProps> = (props) => {
|
||||
const { scopes, estimateItems: items } = appStore;
|
||||
|
||||
return (
|
||||
<div class="h-16 px-6 border-b border-border bg-background/50 flex items-center justify-between sticky top-0 z-50 backdrop-blur-md">
|
||||
<div class="min-h-[4rem] py-3 px-6 border-b border-border bg-background/50 flex flex-wrap gap-y-4 items-center justify-between sticky top-0 z-50 backdrop-blur-md">
|
||||
<div class="flex items-center gap-4">
|
||||
<button
|
||||
onClick={props.onToggleSidebar}
|
||||
@@ -41,7 +41,7 @@ export const BuilderHeader: Component<BuilderHeaderProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<button
|
||||
onClick={props.onAddScope}
|
||||
class="flex items-center gap-2 px-4 py-2 bg-foreground text-background rounded-xl text-sm font-bold hover:bg-foreground/90 transition-all shadow-lg shadow-foreground/10 mr-2"
|
||||
|
||||
@@ -6,7 +6,7 @@ export const ProjectDetailsForm: Component = () => {
|
||||
const { clientInfo, setClientInfo, jobInfo, setJobInfo } = appStore;
|
||||
|
||||
return (
|
||||
<div class="bg-card border border-border rounded-[2.5rem] p-8 shadow-premium transition-all">
|
||||
<div class="bg-card border border-border rounded-[2.5rem] p-6 md:p-8 shadow-premium transition-all w-full max-w-full overflow-hidden">
|
||||
<div class="flex items-center gap-3 text-foreground mb-8">
|
||||
<div class="p-2.5 bg-primary/10 text-primary rounded-2xl shadow-sm">
|
||||
<FolderKanban class="w-5 h-5" />
|
||||
@@ -14,15 +14,15 @@ export const ProjectDetailsForm: Component = () => {
|
||||
<h3 class="font-black text-xl tracking-tight">Client & Project Details</h3>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 lg:gap-x-12 gap-y-8 w-full">
|
||||
<div class="space-y-6">
|
||||
<h4 class="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em] px-1 blur-[0.2px]">Client Information</h4>
|
||||
<div class="grid gap-3">
|
||||
<input type="text" value={clientInfo.name} onInput={(e) => setClientInfo('name', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Client Name" />
|
||||
<input type="text" value={clientInfo.address} onInput={(e) => setClientInfo('address', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Client Address" />
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<input type="text" value={clientInfo.phone} onInput={(e) => setClientInfo('phone', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Phone" />
|
||||
<input type="text" value={clientInfo.fax} onInput={(e) => setClientInfo('fax', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Fax" />
|
||||
<div class="flex flex-col sm:flex-row gap-3">
|
||||
<input type="text" value={clientInfo.phone} onInput={(e) => setClientInfo('phone', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium flex-1 min-w-0" placeholder="Phone" />
|
||||
<input type="text" value={clientInfo.fax} onInput={(e) => setClientInfo('fax', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium flex-1 min-w-0" placeholder="Fax" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -30,9 +30,9 @@ export const ProjectDetailsForm: Component = () => {
|
||||
<div class="space-y-6">
|
||||
<h4 class="text-[10px] font-black text-muted-foreground uppercase tracking-[0.2em] px-1 blur-[0.2px]">Project Information</h4>
|
||||
<div class="grid gap-3">
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<input type="text" value={jobInfo.number} onInput={(e) => setJobInfo('number', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Job Number" />
|
||||
<input type="text" value={jobInfo.name} onInput={(e) => setJobInfo('name', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Job Name" />
|
||||
<div class="flex flex-col sm:flex-row gap-3">
|
||||
<input type="text" value={jobInfo.number} onInput={(e) => setJobInfo('number', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium flex-1 min-w-0" placeholder="Job Number" />
|
||||
<input type="text" value={jobInfo.name} onInput={(e) => setJobInfo('name', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium flex-1 min-w-0" placeholder="Job Name" />
|
||||
</div>
|
||||
<input type="text" value={jobInfo.workOrder} onInput={(e) => setJobInfo('workOrder', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Work Order Number" />
|
||||
<input type="text" value={jobInfo.address} onInput={(e) => setJobInfo('address', e.currentTarget.value)} class="bg-muted/20 border border-border/60 p-3 rounded-2xl text-sm outline-none focus:bg-background focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium" placeholder="Job Site Address" />
|
||||
|
||||
@@ -43,19 +43,21 @@ export const UnassignedItemsSection: Component<UnassignedItemsSectionProps> = (p
|
||||
{props.unassignedItems.length} Items Pending
|
||||
</span>
|
||||
</div>
|
||||
<div class="overflow-x-auto w-full pb-4 -mx-6 px-6">
|
||||
<div class="min-w-[768px]">
|
||||
{/* Sticky Column Headers for Unassigned */}
|
||||
<div class="sticky top-header z-10 bg-background/95 backdrop-blur-sm border-b border-border py-3 mb-4 hidden md:flex items-center gap-4 text-[10px] font-black text-muted-foreground/60 uppercase tracking-[0.2em] px-3">
|
||||
<div class="w-4"></div>
|
||||
<div class="flex-1">Description</div>
|
||||
<div class="w-20 text-right">Qty</div>
|
||||
<div class="w-24 text-right">Unit Price</div>
|
||||
<div class="w-24 text-right">Subtotal</div>
|
||||
<div class="w-4 shrink-0"></div>
|
||||
<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">Unit Price</div>
|
||||
<div class="w-24 shrink-0 text-right">Subtotal</div>
|
||||
<Show when={props.isSidebarCollapsed() || !props.anyDescriptionIsLong()}>
|
||||
<div class="w-32 text-center">Markup</div>
|
||||
<div class="w-32 text-center">Contingency</div>
|
||||
<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 text-right px-2">Total</div>
|
||||
<div class="w-16"></div>
|
||||
<div class="w-28 shrink-0 text-right">Total</div>
|
||||
<div class="w-16 shrink-0"></div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
@@ -79,6 +81,8 @@ export const UnassignedItemsSection: Component<UnassignedItemsSectionProps> = (p
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user