@fayz-ai/plugin-courses 0.2.4 → 0.8.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.
package/dist/index.d.ts CHANGED
@@ -5,6 +5,20 @@ export interface CoursesPluginOptions {
5
5
  navLabel?: string;
6
6
  scope?: PluginScope;
7
7
  verticalId?: VerticalId;
8
+ /**
9
+ * Commerce-vertical modules — ALL OFF by default (the one architectural
10
+ * rule: shared-surface contributions are opt-in, never broadcast — FAY-1247).
11
+ * course-admin (the vertical owner) enables everything via its PluginRef
12
+ * config; a host embedding courses as a lightweight members feature (e.g.
13
+ * agency-os's "Memberships") gets only the base nav entry + editor.
14
+ */
15
+ modules?: {
16
+ membersArea?: boolean;
17
+ sales?: boolean;
18
+ subscriptions?: boolean;
19
+ financial?: boolean;
20
+ reports?: boolean;
21
+ };
8
22
  }
9
23
  export declare function createCoursesPlugin(options?: CoursesPluginOptions): PluginManifest;
10
24
  export { coursesLocales } from './locales';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AA8B5E,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAA;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,cAAc,CA0DlF;AAOD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AA8B5E,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAA;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,aAAa,CAAC,EAAE,OAAO,CAAA;QACvB,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAA;CACF;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,cAAc,CAuElF;AAOD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA"}
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@ import { hashRouterAdapter, registerPluginFactory, registerTranslations, useTran
2
2
  import { setCoursesTenantResolver, getCoursesProviderOptional, setCoursesProvider, createMockCoursesProvider, getCoursesProvider } from '@fayz-ai/courses';
3
3
  import { useOrganizationStore, PluginSettingsPanel, SettingsGroup, SelectRow, ToggleRow } from '@fayz-ai/saas';
4
4
  import * as React2 from 'react';
5
- import { defineKpiWidget, KpiCard, useModuleLayout, PageHeaderActions, Button, Badge, Input, toast, Card, DataTable } from '@fayz-ai/ui';
6
- import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import { defineKpiWidget, useModuleLayout, PageHeaderActions, Button, Badge, Input, KpiCard, DataTable, Card, toast } from '@fayz-ai/ui';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
7
 
8
8
  // src/index.ts
9
9
 
@@ -952,12 +952,14 @@ function FeesKpi() {
952
952
  const s = useSummary();
953
953
  return /* @__PURE__ */ jsx(KpiCard, { label: t("courses.kpi.fees") || "Platform fees", icon: "Percent", loading: !s, value: s ? formatMoney(s.platformFeeTotal, s.currency) : void 0 });
954
954
  }
955
- function createCoursesDashboardWidgets() {
955
+ function createCoursesDashboardWidgets(modules = {}) {
956
956
  return [
957
- defineKpiWidget({ id: "courses.kpi.revenue", title: "courses.kpi.revenue", domain: "courses", defaultOrder: 0, component: RevenueKpi }),
958
- defineKpiWidget({ id: "courses.kpi.sales", title: "courses.kpi.sales", domain: "courses", defaultOrder: 1, component: SalesKpi }),
959
- defineKpiWidget({ id: "courses.kpi.mrr", title: "courses.kpi.mrr", domain: "courses", defaultOrder: 2, component: MrrKpi }),
960
- defineKpiWidget({ id: "courses.kpi.fees", title: "courses.kpi.fees", domain: "courses", defaultOrder: 3, component: FeesKpi })
957
+ ...modules.sales ? [
958
+ defineKpiWidget({ id: "courses.kpi.revenue", title: "courses.kpi.revenue", domain: "courses", defaultOrder: 0, component: RevenueKpi }),
959
+ defineKpiWidget({ id: "courses.kpi.sales", title: "courses.kpi.sales", domain: "courses", defaultOrder: 1, component: SalesKpi })
960
+ ] : [],
961
+ ...modules.subscriptions ? [defineKpiWidget({ id: "courses.kpi.mrr", title: "courses.kpi.mrr", domain: "courses", defaultOrder: 2, component: MrrKpi })] : [],
962
+ ...modules.financial ? [defineKpiWidget({ id: "courses.kpi.fees", title: "courses.kpi.fees", domain: "courses", defaultOrder: 3, component: FeesKpi })] : []
961
963
  ];
962
964
  }
963
965
  function createStripeConnector() {
@@ -997,6 +999,26 @@ function createCoursesPlugin(options) {
997
999
  }
998
1000
  const base = options?.navPosition ?? 1;
999
1001
  const section = options?.navSection ?? "main";
1002
+ const modules = options?.modules ?? {};
1003
+ const navigation = [
1004
+ { section, position: base, label: options?.navLabel ?? "Courses", route: "/courses", icon: "BookOpen", permission: read("courses") },
1005
+ ...modules.membersArea ? [{ section, position: base + 1, label: "Members area", route: "/courses/members", icon: "GraduationCap", permission: read("courses") }] : [],
1006
+ ...modules.sales ? [{ section, position: base + 2, label: "Sales", route: "/courses/sales", icon: "TrendingUp", permission: read("courses.sales") }] : [],
1007
+ ...modules.subscriptions ? [{ section, position: base + 3, label: "Subscriptions", route: "/courses/subscriptions", icon: "Repeat", permission: read("courses.sales") }] : [],
1008
+ ...modules.financial ? [{ section, position: base + 4, label: "Financial", route: "/courses/financial", icon: "CreditCard", permission: read("courses.finance") }] : [],
1009
+ ...modules.reports ? [{ section, position: base + 5, label: "Reports", route: "/courses/reports", icon: "BarChart3", permission: read("courses.sales") }] : []
1010
+ ];
1011
+ const routes = [
1012
+ // Static segments outscore the `:id` param in the saas router, so these
1013
+ // resolve before the editor route (AdminShell sorts by routeScore).
1014
+ { path: "/courses", component: asComp(CoursesListPage), permission: read("courses") },
1015
+ ...modules.membersArea ? [{ path: "/courses/members", component: asComp(MembersAreaPage), permission: read("courses") }] : [],
1016
+ ...modules.sales ? [{ path: "/courses/sales", component: asComp(SalesPage), permission: read("courses.sales") }] : [],
1017
+ ...modules.subscriptions ? [{ path: "/courses/subscriptions", component: asComp(SubscriptionsPage), permission: read("courses.sales") }] : [],
1018
+ ...modules.financial ? [{ path: "/courses/financial", component: asComp(FinancialPage), permission: read("courses.finance") }] : [],
1019
+ ...modules.reports ? [{ path: "/courses/reports", component: asComp(ReportsPage), permission: read("courses.sales") }] : [],
1020
+ { path: "/courses/:id", component: asComp(CourseEditorPage) }
1021
+ ];
1000
1022
  return {
1001
1023
  id: "courses",
1002
1024
  name: options?.navLabel ?? "Courses",
@@ -1004,6 +1026,10 @@ function createCoursesPlugin(options) {
1004
1026
  version: "1.0.0",
1005
1027
  scope: options?.scope ?? "vertical",
1006
1028
  verticalId: options?.verticalId,
1029
+ // LMS is its own business model with opt-in commerce modules
1030
+ // (members/sales/subscriptions — see modules.* below) — targets the
1031
+ // saas/admin Panel world rather than the ecommerce storefront.
1032
+ scaffolds: ["saas"],
1007
1033
  defaultEnabled: true,
1008
1034
  dependencies: [],
1009
1035
  declaredFeatures: [
@@ -1011,27 +1037,12 @@ function createCoursesPlugin(options) {
1011
1037
  { id: "courses.sales", label: "Sales", group: "Courses" },
1012
1038
  { id: "courses.finance", label: "Financial", group: "Courses" }
1013
1039
  ],
1014
- navigation: [
1015
- { section, position: base, label: options?.navLabel ?? "Courses", route: "/courses", icon: "BookOpen", permission: read("courses") },
1016
- { section, position: base + 1, label: "Members area", route: "/courses/members", icon: "GraduationCap", permission: read("courses") },
1017
- { section, position: base + 2, label: "Sales", route: "/courses/sales", icon: "TrendingUp", permission: read("courses.sales") },
1018
- { section, position: base + 3, label: "Subscriptions", route: "/courses/subscriptions", icon: "Repeat", permission: read("courses.sales") },
1019
- { section, position: base + 4, label: "Financial", route: "/courses/financial", icon: "CreditCard", permission: read("courses.finance") },
1020
- { section, position: base + 5, label: "Reports", route: "/courses/reports", icon: "BarChart3", permission: read("courses.sales") }
1021
- ],
1022
- routes: [
1023
- // Static segments outscore the `:id` param in the saas router, so these
1024
- // resolve before the editor route (AdminShell sorts by routeScore).
1025
- { path: "/courses", component: asComp(CoursesListPage), permission: read("courses") },
1026
- { path: "/courses/members", component: asComp(MembersAreaPage), permission: read("courses") },
1027
- { path: "/courses/sales", component: asComp(SalesPage), permission: read("courses.sales") },
1028
- { path: "/courses/subscriptions", component: asComp(SubscriptionsPage), permission: read("courses.sales") },
1029
- { path: "/courses/financial", component: asComp(FinancialPage), permission: read("courses.finance") },
1030
- { path: "/courses/reports", component: asComp(ReportsPage), permission: read("courses.sales") },
1031
- { path: "/courses/:id", component: asComp(CourseEditorPage) }
1032
- ],
1040
+ navigation,
1041
+ routes,
1033
1042
  widgets: [],
1034
- dashboardWidgets: createCoursesDashboardWidgets(),
1043
+ // Commerce KPIs on the shared 'home' surface follow the same opt-in rule:
1044
+ // no module enabled → no widgets broadcast into a host's dashboard.
1045
+ dashboardWidgets: createCoursesDashboardWidgets(modules),
1035
1046
  connectors: [createStripeConnector()],
1036
1047
  settings: [
1037
1048
  { id: "courses", label: "Courses", icon: "BookOpen", component: asComp(CoursesSettingsTab), order: 20, permission: read("courses") }