@drawbridge/components 0.1.4 → 0.1.5

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.
@@ -61,27 +61,25 @@ const CardTask = ({
61
61
  classes.push(className);
62
62
  }
63
63
  const button = () => {
64
- const { element = import_link.default, text, ...props } = rest == null ? void 0 : rest.button;
64
+ const { element = import_link.default, onClick, text, ...props } = rest == null ? void 0 : rest.button;
65
+ const close = () => {
66
+ modal.close();
67
+ queryClient.setQueryData(
68
+ ["drawer"],
69
+ (data) => ({
70
+ ...data,
71
+ active: false
72
+ })
73
+ );
74
+ };
65
75
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
66
76
  import_button.default,
67
77
  {
68
78
  ...{
69
79
  element,
70
- onClick: () => {
71
- modal.close();
72
- queryClient.setQueryData(
73
- ["drawer"],
74
- (data) => ({
75
- ...data,
76
- active: false
77
- })
78
- );
79
- if (props.onClick) {
80
- props.onClick();
81
- }
82
- },
83
80
  size: "small",
84
- ...props
81
+ ...props,
82
+ onClick: onClick || close
85
83
  },
86
84
  children: text
87
85
  }
@@ -29,27 +29,25 @@ const CardTask = ({
29
29
  classes.push(className);
30
30
  }
31
31
  const button = () => {
32
- const { element = Link, text, ...props } = rest == null ? void 0 : rest.button;
32
+ const { element = Link, onClick, text, ...props } = rest == null ? void 0 : rest.button;
33
+ const close = () => {
34
+ modal.close();
35
+ queryClient.setQueryData(
36
+ ["drawer"],
37
+ (data) => ({
38
+ ...data,
39
+ active: false
40
+ })
41
+ );
42
+ };
33
43
  return /* @__PURE__ */ jsx(
34
44
  Button,
35
45
  {
36
46
  ...{
37
47
  element,
38
- onClick: () => {
39
- modal.close();
40
- queryClient.setQueryData(
41
- ["drawer"],
42
- (data) => ({
43
- ...data,
44
- active: false
45
- })
46
- );
47
- if (props.onClick) {
48
- props.onClick();
49
- }
50
- },
51
48
  size: "small",
52
- ...props
49
+ ...props,
50
+ onClick: onClick || close
53
51
  },
54
52
  children: text
55
53
  }
@@ -294,9 +294,9 @@ const DrawerSubscriptionSummary = ({
294
294
  "Subtotal",
295
295
  "$" + (0, import_drawbridge_utils.formatNumber)((first.subtotal || 0) / 100, 2)
296
296
  ),
297
- renderLine(
297
+ first.discount > 0 && renderLine(
298
298
  "Discount",
299
- "-$" + (0, import_drawbridge_utils.formatNumber)((first.discount || 0) / 100, 2)
299
+ "-$" + (0, import_drawbridge_utils.formatNumber)(first.discount / 100, 2)
300
300
  ),
301
301
  renderLine(
302
302
  "Tax",
@@ -262,9 +262,9 @@ const DrawerSubscriptionSummary = ({
262
262
  "Subtotal",
263
263
  "$" + formatNumber((first.subtotal || 0) / 100, 2)
264
264
  ),
265
- renderLine(
265
+ first.discount > 0 && renderLine(
266
266
  "Discount",
267
- "-$" + formatNumber((first.discount || 0) / 100, 2)
267
+ "-$" + formatNumber(first.discount / 100, 2)
268
268
  ),
269
269
  renderLine(
270
270
  "Tax",
@@ -78,7 +78,9 @@ const FormOrganizationCampaignLink = ({
78
78
  import_yup.default.object({
79
79
  asset: import_yup.default.object().label("Asset").nullable(),
80
80
  title: import_yup.default.string().label("Title").required().max(150),
81
- url: import_yup.default.string().label("Url").max(150).matches(import_drawbridge_utils.regex.url, "Url must start with https").required().url()
81
+ // @story links/create
82
+ // The server stores any length; a UTM-tagged URL passes 150 easily.
83
+ url: import_yup.default.string().label("Url").max(2048).matches(import_drawbridge_utils.regex.url, "Url must start with https").required().url()
82
84
  })
83
85
  ),
84
86
  values
@@ -46,7 +46,9 @@ const FormOrganizationCampaignLink = ({
46
46
  yup.object({
47
47
  asset: yup.object().label("Asset").nullable(),
48
48
  title: yup.string().label("Title").required().max(150),
49
- url: yup.string().label("Url").max(150).matches(regex.url, "Url must start with https").required().url()
49
+ // @story links/create
50
+ // The server stores any length; a UTM-tagged URL passes 150 easily.
51
+ url: yup.string().label("Url").max(2048).matches(regex.url, "Url must start with https").required().url()
50
52
  })
51
53
  ),
52
54
  values
@@ -256,6 +256,7 @@ const ChartLine = ({
256
256
  "shortcodes"
257
257
  ],
258
258
  empty,
259
+ format = (value) => value,
259
260
  legend = true
260
261
  }) => {
261
262
  const [active, setActive] = (0, import_react.useState)(datasets);
@@ -432,8 +433,11 @@ const ChartLine = ({
432
433
  import_recharts.Tooltip,
433
434
  {
434
435
  ...{
436
+ // @story redemptions/overview
437
+ // A money chart passes `format` so a day's summed gross reads
438
+ // "$12.50", not 12.500000000000002; counts pass nothing.
435
439
  formatter: (value, name) => [
436
- value,
440
+ format(value),
437
441
  label(name)
438
442
  ]
439
443
  }
@@ -223,6 +223,7 @@ const ChartLine = ({
223
223
  "shortcodes"
224
224
  ],
225
225
  empty,
226
+ format = (value) => value,
226
227
  legend = true
227
228
  }) => {
228
229
  const [active, setActive] = useState(datasets);
@@ -399,8 +400,11 @@ const ChartLine = ({
399
400
  Tooltip,
400
401
  {
401
402
  ...{
403
+ // @story redemptions/overview
404
+ // A money chart passes `format` so a day's summed gross reads
405
+ // "$12.50", not 12.500000000000002; counts pass nothing.
402
406
  formatter: (value, name) => [
403
- value,
407
+ format(value),
404
408
  label(name)
405
409
  ]
406
410
  }
@@ -35,6 +35,7 @@ __export(table_exports, {
35
35
  TableContainer: () => TableContainer,
36
36
  TableHeader: () => TableHeader,
37
37
  TableRow: () => TableRow,
38
+ currencyCell: () => currencyCell,
38
39
  dateCell: () => dateCell,
39
40
  dateTimeCell: () => dateTimeCell,
40
41
  default: () => table_default,
@@ -94,6 +95,14 @@ const rateCell = ({ getValue, row }) => {
94
95
  if (((_a = row == null ? void 0 : row.original) == null ? void 0 : _a.type) === "redemption") return "\u2014";
95
96
  return rate || rate === 0 ? rate + "%" : "\u2014";
96
97
  };
98
+ const currencyCell = ({ getValue, row }) => {
99
+ var _a;
100
+ return (0, import_drawbridge_utils.formatCurrency)({
101
+ // A null code would reach Intl and throw; undefined takes the USD default.
102
+ code: ((_a = row == null ? void 0 : row.original) == null ? void 0 : _a.currency) || void 0,
103
+ value: getValue() || 0
104
+ });
105
+ };
97
106
  const dateTimeCell = ({ getValue }) => {
98
107
  const value = getValue();
99
108
  return value ? (0, import_drawbridge_utils.formatDateString)({
@@ -759,6 +768,7 @@ var table_default = Table;
759
768
  TableContainer,
760
769
  TableHeader,
761
770
  TableRow,
771
+ currencyCell,
762
772
  dateCell,
763
773
  dateTimeCell,
764
774
  rateCell
@@ -2,7 +2,7 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
4
4
  import { useQueryClient } from "@tanstack/react-query";
5
- import { formatDateString } from "@drawbridge/drawbridge-utils";
5
+ import { formatCurrency, formatDateString } from "@drawbridge/drawbridge-utils";
6
6
  import { request } from "@drawbridge/drawbridge-utils/fetch";
7
7
  import Link from "./link.mjs";
8
8
  import { forwardRef, useMemo } from "react";
@@ -52,6 +52,14 @@ const rateCell = ({ getValue, row }) => {
52
52
  if (((_a = row == null ? void 0 : row.original) == null ? void 0 : _a.type) === "redemption") return "\u2014";
53
53
  return rate || rate === 0 ? rate + "%" : "\u2014";
54
54
  };
55
+ const currencyCell = ({ getValue, row }) => {
56
+ var _a;
57
+ return formatCurrency({
58
+ // A null code would reach Intl and throw; undefined takes the USD default.
59
+ code: ((_a = row == null ? void 0 : row.original) == null ? void 0 : _a.currency) || void 0,
60
+ value: getValue() || 0
61
+ });
62
+ };
55
63
  const dateTimeCell = ({ getValue }) => {
56
64
  const value = getValue();
57
65
  return value ? formatDateString({
@@ -716,6 +724,7 @@ export {
716
724
  TableContainer,
717
725
  TableHeader,
718
726
  TableRow,
727
+ currencyCell,
719
728
  dateCell,
720
729
  dateTimeCell,
721
730
  table_default as default,
@@ -620,19 +620,23 @@ const TemplateDashboardResource = ({
620
620
  refetchOnMount,
621
621
  ...chrome
622
622
  }) => {
623
+ const dynamic = Object.values(chrome).some((value) => value instanceof Function);
623
624
  const errorHandler = error || ((query) => {
624
625
  var _a, _b, _c;
625
- if (((_a = query == null ? void 0 : query.error) == null ? void 0 : _a.status) === 403 || (0, import_fetch.isTransientError)(query == null ? void 0 : query.error)) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TemplateDashboard, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
626
- TemplateDashboardError,
627
- {
628
- ...{
629
- error: {
630
- ...(_b = query == null ? void 0 : query.error) == null ? void 0 : _b.data,
631
- message: (_c = query == null ? void 0 : query.error) == null ? void 0 : _c.message
626
+ if (((_a = query == null ? void 0 : query.error) == null ? void 0 : _a.status) === 403 || (0, import_fetch.isTransientError)(query == null ? void 0 : query.error)) {
627
+ const panel = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
628
+ TemplateDashboardError,
629
+ {
630
+ ...{
631
+ error: {
632
+ ...(_b = query == null ? void 0 : query.error) == null ? void 0 : _b.data,
633
+ message: (_c = query == null ? void 0 : query.error) == null ? void 0 : _c.message
634
+ }
632
635
  }
633
636
  }
634
- }
635
- ) });
637
+ );
638
+ return dynamic ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TemplateDashboard, { children: panel }) : panel;
639
+ }
636
640
  (0, import_navigation.notFound)();
637
641
  });
638
642
  const provider = {
@@ -654,7 +658,6 @@ const TemplateDashboardResource = ({
654
658
  }
655
659
  };
656
660
  const resolve = (value, data) => value instanceof Function ? value(data) : value;
657
- const dynamic = Object.values(chrome).some((value) => value instanceof Function);
658
661
  if (!dynamic) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
659
662
  TemplateDashboard,
660
663
  {
@@ -585,19 +585,23 @@ const TemplateDashboardResource = ({
585
585
  refetchOnMount,
586
586
  ...chrome
587
587
  }) => {
588
+ const dynamic = Object.values(chrome).some((value) => value instanceof Function);
588
589
  const errorHandler = error || ((query) => {
589
590
  var _a, _b, _c;
590
- if (((_a = query == null ? void 0 : query.error) == null ? void 0 : _a.status) === 403 || isTransientError(query == null ? void 0 : query.error)) return /* @__PURE__ */ jsx(TemplateDashboard, { children: /* @__PURE__ */ jsx(
591
- TemplateDashboardError,
592
- {
593
- ...{
594
- error: {
595
- ...(_b = query == null ? void 0 : query.error) == null ? void 0 : _b.data,
596
- message: (_c = query == null ? void 0 : query.error) == null ? void 0 : _c.message
591
+ if (((_a = query == null ? void 0 : query.error) == null ? void 0 : _a.status) === 403 || isTransientError(query == null ? void 0 : query.error)) {
592
+ const panel = /* @__PURE__ */ jsx(
593
+ TemplateDashboardError,
594
+ {
595
+ ...{
596
+ error: {
597
+ ...(_b = query == null ? void 0 : query.error) == null ? void 0 : _b.data,
598
+ message: (_c = query == null ? void 0 : query.error) == null ? void 0 : _c.message
599
+ }
597
600
  }
598
601
  }
599
- }
600
- ) });
602
+ );
603
+ return dynamic ? /* @__PURE__ */ jsx(TemplateDashboard, { children: panel }) : panel;
604
+ }
601
605
  notFound();
602
606
  });
603
607
  const provider = {
@@ -619,7 +623,6 @@ const TemplateDashboardResource = ({
619
623
  }
620
624
  };
621
625
  const resolve = (value, data) => value instanceof Function ? value(data) : value;
622
- const dynamic = Object.values(chrome).some((value) => value instanceof Function);
623
626
  if (!dynamic) return /* @__PURE__ */ jsx(
624
627
  TemplateDashboard,
625
628
  {
@@ -171,6 +171,9 @@ const TemplateSocketCampaign = ({
171
171
  queryClient.invalidateQueries({
172
172
  queryKey: ["organization-campaign-prize-draws", prize]
173
173
  });
174
+ queryClient.invalidateQueries({
175
+ queryKey: ["organization-campaign-prizes", params.organization, params.campaign]
176
+ });
174
177
  }
175
178
  },
176
179
  // The live handler applies leads as a delta, which can't be replayed after
@@ -184,7 +187,8 @@ const TemplateSocketCampaign = ({
184
187
  resync: [
185
188
  ["campaign", params == null ? void 0 : params.campaign],
186
189
  ["campaign-advertisements", params == null ? void 0 : params.organization, params == null ? void 0 : params.campaign],
187
- ["organization-campaign-advertisement"]
190
+ ["organization-campaign-advertisement"],
191
+ ["organization-campaign-prizes", params == null ? void 0 : params.organization, params == null ? void 0 : params.campaign]
188
192
  ]
189
193
  });
190
194
  return children;
@@ -136,6 +136,9 @@ const TemplateSocketCampaign = ({
136
136
  queryClient.invalidateQueries({
137
137
  queryKey: ["organization-campaign-prize-draws", prize]
138
138
  });
139
+ queryClient.invalidateQueries({
140
+ queryKey: ["organization-campaign-prizes", params.organization, params.campaign]
141
+ });
139
142
  }
140
143
  },
141
144
  // The live handler applies leads as a delta, which can't be replayed after
@@ -149,7 +152,8 @@ const TemplateSocketCampaign = ({
149
152
  resync: [
150
153
  ["campaign", params == null ? void 0 : params.campaign],
151
154
  ["campaign-advertisements", params == null ? void 0 : params.organization, params == null ? void 0 : params.campaign],
152
- ["organization-campaign-advertisement"]
155
+ ["organization-campaign-advertisement"],
156
+ ["organization-campaign-prizes", params == null ? void 0 : params.organization, params == null ? void 0 : params.campaign]
153
157
  ]
154
158
  });
155
159
  return children;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawbridge/components",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "exports": {
5
5
  "./advertisement": {
6
6
  "types": "./types/advertisement.d.ts",
@@ -1636,7 +1636,7 @@
1636
1636
  },
1637
1637
  "devDependencies": {
1638
1638
  "@analytics/google-tag-manager": "0.5.5",
1639
- "@drawbridge/drawbridge-agents": "0.1.74",
1639
+ "@drawbridge/drawbridge-agents": "0.1.79",
1640
1640
  "@drawbridge/drawbridge-telemetry": "0.0.19",
1641
1641
  "@drawbridge/drawbridge-utils": "0.0.221",
1642
1642
  "@headlessui/react": "2.2.9",
@@ -23,6 +23,9 @@ export interface ChartLineProps {
23
23
  // when every point is zero across these.
24
24
  datasets?: ChartDataset[];
25
25
  empty?: ChartEmptyProps;
26
+ // Formats each value in the hover tooltip; a money chart passes one so a
27
+ // summed amount reads "$12.50". Defaults to the raw value.
28
+ format?: ( value: number ) => ReactNode;
26
29
  // Clicking an entry toggles its series.
27
30
  legend?: boolean;
28
31
  }
@@ -83,6 +83,8 @@ export declare const TableCellId: ComponentType<{ id?: string | null }>;
83
83
  export declare const dateTimeCell: TableCellRenderer;
84
84
  // 'N%', '—' when empty or on a redemption row.
85
85
  export declare const rateCell: TableCellRenderer;
86
+ // The amount in its row's own `currency` ('€12.50' on a EUR row), USD when the row has none.
87
+ export declare const currencyCell: TableCellRenderer;
86
88
 
87
89
  export declare const TableContainer: ComponentType<{ children?: ReactNode; className?: string }>;
88
90