@fayz-ai/plugin-reports 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +4 -4
  2. package/dist/{chunk-LODXZ2SC.js → chunk-2ZFN6ECM.js} +3 -3
  3. package/dist/chunk-2ZFN6ECM.js.map +1 -0
  4. package/dist/data/aggregate.d.ts +14 -0
  5. package/dist/data/aggregate.d.ts.map +1 -0
  6. package/dist/data/analytics-mock.d.ts +3 -0
  7. package/dist/data/analytics-mock.d.ts.map +1 -0
  8. package/dist/data/analytics-supabase.d.ts +7 -0
  9. package/dist/data/analytics-supabase.d.ts.map +1 -0
  10. package/dist/{excel-QHUSM6IH.js → excel-WE73YE2V.js} +3 -3
  11. package/dist/{excel-QHUSM6IH.js.map → excel-WE73YE2V.js.map} +1 -1
  12. package/dist/index.d.ts +73 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1207 -654
  15. package/dist/index.js.map +1 -1
  16. package/dist/lib/lastViewed.d.ts +5 -0
  17. package/dist/lib/lastViewed.d.ts.map +1 -0
  18. package/dist/lib/legacy.d.ts +5 -0
  19. package/dist/lib/legacy.d.ts.map +1 -0
  20. package/dist/lib/tenant.d.ts +1 -0
  21. package/dist/lib/tenant.d.ts.map +1 -1
  22. package/dist/locales/en.d.ts.map +1 -1
  23. package/dist/locales/pt-BR.d.ts.map +1 -1
  24. package/dist/{pdf-HETKN26Y.js → pdf-E6DXHFXU.js} +3 -3
  25. package/dist/{pdf-HETKN26Y.js.map → pdf-E6DXHFXU.js.map} +1 -1
  26. package/dist/views/AnalyticsModule.d.ts +10 -0
  27. package/dist/views/AnalyticsModule.d.ts.map +1 -0
  28. package/dist/views/AnalyticsOverview.d.ts +3 -0
  29. package/dist/views/AnalyticsOverview.d.ts.map +1 -0
  30. package/dist/views/AnalyticsReportViewer.d.ts +5 -0
  31. package/dist/views/AnalyticsReportViewer.d.ts.map +1 -0
  32. package/dist/views/AnalyticsSurface.d.ts +97 -0
  33. package/dist/views/AnalyticsSurface.d.ts.map +1 -0
  34. package/dist/views/LiveViewPage.d.ts +3 -0
  35. package/dist/views/LiveViewPage.d.ts.map +1 -0
  36. package/dist/views/ReportsListPage.d.ts +3 -0
  37. package/dist/views/ReportsListPage.d.ts.map +1 -0
  38. package/package.json +5 -7
  39. package/dist/ReportsContext.d.ts +0 -16
  40. package/dist/ReportsContext.d.ts.map +0 -1
  41. package/dist/ReportsPage.d.ts +0 -8
  42. package/dist/ReportsPage.d.ts.map +0 -1
  43. package/dist/chunk-LODXZ2SC.js.map +0 -1
  44. package/dist/components/ReportCard.d.ts +0 -9
  45. package/dist/components/ReportCard.d.ts.map +0 -1
  46. package/dist/components/ReportFilterBar.d.ts +0 -12
  47. package/dist/components/ReportFilterBar.d.ts.map +0 -1
  48. package/dist/components/ReportSummaryRow.d.ts +0 -10
  49. package/dist/components/ReportSummaryRow.d.ts.map +0 -1
  50. package/dist/hooks/useReportData.d.ts +0 -19
  51. package/dist/hooks/useReportData.d.ts.map +0 -1
  52. package/dist/views/ReportHub.d.ts +0 -8
  53. package/dist/views/ReportHub.d.ts.map +0 -1
  54. package/dist/views/ReportViewer.d.ts +0 -9
  55. package/dist/views/ReportViewer.d.ts.map +0 -1
  56. package/src/ReportsContext.tsx +0 -33
  57. package/src/ReportsPage.tsx +0 -62
  58. package/src/components/ExportDropdown.tsx +0 -63
  59. package/src/components/ReportCard.tsx +0 -38
  60. package/src/components/ReportFilterBar.tsx +0 -132
  61. package/src/components/ReportPagination.tsx +0 -59
  62. package/src/components/ReportSummaryRow.tsx +0 -68
  63. package/src/data/index.ts +0 -4
  64. package/src/data/mock.ts +0 -9
  65. package/src/data/supabase.ts +0 -200
  66. package/src/data/types.ts +0 -10
  67. package/src/export/csv.ts +0 -21
  68. package/src/export/excel.ts +0 -42
  69. package/src/export/pdf.ts +0 -47
  70. package/src/hooks/useReportData.ts +0 -123
  71. package/src/index.ts +0 -142
  72. package/src/lib/columns.ts +0 -130
  73. package/src/lib/tenant.ts +0 -3
  74. package/src/locales/en.ts +0 -28
  75. package/src/locales/index.ts +0 -7
  76. package/src/locales/pt-BR.ts +0 -28
  77. package/src/types.ts +0 -171
  78. package/src/views/ReportHub.tsx +0 -97
  79. package/src/views/ReportViewer.tsx +0 -182
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy.d.ts","sourceRoot":"","sources":["../../src/lib/legacy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA0C,MAAM,eAAe,CAAA;AAC7F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAgBzC,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAkDvF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAE9F"}
@@ -1,3 +1,4 @@
1
+ /** Pin the surface to a tenant, overriding the active organization. */
1
2
  export declare function setReportsTenantId(id: string | undefined): void;
