@burdenoff/microfe-movethewheels 2026.804.1 → 2026.805.1

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.
@@ -0,0 +1,184 @@
1
+ import { Calendar as e } from "../node_modules/lucide-react/dist/esm/icons/calendar.js";
2
+ import { CircleAlert as t } from "../node_modules/lucide-react/dist/esm/icons/circle-alert.js";
3
+ import { TrendingDown as n } from "../node_modules/lucide-react/dist/esm/icons/trending-down.js";
4
+ import { TrendingUp as r } from "../node_modules/lucide-react/dist/esm/icons/trending-up.js";
5
+ import { Card as i, CardContent as a, CardHeader as o, CardTitle as s, Skeleton as c } from "./ui.js";
6
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
+ //#region src/movethewheels/components/UpcomingDemandPanel.tsx
8
+ var d = (e) => {
9
+ let t = new Date(e);
10
+ return Number.isNaN(t.getTime()) ? e : t.toLocaleDateString(void 0, {
11
+ month: "short",
12
+ day: "numeric"
13
+ });
14
+ }, f = (e, t) => [...e.filter((e) => e.periodStart === t)].sort((e, t) => t.predictedVolume - e.predictedVolume).slice(0, 3), p = (e, t) => [...e.filter((e) => e.periodStart === t)].sort((e, t) => t.predictedRevenue - e.predictedRevenue).slice(0, 3), m = (e, t) => e.filter((e) => e.periodStart === t).reduce((e, t) => e + t.predictedVolume, 0), h = (e) => e <= 0 ? "Not enough history" : `${Math.round(e * 100)}% confidence`;
15
+ function g({ laneForecast: n, customerForecast: r, laneVariance: g, customerVariance: y, isLoading: b, error: x, onRetry: S }) {
16
+ if (x && !b) return /* @__PURE__ */ l(i, {
17
+ className: "border-status-error-border",
18
+ children: /* @__PURE__ */ u(a, {
19
+ className: "p-6 text-center space-y-3",
20
+ children: [
21
+ /* @__PURE__ */ l("p", {
22
+ className: "text-status-error-text font-medium",
23
+ children: "Couldn't load demand forecast"
24
+ }),
25
+ /* @__PURE__ */ l("p", {
26
+ className: "text-sm text-text-secondary",
27
+ children: x.message
28
+ }),
29
+ /* @__PURE__ */ l("button", {
30
+ type: "button",
31
+ onClick: S,
32
+ className: "text-sm font-medium text-primary hover:underline",
33
+ children: "Retry"
34
+ })
35
+ ]
36
+ })
37
+ });
38
+ if (b) return /* @__PURE__ */ u(i, { children: [/* @__PURE__ */ l(o, { children: /* @__PURE__ */ l(s, { children: "Upcoming demand" }) }), /* @__PURE__ */ u(a, {
39
+ className: "space-y-4",
40
+ children: [
41
+ /* @__PURE__ */ l(c, { className: "h-16 w-full" }),
42
+ /* @__PURE__ */ l(c, { className: "h-16 w-full" }),
43
+ /* @__PURE__ */ l(c, { className: "h-16 w-full" })
44
+ ]
45
+ })] });
46
+ let C = n[0]?.periodStart ?? r[0]?.periodStart ?? null;
47
+ if (!C || n.length === 0) return /* @__PURE__ */ u(i, { children: [/* @__PURE__ */ l(o, { children: /* @__PURE__ */ u(s, {
48
+ className: "flex items-center gap-2",
49
+ children: [/* @__PURE__ */ l(e, {
50
+ size: 18,
51
+ "aria-hidden": "true"
52
+ }), "Upcoming demand"]
53
+ }) }), /* @__PURE__ */ l(a, { children: /* @__PURE__ */ u("div", {
54
+ className: "flex items-start gap-2 rounded-lg border border-border/60 bg-muted/40 p-4 text-sm text-text-secondary",
55
+ children: [/* @__PURE__ */ l(t, {
56
+ size: 16,
57
+ "aria-hidden": "true",
58
+ className: "mt-0.5 shrink-0"
59
+ }), /* @__PURE__ */ l("p", { children: "Not enough history to forecast next week yet. Once you have at least 4 weeks of completed orders, this panel will surface demand by lane and customer." })]
60
+ }) })] });
61
+ let w = f(n, C), T = p(n, C), E = f(r, C), D = m(n, C), O = [...g, ...y].sort((e, t) => Math.abs(t.volumeVariance) - Math.abs(e.volumeVariance)).slice(0, 3);
62
+ return /* @__PURE__ */ u(i, { children: [/* @__PURE__ */ l(o, { children: /* @__PURE__ */ u(s, {
63
+ className: "flex items-center gap-2",
64
+ children: [
65
+ /* @__PURE__ */ l(e, {
66
+ size: 18,
67
+ "aria-hidden": "true"
68
+ }),
69
+ "Upcoming demand — week of ",
70
+ d(C)
71
+ ]
72
+ }) }), /* @__PURE__ */ u(a, {
73
+ className: "space-y-4",
74
+ children: [/* @__PURE__ */ u("div", {
75
+ className: "flex items-baseline justify-between rounded-lg border border-border/60 bg-muted/40 px-4 py-3",
76
+ children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
77
+ className: "text-xs uppercase tracking-wide text-text-secondary",
78
+ children: "Predicted jobs (all lanes)"
79
+ }), /* @__PURE__ */ l("p", {
80
+ className: "text-2xl font-bold",
81
+ children: D
82
+ })] }), /* @__PURE__ */ l("p", {
83
+ className: "text-xs text-text-secondary",
84
+ children: w[0] ? h(w[0].confidence) : ""
85
+ })]
86
+ }), /* @__PURE__ */ u("div", {
87
+ className: "grid grid-cols-1 md:grid-cols-2 gap-4",
88
+ children: [
89
+ /* @__PURE__ */ l(_, {
90
+ title: "Top lanes (volume)",
91
+ rows: w
92
+ }),
93
+ /* @__PURE__ */ l(_, {
94
+ title: "Top lanes (revenue)",
95
+ rows: T
96
+ }),
97
+ /* @__PURE__ */ l(_, {
98
+ title: "Top customers (volume)",
99
+ rows: E
100
+ }),
101
+ /* @__PURE__ */ l(v, { rows: O })
102
+ ]
103
+ })]
104
+ })] });
105
+ }
106
+ function _({ title: e, rows: t }) {
107
+ return t.length === 0 ? /* @__PURE__ */ u("div", {
108
+ className: "rounded-lg border border-border/60 p-4",
109
+ children: [/* @__PURE__ */ l("p", {
110
+ className: "text-sm font-medium mb-2",
111
+ children: e
112
+ }), /* @__PURE__ */ l("p", {
113
+ className: "text-xs text-text-secondary",
114
+ children: "No forecasts yet for this week."
115
+ })]
116
+ }) : /* @__PURE__ */ u("div", {
117
+ className: "rounded-lg border border-border/60 p-4",
118
+ children: [/* @__PURE__ */ l("p", {
119
+ className: "text-sm font-medium mb-3",
120
+ children: e
121
+ }), /* @__PURE__ */ l("ul", {
122
+ className: "space-y-2",
123
+ children: t.map((e) => /* @__PURE__ */ u("li", {
124
+ className: "flex items-center justify-between text-sm",
125
+ children: [/* @__PURE__ */ l("span", {
126
+ className: "truncate font-medium",
127
+ children: e.scopeKey
128
+ }), /* @__PURE__ */ u("span", {
129
+ className: "ml-2 shrink-0 text-text-secondary",
130
+ children: [
131
+ e.predictedVolume,
132
+ " jobs ·",
133
+ " ",
134
+ new Intl.NumberFormat(void 0, {
135
+ style: "currency",
136
+ currency: "USD",
137
+ maximumFractionDigits: 0
138
+ }).format(e.predictedRevenue)
139
+ ]
140
+ })]
141
+ }, `${e.scopeType}-${e.scopeKey}`))
142
+ })]
143
+ });
144
+ }
145
+ function v({ rows: e }) {
146
+ return /* @__PURE__ */ u("div", {
147
+ className: "rounded-lg border border-border/60 p-4",
148
+ children: [/* @__PURE__ */ l("p", {
149
+ className: "text-sm font-medium mb-3",
150
+ children: "Recent forecast variance"
151
+ }), e.length === 0 ? /* @__PURE__ */ l("p", {
152
+ className: "text-xs text-text-secondary",
153
+ children: "No closed periods to compare yet."
154
+ }) : /* @__PURE__ */ l("ul", {
155
+ className: "space-y-2",
156
+ children: e.map((e) => {
157
+ let t = e.volumeVariance > 0, i = t ? r : n, a = t ? "text-emerald-600 dark:text-emerald-400" : "text-rose-600 dark:text-rose-400";
158
+ return /* @__PURE__ */ u("li", {
159
+ className: "flex items-center justify-between text-sm",
160
+ children: [/* @__PURE__ */ u("span", {
161
+ className: "flex items-center gap-2 truncate",
162
+ children: [/* @__PURE__ */ l(i, {
163
+ size: 14,
164
+ className: a,
165
+ "aria-hidden": "true"
166
+ }), /* @__PURE__ */ l("span", {
167
+ className: "truncate font-medium",
168
+ children: e.scopeKey
169
+ })]
170
+ }), /* @__PURE__ */ u("span", {
171
+ className: `ml-2 shrink-0 ${a}`,
172
+ children: [
173
+ t ? "+" : "",
174
+ e.volumeVariance,
175
+ " jobs"
176
+ ]
177
+ })]
178
+ }, `${e.scopeType}-${e.scopeKey}-${e.periodStart}`);
179
+ })
180
+ })]
181
+ });
182
+ }
183
+ //#endregion
184
+ export { g as UpcomingDemandPanel };
@@ -1404,6 +1404,62 @@ export type GetWarehouseQuery = {
1404
1404
  }>;
