Files
fourge-portal/src/components/InvoiceDetailPopup.jsx
T
Krao Hasanee c91e292066 redesign: Layout2 design-system + dashboard/tasks rework + perf
Design system (Layout2):
- Solid token-driven theme (no animated grid); single-source tokens for bg,
  cards (bg/border/radius), popups, fonts (Inter), and full semantic +
  data-viz color palette. Swept ~168 hardcoded colors to tokens.

Dashboard:
- Reflow: To Do + Calendar row (fixed right rail) over Activity / In-Progress /
  Team Performance; CSS height-match (To Do = Calendar); responsive stacking.
- 'Tasks Not Started' -> 'To Do' card with R#/Assigned columns; compact money fmt.

Tasks page:
- Combined tabs into Tasks + Completed with a Status column.
- Column-header sort + filter (Status, R#/new-vs-revision, Project, Task Type,
  Company) via portaled, scrollable FilterDropdown; removed toolbar filters and
  the projects side panel; headers stay visible when empty; renamed to 'Tasks'.

Perf:
- FK/filter index migration; removed redundant client/external scope waterfall
  (rely on RLS); parallel follow-up queries.

Mobile:
- Responsive grids; mobile topbar = hamburger only, blends with bg, proper offset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 10:08:40 -04:00

79 lines
2.9 KiB
React

import { popupOverlayStyle, popupSurfaceStyle } from '../lib/popupStyles';
import PageLoader from './PageLoader';
export const POPUP_FIELD_LABEL = {
fontSize: 11,
fontWeight: 500,
color: 'var(--text-secondary)',
textTransform: 'uppercase',
letterSpacing: 0.8,
display: 'block',
marginBottom: 4,
};
export default function InvoiceDetailPopup({
title,
subtitle,
headerRight,
onClose,
blockClose = false,
metaContent, // JSX fields rendered in flat meta grid (no cards)
metaActions, // optional JSX rendered right-aligned beside meta grid (e.g. Edit Dates)
metaCols = 4, // number of grid columns for meta strip
footerActions,
loading = false,
children,
}) {
return (
<div style={popupOverlayStyle} onClick={() => { if (!blockClose) onClose?.(); }}>
<div
style={{ ...popupSurfaceStyle, width: '80vw', height: '80vh', display: 'flex', flexDirection: 'column', gap: 0 }}
onClick={e => e.stopPropagation()}
>
{/* Header */}
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16, paddingBottom: 18, borderBottom: '1px solid var(--border)', flexShrink: 0 }}>
<div>
<div style={{ fontSize: 18, fontWeight: 500, color: 'var(--text-primary)', letterSpacing: 0.2, lineHeight: 1.1 }}>{title}</div>
{subtitle && <div style={{ marginTop: 6, fontSize: 13, color: 'var(--text-secondary)' }}>{subtitle}</div>}
</div>
{headerRight && <div style={{ flexShrink: 0 }}>{headerRight}</div>}
</div>
{/* Flat meta strip */}
{metaContent && (
<div style={{ padding: '18px 0', borderBottom: '1px solid var(--border)', flexShrink: 0 }}>
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
<div style={{ display: 'grid', gridTemplateColumns: `repeat(${metaCols}, minmax(0, 1fr))`, gap: '14px 18px', flex: 1 }}>
{metaContent}
</div>
{metaActions && (
<div style={{ flexShrink: 0, display: 'flex', gap: 8, alignItems: 'flex-start' }}>
{metaActions}
</div>
)}
</div>
</div>
)}
{/* Body */}
{loading ? (
<div style={{ flex: 1, minHeight: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<PageLoader />
</div>
) : (
<div className="scrollbar-thin-theme table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto', paddingTop: 18 }}>
{children}
</div>
)}
{/* Footer */}
{footerActions && (
<div className="modal-action-row" style={{ paddingTop: 18, borderTop: '1px solid var(--border)', flexShrink: 0 }}>
{footerActions}
</div>
)}
</div>
</div>
);
}