@cellarnode/ui 0.189.0 → 0.191.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 (57) hide show
  1. package/dist/brand/brand-assets-section.d.ts +7 -1
  2. package/dist/brand/brand-assets-section.d.ts.map +1 -1
  3. package/dist/brand/brand-assets-section.js +3 -3
  4. package/dist/brand/brand-assets-section.js.map +1 -1
  5. package/dist/brand/brand-font-upload.js +2 -2
  6. package/dist/brand/brand-font-upload.js.map +1 -1
  7. package/dist/brand/brand-generation-client.d.ts +7 -1
  8. package/dist/brand/brand-generation-client.d.ts.map +1 -1
  9. package/dist/brand/brand-generation-client.js +19 -8
  10. package/dist/brand/brand-generation-client.js.map +1 -1
  11. package/dist/brand/brand-generation-start-error.d.ts +24 -0
  12. package/dist/brand/brand-generation-start-error.d.ts.map +1 -0
  13. package/dist/brand/brand-generation-start-error.js +37 -0
  14. package/dist/brand/brand-generation-start-error.js.map +1 -0
  15. package/dist/brand/brand-generation-start.d.ts +27 -1
  16. package/dist/brand/brand-generation-start.d.ts.map +1 -1
  17. package/dist/brand/brand-generation-start.js +53 -6
  18. package/dist/brand/brand-generation-start.js.map +1 -1
  19. package/dist/brand/index.d.ts +1 -0
  20. package/dist/brand/index.d.ts.map +1 -1
  21. package/dist/brand/index.js +1 -0
  22. package/dist/brand/index.js.map +1 -1
  23. package/dist/brand/scan-page-banner.js +1 -1
  24. package/dist/brand/scan-page-banner.js.map +1 -1
  25. package/dist/brand/use-brand-generation.d.ts +5 -0
  26. package/dist/brand/use-brand-generation.d.ts.map +1 -1
  27. package/dist/brand/use-brand-generation.js +16 -2
  28. package/dist/brand/use-brand-generation.js.map +1 -1
  29. package/dist/components/country-flag.d.ts +11 -1
  30. package/dist/components/country-flag.d.ts.map +1 -1
  31. package/dist/components/country-flag.js +5 -3
  32. package/dist/components/country-flag.js.map +1 -1
  33. package/dist/markets/deadline.d.ts +35 -0
  34. package/dist/markets/deadline.d.ts.map +1 -0
  35. package/dist/markets/deadline.js +58 -0
  36. package/dist/markets/deadline.js.map +1 -0
  37. package/dist/markets/index.d.ts +4 -0
  38. package/dist/markets/index.d.ts.map +1 -0
  39. package/dist/markets/index.js +4 -0
  40. package/dist/markets/index.js.map +1 -0
  41. package/dist/markets/market-list-item.d.ts +41 -0
  42. package/dist/markets/market-list-item.d.ts.map +1 -0
  43. package/dist/markets/market-list-item.js +25 -0
  44. package/dist/markets/market-list-item.js.map +1 -0
  45. package/dist/markets/market-opportunities-table.d.ts +137 -0
  46. package/dist/markets/market-opportunities-table.d.ts.map +1 -0
  47. package/dist/markets/market-opportunities-table.js +282 -0
  48. package/dist/markets/market-opportunities-table.js.map +1 -0
  49. package/dist/markets/market-workspace-header.d.ts +53 -0
  50. package/dist/markets/market-workspace-header.d.ts.map +1 -0
  51. package/dist/markets/market-workspace-header.js +34 -0
  52. package/dist/markets/market-workspace-header.js.map +1 -0
  53. package/dist/opportunities/opportunities-table.d.ts +3 -1
  54. package/dist/opportunities/opportunities-table.d.ts.map +1 -1
  55. package/dist/opportunities/opportunities-table.js +24 -56
  56. package/dist/opportunities/opportunities-table.js.map +1 -1
  57. package/package.json +5 -1
