{"version":3,"sources":["../src/components/shared/ReportLayout.tsx","../src/components/shared/ReportGridUtils.ts"],"sourcesContent":["import { type HTMLAttributes, type ReactNode, useState } from 'react';\nimport Menu, { MenuContent, MenuItem } from '../Menu/Menu';\nimport { cn } from '../../utils/utils';\nimport { getGridColumnsClass } from './ReportGridUtils';\n\n/**\n * Base tab shape for the generic ReportLayout.\n * Specific reports extend this with their own card type.\n */\nexport interface ReportLayoutTab<TCard extends { id: string }> {\n  value: string;\n  label: string;\n  icon?: ReactNode;\n  cards: TCard[];\n}\n\n/**\n * Props for the ReportLayout component.\n */\nexport interface ReportLayoutProps<\n  TCard extends { id: string },\n> extends HTMLAttributes<HTMLDivElement> {\n  /** Tab configurations */\n  tabs: ReportLayoutTab<TCard>[];\n  /** Default active tab value */\n  defaultTab?: string;\n  /** Controlled active tab value */\n  activeTab?: string;\n  /** Callback when active tab changes */\n  onTabChange?: (value: string) => void;\n  /** Render function for each card */\n  renderCard: (card: TCard) => ReactNode;\n  /** data-testid for the cards grid container */\n  gridTestId?: string;\n}\n\n/**\n * Generic tabbed report layout shared between TimeReport and PerformanceReport.\n * Handles controlled/uncontrolled tab state, tab navigation, and responsive card grid.\n */\nexport const ReportLayout = <TCard extends { id: string }>({\n  tabs,\n  defaultTab,\n  activeTab: controlledTab,\n  onTabChange,\n  renderCard,\n  gridTestId,\n  className,\n  ...props\n}: ReportLayoutProps<TCard>) => {\n  const firstTabValue = tabs[0]?.value ?? '';\n  const [internalTab, setInternalTab] = useState(defaultTab ?? firstTabValue);\n\n  const isControlled = controlledTab !== undefined;\n  const activeTabValue = isControlled ? controlledTab : internalTab;\n  const activeTabData = tabs.find((t) => t.value === activeTabValue);\n  const cards = activeTabData?.cards ?? [];\n\n  const handleTabChange = (value: string) => {\n    if (!isControlled) {\n      setInternalTab(value);\n    }\n    onTabChange?.(value);\n  };\n\n  if (tabs.length === 0) {\n    return null;\n  }\n\n  return (\n    <div className={cn('flex flex-col gap-4', className)} {...props}>\n      {/* Tab Navigation */}\n      {tabs.length > 1 && (\n        <Menu\n          defaultValue={defaultTab ?? firstTabValue}\n          value={controlledTab}\n          variant=\"menu2\"\n          onValueChange={handleTabChange}\n        >\n          <MenuContent variant=\"menu2\">\n            {tabs.map((tab) => (\n              <MenuItem\n                key={tab.value}\n                value={tab.value}\n                variant=\"menu-overflow\"\n                className=\"!text-sm !leading-[100%] !tracking-[0.2px]\"\n              >\n                {tab.icon && (\n                  <span className=\"[&>svg]:w-[21px] [&>svg]:h-[21px]\">\n                    {tab.icon}\n                  </span>\n                )}\n                {tab.label}\n              </MenuItem>\n            ))}\n          </MenuContent>\n        </Menu>\n      )}\n\n      {/* Cards Grid */}\n      <div\n        className={cn(\n          'grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4',\n          getGridColumnsClass(cards.length)\n        )}\n        data-testid={gridTestId}\n      >\n        {cards.map((card) => renderCard(card))}\n      </div>\n    </div>\n  );\n};\n","/**\n * Get responsive grid columns class based on item count.\n * Shared between TimeReport and PerformanceReport.\n */\nexport const getGridColumnsClass = (count: number): string => {\n  if (count >= 5) return 'lg:grid-cols-5';\n  if (count === 4) return 'lg:grid-cols-4';\n  if (count === 3) return 'lg:grid-cols-3';\n  if (count === 2) return 'lg:grid-cols-2';\n  return '';\n};\n"],"mappings":";;;;;;;;;;AAAA,SAA8C,gBAAgB;;;ACIvD,IAAM,sBAAsB,CAAC,UAA0B;AAC5D,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI,UAAU,EAAG,QAAO;AACxB,MAAI,UAAU,EAAG,QAAO;AACxB,MAAI,UAAU,EAAG,QAAO;AACxB,SAAO;AACT;;;ADuEc,SAOI,KAPJ;AAzCP,IAAM,eAAe,CAA+B;AAAA,EACzD;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAgC;AAC9B,QAAM,gBAAgB,KAAK,CAAC,GAAG,SAAS;AACxC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,cAAc,aAAa;AAE1E,QAAM,eAAe,kBAAkB;AACvC,QAAM,iBAAiB,eAAe,gBAAgB;AACtD,QAAM,gBAAgB,KAAK,KAAK,CAAC,MAAM,EAAE,UAAU,cAAc;AACjE,QAAM,QAAQ,eAAe,SAAS,CAAC;AAEvC,QAAM,kBAAkB,CAAC,UAAkB;AACzC,QAAI,CAAC,cAAc;AACjB,qBAAe,KAAK;AAAA,IACtB;AACA,kBAAc,KAAK;AAAA,EACrB;AAEA,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO;AAAA,EACT;AAEA,SACE,qBAAC,SAAI,WAAW,GAAG,uBAAuB,SAAS,GAAI,GAAG,OAEvD;AAAA,SAAK,SAAS,KACb;AAAA,MAAC;AAAA;AAAA,QACC,cAAc,cAAc;AAAA,QAC5B,OAAO;AAAA,QACP,SAAQ;AAAA,QACR,eAAe;AAAA,QAEf,8BAAC,eAAY,SAAQ,SAClB,eAAK,IAAI,CAAC,QACT;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO,IAAI;AAAA,YACX,SAAQ;AAAA,YACR,WAAU;AAAA,YAET;AAAA,kBAAI,QACH,oBAAC,UAAK,WAAU,qCACb,cAAI,MACP;AAAA,cAED,IAAI;AAAA;AAAA;AAAA,UAVA,IAAI;AAAA,QAWX,CACD,GACH;AAAA;AAAA,IACF;AAAA,IAIF;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,oBAAoB,MAAM,MAAM;AAAA,QAClC;AAAA,QACA,eAAa;AAAA,QAEZ,gBAAM,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC;AAAA;AAAA,IACvC;AAAA,KACF;AAEJ;","names":[]}