analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1 lines • 5.16 kB
Source Map (JSON)
{"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":[]}