@@ -0,0 +1,282 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { AlertTriangle, CircleCheck, CircleX, ArrowDown, ArrowUp, ChevronDown, ChevronsUpDown, ChevronLeft, ChevronRight, Clock, FileText, Inbox, SearchX, SlidersHorizontal, } from "lucide-react";
4
+ import { cn } from "../lib/utils.js";
5
+ import { EmptyState } from "../components/empty-state.js";
6
+ import { ShadcnButton } from "../components/shadcn-button.js";
7
+ import { ShadcnInput } from "../components/shadcn-input.js";
8
+ import { Skeleton } from "../components/skeleton.js";
9
+ import { ChannelBadge } from "../opportunities/opportunity-channel-badge.js";
10
+ import { DeadlineValue } from "./deadline.js";
11
+ export const defaultMarketOpportunitiesTableLabels = {
12
+ tableCaption: "Opportunities in this market",
13
+ searchLabel: "Search opportunities",
14
+ searchPlaceholder: "Search by name",
15
+ statusFilterLabel: "Status",
16
+ deadlineFilterLabel: "Deadline",
17
+ sortLabel: "Sort by",
18
+ filterAndSort: "Filter and sort",
19
+ filterAndSortWithCount: (n) => `Filter and sort (${n})`,
20
+ columnName: "Opportunity",
21
+ columnDeadline: "Deadline",
22
+ columnStatus: "Status",
23
+ columnVolume: "Volume",
24
+ columnChannel: "Channel",
25
+ columnOffers: "Offers received",
26
+ expandRow: (name) => `Show details for ${name}`,
27
+ collapseRow: (name) => `Hide details for ${name}`,
28
+ detailsRegion: (name) => `Details for ${name}`,
29
+ notSet: "Not set",
30
+ noDeadline: "No deadline",
31
+ offersCount: (n) => `${n} ${n === 1 ? "offer" : "offers"}`,
32
+ noOffers: "None yet",
33
+ resultCount: (n) => `${n} ${n === 1 ? "opportunity" : "opportunities"}`,
34
+ loading: "Loading opportunities",
35
+ emptyHeadline: "No opportunities yet",
36
+ emptyDescription: "Opportunities published in this market will appear here.",
37
+ filteredEmptyHeadline: "No opportunities match",
38
+ filteredEmptyDescription: "Try a different search or clear the filters.",
39
+ clearFilters: "Clear filters",
40
+ errorHeadline: "Opportunities did not load",
41
+ errorDescription: "Check your connection and try again.",
42
+ retry: "Try again",
43
+ paginationLabel: "Opportunities pagination",
44
+ previousPage: "Previous page",
45
+ nextPage: "Next page",
46
+ showingRange: (from, to, total) => `Showing ${from} to ${to} of ${total}`,
47
+ statusLabels: { open: "Open", closed: "Closed", expired: "Expired", draft: "Draft" },
48
+ };
49
+ export const defaultMarketStatusOptions = [
50
+ { value: "open", label: "Open" },
51
+ { value: "closed", label: "Closed" },
52
+ { value: "expired", label: "Expired" },
53
+ { value: "all", label: "All statuses" },
54
+ ];
55
+ export const defaultMarketDeadlineOptions = [
56
+ { value: "any", label: "Any deadline" },
57
+ { value: "7d", label: "Next 7 days" },
58
+ { value: "30d", label: "Next 30 days" },
59
+ { value: "90d", label: "Next 90 days" },
60
+ ];
61
+ export const defaultMarketSortOptions = [
62
+ { value: "deadline", label: "Deadline, soonest first" },
63
+ { value: "deadline-desc", label: "Deadline, latest first" },
64
+ { value: "newest", label: "Newest first" },
65
+ { value: "name", label: "Name, A to Z" },
66
+ { value: "name-desc", label: "Name, Z to A" },
67
+ ];
68
+ /** Sort values a sortable column header toggles between. Must exist in `sortOptions`. */
69
+ export const defaultMarketSortColumns = {
70
+ name: { asc: "name", desc: "name-desc" },
71
+ deadline: { asc: "deadline", desc: "deadline-desc" },
72
+ };
73
+ // ─── Small pieces ─────────────────────────────────────────────────────────────
74
+ const STATUS_VARIANTS = {
75
+ open: {
76
+ Icon: CircleCheck,
77
+ classes: "bg-[var(--tone-success-soft)] text-[var(--tone-success-fg)] ring-1 ring-inset ring-[var(--tone-success-border)]",
78
+ },
79
+ closed: {
80
+ Icon: CircleX,
81
+ classes: "bg-[var(--tone-neutral-soft)] text-[var(--tone-neutral-fg)] ring-1 ring-inset ring-[var(--tone-neutral-border)]",
82
+ },
83
+ expired: {
84
+ Icon: Clock,
85
+ classes: "bg-[var(--tone-warning-soft)] text-[var(--tone-warning-fg)] ring-1 ring-inset ring-[var(--tone-warning-border)]",
86
+ },
87
+ draft: {
88
+ Icon: FileText,
89
+ classes: "bg-transparent text-[var(--tone-neutral-fg)] ring-1 ring-inset ring-[var(--tone-neutral-border)]",
90
+ },
91
+ };
92
+ function StatusLabelPill({ status, label }) {
93
+ const { Icon, classes } = STATUS_VARIANTS[status];
94
+ return (_jsxs("span", { "data-status": status, className: cn("inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium", classes), children: [_jsx(Icon, { "aria-hidden": true, className: "size-3.5" }), label] }));
95
+ }
96
+ const selectClass = "w-full rounded-md border border-input bg-background px-3 text-sm text-foreground shadow-xs outline-hidden transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/70 dark:bg-input/30";
97
+ function ToolbarSelect({ label, value, onChange, options, touch, }) {
98
+ return (_jsxs("label", { className: "flex min-w-0 flex-col gap-1 text-xs font-medium text-muted-foreground", children: [label, _jsx("select", { className: cn(selectClass, touch ? "h-11" : "h-9"), value: value, onChange: (e) => onChange(e.target.value), children: options.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) })] }));
99
+ }
100
+ const WIDE_PX = 720;
101
+ function CardFact({ label, children }) {
102
+ return (_jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [_jsx("dt", { className: "text-xs font-semibold text-muted-foreground", children: label }), _jsx("dd", { className: "min-w-0 text-sm text-foreground", children: children })] }));
103
+ }
104
+ function useIsWide(layout) {
105
+ const ref = React.useRef(null);
106
+ const [wide, setWide] = React.useState(true);
107
+ const wideRef = React.useRef(true);
108
+ const restoreId = React.useRef(null);
109
+ React.useLayoutEffect(() => {
110
+ if (layout !== "auto")
111
+ return;
112
+ const el = ref.current;
113
+ if (!el)
114
+ return;
115
+ const measure = (width) => {
116
+ // jsdom reports 0 width: keep the table so tests are deterministic.
117
+ if (width <= 0)
118
+ return;
119
+ const next = width >= WIDE_PX;
120
+ if (next === wideRef.current)
121
+ return;
122
+ // The switch remounts the markup. Remember what had focus so it can be
123
+ // restored (row toggles keep the same id in both layouts).
124
+ const active = document.activeElement;
125
+ if (active && active !== document.body && el.contains(active)) {
126
+ restoreId.current = active.id;
127
+ }
128
+ wideRef.current = next;
129
+ setWide(next);
130
+ };
131
+ measure(el.getBoundingClientRect().width);
132
+ if (typeof ResizeObserver === "undefined")
133
+ return;
134
+ const ro = new ResizeObserver((entries) => {
135
+ const entry = entries[0];
136
+ if (entry)
137
+ measure(entry.contentRect.width);
138
+ });
139
+ ro.observe(el);
140
+ return () => ro.disconnect();
141
+ }, [layout]);
142
+ React.useLayoutEffect(() => {
143
+ const id = restoreId.current;
144
+ if (id === null)
145
+ return;
146
+ restoreId.current = null;
147
+ const el = ref.current;
148
+ if (!el)
149
+ return;
150
+ const active = document.activeElement;
151
+ if (active && active !== document.body && el.contains(active))
152
+ return;
153
+ const target = (id ? document.getElementById(id) : null) ??
154
+ el.querySelector("input[type=search]");
155
+ target?.focus();
156
+ }, [wide]);
157
+ return { ref, wide: layout === "auto" ? wide : layout === "table" };
158
+ }
159
+ // ─── Component ────────────────────────────────────────────────────────────────
160
+ /**
161
+ * Opportunities of one assigned market (CEL-2135): a desktop table that becomes
162
+ * a card list on narrow containers. Fully controlled toolbar (search, status,
163
+ * deadline, sort), in-place row expansion through `renderExpanded` (one row at
164
+ * a time, `aria-expanded`, Escape closes), and loading / empty / filtered-empty
165
+ * / error / offset-pagination states. Router-agnostic: the offers count links
166
+ * through `renderOffersLink`.
167
+ */
168
+ export function MarketOpportunitiesTable(props) {
169
+ const { rows, total: totalProp, search, onSearchChange, status, onStatusChange, deadline, onDeadlineChange, sort, onSortChange, statusOptions = defaultMarketStatusOptions, deadlineOptions = defaultMarketDeadlineOptions, sortOptions = defaultMarketSortOptions, sortColumns = defaultMarketSortColumns, activeFilterCount, hasActiveFilters = false, onClearFilters, isLoading = false, isError = false, onRetry, page = 1, pageSize, onPageChange, pageSizeSlot, renderExpanded, expandedId: expandedIdProp, onExpandedChange, renderOffersLink, channelLabel, layout = "auto", now, labels: labelsProp, className, locale, formatRelative, formatAbsolute, } = props;
170
+ const labels = { ...defaultMarketOpportunitiesTableLabels, ...labelsProp };
171
+ labels.statusLabels = {
172
+ ...defaultMarketOpportunitiesTableLabels.statusLabels,
173
+ ...labelsProp?.statusLabels,
174
+ };
175
+ const total = totalProp ?? rows.length;
176
+ const baseId = React.useId();
177
+ const [fallbackNow] = React.useState(() => new Date());
178
+ const reference = now ?? fallbackNow;
179
+ const { ref, wide } = useIsWide(layout);
180
+ const [filtersOpen, setFiltersOpen] = React.useState(false);
181
+ const [expandedInternal, setExpandedInternal] = React.useState(null);
182
+ const expandedId = expandedIdProp !== undefined ? expandedIdProp : expandedInternal;
183
+ const setExpanded = (id) => {
184
+ if (expandedIdProp === undefined)
185
+ setExpandedInternal(id);
186
+ onExpandedChange?.(id);
187
+ };
188
+ const toggleRefs = React.useRef(new Map());
189
+ const fmt = { locale, formatRelative, formatAbsolute };
190
+ const toggleId = (row) => `${baseId}-toggle-${row.id}`;
191
+ const panelId = (row) => `${baseId}-panel-${row.id}`;
192
+ const renderToggle = (row, open) => (_jsxs("button", { type: "button", id: toggleId(row), ref: (el) => {
193
+ if (el)
194
+ toggleRefs.current.set(row.id, el);
195
+ else
196
+ toggleRefs.current.delete(row.id);
197
+ }, "aria-expanded": open, "aria-controls": open ? panelId(row) : undefined, "aria-label": open ? labels.collapseRow(row.name) : labels.expandRow(row.name), onClick: () => setExpanded(open ? null : row.id), className: "group/toggle -mx-1 flex min-w-0 items-center gap-2 rounded-md px-1 text-left min-h-11 outline-hidden focus-visible:ring-3 focus-visible:ring-ring/70", children: [_jsx(ChevronDown, { "aria-hidden": true, className: cn("size-4 shrink-0 text-muted-foreground transition-transform duration-[var(--duration-standard)] motion-reduce:transition-none", open && "rotate-180") }), _jsx("span", { className: "min-w-0 text-sm font-semibold text-foreground group-hover/toggle:underline", children: row.name })] }));
198
+ const renderPanel = (row) => (_jsx("div", { id: panelId(row), role: "region", "aria-label": labels.detailsRegion(row.name), onKeyDown: (e) => {
199
+ if (e.key === "Escape") {
200
+ e.stopPropagation();
201
+ setExpanded(null);
202
+ toggleRefs.current.get(row.id)?.focus();
203
+ }
204
+ }, children: renderExpanded?.(row) }));
205
+ const offersContent = (row) => {
206
+ const n = row.offersReceivedCount;
207
+ if (typeof n !== "number") {
208
+ return _jsx("span", { className: "text-muted-foreground", children: labels.notSet });
209
+ }
210
+ if (n === 0)
211
+ return _jsx("span", { className: "text-muted-foreground", children: labels.noOffers });
212
+ const text = _jsx("span", { className: "font-tabular font-medium", children: labels.offersCount(n) });
213
+ if (n > 0 && renderOffersLink)
214
+ return renderOffersLink(row, text);
215
+ return text;
216
+ };
217
+ const channelContent = (row) => row.channel ? (_jsx(ChannelBadge, { channel: row.channel, creatorOrgName: row.creatorOrgName, label: channelLabel?.(row) })) : (_jsx("span", { className: "text-sm text-muted-foreground", children: labels.notSet }));
218
+ const deadlineContent = (row) => (_jsx(DeadlineValue, { deadline: row.deadline, now: reference, emphasise: row.status === "open", emptyLabel: labels.noDeadline, ...fmt }));
219
+ const resultsRef = React.useRef(null);
220
+ const focusResultsOnPage = React.useRef(false);
221
+ React.useEffect(() => {
222
+ if (!focusResultsOnPage.current)
223
+ return;
224
+ focusResultsOnPage.current = false;
225
+ resultsRef.current?.focus();
226
+ }, [page]);
227
+ const changePage = (next) => {
228
+ focusResultsOnPage.current = true;
229
+ onPageChange?.(next);
230
+ };
231
+ const filtersActive = hasActiveFilters;
232
+ const showFooter = pageSize != null && total > pageSize;
233
+ const pageCount = pageSize ? Math.max(1, Math.ceil(total / pageSize)) : 1;
234
+ const from = rows.length === 0 ? 0 : (page - 1) * (pageSize ?? rows.length) + 1;
235
+ const to = rows.length === 0 ? 0 : from + rows.length - 1;
236
+ const filterControls = (_jsxs(_Fragment, { children: [_jsx(ToolbarSelect, { touch: !wide, label: labels.statusFilterLabel, value: status, onChange: onStatusChange, options: statusOptions }), _jsx(ToolbarSelect, { touch: !wide, label: labels.deadlineFilterLabel, value: deadline, onChange: onDeadlineChange, options: deadlineOptions }), _jsx(ToolbarSelect, { touch: !wide, label: labels.sortLabel, value: sort, onChange: onSortChange, options: sortOptions })] }));
237
+ const headerColumns = [
238
+ { label: labels.columnName, sortKey: "name" },
239
+ { label: labels.columnDeadline, sortKey: "deadline" },
240
+ { label: labels.columnStatus },
241
+ { label: labels.columnVolume },
242
+ { label: labels.columnChannel },
243
+ { label: labels.columnOffers },
244
+ ];
245
+ let body;
246
+ if (isLoading) {
247
+ body = (_jsxs("div", { role: "status", "aria-busy": "true", className: "flex flex-col gap-3", children: [_jsx("span", { className: "sr-only", children: labels.loading }), Array.from({ length: 5 }, (_, i) => (_jsxs("div", { "data-testid": "market-opportunity-skeleton", className: "flex items-center gap-4 rounded-lg border border-border px-4 py-4", children: [_jsxs("div", { className: "flex flex-1 flex-col gap-2", children: [_jsx(Skeleton, { className: "h-4 w-1/2" }), _jsx(Skeleton, { className: "h-3 w-1/3" })] }), _jsx(Skeleton, { className: "h-5 w-16 rounded-full" })] }, i)))] }));
248
+ }
249
+ else if (isError) {
250
+ body = (_jsx(EmptyState, { tone: "danger", icon: _jsx(AlertTriangle, { className: "size-6" }), headline: labels.errorHeadline, description: labels.errorDescription, actions: onRetry ? (_jsx(ShadcnButton, { variant: "outline", onClick: onRetry, children: labels.retry })) : undefined, entranceMotion: false }));
251
+ }
252
+ else if (rows.length === 0) {
253
+ body = filtersActive ? (_jsx(EmptyState, { icon: _jsx(SearchX, { className: "size-6" }), headline: labels.filteredEmptyHeadline, description: labels.filteredEmptyDescription, actions: onClearFilters ? (_jsx(ShadcnButton, { variant: "outline", onClick: onClearFilters, children: labels.clearFilters })) : undefined, entranceMotion: false })) : (_jsx(EmptyState, { icon: _jsx(Inbox, { className: "size-6" }), headline: labels.emptyHeadline, description: labels.emptyDescription, entranceMotion: false }));
254
+ }
255
+ else if (wide) {
256
+ body = (_jsx("div", { className: "max-h-dvh overflow-auto rounded-lg border border-border", children: _jsxs("table", { className: "w-full border-collapse text-left", children: [_jsx("caption", { className: "sr-only", children: labels.tableCaption }), _jsx("thead", { children: _jsx("tr", { children: headerColumns.map((col) => {
257
+ const cfg = col.sortKey ? sortColumns[col.sortKey] : undefined;
258
+ const dir = cfg
259
+ ? sort === cfg.asc
260
+ ? "ascending"
261
+ : sort === cfg.desc
262
+ ? "descending"
263
+ : undefined
264
+ : undefined;
265
+ const Icon = dir === "ascending" ? ArrowUp : dir === "descending" ? ArrowDown : ChevronsUpDown;
266
+ return (_jsx("th", { scope: "col", "aria-sort": dir, className: "sticky top-0 z-10 bg-muted px-4 py-3 text-xs font-semibold tracking-wide text-muted-foreground after:absolute after:inset-x-0 after:bottom-0 after:h-px after:bg-border", children: cfg ? (_jsxs("button", { type: "button", onClick: () => onSortChange(dir === "ascending" ? cfg.desc : cfg.asc), className: "-mx-1 inline-flex items-center gap-1.5 rounded-md px-1 py-1 font-semibold outline-hidden hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/70", children: [col.label, _jsx(Icon, { "aria-hidden": true, className: cn("size-3.5", !dir && "opacity-60") })] })) : (col.label) }, col.label));
267
+ }) }) }), _jsx("tbody", { children: rows.map((row) => {
268
+ const open = expandedId === row.id;
269
+ return (_jsxs(React.Fragment, { children: [_jsxs("tr", { "data-expanded": open, className: cn("border-b border-border transition-colors duration-[var(--duration-micro)] last:border-b-0 hover:bg-muted/40", open && "bg-muted/30"), children: [_jsx("th", { scope: "row", className: "max-w-xs px-4 py-3 text-left font-normal", children: renderToggle(row, open) }), _jsx("td", { className: "px-4 py-3 align-top", children: deadlineContent(row) }), _jsx("td", { className: "px-4 py-3 align-top", children: _jsx(StatusLabelPill, { status: row.status, label: labels.statusLabels[row.status] }) }), _jsx("td", { className: "font-tabular px-4 py-3 align-top text-sm text-foreground", children: row.volumeLabel ?? (_jsx("span", { className: "text-muted-foreground", children: labels.notSet })) }), _jsx("td", { className: "px-4 py-3 align-top", children: channelContent(row) }), _jsx("td", { className: "px-4 py-3 align-top text-sm", children: offersContent(row) })] }), open && renderExpanded ? (_jsx("tr", { className: "border-b border-border bg-muted/20 last:border-b-0", children: _jsx("td", { colSpan: 6, className: "px-4 py-4", children: renderPanel(row) }) })) : null] }, row.id));
270
+ }) })] }) }));
271
+ }
272
+ else {
273
+ body = (_jsx("ul", { className: "flex flex-col gap-3", children: rows.map((row) => {
274
+ const open = expandedId === row.id;
275
+ return (_jsxs("li", { "data-expanded": open, className: "flex flex-col gap-3 rounded-lg border border-border bg-card px-4 py-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [renderToggle(row, open), _jsx(StatusLabelPill, { status: row.status, label: labels.statusLabels[row.status] })] }), _jsxs("dl", { className: "grid grid-cols-2 gap-x-4 gap-y-3", children: [_jsx(CardFact, { label: labels.columnDeadline, children: deadlineContent(row) }), _jsx(CardFact, { label: labels.columnOffers, children: offersContent(row) }), row.volumeLabel ? (_jsx(CardFact, { label: labels.columnVolume, children: _jsx("span", { className: "font-tabular text-sm text-foreground", children: row.volumeLabel }) })) : null, row.channel ? (_jsx(CardFact, { label: labels.columnChannel, children: channelContent(row) })) : null] }), open && renderExpanded ? (_jsx("div", { className: "border-t border-border pt-3", children: renderPanel(row) })) : null] }, row.id));
276
+ }) }));
277
+ }
278
+ return (_jsxs("div", { ref: ref, "data-slot": "market-opportunities-table", "data-layout": wide ? "table" : "cards", className: cn("flex flex-col gap-4", className), children: [_jsxs("div", { role: "search", className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [_jsxs("label", { className: "flex min-w-48 flex-1 flex-col gap-1 text-xs font-medium text-muted-foreground", children: [_jsx("span", { className: "sr-only", children: labels.searchLabel }), _jsx(ShadcnInput, { type: "search", value: search, onChange: (e) => onSearchChange(e.target.value), placeholder: labels.searchPlaceholder, "aria-label": labels.searchLabel, className: wide ? undefined : "h-11" })] }), wide ? null : (_jsxs(ShadcnButton, { id: `${baseId}-filter-toggle`, variant: "outline", className: "min-h-11", "aria-expanded": filtersOpen, "aria-controls": `${baseId}-filters`, onClick: () => setFiltersOpen((v) => !v), children: [_jsx(SlidersHorizontal, { "aria-hidden": true }), activeFilterCount && activeFilterCount > 0
279
+ ? labels.filterAndSortWithCount(activeFilterCount)
280
+ : labels.filterAndSort] }))] }), wide || filtersOpen ? (_jsx("div", { id: `${baseId}-filters`, className: cn("grid gap-3", wide ? "grid-cols-3 max-w-2xl" : "grid-cols-1"), children: filterControls })) : null] }), !isLoading && !isError ? (_jsx("p", { ref: resultsRef, tabIndex: -1, "aria-live": "polite", className: "font-tabular text-sm text-muted-foreground outline-hidden", children: labels.resultCount(total) })) : null, body, showFooter && !isLoading && !isError ? (_jsxs("nav", { "aria-label": labels.paginationLabel, className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("p", { role: "status", className: "font-tabular text-sm text-muted-foreground", children: labels.showingRange(from, to, total) }), _jsxs("div", { className: "flex items-center gap-2", children: [pageSizeSlot, _jsxs(ShadcnButton, { variant: "outline", size: "sm", className: "min-h-11", disabled: page <= 1, onClick: () => changePage(page - 1), children: [_jsx(ChevronLeft, { "aria-hidden": true }), labels.previousPage] }), _jsxs(ShadcnButton, { variant: "outline", size: "sm", className: "min-h-11", disabled: page >= pageCount, onClick: () => changePage(page + 1), children: [labels.nextPage, _jsx(ChevronRight, { "aria-hidden": true })] })] })] })) : null] }));
281
+ }
282
+ //# sourceMappingURL=market-opportunities-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"market-opportunities-table.js","sourceRoot":"","sources":["../../src/markets/market-opportunities-table.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import * as React from "react";
2
+ import { type DeadlineInput } from "./deadline.js";
3
+ export interface MarketOperationalMarket {
4
+ /** ISO-3166 alpha-2 code. */
5
+ code: string;
6
+ /** Display name; resolved from the ISO registry when omitted. */
7
+ name?: string;
8
+ }
9
+ export interface MarketWorkspaceHeaderLabels {
10
+ /** Visible label of the country fact. */
11
+ country: string;
12
+ marketType: string;
13
+ operationalMarkets: string;
14
+ assignedOn: string;
15
+ /** Shown when a fact has no value. */
16
+ notSet: string;
17
+ }
18
+ export declare const defaultMarketWorkspaceHeaderLabels: MarketWorkspaceHeaderLabels;
19
+ export interface MarketWorkspaceHeaderProps {
20
+ /** Market name, rendered as the page heading. */
21
+ name: string;
22
+ /** ISO-3166 alpha-2 code of the market's country. */
23
+ countryCode: string;
24
+ /** Country display name; resolved from the ISO registry when omitted. */
25
+ countryName?: string;
26
+ /** Already-localised market type label (e.g. "State monopoly"). */
27
+ marketType?: string | null;
28
+ operationalMarkets?: readonly MarketOperationalMarket[];
29
+ /** When the importer was assigned to this market. */
30
+ assignedAt?: DeadlineInput;
31
+ /** BCP 47 locale for the assigned date. Default `"en"`. */
32
+ locale?: string;
33
+ /** Override the assigned-date text. */
34
+ formatDate?: (date: Date) => string;
35
+ /** Slot above the heading: breadcrumb trail or a back link. */
36
+ breadcrumb?: React.ReactNode;
37
+ /** Optional market switcher, rendered beside the heading. */
38
+ switcher?: React.ReactNode;
39
+ /** Optional trailing actions (right of the heading on wide layouts). */
40
+ actions?: React.ReactNode;
41
+ /** Heading level. Default 1. */
42
+ headingLevel?: 1 | 2 | 3;
43
+ labels?: Partial<MarketWorkspaceHeaderLabels>;
44
+ className?: string;
45
+ }
46
+ /**
47
+ * Header of one assigned market's workspace (CEL-2135): the market name and
48
+ * its facts (country with flag, type, operational markets, assignment date),
49
+ * plus slots for the breadcrumb or back link and an optional market switcher.
50
+ * Router-agnostic and copy-agnostic: every string is overridable.
51
+ */
52
+ export declare function MarketWorkspaceHeader({ name, countryCode, countryName, marketType, operationalMarkets, assignedAt, locale, formatDate, breadcrumb, switcher, actions, headingLevel, labels: labelsProp, className, }: MarketWorkspaceHeaderProps): import("react/jsx-runtime").JSX.Element;
53
+ //# sourceMappingURL=market-workspace-header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"market-workspace-header.d.ts","sourceRoot":"","sources":["../../src/markets/market-workspace-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,2BAA2B;IAC1C,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,kCAAkC,EAAE,2BAMhD,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACxD,qDAAqD;IACrD,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IACpC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,wEAAwE;IACxE,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gCAAgC;IAChC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgBD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,WAAW,EACX,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,MAAM,EACN,UAAU,EACV,UAAU,EACV,QAAQ,EACR,OAAO,EACP,YAAgB,EAChB,MAAM,EAAE,UAAU,EAClB,SAAS,GACV,EAAE,0BAA0B,2CA6D5B"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CountryFlag } from "../components/country-flag.js";
3
+ import { COUNTRY_NAMES } from "../lib/country-registry.js";
4
+ import { cn } from "../lib/utils.js";
5
+ import { formatAbsoluteDate, toDate } from "./deadline.js";
6
+ export const defaultMarketWorkspaceHeaderLabels = {
7
+ country: "Country",
8
+ marketType: "Market type",
9
+ operationalMarkets: "Operational markets",
10
+ assignedOn: "Assigned on",
11
+ notSet: "Not set",
12
+ };
13
+ function resolveName(code, name) {
14
+ if (name)
15
+ return name;
16
+ return COUNTRY_NAMES[code.toUpperCase()] ?? code;
17
+ }
18
+ function Fact({ label, children }) {
19
+ return (_jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [_jsx("dt", { className: "text-xs font-semibold text-muted-foreground", children: label }), _jsx("dd", { className: "min-w-0 text-sm text-foreground", children: children })] }));
20
+ }
21
+ /**
22
+ * Header of one assigned market's workspace (CEL-2135): the market name and
23
+ * its facts (country with flag, type, operational markets, assignment date),
24
+ * plus slots for the breadcrumb or back link and an optional market switcher.
25
+ * Router-agnostic and copy-agnostic: every string is overridable.
26
+ */
27
+ export function MarketWorkspaceHeader({ name, countryCode, countryName, marketType, operationalMarkets, assignedAt, locale, formatDate, breadcrumb, switcher, actions, headingLevel = 1, labels: labelsProp, className, }) {
28
+ const labels = { ...defaultMarketWorkspaceHeaderLabels, ...labelsProp };
29
+ const Heading = `h${headingLevel}`;
30
+ const assigned = toDate(assignedAt);
31
+ const markets = operationalMarkets ?? [];
32
+ return (_jsxs("header", { "data-slot": "market-workspace-header", className: cn("flex flex-col gap-4 border-b border-border pb-6", className), children: [breadcrumb ? _jsx("div", { className: "text-sm text-muted-foreground", children: breadcrumb }) : null, _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-x-6 gap-y-3", children: [_jsx("div", { className: "flex min-w-0 items-center gap-3", children: _jsx(Heading, { className: "min-w-0 text-balance text-2xl/8 font-semibold text-foreground", children: name }) }), switcher || actions ? (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [switcher, actions] })) : null] }), _jsxs("dl", { className: "grid grid-cols-1 gap-x-8 gap-y-4 sm:grid-cols-2 lg:grid-cols-4", children: [_jsx(Fact, { label: labels.country, children: _jsxs("span", { className: "inline-flex items-center gap-2", children: [_jsx(CountryFlag, { decorative: true, code: countryCode, className: "text-base" }), resolveName(countryCode, countryName)] }) }), _jsx(Fact, { label: labels.marketType, children: marketType ? marketType : _jsx("span", { className: "text-muted-foreground", children: labels.notSet }) }), _jsx(Fact, { label: labels.operationalMarkets, children: markets.length > 0 ? (_jsx("ul", { className: "flex flex-wrap gap-x-3 gap-y-1", children: markets.map((m) => (_jsxs("li", { className: "inline-flex items-center gap-1.5", children: [_jsx(CountryFlag, { decorative: true, code: m.code, className: "text-base" }), resolveName(m.code, m.name)] }, m.code))) })) : (_jsx("span", { className: "text-muted-foreground", children: labels.notSet })) }), _jsx(Fact, { label: labels.assignedOn, children: assigned ? (_jsx("time", { dateTime: assigned.toISOString(), className: "font-tabular", children: formatDate ? formatDate(assigned) : formatAbsoluteDate(assigned, { locale }) })) : (_jsx("span", { className: "text-muted-foreground", children: labels.notSet })) })] })] }));
33
+ }
34
+ //# sourceMappingURL=market-workspace-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"market-workspace-header.js","sourceRoot":"","sources":["../../src/markets/market-workspace-header.tsx"],"names":[],"mappings":"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"}
@@ -17,11 +17,13 @@ export interface OpportunitiesTableProps {
17
17
  /** Build href for a row. If not provided, rows are not clickable. */
18
18
  getRowHref?: (row: OpportunityRow) => string;
19
19
  emptyMessage?: string;
20
+ /** Text for a missing value (deadline, country, type, identifier). Default "Not set". */
21
+ notSetLabel?: string;
20
22
  pageSize?: number;
21
23
  }
22
24
  /**
23
25
  * @deprecated Since 0.19.0. Use `OpportunityStackedList` with `OpportunityStackedCard` slots instead.
24
26
  * Scheduled for removal in 0.20.0. See `docs/superpowers/specs/2026-04-20-opportunity-experience-redesign-design.md`.
25
27
  */
26
- export declare function OpportunitiesTable({ data, isLoading, renderLink, getRowHref, emptyMessage, pageSize, }: OpportunitiesTableProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function OpportunitiesTable({ data, isLoading, renderLink, getRowHref, emptyMessage, notSetLabel, pageSize, }: OpportunitiesTableProps): import("react/jsx-runtime").JSX.Element;
27
29
  //# sourceMappingURL=opportunities-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opportunities-table.d.ts","sourceRoot":"","sources":["../../src/opportunities/opportunities-table.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAkB/B,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1E,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA6SD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,SAAiB,EACjB,UAAU,EACV,UAAU,EACV,YAAwC,EACxC,QAAa,GACd,EAAE,uBAAuB,2CAyHzB"}
1
+ {"version":3,"file":"opportunities-table.d.ts","sourceRoot":"","sources":["../../src/opportunities/opportunities-table.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoB/B,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1E,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAyRD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,SAAiB,EACjB,UAAU,EACV,UAAU,EACV,YAAwC,EACxC,WAAuB,EACvB,QAAa,GACd,EAAE,uBAAuB,2CA0HzB"}
@@ -8,49 +8,9 @@ import { cn } from "../lib/utils.js";
8
8
  import { ShadcnButton } from "../components/shadcn-button.js";
9
9
  import { ShadcnInput } from "../components/shadcn-input.js";
10
10
  import { Skeleton } from "../components/skeleton.js";
11
+ import { CountryFlag } from "../components/country-flag.js";
12
+ import { COUNTRY_NAMES } from "../lib/country-registry.js";
11
13
  // ─── Country flags ────────────────────────────────────────────────────────────
12
- const COUNTRY_FLAGS = {
13
- AR: "🇦🇷",
14
- AU: "🇦🇺",
15
- AT: "🇦🇹",
16
- BE: "🇧🇪",
17
- BR: "🇧🇷",
18
- CA: "🇨🇦",
19
- CL: "🇨🇱",
20
- CN: "🇨🇳",
21
- HR: "🇭🇷",
22
- CZ: "🇨🇿",
23
- DK: "🇩🇰",
24
- FR: "🇫🇷",
25
- DE: "🇩🇪",
26
- GR: "🇬🇷",
27
- HU: "🇭🇺",
28
- IE: "🇮🇪",
29
- IT: "🇮🇹",
30
- JP: "🇯🇵",
31
- MX: "🇲🇽",
32
- NL: "🇳🇱",
33
- NO: "🇳🇴",
34
- PL: "🇵🇱",
35
- PT: "🇵🇹",
36
- ES: "🇪🇸",
37
- SE: "🇸🇪",
38
- CH: "🇨🇭",
39
- TR: "🇹🇷",
40
- GB: "🇬🇧",
41
- US: "🇺🇸",
42
- ZA: "🇿🇦",
43
- KR: "🇰🇷",
44
- NZ: "🇳🇿",
45
- SK: "🇸🇰",
46
- SI: "🇸🇮",
47
- FI: "🇫🇮",
48
- EE: "🇪🇪",
49
- LV: "🇱🇻",
50
- LT: "🇱🇹",
51
- LU: "🇱🇺",
52
- RO: "🇷🇴",
53
- };
54
14
  const COUNTRY_NAME_TO_ISO = {
55
15
  Argentina: "AR",
56
16
  Australia: "AU",
@@ -97,23 +57,31 @@ const COUNTRY_NAME_TO_ISO = {
97
57
  Luxembourg: "LU",
98
58
  Romania: "RO",
99
59
  };
100
- function getFlag(country) {
60
+ /** Resolve an ISO alpha-2 code from a code or an English country name; "" when unknown. */
61
+ function resolveCountryCode(country) {
101
62
  if (!country)
102
- return "🏳️";
103
- const upper = country.toUpperCase();
104
- if (COUNTRY_FLAGS[upper])
105
- return COUNTRY_FLAGS[upper];
106
- const iso = COUNTRY_NAME_TO_ISO[country];
107
- return iso ? (COUNTRY_FLAGS[iso] ?? "🏳️") : "🏳️";
63
+ return "";
64
+ const trimmed = country.trim();
65
+ if (/^[A-Za-z]{2}$/.test(trimmed))
66
+ return trimmed.toUpperCase();
67
+ const alias = COUNTRY_NAME_TO_ISO[trimmed];
68
+ if (alias)
69
+ return alias;
70
+ const lower = trimmed.toLowerCase();
71
+ for (const [code, name] of Object.entries(COUNTRY_NAMES)) {
72
+ if (name.toLowerCase() === lower)
73
+ return code;
74
+ }
75
+ return "";
108
76
  }
109
77
  // ─── Helpers ──────────────────────────────────────────────────────────────────
110
78
  function StatusBadge({ status }) {
111
79
  const normalised = status.toLowerCase();
112
80
  return (_jsx("span", { className: cn("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold", normalised === "open" && "bg-[var(--tone-success-soft)] text-[var(--tone-success-fg)]", normalised === "closed" && "bg-muted text-muted-foreground", normalised === "draft" && "bg-[var(--tone-warning-soft)] text-[var(--tone-warning-fg)]", !["open", "closed", "draft"].includes(normalised) && "bg-muted text-muted-foreground"), children: status }));
113
81
  }
114
- function DeadlineDisplay({ deadline, full = false }) {
82
+ function DeadlineDisplay({ deadline, full = false, notSetLabel, }) {
115
83
  if (!deadline)
116
- return _jsx("span", { className: "text-muted-foreground", children: "\u2014" });
84
+ return _jsx("span", { className: "text-muted-foreground", children: notSetLabel });
117
85
  const date = parseISO(deadline);
118
86
  const past = isPast(date);
119
87
  // eslint-disable-next-line @eslint-react/purity, react-hooks/purity
@@ -130,12 +98,12 @@ function DetailField({ label, children }) {
130
98
  return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: label }), _jsx("span", { className: "text-sm text-foreground", children: children })] }));
131
99
  }
132
100
  // ─── Row item ─────────────────────────────────────────────────────────────────
133
- function OpportunityRowItem({ row, density, renderLink, getRowHref, }) {
101
+ function OpportunityRowItem({ row, density, renderLink, getRowHref, notSetLabel, }) {
134
102
  const [expanded, setExpanded] = React.useState(false);
135
103
  const href = getRowHref?.(row);
136
- const flag = getFlag(row.countryOfOrigin);
104
+ const countryCode = resolveCountryCode(row.countryOfOrigin);
137
105
  const nameContent = (_jsx("span", { className: "text-sm font-semibold text-foreground hover:underline", children: row.name }));
138
- return (_jsxs("li", { className: "bg-card", children: [_jsxs("div", { className: cn("flex items-center gap-3 px-4", density === "comfortable" ? "py-3.5" : "py-2"), children: [_jsx("span", { className: "shrink-0 text-xl/5", role: "img", "aria-label": row.countryOfOrigin ?? "Unknown country", children: flag }), _jsxs("div", { className: "min-w-0 flex-1", children: [href && renderLink ? renderLink(href, nameContent) : nameContent, row.marketIdentifier && (_jsx("p", { className: "truncate text-xs text-muted-foreground", children: row.marketIdentifier }))] }), row.beverageType && (_jsx("span", { className: "hidden shrink-0 rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground sm:inline-block", children: row.beverageType })), _jsx(StatusBadge, { status: row.status }), _jsx("span", { className: "hidden shrink-0 md:inline-flex", children: _jsx(DeadlineDisplay, { deadline: row.submissionDeadline }) }), _jsx("button", { type: "button", onClick: () => setExpanded((v) => !v), "aria-expanded": expanded, "aria-label": expanded ? "Collapse details" : "Expand details", className: "shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(ChevronDown, { className: cn("size-4 transition-transform duration-[var(--duration-standard)]", expanded && "rotate-180") }) })] }), _jsx(AnimatePresence, { initial: false, children: expanded && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeInOut" }, className: "overflow-hidden", children: _jsx("div", { className: "border-t border-border/40 bg-muted/20 px-4 pb-4 pt-3", children: _jsxs("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3", children: [_jsx(DetailField, { label: "Country of Origin", children: row.countryOfOrigin ? `${flag} ${row.countryOfOrigin}` : "—" }), _jsx(DetailField, { label: "Beverage Type", children: row.beverageType ?? "—" }), _jsx(DetailField, { label: "Submission Deadline", children: _jsx(DeadlineDisplay, { deadline: row.submissionDeadline, full: true }) }), _jsx(DetailField, { label: "Market Identifier", children: row.marketIdentifier ?? "—" }), _jsx(DetailField, { label: "Status", children: _jsx(StatusBadge, { status: row.status }) })] }) }) }, "detail")) })] }));
106
+ return (_jsxs("li", { className: "bg-card", children: [_jsxs("div", { className: cn("flex items-center gap-3 px-4", density === "comfortable" ? "py-3.5" : "py-2"), children: [_jsx(CountryFlag, { code: countryCode, className: "shrink-0 text-xl/5" }), _jsxs("div", { className: "min-w-0 flex-1", children: [href && renderLink ? renderLink(href, nameContent) : nameContent, row.marketIdentifier && (_jsx("p", { className: "truncate text-xs text-muted-foreground", children: row.marketIdentifier }))] }), row.beverageType && (_jsx("span", { className: "hidden shrink-0 rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground sm:inline-block", children: row.beverageType })), _jsx(StatusBadge, { status: row.status }), _jsx("span", { className: "hidden shrink-0 md:inline-flex", children: _jsx(DeadlineDisplay, { deadline: row.submissionDeadline, notSetLabel: notSetLabel }) }), _jsx("button", { type: "button", onClick: () => setExpanded((v) => !v), "aria-expanded": expanded, "aria-label": expanded ? "Collapse details" : "Expand details", className: "shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(ChevronDown, { className: cn("size-4 transition-transform duration-[var(--duration-standard)]", expanded && "rotate-180") }) })] }), _jsx(AnimatePresence, { initial: false, children: expanded && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeInOut" }, className: "overflow-hidden", children: _jsx("div", { className: "border-t border-border/40 bg-muted/20 px-4 pb-4 pt-3", children: _jsxs("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3", children: [_jsx(DetailField, { label: "Country of Origin", children: row.countryOfOrigin ? (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [_jsx(CountryFlag, { code: countryCode, className: "text-base" }), row.countryOfOrigin] })) : (notSetLabel) }), _jsx(DetailField, { label: "Beverage Type", children: row.beverageType ?? notSetLabel }), _jsx(DetailField, { label: "Submission Deadline", children: _jsx(DeadlineDisplay, { deadline: row.submissionDeadline, full: true, notSetLabel: notSetLabel }) }), _jsx(DetailField, { label: "Market Identifier", children: row.marketIdentifier ?? notSetLabel }), _jsx(DetailField, { label: "Status", children: _jsx(StatusBadge, { status: row.status }) })] }) }) }, "detail")) })] }));
139
107
  }