2
3
  export declare function getReportsTenantId(): string | undefined;
3
4
  //# sourceMappingURL=tenant.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/lib/tenant.ts"],"names":[],"mappings":"AACA,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,QAAW;AACpE,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAAa"}
1
+ {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/lib/tenant.ts"],"names":[],"mappings":"AAeA,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE/D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CASvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2BrC,CAAA"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAwCrC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"pt-BR.d.ts","sourceRoot":"","sources":["../../src/locales/pt-BR.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2BvC,CAAA"}
1
+ {"version":3,"file":"pt-BR.d.ts","sourceRoot":"","sources":["../../src/locales/pt-BR.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAqCvC,CAAA"}
@@ -1,4 +1,4 @@
1
- import { formatValuePlain } from './chunk-LODXZ2SC.js';
1
+ import { formatValuePlain } from './chunk-2ZFN6ECM.js';
2
2
 
3
3
  // src/export/pdf.ts
4
4
  var load = (m) => new Function("m", "return import(m)")(m);
@@ -33,5 +33,5 @@ async function isPdfAvailable() {
33
33
  }
34
34
 
35
35
  export { exportToPdf, isPdfAvailable };
36
- //# sourceMappingURL=pdf-HETKN26Y.js.map
37
- //# sourceMappingURL=pdf-HETKN26Y.js.map
36
+ //# sourceMappingURL=pdf-E6DXHFXU.js.map
37
+ //# sourceMappingURL=pdf-E6DXHFXU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/export/pdf.ts"],"names":[],"mappings":";;;AAKA,IAAM,IAAA,GAAO,CAAC,CAAA,KAAc,IAAI,SAAS,GAAA,EAAK,kBAAkB,EAAE,CAAC,CAAA;AAEnE,eAAsB,WAAA,CACpB,OAAA,EACA,IAAA,EACA,QAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,KAAK,OAAO,CAAA;AAC7C,EAAA,MAAM,KAAK,iBAAiB,CAAA;AAE5B,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,KAAK,CAAA;AAE7D,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,EAAE,WAAA,EAAa,YAAY,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,UAAA,EAAY,CAAA;AAExF,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,GAAA,CAAI,YAAY,EAAE,CAAA;AAClB,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAA,EAAI,EAAE,CAAA;AAAA,EAChC;AAEC,EAAC,IAAY,SAAA,CAAU;AAAA,IACtB,MAAA,EAAQ,OAAA,EAAS,KAAA,GAAQ,EAAA,GAAK,EAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,IACtC,MAAM,IAAA,CAAK,GAAA;AAAA,MAAI,CAAC,GAAA,KACd,WAAA,CAAY,GAAA,CAAI,CAAC,GAAA,KAAQ,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,EAAG,GAAA,EAAK,OAAA,EAAS,QAAQ,CAAC;AAAA,KACjF;AAAA,IACA,MAAA,EAAQ,EAAE,QAAA,EAAU,CAAA,EAAE;AAAA,IACtB,YAAY,EAAE,SAAA,EAAW,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAAE,GAC1C,CAAA;AAED,EAAA,GAAA,CAAI,IAAA,CAAK,CAAA,EAAG,QAAQ,CAAA,IAAA,CAAM,CAAA;AAC5B;AAEA,eAAsB,cAAA,GAAmC;AACvD,EAAA,IAAI;AACF,IAAA,MAAM,KAAK,OAAO,CAAA;AAClB,IAAA,MAAM,KAAK,iBAAiB,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"pdf-HETKN26Y.js","sourcesContent":["import type { ReportColumnDef } from '../types'\nimport { formatValuePlain } from '../lib/columns'\n\n// Opaque dynamic import — hidden from Vite's static analysis so it won't\n// fail when jspdf is not installed (it's an optional peer dependency).\nconst load = (m: string) => new Function('m', 'return import(m)')(m) as Promise<any>\n\nexport async function exportToPdf(\n columns: ReportColumnDef[],\n data: Record<string, any>[],\n filename: string,\n options?: { title?: string; currency?: string },\n): Promise<void> {\n const { default: jsPDF } = await load('jspdf')\n await load('jspdf-autotable')\n\n const visibleCols = columns.filter((c) => c.visible !== false)\n\n const doc = new jsPDF({ orientation: visibleCols.length > 6 ? 'landscape' : 'portrait' })\n\n if (options?.title) {\n doc.setFontSize(14)\n doc.text(options.title, 14, 20)\n }\n\n ;(doc as any).autoTable({\n startY: options?.title ? 30 : 14,\n head: [visibleCols.map((c) => c.label)],\n body: data.map((row) =>\n visibleCols.map((col) => formatValuePlain(row[col.key], col, options?.currency)),\n ),\n styles: { fontSize: 8 },\n headStyles: { fillColor: [100, 100, 100] },\n })\n\n doc.save(`${filename}.pdf`)\n}\n\nexport async function isPdfAvailable(): Promise<boolean> {\n try {\n await load('jspdf')\n await load('jspdf-autotable')\n return true\n } catch {\n return false\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/export/pdf.ts"],"names":[],"mappings":";;;AAKA,IAAM,IAAA,GAAO,CAAC,CAAA,KAAc,IAAI,SAAS,GAAA,EAAK,kBAAkB,EAAE,CAAC,CAAA;AAEnE,eAAsB,WAAA,CACpB,OAAA,EACA,IAAA,EACA,QAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,KAAK,OAAO,CAAA;AAC7C,EAAA,MAAM,KAAK,iBAAiB,CAAA;AAE5B,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,KAAK,CAAA;AAE7D,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,EAAE,WAAA,EAAa,YAAY,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,UAAA,EAAY,CAAA;AAExF,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,GAAA,CAAI,YAAY,EAAE,CAAA;AAClB,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAA,EAAI,EAAE,CAAA;AAAA,EAChC;AAEC,EAAC,IAAY,SAAA,CAAU;AAAA,IACtB,MAAA,EAAQ,OAAA,EAAS,KAAA,GAAQ,EAAA,GAAK,EAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,IACtC,MAAM,IAAA,CAAK,GAAA;AAAA,MAAI,CAAC,GAAA,KACd,WAAA,CAAY,GAAA,CAAI,CAAC,GAAA,KAAQ,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,EAAG,GAAA,EAAK,OAAA,EAAS,QAAQ,CAAC;AAAA,KACjF;AAAA,IACA,MAAA,EAAQ,EAAE,QAAA,EAAU,CAAA,EAAE;AAAA,IACtB,YAAY,EAAE,SAAA,EAAW,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAAE,GAC1C,CAAA;AAED,EAAA,GAAA,CAAI,IAAA,CAAK,CAAA,EAAG,QAAQ,CAAA,IAAA,CAAM,CAAA;AAC5B;AAEA,eAAsB,cAAA,GAAmC;AACvD,EAAA,IAAI;AACF,IAAA,MAAM,KAAK,OAAO,CAAA;AAClB,IAAA,MAAM,KAAK,iBAAiB,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"pdf-E6DXHFXU.js","sourcesContent":["import type { ReportColumnDef } from '../types'\nimport { formatValuePlain } from '../lib/columns'\n\n// Opaque dynamic import — hidden from Vite's static analysis so it won't\n// fail when jspdf is not installed (it's an optional peer dependency).\nconst load = (m: string) => new Function('m', 'return import(m)')(m) as Promise<any>\n\nexport async function exportToPdf(\n columns: ReportColumnDef[],\n data: Record<string, any>[],\n filename: string,\n options?: { title?: string; currency?: string },\n): Promise<void> {\n const { default: jsPDF } = await load('jspdf')\n await load('jspdf-autotable')\n\n const visibleCols = columns.filter((c) => c.visible !== false)\n\n const doc = new jsPDF({ orientation: visibleCols.length > 6 ? 'landscape' : 'portrait' })\n\n if (options?.title) {\n doc.setFontSize(14)\n doc.text(options.title, 14, 20)\n }\n\n ;(doc as any).autoTable({\n startY: options?.title ? 30 : 14,\n head: [visibleCols.map((c) => c.label)],\n body: data.map((row) =>\n visibleCols.map((col) => formatValuePlain(row[col.key], col, options?.currency)),\n ),\n styles: { fontSize: 8 },\n headStyles: { fillColor: [100, 100, 100] },\n })\n\n doc.save(`${filename}.pdf`)\n}\n\nexport async function isPdfAvailable(): Promise<boolean> {\n try {\n await load('jspdf')\n await load('jspdf-autotable')\n return true\n } catch {\n return false\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ export type AnalyticsView = 'overview' | 'reports' | 'report' | 'live';
3
+ export interface AnalyticsModuleProps {
4
+ view: AnalyticsView;
5
+ /** Route param when `view === 'report'` — marks the active entry. */
6
+ cardId?: string;
7
+ children?: React.ReactNode;
8
+ }
9
+ export declare function AnalyticsModule({ view, cardId, children }: AnalyticsModuleProps): React.JSX.Element;
10
+ //# sourceMappingURL=AnalyticsModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsModule.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsModule.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AA8BzB,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEtE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,aAAa,CAAA;IACnB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAuCD,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,oBAAoB,qBAuE/E"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare function AnalyticsOverview(): React.JSX.Element;
3
+ //# sourceMappingURL=AnalyticsOverview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsOverview.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsOverview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAgBzB,wBAAgB,iBAAiB,sBA4DhC"}
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export declare function AnalyticsReportViewer({ cardId }: {
3
+ cardId?: string;
4
+ }): React.JSX.Element;
5
+ //# sourceMappingURL=AnalyticsReportViewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsReportViewer.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsReportViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAwGzB,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,qBA8CpE"}
@@ -0,0 +1,97 @@
1
+ import React from 'react';
2
+ import { type AnalyticsCardDef, type AnalyticsProvider as AnalyticsProviderType, type AnalyticsColumnDef, type AnalyticsCompare } from '@fayz-ai/core';
3
+ import { type AnalyticsRangePreset } from '@fayz-ai/ui';
4
+ export declare const ANALYTICS_BASE = "/analytics";
5
+ export declare const REPORTS_BASE = "/analytics/reports";
6
+ export interface AnalyticsLabels {
7
+ analytics: string;
8
+ reports: string;
9
+ liveView: string;
10
+ /** Rail entry for the card grid. Falls back to the `reports.overview` key. */
11
+ overview?: string;
12
+ overviewSubtitle: string;
13
+ reportsSubtitle: string;
14
+ searchReports: string;
15
+ category: string;
16
+ createdBy: string;
17
+ /** Cleared state of each facet chip: "All categories" / "All authors". */
18
+ allCategories: string;
19
+ allCreatedBy: string;
20
+ lastViewed: string;
21
+ name: string;
22
+ noResults: string;
23
+ never: string;
24
+ back: string;
25
+ export: string;
26
+ print: string;
27
+ unavailableTitle: string;
28
+ unavailableDescription: string;
29
+ emptyOverviewTitle: string;
30
+ emptyOverviewDescription: string;
31
+ liveViewSoon: string;
32
+ results: string;
33
+ }
34
+ /** How the assistant introduces itself on the analytics screens. Every field is
35
+ * optional: what is not set falls back to the plugin's own locale strings. */
36
+ export interface AnalyticsAssistantConfig {
37
+ /** Names the assistant here — "Growth Analyst". */
38
+ persona?: string;
39
+ /** Hero headline. `{{name}}` resolves to the signed-in user's first name. */
40
+ headline?: string;
41
+ pitch?: string;
42
+ description?: string;
43
+ placeholder?: string;
44
+ suggestions?: {
45
+ label: string;
46
+ prompt?: string;
47
+ }[];
48
+ }
49
+ export interface ResolvedAnalyticsConfig {
50
+ /** Cards declared by the host app (merged with the plugin registry at render). */
51
+ cards: AnalyticsCardDef[];
52
+ labels: AnalyticsLabels;
53
+ currency: {
54
+ code: string;
55
+ locale: string;
56
+ symbol: string;
57
+ };
58
+ /** Attribution for pre-built cards — the product name, e.g. "FayzShop". */
59
+ createdBy: string;
60
+ defaultPageSize: number;
61
+ showHeader: boolean;
62
+ /** Range the surface opens on. A salon reads 30 days; a school reads a term. */
63
+ defaultRange: AnalyticsRangePreset;
64
+ defaultCompare: AnalyticsCompare;
65
+ /** Whether the Live View entry appears in the module rail. */
66
+ showLiveView: boolean;
67
+ /** `null` mounts no invite — the screen opens on its numbers, not on a
68
+ * conversation. Otherwise: the overrides, over the locale defaults. */
69
+ assistant: AnalyticsAssistantConfig | null;
70
+ }
71
+ export declare function useAnalyticsConfig(): ResolvedAnalyticsConfig;
72
+ /**
73
+ * Every card visible on this surface, registry + app, de-duplicated by id.
74
+ *
75
+ * The app's own definition wins a collision so a host can retune a card the
76
+ * plugin shipped (relabel it, move it off the overview) without forking the
77
+ * plugin — the alternative is apps carrying patched copies of plugin cards.
78
+ */
79
+ export declare function useAnalyticsCards(): AnalyticsCardDef[];
80
+ /** Cards a pack placed on the overview grid, in their declared order. */
81
+ export declare function useOverviewCards(): AnalyticsCardDef[];
82
+ /**
83
+ * Columns for a card's tabular view.
84
+ *
85
+ * An aggregate card has no `columns` of its own — its table IS its dimensions
86
+ * and measures, so deriving them keeps one definition instead of asking every
87
+ * card author to restate the same fields twice and let the two drift.
88
+ */
89
+ export declare function cardColumns(card: AnalyticsCardDef): AnalyticsColumnDef[];
90
+ export declare function navigateAnalytics(path: string): void;
91
+ export interface AnalyticsSurfaceProps {
92
+ config: ResolvedAnalyticsConfig;
93
+ provider: AnalyticsProviderType;
94
+ children?: React.ReactNode;
95
+ }
96
+ export declare function AnalyticsSurface({ config, provider, children }: AnalyticsSurfaceProps): React.JSX.Element;
97
+ //# sourceMappingURL=AnalyticsSurface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsSurface.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsSurface.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare function LiveViewPage(): React.JSX.Element;
3
+ //# sourceMappingURL=LiveViewPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveViewPage.d.ts","sourceRoot":"","sources":["../../src/views/LiveViewPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAazB,wBAAgB,YAAY,sBAW3B"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare function ReportsListPage(): React.JSX.Element;
3
+ //# sourceMappingURL=ReportsListPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportsListPage.d.ts","sourceRoot":"","sources":["../../src/views/ReportsListPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAiCzB,wBAAgB,eAAe,sBAmK9B"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "fayz": {
4
4
  "status": "preview"
5
5
  },
6
- "version": "0.9.0",
6
+ "version": "0.10.0",
7
7
  "description": "[experimental] Fayz SDK — plugin-reports plugin",
8
8
  "type": "module",
9
9
  "sideEffects": false,
@@ -12,14 +12,12 @@
12
12
  "types": "./dist/index.d.ts",
13
13
  "exports": {
14
14
  ".": {
15
- "source": "./src/index.ts",
16
15
  "types": "./dist/index.d.ts",
17
16
  "import": "./dist/index.js"
18
17
  }
19
18
  },
20
19
  "files": [
21
- "dist",
22
- "src"
20
+ "dist"
23
21
  ],
24
22
  "peerDependencies": {
25
23
  "react": "^18.0.0 || ^19.0.0",
@@ -29,9 +27,9 @@
29
27
  },
30
28
  "dependencies": {
31
29
  "@tanstack/react-table": "^8.20.0",
32
- "@fayz-ai/core": "^0.9.0",
33
- "@fayz-ai/ui": "^0.9.0",
34
- "@fayz-ai/saas": "^0.9.0"
30
+ "@fayz-ai/core": "^0.11.0",
31
+ "@fayz-ai/ui": "^0.11.0",
32
+ "@fayz-ai/admin": "^0.11.0"
35
33
  },
36
34
  "devDependencies": {
37
35
  "@types/react": "^18.3.0",
@@ -1,16 +0,0 @@
1
- import React from 'react';
2
- import type { ResolvedReportsConfig, ReportDef } from './types';
3
- import type { ReportDataProvider } from './data/types';
4
- interface ReportsContextValue {
5
- config: ResolvedReportsConfig;
6
- provider: ReportDataProvider;
7
- reports: ReportDef[];
8
- }
9
- export declare function useReportsContext(): ReportsContextValue;
10
- export declare function ReportsContextProvider({ config, provider, children, }: {
11
- config: ResolvedReportsConfig;
12
- provider: ReportDataProvider;
13
- children: React.ReactNode;
14
- }): React.JSX.Element;
15
- export {};
16
- //# sourceMappingURL=ReportsContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportsContext.d.ts","sourceRoot":"","sources":["../src/ReportsContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAA;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEtD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,qBAAqB,CAAA;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,OAAO,EAAE,SAAS,EAAE,CAAA;CACrB;AAID,wBAAgB,iBAAiB,IAAI,mBAAmB,CAIvD;AAED,wBAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,qBAAqB,CAAA;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,qBAMA"}
@@ -1,8 +0,0 @@
1
- import React from 'react';
2
- import type { ResolvedReportsConfig } from './types';
3
- import type { ReportDataProvider } from './data/types';
4
- export declare function ReportsPage({ config, provider, }: {
5
- config: ResolvedReportsConfig;
6
- provider: ReportDataProvider;
7
- }): React.JSX.Element;
8
- //# sourceMappingURL=ReportsPage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportsPage.d.ts","sourceRoot":"","sources":["../src/ReportsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAA;AAI/D,OAAO,KAAK,EAAE,qBAAqB,EAAa,MAAM,SAAS,CAAA;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAYtD,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,qBAAqB,CAAA;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;CAC7B,qBAsCA"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/columns.ts"],"names":["formatCurrencyLocale","formatDateLocale","formatDateTimeLocale"],"mappings":"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","file":"chunk-LODXZ2SC.js","sourcesContent":["import React from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport type { ReportColumnDef } from '../types'\nimport { PersonLink } from '@fayz-ai/saas'\nimport {\n formatCurrency as formatCurrencyLocale,\n formatDate as formatDateLocale,\n formatDateTime as formatDateTimeLocale,\n} from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Formatters (mirrors fieldToColumn.tsx logic)\n// ---------------------------------------------------------------------------\n\nfunction formatCurrency(value: any, currency?: string): string {\n const num = typeof value === 'number' ? value : parseFloat(value)\n if (isNaN(num)) return '—'\n return formatCurrencyLocale(num, currency)\n}\n\nfunction formatDate(value: any): string {\n if (!value) return '—'\n return formatDateLocale(value)\n}\n\nfunction formatDateTime(value: any): string {\n if (!value) return '—'\n return formatDateTimeLocale(value)\n}\n\nfunction formatNumber(value: any): string {\n if (value == null) return '—'\n return typeof value === 'number' ? value.toLocaleString() : String(value)\n}\n\n// ---------------------------------------------------------------------------\n// Plain-text formatter for exports\n// ---------------------------------------------------------------------------\n\nexport function formatValuePlain(value: any, col: ReportColumnDef, currency?: string): string {\n if (value == null || value === '') return ''\n switch (col.type) {\n case 'currency':\n return formatCurrency(value, col.currency ?? currency)\n case 'date':\n return formatDate(value)\n case 'datetime':\n return formatDateTime(value)\n case 'number':\n return formatNumber(value)\n case 'boolean':\n return value ? 'Yes' : 'No'\n default:\n return String(value)\n }\n}\n\n// ---------------------------------------------------------------------------\n// ReportColumnDef[] → TanStack ColumnDef[]\n// ---------------------------------------------------------------------------\n\nexport function reportColumnsToTanstack(\n columns: ReportColumnDef[],\n currency?: string,\n): ColumnDef<Record<string, any>>[] {\n return columns\n .filter((c) => c.visible !== false)\n .map((col): ColumnDef<Record<string, any>> => {\n const sortable = col.sortable ?? ['text', 'number', 'currency', 'date', 'datetime', 'email'].includes(col.type)\n const alignRight = col.align === 'right' || (!col.align && (col.type === 'currency' || col.type === 'number'))\n const alignCenter = col.align === 'center'\n\n return {\n accessorKey: col.key,\n header: col.label,\n enableSorting: sortable,\n cell: (ctx) => {\n const value = ctx.getValue()\n const row = ctx.row.original\n\n if (col.renderCell) {\n return col.renderCell(value, row)\n }\n\n if (value == null || value === '') {\n return React.createElement('span', { className: 'text-muted-foreground' }, '—')\n }\n\n let content: React.ReactNode\n switch (col.type) {\n case 'person':\n content = React.createElement(PersonLink, {\n personId: col.idKey ? row[col.idKey] : null,\n name: String(value),\n size: 'sm',\n className: 'text-xs',\n })\n break\n case 'currency':\n content = formatCurrency(value, col.currency ?? currency)\n break\n case 'date':\n content = formatDate(value)\n break\n case 'datetime':\n content = formatDateTime(value)\n break\n case 'boolean':\n content = value\n ? React.createElement('svg', { className: 'h-4 w-4 text-success', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2' },\n React.createElement('polyline', { points: '20 6 9 17 4 12' }),\n )\n : React.createElement('span', { className: 'text-muted-foreground' }, '—')\n break\n case 'number':\n content = formatNumber(value)\n break\n default:\n content = String(value)\n }\n\n const cls = alignRight ? 'text-right' : alignCenter ? 'text-center' : undefined\n return cls\n ? React.createElement('div', { className: cls }, content)\n : React.createElement(React.Fragment, null, content)\n },\n meta: { align: alignRight ? 'right' : alignCenter ? 'center' : 'left' },\n }\n })\n}\n"]}
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import type { ReportDef } from '../types';
3
- interface ReportCardProps {
4
- report: ReportDef;
5
- onClick: (report: ReportDef) => void;
6
- }
7
- export declare function ReportCard({ report, onClick }: ReportCardProps): React.JSX.Element;
8
- export {};
9
- //# sourceMappingURL=ReportCard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportCard.d.ts","sourceRoot":"","sources":["../../src/components/ReportCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,eAAe;IACvB,MAAM,EAAE,SAAS,CAAA;IACjB,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;CACrC;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,eAAe,qBA2B9D"}
@@ -1,12 +0,0 @@
1
- import React from 'react';
2
- import type { ReportFilterDef, ReportDateRange } from '../types';
3
- interface ReportFilterBarProps {
4
- dateRange: ReportDateRange;
5
- onDateRangeChange: (range: ReportDateRange) => void;
6
- filters: ReportFilterDef[];
7
- filterValues: Record<string, any>;
8
- onFilterChange: (key: string, value: any) => void;
9
- }
10
- export declare function ReportFilterBar({ dateRange, onDateRangeChange, filters, filterValues, onFilterChange, }: ReportFilterBarProps): React.JSX.Element;
11
- export {};
12
- //# sourceMappingURL=ReportFilterBar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportFilterBar.d.ts","sourceRoot":"","sources":["../../src/components/ReportFilterBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAKlD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAsB,MAAM,UAAU,CAAA;AAEpF,UAAU,oBAAoB;IAC5B,SAAS,EAAE,eAAe,CAAA;IAC1B,iBAAiB,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IACnD,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACjC,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAA;CAClD;AAED,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,YAAY,EACZ,cAAc,GACf,EAAE,oBAAoB,qBAkCtB"}
@@ -1,10 +0,0 @@
1
- import React from 'react';
2
- import type { ReportColumnDef } from '../types';
3
- interface ReportSummaryRowProps {
4
- columns: ReportColumnDef[];
5
- data: Record<string, any>[];
6
- currency?: string;
7
- }
8
- export declare function ReportSummaryRow({ columns, data, currency }: ReportSummaryRowProps): React.JSX.Element | null;
9
- export {};
10
- //# sourceMappingURL=ReportSummaryRow.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportSummaryRow.d.ts","sourceRoot":"","sources":["../../src/components/ReportSummaryRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG/C,UAAU,qBAAqB;IAC7B,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,qBAAqB,4BA+BlF"}
@@ -1,19 +0,0 @@
1
- import type { ReportDef, ReportQueryState, ReportDateRange } from '../types';
2
- import type { ReportDataProvider } from '../data/types';
3
- export interface UseReportDataReturn {
4
- data: Record<string, any>[];
5
- total: number;
6
- loading: boolean;
7
- generated: boolean;
8
- error: string | null;
9
- query: ReportQueryState;
10
- generate: () => void;
11
- setDateRange: (range: ReportDateRange) => void;
12
- setFilter: (key: string, value: any) => void;
13
- setSort: (sortBy: string) => void;
14
- setPage: (page: number) => void;
15
- setPageSize: (size: number) => void;
16
- setSearch: (search: string) => void;
17
- }
18
- export declare function useReportData(report: ReportDef, provider: ReportDataProvider, defaultPageSize?: number): UseReportDataReturn;
19
- //# sourceMappingURL=useReportData.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useReportData.d.ts","sourceRoot":"","sources":["../../src/hooks/useReportData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,eAAe,CAAA;AAkBrE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,EAAE,gBAAgB,CAAA;IACvB,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,YAAY,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IAC9C,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAA;IAC5C,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,kBAAkB,EAC5B,eAAe,GAAE,MAAW,GAC3B,mBAAmB,CAkFrB"}
@@ -1,8 +0,0 @@
1
- import React from 'react';
2
- import type { ReportDef } from '../types';
3
- interface ReportHubProps {
4
- onSelect: (report: ReportDef) => void;
5
- }
6
- export declare function ReportHub({ onSelect }: ReportHubProps): React.JSX.Element;
7
- export {};
8
- //# sourceMappingURL=ReportHub.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportHub.d.ts","sourceRoot":"","sources":["../../src/views/ReportHub.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAMhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,cAAc;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;CACtC;AAOD,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,cAAc,qBA+ErD"}
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import type { ReportDef } from '../types';
3
- interface ReportViewerProps {
4
- report: ReportDef;
5
- onBack: () => void;
6
- }
7
- export declare function ReportViewer({ report, onBack }: ReportViewerProps): React.JSX.Element;
8
- export {};
9
- //# sourceMappingURL=ReportViewer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportViewer.d.ts","sourceRoot":"","sources":["../../src/views/ReportViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAYtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,iBAAiB;IACzB,MAAM,EAAE,SAAS,CAAA;IACjB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,iBAAiB,qBAkKjE"}
@@ -1,33 +0,0 @@
1
- import React, { createContext, useContext } from 'react'
2
- import type { ResolvedReportsConfig, ReportDef } from './types'
3
- import type { ReportDataProvider } from './data/types'
4
-
5
- interface ReportsContextValue {
6
- config: ResolvedReportsConfig
7
- provider: ReportDataProvider
8
- reports: ReportDef[]
9
- }
10
-
11
- const ReportsContext = createContext<ReportsContextValue | null>(null)
12
-
13
- export function useReportsContext(): ReportsContextValue {
14
- const ctx = useContext(ReportsContext)
15
- if (!ctx) throw new Error('useReportsContext must be used within ReportsContextProvider')
16
- return ctx
17
- }
18
-
19
- export function ReportsContextProvider({
20
- config,
21
- provider,
22
- children,
23
- }: {
24
- config: ResolvedReportsConfig
25
- provider: ReportDataProvider
26
- children: React.ReactNode
27
- }) {
28
- return (
29
- <ReportsContext.Provider value={{ config, provider, reports: config.reports }}>
30
- {children}
31
- </ReportsContext.Provider>
32
- )
33
- }
@@ -1,62 +0,0 @@
1
- import React, { useState, useEffect, useCallback } from 'react'
2
- import { ReportsContextProvider } from './ReportsContext'
3
- import { ReportHub } from './views/ReportHub'
4
- import { ReportViewer } from './views/ReportViewer'
5
- import type { ResolvedReportsConfig, ReportDef } from './types'
6
- import type { ReportDataProvider } from './data/types'
7
-
8
- const HASH_BASE = '/reports'
9
-
10
- function getReportIdFromHash(): string | null {
11
- const hash = (window.location.hash.slice(1) || '/').split('?')[0]
12
- if (hash.startsWith(HASH_BASE + '/') && hash.length > HASH_BASE.length + 1) {
13
- return hash.slice(HASH_BASE.length + 1)
14
- }
15
- return null
16
- }
17
-
18
- export function ReportsPage({
19
- config,
20
- provider,
21
- }: {
22
- config: ResolvedReportsConfig
23
- provider: ReportDataProvider
24
- }) {
25
- const [activeReportId, setActiveReportId] = useState<string | null>(getReportIdFromHash)
26
-
27
- useEffect(() => {
28
- function handler() {
29
- setActiveReportId(getReportIdFromHash())
30
- }
31
- window.addEventListener('hashchange', handler)
32
- return () => window.removeEventListener('hashchange', handler)
33
- }, [])
34
-
35
- const handleSelect = useCallback((report: ReportDef) => {
36
- window.location.hash = `${HASH_BASE}/${report.id}`
37
- }, [])
38
-
39
- const handleBack = useCallback(() => {
40
- window.location.hash = HASH_BASE
41
- }, [])
42
-
43
- const activeReport = activeReportId
44
- ? config.reports.find((r) => r.id === activeReportId) ?? null
45
- : null
46
-
47
- return (
48
- <ReportsContextProvider config={config} provider={provider}>
49
- <div className="p-1">
50
- {activeReport ? (
51
- <ReportViewer
52
- key={activeReport.id}
53
- report={activeReport}
54
- onBack={handleBack}
55
- />
56
- ) : (
57
- <ReportHub onSelect={handleSelect} />
58
- )}
59
- </div>
60
- </ReportsContextProvider>
61
- )
62
- }
@@ -1,63 +0,0 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { Download } from 'lucide-react'
3
- import { Button } from '@fayz-ai/ui'
4
- import {
5
- Dropdown,
6
- DropdownTrigger,
7
- DropdownContent,
8
- DropdownItem,
9
- } from '@fayz-ai/ui'
10
- import { useTranslation } from '@fayz-ai/core'
11
- import type { ReportColumnDef } from '../types'
12
- import { exportToCsv } from '../export/csv'
13
-
14
- interface ExportDropdownProps {
15
- columns: ReportColumnDef[]
16
- data: Record<string, any>[]
17
- filename: string
18
- currency?: string
19
- title?: string
20
- }
21
-
22
- export function ExportDropdown({ columns, data, filename, currency, title }: ExportDropdownProps) {
23
- const t = useTranslation()
24
- const [excelAvailable, setExcelAvailable] = useState(false)
25
- const [pdfAvailable, setPdfAvailable] = useState(false)
26
-
27
- useEffect(() => {
28
- import('../export/excel').then((m) => m.isExcelAvailable()).then(setExcelAvailable).catch(() => {})
29
- import('../export/pdf').then((m) => m.isPdfAvailable()).then(setPdfAvailable).catch(() => {})
30
- }, [])
31
-
32
- const handleCsv = () => exportToCsv(columns, data, filename, currency)
33
-
34
- const handleExcel = async () => {
35
- const { exportToExcel } = await import('../export/excel')
36
- await exportToExcel(columns, data, filename, currency)
37
- }
38
-
39
- const handlePdf = async () => {
40
- const { exportToPdf } = await import('../export/pdf')
41
- await exportToPdf(columns, data, filename, { title, currency })
42
- }
43
-
44
- return (
45
- <Dropdown>
46
- <DropdownTrigger asChild>
47
- <Button variant="outline" size="sm">
48
- <Download className="h-4 w-4 mr-1.5" />
49
- {t('reports.export')}
50
- </Button>
51
- </DropdownTrigger>
52
- <DropdownContent align="end">
53
- <DropdownItem onClick={handleCsv}>{t('reports.exportCsv')}</DropdownItem>
54
- {excelAvailable && (
55
- <DropdownItem onClick={handleExcel}>{t('reports.exportExcel')}</DropdownItem>
56
- )}
57
- {pdfAvailable && (
58
- <DropdownItem onClick={handlePdf}>{t('reports.exportPdf')}</DropdownItem>
59
- )}
60
- </DropdownContent>
61
- </Dropdown>
62
- )
63
- }
@@ -1,38 +0,0 @@
1
- import React from 'react'
2
- import { FileText } from 'lucide-react'
3
- import { Badge, getLucideIcon } from '@fayz-ai/ui'
4
- import type { ReportDef } from '../types'
5
-
6
- interface ReportCardProps {
7
- report: ReportDef
8
- onClick: (report: ReportDef) => void
9
- }
10
-
11
- export function ReportCard({ report, onClick }: ReportCardProps) {
12
- const IconComp = getLucideIcon(report.icon) ?? FileText
13
-
14
- return (
15
- <button
16
- type="button"
17
- onClick={() => onClick(report)}
18
- className="flex flex-col items-start gap-2 rounded-xl border bg-card p-4 text-left transition-all hover:border-primary/30 hover:shadow-md"
19
- >
20
- <div className="flex w-full items-start justify-between">
21
- <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary">
22
- <IconComp className="h-5 w-5" />
23
- </div>
24
- {report.badge && (
25
- <Badge variant="secondary" className="text-xs capitalize">
26
- {report.badge}
27
- </Badge>
28
- )}
29
- </div>
30
- <div>
31
- <h4 className="font-medium text-sm">{report.name}</h4>
32
- {report.description && (
33
- <p className="text-xs text-muted-foreground mt-0.5 line-clamp-2">{report.description}</p>
34
- )}
35
- </div>
36
- </button>
37
- )
38
- }