1405
1405
  } | null;
1406
1406
  };
1407
+ export type GetMovethewheelsDemandForecastByLaneQueryVariables = Types.Exact<{
1408
+ weeks: Types.Scalars['Int']['input'];
1409
+ }>;
1410
+ export type GetMovethewheelsDemandForecastByLaneQuery = {
1411
+ __typename?: 'Query';
1412
+ demandForecastByLane: Array<{
1413
+ __typename?: 'MtwDemandForecastPoint';
1414
+ scopeType: Types.DemandForecastScope;
1415
+ scopeKey: string;
1416
+ periodStart: string;
1417
+ periodEnd: string;
1418
+ predictedVolume: number;
1419
+ predictedRevenue: number;
1420
+ actualVolume?: number | null;
1421
+ actualRevenue?: number | null;
1422
+ confidence: number;
1423
+ }>;
1424
+ };
1425
+ export type GetMovethewheelsDemandForecastByCustomerQueryVariables = Types.Exact<{
1426
+ weeks: Types.Scalars['Int']['input'];
1427
+ }>;
1428
+ export type GetMovethewheelsDemandForecastByCustomerQuery = {
1429
+ __typename?: 'Query';
1430
+ demandForecastByCustomer: Array<{
1431
+ __typename?: 'MtwDemandForecastPoint';
1432
+ scopeType: Types.DemandForecastScope;
1433
+ scopeKey: string;
1434
+ periodStart: string;
1435
+ periodEnd: string;
1436
+ predictedVolume: number;
1437
+ predictedRevenue: number;
1438
+ actualVolume?: number | null;
1439
+ actualRevenue?: number | null;
1440
+ confidence: number;
1441
+ }>;
1442
+ };
1443
+ export type GetMovethewheelsDemandForecastVarianceQueryVariables = Types.Exact<{
1444
+ scopeType: Types.DemandForecastScope;
1445
+ limit: Types.Scalars['Int']['input'];
1446
+ }>;
1447
+ export type GetMovethewheelsDemandForecastVarianceQuery = {
1448
+ __typename?: 'Query';
1449
+ demandForecastVariance: Array<{
1450
+ __typename?: 'MtwDemandForecastVariance';
1451
+ scopeType: Types.DemandForecastScope;
1452
+ scopeKey: string;
1453
+ periodStart: string;
1454
+ periodEnd: string;
1455
+ predictedVolume: number;
1456
+ actualVolume: number;
1457
+ volumeVariance: number;
1458
+ predictedRevenue: number;
1459
+ actualRevenue: number;
1460
+ revenueVariance: number;
1461
+ }>;
1462
+ };
1407
1463
  export type ListInventoryItemsQueryVariables = Types.Exact<{
1408
1464
  filter?: Types.InputMaybe<Types.InventoryFilterInput>;
1409
1465
  pagination?: Types.InputMaybe<Types.PaginationInput>;
@@ -3232,6 +3288,97 @@ export type GetWarehouseQueryHookResult = ReturnType<typeof useGetWarehouseQuery
3232
3288
  export type GetWarehouseLazyQueryHookResult = ReturnType<typeof useGetWarehouseLazyQuery>;
3233
3289
  export type GetWarehouseSuspenseQueryHookResult = ReturnType<typeof useGetWarehouseSuspenseQuery>;
3234
3290
  export type GetWarehouseQueryResult = Apollo.QueryResult<Types.GetWarehouseQuery, Types.GetWarehouseQueryVariables>;
3291
+ export declare const GetMovethewheelsDemandForecastByLaneDocument: Apollo.DocumentNode;
3292
+ /**
3293
+ * __useGetMovethewheelsDemandForecastByLaneQuery__
3294
+ *
3295
+ * To run a query within a React component, call `useGetMovethewheelsDemandForecastByLaneQuery` and pass it any options that fit your needs.
3296
+ * When your component renders, `useGetMovethewheelsDemandForecastByLaneQuery` returns an object from Apollo Client that contains loading, error, and data properties
3297
+ * you can use to render your UI.
3298
+ *
3299
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
3300
+ *
3301
+ * @example
3302
+ * const { data, loading, error } = useGetMovethewheelsDemandForecastByLaneQuery({
3303
+ * variables: {
3304
+ * weeks: // value for 'weeks'
3305
+ * },
3306
+ * });
3307
+ */
3308
+ export declare function useGetMovethewheelsDemandForecastByLaneQuery(baseOptions: ApolloReactHooks.QueryHookOptions<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables> & ({
3309
+ variables: Types.GetMovethewheelsDemandForecastByLaneQueryVariables;
3310
+ skip?: boolean;
3311
+ } | {
3312
+ skip: boolean;
3313
+ })): ApolloReactHooks.useQuery.Result<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables, "empty" | "complete" | "streaming", Types.GetMovethewheelsDemandForecastByLaneQueryVariables>;
3314
+ export declare function useGetMovethewheelsDemandForecastByLaneLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables>): ApolloReactHooks.useLazyQuery.ResultTuple<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables, "empty" | "complete" | "streaming">;
3315
+ export declare function useGetMovethewheelsDemandForecastByLaneSuspenseQuery(baseOptions?: ApolloReactHooks.SuspenseQueryHookOptions<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables>;
3316
+ export declare function useGetMovethewheelsDemandForecastByLaneSuspenseQuery(baseOptions?: ApolloReactHooks.SkipToken | ApolloReactHooks.SuspenseQueryHookOptions<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetMovethewheelsDemandForecastByLaneQuery | undefined, Types.GetMovethewheelsDemandForecastByLaneQueryVariables>;
3317
+ export type GetMovethewheelsDemandForecastByLaneQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastByLaneQuery>;
3318
+ export type GetMovethewheelsDemandForecastByLaneLazyQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastByLaneLazyQuery>;
3319
+ export type GetMovethewheelsDemandForecastByLaneSuspenseQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastByLaneSuspenseQuery>;
3320
+ export type GetMovethewheelsDemandForecastByLaneQueryResult = Apollo.QueryResult<Types.GetMovethewheelsDemandForecastByLaneQuery, Types.GetMovethewheelsDemandForecastByLaneQueryVariables>;
3321
+ export declare const GetMovethewheelsDemandForecastByCustomerDocument: Apollo.DocumentNode;
3322
+ /**
3323
+ * __useGetMovethewheelsDemandForecastByCustomerQuery__
3324
+ *
3325
+ * To run a query within a React component, call `useGetMovethewheelsDemandForecastByCustomerQuery` and pass it any options that fit your needs.
3326
+ * When your component renders, `useGetMovethewheelsDemandForecastByCustomerQuery` returns an object from Apollo Client that contains loading, error, and data properties
3327
+ * you can use to render your UI.
3328
+ *
3329
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
3330
+ *
3331
+ * @example
3332
+ * const { data, loading, error } = useGetMovethewheelsDemandForecastByCustomerQuery({
3333
+ * variables: {
3334
+ * weeks: // value for 'weeks'
3335
+ * },
3336
+ * });
3337
+ */
3338
+ export declare function useGetMovethewheelsDemandForecastByCustomerQuery(baseOptions: ApolloReactHooks.QueryHookOptions<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables> & ({
3339
+ variables: Types.GetMovethewheelsDemandForecastByCustomerQueryVariables;
3340
+ skip?: boolean;
3341
+ } | {
3342
+ skip: boolean;
3343
+ })): ApolloReactHooks.useQuery.Result<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables, "empty" | "complete" | "streaming", Types.GetMovethewheelsDemandForecastByCustomerQueryVariables>;
3344
+ export declare function useGetMovethewheelsDemandForecastByCustomerLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables>): ApolloReactHooks.useLazyQuery.ResultTuple<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables, "empty" | "complete" | "streaming">;
3345
+ export declare function useGetMovethewheelsDemandForecastByCustomerSuspenseQuery(baseOptions?: ApolloReactHooks.SuspenseQueryHookOptions<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables>;
3346
+ export declare function useGetMovethewheelsDemandForecastByCustomerSuspenseQuery(baseOptions?: ApolloReactHooks.SkipToken | ApolloReactHooks.SuspenseQueryHookOptions<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetMovethewheelsDemandForecastByCustomerQuery | undefined, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables>;
3347
+ export type GetMovethewheelsDemandForecastByCustomerQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastByCustomerQuery>;
3348
+ export type GetMovethewheelsDemandForecastByCustomerLazyQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastByCustomerLazyQuery>;
3349
+ export type GetMovethewheelsDemandForecastByCustomerSuspenseQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastByCustomerSuspenseQuery>;
3350
+ export type GetMovethewheelsDemandForecastByCustomerQueryResult = Apollo.QueryResult<Types.GetMovethewheelsDemandForecastByCustomerQuery, Types.GetMovethewheelsDemandForecastByCustomerQueryVariables>;
3351
+ export declare const GetMovethewheelsDemandForecastVarianceDocument: Apollo.DocumentNode;
3352
+ /**
3353
+ * __useGetMovethewheelsDemandForecastVarianceQuery__
3354
+ *
3355
+ * To run a query within a React component, call `useGetMovethewheelsDemandForecastVarianceQuery` and pass it any options that fit your needs.
3356
+ * When your component renders, `useGetMovethewheelsDemandForecastVarianceQuery` returns an object from Apollo Client that contains loading, error, and data properties
3357
+ * you can use to render your UI.
3358
+ *
3359
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
3360
+ *
3361
+ * @example
3362
+ * const { data, loading, error } = useGetMovethewheelsDemandForecastVarianceQuery({
3363
+ * variables: {
3364
+ * scopeType: // value for 'scopeType'
3365
+ * limit: // value for 'limit'
3366
+ * },
3367
+ * });
3368
+ */
3369
+ export declare function useGetMovethewheelsDemandForecastVarianceQuery(baseOptions: ApolloReactHooks.QueryHookOptions<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables> & ({
3370
+ variables: Types.GetMovethewheelsDemandForecastVarianceQueryVariables;
3371
+ skip?: boolean;
3372
+ } | {
3373
+ skip: boolean;
3374
+ })): ApolloReactHooks.useQuery.Result<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables, "empty" | "complete" | "streaming", Types.GetMovethewheelsDemandForecastVarianceQueryVariables>;
3375
+ export declare function useGetMovethewheelsDemandForecastVarianceLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables>): ApolloReactHooks.useLazyQuery.ResultTuple<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables, "empty" | "complete" | "streaming">;
3376
+ export declare function useGetMovethewheelsDemandForecastVarianceSuspenseQuery(baseOptions?: ApolloReactHooks.SuspenseQueryHookOptions<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables>;
3377
+ export declare function useGetMovethewheelsDemandForecastVarianceSuspenseQuery(baseOptions?: ApolloReactHooks.SkipToken | ApolloReactHooks.SuspenseQueryHookOptions<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables>): ApolloReactHooks.UseSuspenseQueryResult<Types.GetMovethewheelsDemandForecastVarianceQuery | undefined, Types.GetMovethewheelsDemandForecastVarianceQueryVariables>;
3378
+ export type GetMovethewheelsDemandForecastVarianceQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastVarianceQuery>;
3379
+ export type GetMovethewheelsDemandForecastVarianceLazyQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastVarianceLazyQuery>;
3380
+ export type GetMovethewheelsDemandForecastVarianceSuspenseQueryHookResult = ReturnType<typeof useGetMovethewheelsDemandForecastVarianceSuspenseQuery>;
3381
+ export type GetMovethewheelsDemandForecastVarianceQueryResult = Apollo.QueryResult<Types.GetMovethewheelsDemandForecastVarianceQuery, Types.GetMovethewheelsDemandForecastVarianceQueryVariables>;
3235
3382
  export declare const ListInventoryItemsDocument: Apollo.DocumentNode;
3236
3383
  /**
3237
3384
  * __useListInventoryItemsQuery__
@@ -9117,6 +9117,10 @@ export declare enum DeliveryChannelType {
9117
9117
  Storage = "STORAGE",
9118
9118
  Webhook = "WEBHOOK"
9119
9119
  }
9120
+ export declare enum DemandForecastScope {
9121
+ Customer = "CUSTOMER",
9122
+ Lane = "LANE"
9123
+ }
9120
9124
  export type DependencyHealth = {
9121
9125
  __typename?: 'DependencyHealth';
9122
9126
  message: Scalars['String']['output'];
@@ -18999,6 +19003,31 @@ export type MovethewheelsReportFilterInput = {
18999
19003
  status?: InputMaybe<Scalars['String']['input']>;
19000
19004
  type?: InputMaybe<Scalars['String']['input']>;
19001
19005
  };
19006
+ export type MtwDemandForecastPoint = {
19007
+ __typename?: 'MtwDemandForecastPoint';
19008
+ actualRevenue?: Maybe<Scalars['Float']['output']>;
19009
+ actualVolume?: Maybe<Scalars['Int']['output']>;
19010
+ confidence: Scalars['Float']['output'];
19011
+ periodEnd: Scalars['DateTime']['output'];
19012
+ periodStart: Scalars['DateTime']['output'];
19013
+ predictedRevenue: Scalars['Float']['output'];
19014
+ predictedVolume: Scalars['Int']['output'];
19015
+ scopeKey: Scalars['String']['output'];
19016
+ scopeType: DemandForecastScope;
19017
+ };
19018
+ export type MtwDemandForecastVariance = {
19019
+ __typename?: 'MtwDemandForecastVariance';
19020
+ actualRevenue: Scalars['Float']['output'];
19021
+ actualVolume: Scalars['Int']['output'];
19022
+ periodEnd: Scalars['DateTime']['output'];
19023
+ periodStart: Scalars['DateTime']['output'];
19024
+ predictedRevenue: Scalars['Float']['output'];
19025
+ predictedVolume: Scalars['Int']['output'];
19026
+ revenueVariance: Scalars['Float']['output'];
19027
+ scopeKey: Scalars['String']['output'];
19028
+ scopeType: DemandForecastScope;
19029
+ volumeVariance: Scalars['Int']['output'];
19030
+ };
19002
19031
  /**
19003
19032
  * Base Mutation type with placeholder field.
19004
19033
  * Extended by individual mutation files.
@@ -20753,6 +20782,7 @@ export type Mutation = {
20753
20782
  /** Reactivate an archived workspace (sets status to ACTIVE) */
20754
20783
  reactivateWorkspace: Workspace;
20755
20784
  rebuildKnowledgeBaseIndex: Scalars['Boolean']['output'];
20785
+ recalculateDemandForecasts: Scalars['Int']['output'];
20756
20786
  /**
20757
20787
  * Recalculate resource usage for the current workspace.
20758
20788
  * Workspace ID is read from gateway context (x-workspace-id header).
@@ -28817,6 +28847,13 @@ export type MutationReactivateWorkspaceArgs = {
28817
28847
  export type MutationRebuildKnowledgeBaseIndexArgs = {
28818
28848
  knowledgeBaseId: Scalars['ID']['input'];
28819
28849
  };
28850
+ /**
28851
+ * Base Mutation type with placeholder field.
28852
+ * Extended by individual mutation files.
28853
+ */
28854
+ export type MutationRecalculateDemandForecastsArgs = {
28855
+ weeksOfHistory?: InputMaybe<Scalars['Int']['input']>;
28856
+ };
28820
28857
  /**
28821
28858
  * Base Mutation type with placeholder field.
28822
28859
  * Extended by individual mutation files.
@@ -36315,6 +36352,10 @@ export type Query = {
36315
36352
  deadLetterQueueEntry?: Maybe<DeadLetterQueue>;
36316
36353
  decryptSecret?: Maybe<DecryptedSecret>;
36317
36354
  defaultVibeDeck?: Maybe<VibeDeck>;
36355
+ /** Demand forecasting / S&OP v1 (BOFF-4393). Heuristic next-week forecasts. */
36356
+ demandForecastByCustomer: Array<MtwDemandForecastPoint>;
36357
+ demandForecastByLane: Array<MtwDemandForecastPoint>;
36358
+ demandForecastVariance: Array<MtwDemandForecastVariance>;
36318
36359
  /** Check the health status of all system dependencies */
36319
36360
  dependenciesHealth: HealthCheckResponse;
36320
36361
  /**
@@ -38601,6 +38642,28 @@ export type QueryDeadLetterQueueEntryArgs = {
38601
38642
  export type QueryDecryptSecretArgs = {
38602
38643
  id: Scalars['ID']['input'];
38603
38644
  };
38645
+ /**
38646
+ * Base Query type with placeholder field.
38647
+ * Extended by individual query files.
38648
+ */
38649
+ export type QueryDemandForecastByCustomerArgs = {
38650
+ weeks?: InputMaybe<Scalars['Int']['input']>;
38651
+ };
38652
+ /**
38653
+ * Base Query type with placeholder field.
38654
+ * Extended by individual query files.
38655
+ */
38656
+ export type QueryDemandForecastByLaneArgs = {
38657
+ weeks?: InputMaybe<Scalars['Int']['input']>;
38658
+ };
38659
+ /**
38660
+ * Base Query type with placeholder field.
38661
+ * Extended by individual query files.
38662
+ */
38663
+ export type QueryDemandForecastVarianceArgs = {
38664
+ limit?: InputMaybe<Scalars['Int']['input']>;
38665
+ scopeType: DemandForecastScope;
38666
+ };
38604
38667
  /**
38605
38668
  * Base Query type with placeholder field.
38606
38669
  * Extended by individual query files.
@@ -0,0 +1,54 @@
1
+ import { useMoveTheWheels as e } from "../providers/MoveTheWheelsProvider.js";
2
+ import { executeGraphQL as t } from "../utils/graphqlClient.js";
3
+ import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "react";
4
+ //#region src/movethewheels/hooks/useDemandForecast.ts
5
+ var o = "\n query GetMovethewheelsDemandForecast($weeks: Int!, $varianceLimit: Int!) {\n demandForecastByLane(weeks: $weeks) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n predictedRevenue\n actualVolume\n actualRevenue\n confidence\n }\n demandForecastByCustomer(weeks: $weeks) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n predictedRevenue\n actualVolume\n actualRevenue\n confidence\n }\n laneVariance: demandForecastVariance(scopeType: LANE, limit: $varianceLimit) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n actualVolume\n volumeVariance\n predictedRevenue\n actualRevenue\n revenueVariance\n }\n customerVariance: demandForecastVariance(scopeType: CUSTOMER, limit: $varianceLimit) {\n scopeType\n scopeKey\n periodStart\n periodEnd\n predictedVolume\n actualVolume\n volumeVariance\n predictedRevenue\n actualRevenue\n revenueVariance\n }\n }\n";
6
+ function s(s = 4, c = 8) {
7
+ let { apiGatewayUrl: l, authToken: u, workspaceToken: d, workspaceId: f, tenantId: p, currentUser: m } = e(), [h, g] = a([]), [_, v] = a([]), [y, b] = a([]), [x, S] = a([]), [C, w] = a(!1), [T, E] = a(null), D = i(() => ({
8
+ apiGatewayUrl: l,
9
+ authToken: u,
10
+ workspaceToken: d,
11
+ workspaceId: f,
12
+ tenantId: p,
13
+ actorId: m?.id
14
+ }), [
15
+ l,
16
+ u,
17
+ d,
18
+ f,
19
+ p,
20
+ m?.id
21
+ ]), O = n(async () => {
22
+ w(!0), E(null);
23
+ try {
24
+ let e = await t(D, o, {
25
+ weeks: s,
26
+ varianceLimit: c
27
+ });
28
+ g(e.demandForecastByLane ?? []), v(e.demandForecastByCustomer ?? []), b(e.laneVariance ?? []), S(e.customerVariance ?? []);
29
+ } catch (e) {
30
+ E(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load demand forecast"));
31
+ } finally {
32
+ w(!1);
33
+ }
34
+ }, [
35
+ D,
36
+ s,
37
+ c
38
+ ]);
39
+ return r(() => {
40
+ O();
41
+ }, [O]), {
42
+ laneForecast: h,
43
+ customerForecast: _,
44
+ laneVariance: y,
45
+ customerVariance: x,
46
+ isLoading: C,
47
+ error: T,
48
+ refetch: n(() => {
49
+ O();
50
+ }, [O])
51
+ };
52
+ }
53
+ //#endregion
54
+ export { s as useDemandForecast };
@@ -0,0 +1,13 @@
1
+ import { ForecastPoint, ForecastVariance } from '../hooks/useDemandForecast';
2
+
3
+ interface UpcomingDemandPanelProps {
4
+ laneForecast: ForecastPoint[];
5
+ customerForecast: ForecastPoint[];
6
+ laneVariance: ForecastVariance[];
7
+ customerVariance: ForecastVariance[];
8
+ isLoading: boolean;
9
+ error: Error | null;
10
+ onRetry: () => void;
11
+ }
12
+ export declare function UpcomingDemandPanel({ laneForecast, customerForecast, laneVariance, customerVariance, isLoading, error, onRetry, }: UpcomingDemandPanelProps): import("react").JSX.Element;
13
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Demand forecasting hook (BOFF-4393). Pulls next-N-week forecasts by lane
3
+ * and customer plus the recent closed-period variance. Read-side only — the
4
+ * admin console exposes `recalculateDemandForecasts` separately.
5
+ */
6
+ export interface ForecastPoint {
7
+ scopeType: 'LANE' | 'CUSTOMER';
8
+ scopeKey: string;
9
+ periodStart: string;
10
+ periodEnd: string;
11
+ predictedVolume: number;
12
+ predictedRevenue: number;
13
+ actualVolume: number | null;
14
+ actualRevenue: number | null;
15
+ confidence: number;
16
+ }
17
+ export interface ForecastVariance {
18
+ scopeType: 'LANE' | 'CUSTOMER';
19
+ scopeKey: string;
20
+ periodStart: string;
21
+ periodEnd: string;
22
+ predictedVolume: number;
23
+ actualVolume: number;
24
+ volumeVariance: number;
25
+ predictedRevenue: number;
26
+ actualRevenue: number;
27
+ revenueVariance: number;
28
+ }
29
+ interface UseDemandForecastResult {
30
+ laneForecast: ForecastPoint[];
31
+ customerForecast: ForecastPoint[];
32
+ laneVariance: ForecastVariance[];
33
+ customerVariance: ForecastVariance[];
34
+ isLoading: boolean;
35
+ error: Error | null;
36
+ refetch: () => void;
37
+ }
38
+ export declare function useDemandForecast(weeks?: number, varianceLimit?: number): UseDemandForecastResult;
39
+ export {};
@@ -0,0 +1,11 @@
1
+ import { createLucideIcon as e } from "../createLucideIcon.js";
2
+ //#region node_modules/lucide-react/dist/esm/icons/trending-down.js
3
+ var t = e("TrendingDown", [["polyline", {
4
+ points: "22 17 13.5 8.5 8.5 13.5 2 7",
5
+ key: "1r2t7k"
6
+ }], ["polyline", {
7
+ points: "16 17 22 17 22 11",
8
+ key: "11uiuu"
9
+ }]]);
10
+ //#endregion
11
+ export { t as TrendingDown };