140
108
  // ─── Main component ───────────────────────────────────────────────────────────
141
109
  const DUMMY_COLUMNS = [
@@ -150,7 +118,7 @@ const DUMMY_COLUMNS = [
150
118
  * @deprecated Since 0.19.0. Use `OpportunityStackedList` with `OpportunityStackedCard` slots instead.
151
119
  * Scheduled for removal in 0.20.0. See `docs/superpowers/specs/2026-04-20-opportunity-experience-redesign-design.md`.
152
120
  */
153
- export function OpportunitiesTable({ data, isLoading = false, renderLink, getRowHref, emptyMessage = "No opportunities found.", pageSize = 10, }) {
121
+ export function OpportunitiesTable({ data, isLoading = false, renderLink, getRowHref, emptyMessage = "No opportunities found.", notSetLabel = "Not set", pageSize = 10, }) {
154
122
  const [globalFilter, setGlobalFilter] = React.useState("");
155
123
  const [density, setDensity] = React.useState("comfortable");
156
124
  // eslint-disable-next-line react-hooks/incompatible-library
@@ -178,6 +146,6 @@ export function OpportunitiesTable({ data, isLoading = false, renderLink, getRow
178
146
  // eslint-disable-next-line @eslint-react/no-array-index-key
179
147
  _jsx(RowSkeleton, { density: density }, i)))) : table.getRowModel().rows.length === 0 ? (_jsx("li", { className: "py-16 text-center text-sm text-muted-foreground", children: emptyMessage })) : (table
180
148
  .getRowModel()
181
- .rows.map((row) => (_jsx(OpportunityRowItem, { row: row.original, density: density, renderLink: renderLink, getRowHref: getRowHref }, row.id)))) }), !isLoading && pageCount > 1 && (_jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Page ", pageIndex + 1, " of ", pageCount] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(ShadcnButton, { variant: "outline", size: "sm", onClick: () => table.previousPage(), disabled: !table.getCanPreviousPage(), children: [_jsx(ChevronLeft, { className: "size-4" }), "Previous"] }), _jsxs(ShadcnButton, { variant: "outline", size: "sm", onClick: () => table.nextPage(), disabled: !table.getCanNextPage(), children: ["Next", _jsx(ChevronRight, { className: "size-4" })] })] })] }))] }));
149
+ .rows.map((row) => (_jsx(OpportunityRowItem, { row: row.original, density: density, renderLink: renderLink, getRowHref: getRowHref, notSetLabel: notSetLabel }, row.id)))) }), !isLoading && pageCount > 1 && (_jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Page ", pageIndex + 1, " of ", pageCount] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(ShadcnButton, { variant: "outline", size: "sm", onClick: () => table.previousPage(), disabled: !table.getCanPreviousPage(), children: [_jsx(ChevronLeft, { className: "size-4" }), "Previous"] }), _jsxs(ShadcnButton, { variant: "outline", size: "sm", onClick: () => table.nextPage(), disabled: !table.getCanNextPage(), children: ["Next", _jsx(ChevronRight, { className: "size-4" })] })] })] }))] }));
182
150
  }
183
151
  //# sourceMappingURL=opportunities-table.js.map