@cellarnode/ui 0.19.1 → 0.20.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.
- package/dist/chat/chat-ws.d.ts +56 -0
- package/dist/chat/chat-ws.d.ts.map +1 -1
- package/dist/chat/chat-ws.js +103 -0
- package/dist/chat/chat-ws.js.map +1 -1
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.d.ts.map +1 -1
- package/dist/components/journey-card.d.ts +9 -1
- package/dist/components/journey-card.d.ts.map +1 -1
- package/dist/components/journey-card.js +13 -6
- package/dist/components/journey-card.js.map +1 -1
- package/dist/components/journey-card.stories.d.ts +2 -0
- package/dist/components/journey-card.stories.d.ts.map +1 -1
- package/dist/components/journey-card.stories.js +43 -0
- package/dist/components/journey-card.stories.js.map +1 -1
- package/dist/components/sortable-card-context.d.ts +18 -0
- package/dist/components/sortable-card-context.d.ts.map +1 -0
- package/dist/components/sortable-card-context.js +18 -0
- package/dist/components/sortable-card-context.js.map +1 -0
- package/dist/components/sortable-card-shell.d.ts +40 -21
- package/dist/components/sortable-card-shell.d.ts.map +1 -1
- package/dist/components/sortable-card-shell.js +46 -39
- package/dist/components/sortable-card-shell.js.map +1 -1
- package/dist/components/sortable-card-shell.stories.d.ts +1 -1
- package/dist/components/sortable-card-shell.stories.d.ts.map +1 -1
- package/dist/components/sortable-card-shell.stories.js +28 -15
- package/dist/components/sortable-card-shell.stories.js.map +1 -1
- package/dist/components/sortable-card-shell.test.js +57 -16
- package/dist/components/sortable-card-shell.test.js.map +1 -1
- package/dist/offer/attachments-card.d.ts +7 -1
- package/dist/offer/attachments-card.d.ts.map +1 -1
- package/dist/offer/attachments-card.js +3 -3
- package/dist/offer/attachments-card.js.map +1 -1
- package/dist/offer/index.d.ts +1 -1
- package/dist/offer/index.d.ts.map +1 -1
- package/dist/offer/negotiation-section.d.ts +9 -1
- package/dist/offer/negotiation-section.d.ts.map +1 -1
- package/dist/offer/negotiation-section.js +2 -2
- package/dist/offer/negotiation-section.js.map +1 -1
- package/dist/offer/offer-document.d.ts +24 -24
- package/dist/offer/offer-document.d.ts.map +1 -1
- package/dist/offer/offer-document.js +269 -49
- package/dist/offer/offer-document.js.map +1 -1
- package/dist/offer/offer-document.stories.d.ts +11 -0
- package/dist/offer/offer-document.stories.d.ts.map +1 -1
- package/dist/offer/offer-document.stories.js +136 -84
- package/dist/offer/offer-document.stories.js.map +1 -1
- package/dist/offer/types.d.ts +81 -0
- package/dist/offer/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/offer/index.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ export type { NegotiationSectionProps } from "./negotiation-section";
|
|
|
62
62
|
export { OfferExportButton } from "./offer-export-button";
|
|
63
63
|
export type { OfferExportButtonProps } from "./offer-export-button";
|
|
64
64
|
export { OfferDocument } from "./offer-document";
|
|
65
|
-
export type { OfferDocumentProps
|
|
65
|
+
export type { OfferDocumentProps } from "./offer-document";
|
|
66
66
|
export { ImporterPickerModal, type ImporterPickerModalProps, type ImporterPickerImporter, type ImporterPickerMode, } from "../components/importer-picker-modal";
|
|
67
67
|
export { OffersSentPanel, type OffersSentPanelProps, type OfferBranch, } from "../components/branch-overview-panel";
|
|
68
68
|
export { FinalizeDealModal, type FinalizeDealModalProps, type FinalizeDealTerm, type FinalizeDealClosedBranch, } from "../components/branch-resolution-modal";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/offer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAKlE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,eAAe,GAChB,MAAM,SAAS,CAAC;AASjB,mBAAmB,SAAS,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,YAAY,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,YAAY,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE/F,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/offer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,15 @@ export interface NegotiationSectionProps {
|
|
|
5
5
|
viewerRole?: Perspective;
|
|
6
6
|
viewerAdvantageFor?: (event: TimelineEventData) => ViewerAdvantage;
|
|
7
7
|
onOpenComposer?: () => void;
|
|
8
|
+
/**
|
|
9
|
+
* Optional pagination hook — when provided, renders a "Load older events"
|
|
10
|
+
* button at the top of the timeline that invokes the handler. Undefined
|
|
11
|
+
* means "all events loaded; no pagination affordance".
|
|
12
|
+
*/
|
|
13
|
+
onLoadOlder?: () => void;
|
|
14
|
+
/** Disables the load-older button while a prior request is in flight. */
|
|
15
|
+
loadOlderDisabled?: boolean;
|
|
8
16
|
className?: string;
|
|
9
17
|
}
|
|
10
|
-
export declare function NegotiationSection({ events, viewerOrgId: _viewerOrgId, viewerRole: _viewerRole, viewerAdvantageFor, onOpenComposer, className, }: NegotiationSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export declare function NegotiationSection({ events, viewerOrgId: _viewerOrgId, viewerRole: _viewerRole, viewerAdvantageFor, onOpenComposer, onLoadOlder, loadOlderDisabled, className, }: NegotiationSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
11
19
|
//# sourceMappingURL=negotiation-section.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation-section.d.ts","sourceRoot":"","sources":["../../src/offer/negotiation-section.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,eAAe,CAAC;IACnE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,WAAW,EAAE,YAAY,EACzB,UAAU,EAAE,WAAW,EACvB,kBAAkB,EAClB,cAAc,EACd,SAAS,GACV,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"negotiation-section.d.ts","sourceRoot":"","sources":["../../src/offer/negotiation-section.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,eAAe,CAAC;IACnE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,WAAW,EAAE,YAAY,EACzB,UAAU,EAAE,WAAW,EACvB,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,SAAS,GACV,EAAE,uBAAuB,2CA+LzB"}
|
|
@@ -6,7 +6,7 @@ import { ShadcnButton as Button } from "../components/shadcn-button";
|
|
|
6
6
|
import { useSafeVirtualizer } from "../chat/use-safe-virtualizer";
|
|
7
7
|
import { TimelineEvent } from "./timeline-event";
|
|
8
8
|
import { NewActivityPill } from "./new-activity-pill";
|
|
9
|
-
export function NegotiationSection({ events, viewerOrgId: _viewerOrgId, viewerRole: _viewerRole, viewerAdvantageFor, onOpenComposer, className, }) {
|
|
9
|
+
export function NegotiationSection({ events, viewerOrgId: _viewerOrgId, viewerRole: _viewerRole, viewerAdvantageFor, onOpenComposer, onLoadOlder, loadOlderDisabled, className, }) {
|
|
10
10
|
const scrollRef = useRef(null);
|
|
11
11
|
const [newEventCount, setNewEventCount] = useState(0);
|
|
12
12
|
const [focusedIndex, setFocusedIndex] = useState(0);
|
|
@@ -80,7 +80,7 @@ export function NegotiationSection({ events, viewerOrgId: _viewerOrgId, viewerRo
|
|
|
80
80
|
else
|
|
81
81
|
eventListRef.current.delete(index);
|
|
82
82
|
}, []);
|
|
83
|
-
return (_jsxs("section", { "aria-labelledby": "negotiation-heading", className: cn("rounded-2xl border border-border/60 bg-card p-4", className), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { id: "negotiation-heading", className: "text-xs/5 font-semibold uppercase tracking-wide text-muted-foreground", children: "Negotiation" }), onOpenComposer && (_jsxs(Button, { size: "sm", onClick: onOpenComposer, children: [_jsx(ArrowLeftRight, { "aria-hidden": true, className: "size-4" }), "Counter"] }))] }), _jsxs("div", { ref: scrollRef, className: "relative mt-3 max-h-[480px] overflow-y-auto", children: [events.length === 0 ? (_jsx("p", { className: "py-6 text-center text-sm text-muted-foreground", children: "No activity yet." })) : shouldVirtualize ? (_jsx("ol", { role: "list", "aria-label": "Negotiation timeline", className: "relative", style: { height: virtualizer.getTotalSize() }, onKeyDown: handleKeyDown, children: virtualizer.getVirtualItems().map((row) => {
|
|
83
|
+
return (_jsxs("section", { "aria-labelledby": "negotiation-heading", className: cn("rounded-2xl border border-border/60 bg-card p-4", className), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { id: "negotiation-heading", className: "text-xs/5 font-semibold uppercase tracking-wide text-muted-foreground", children: "Negotiation" }), onOpenComposer && (_jsxs(Button, { size: "sm", onClick: onOpenComposer, children: [_jsx(ArrowLeftRight, { "aria-hidden": true, className: "size-4" }), "Counter"] }))] }), _jsxs("div", { ref: scrollRef, className: "relative mt-3 max-h-[480px] overflow-y-auto", children: [onLoadOlder && events.length > 0 && (_jsx("div", { className: "mb-2 flex justify-center", children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onLoadOlder, disabled: loadOlderDisabled, "aria-label": "Load older events", className: "h-7 text-xs", children: "Load older events" }) })), events.length === 0 ? (_jsx("p", { className: "py-6 text-center text-sm text-muted-foreground", children: "No activity yet." })) : shouldVirtualize ? (_jsx("ol", { role: "list", "aria-label": "Negotiation timeline", className: "relative", style: { height: virtualizer.getTotalSize() }, onKeyDown: handleKeyDown, children: virtualizer.getVirtualItems().map((row) => {
|
|
84
84
|
const ev = events[row.index];
|
|
85
85
|
return (_jsx("div", { ref: virtualizer.measureElement, "data-index": row.index, style: {
|
|
86
86
|
position: "absolute",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation-section.js","sourceRoot":"","sources":["../../src/offer/negotiation-section.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"negotiation-section.js","sourceRoot":"","sources":["../../src/offer/negotiation-section.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type OfferProductBeverage, type OfferProductVariant } from "./offer-product-card";
|
|
3
|
-
import { type OpportunityCardData } from "./opportunity-card";
|
|
4
|
-
import type { MatchEvaluation, OfferAttachmentItem, OfferFxInfo, OfferPartyInfo, OfferPresenceEntry, OfferSectionId, OfferTerms, Perspective, SectionOverride, TimelineEventData } from "./types";
|
|
5
|
-
export type OfferDocumentAction = "counter" | "accept" | "decline" | "withdraw" | "reopen" | "renew";
|
|
1
|
+
import type { MatchEvaluation, OfferAttachmentItem, OfferCounterBody, OfferCounts, OfferFxInfo, OfferParties, OfferPresenceEntry, OfferRaw, OfferSectionId, Perspective, SectionOverride, TimelineEventData } from "./types";
|
|
6
2
|
export interface OfferDocumentProps {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
offer: OfferRaw;
|
|
4
|
+
matchEvaluation: MatchEvaluation | null;
|
|
5
|
+
counts?: OfferCounts;
|
|
6
|
+
fx?: OfferFxInfo | null;
|
|
7
|
+
presence?: OfferPresenceEntry[];
|
|
8
|
+
parties: OfferParties;
|
|
9
|
+
timelineEvents: TimelineEventData[];
|
|
10
|
+
/** Whether there are older timeline events beyond what's loaded. */
|
|
11
|
+
hasMoreTimeline?: boolean;
|
|
12
|
+
/** Load the next older page; OfferDocument exposes this via the negotiation shell. */
|
|
13
|
+
onLoadOlderTimeline?: () => void;
|
|
10
14
|
perspective: Perspective;
|
|
11
15
|
viewerOrgId: string;
|
|
12
|
-
|
|
13
|
-
importer: OfferPartyInfo;
|
|
14
|
-
opportunity: OpportunityCardData;
|
|
15
|
-
beverage: OfferProductBeverage;
|
|
16
|
-
variant: OfferProductVariant;
|
|
17
|
-
terms: OfferTerms;
|
|
18
|
-
previousTerms?: OfferTerms;
|
|
19
|
-
evaluation: MatchEvaluation;
|
|
20
|
-
attachments: OfferAttachmentItem[];
|
|
21
|
-
events: TimelineEventData[];
|
|
22
|
-
presence: OfferPresenceEntry[];
|
|
23
|
-
fx?: OfferFxInfo;
|
|
16
|
+
/** Currency the tender was denominated in — enables FX display in FactsCard. */
|
|
24
17
|
tenderCurrency?: string;
|
|
25
|
-
|
|
18
|
+
onCounter: (body: OfferCounterBody) => Promise<void>;
|
|
19
|
+
onAccept: () => Promise<void>;
|
|
20
|
+
onDecline: () => Promise<void>;
|
|
21
|
+
onWithdraw: () => Promise<void>;
|
|
22
|
+
onUploadAttachment?: (file: File) => Promise<void>;
|
|
23
|
+
/** Optional "reopen" / "renew" terminal-state escape hatches. */
|
|
24
|
+
onReopen?: () => Promise<void>;
|
|
25
|
+
onRenew?: () => Promise<void>;
|
|
26
|
+
/** True when the socket is reconnecting; renders a non-blocking banner. */
|
|
27
|
+
isReconnecting?: boolean;
|
|
26
28
|
sections?: Partial<Record<OfferSectionId, SectionOverride>>;
|
|
27
|
-
onAction: (action: OfferDocumentAction) => void;
|
|
28
|
-
onOpenComposer?: () => void;
|
|
29
29
|
onOpenAttachment?: (a: OfferAttachmentItem) => void;
|
|
30
30
|
className?: string;
|
|
31
31
|
}
|
|
32
|
-
export declare function OfferDocument({
|
|
32
|
+
export declare function OfferDocument({ offer, matchEvaluation, counts, fx, presence, parties, timelineEvents, hasMoreTimeline: _hasMoreTimeline, onLoadOlderTimeline, perspective, viewerOrgId, tenderCurrency, onCounter, onAccept, onDecline, onWithdraw, onUploadAttachment, onReopen, onRenew, isReconnecting, sections, onOpenAttachment, className, }: OfferDocumentProps): import("react/jsx-runtime").JSX.Element;
|
|
33
33
|
//# sourceMappingURL=offer-document.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offer-document.d.ts","sourceRoot":"","sources":["../../src/offer/offer-document.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"offer-document.d.ts","sourceRoot":"","sources":["../../src/offer/offer-document.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,YAAY,EAEZ,kBAAkB,EAClB,QAAQ,EACR,cAAc,EAEd,WAAW,EACX,eAAe,EACf,iBAAiB,EAElB,MAAM,SAAS,CAAC;AASjB,MAAM,WAAW,kBAAkB;IAEjC,KAAK,EAAE,QAAQ,CAAC;IAChB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,EAAE,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,oEAAoE;IACpE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sFAAsF;IACtF,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IAGjC,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,SAAS,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAG9B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,CAAC;IAC5D,gBAAgB,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgOD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,eAAe,EACf,MAAM,EACN,EAAE,EACF,QAAQ,EACR,OAAO,EACP,cAAc,EACd,eAAe,EAAE,gBAAgB,EACjC,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,cAAc,EACd,SAAS,EACT,QAAQ,EACR,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,OAAO,EACP,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,SAAS,GACV,EAAE,kBAAkB,2CAmSpB"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useMemo } from "react";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { cn } from "../lib/utils";
|
|
4
4
|
import { ShadcnButton as Button } from "../components/shadcn-button";
|
|
5
5
|
import { AttachmentsCard } from "./attachments-card";
|
|
6
6
|
import { BuyerNotesCard } from "./buyer-notes-card";
|
|
7
|
+
import { CounterSlideOver } from "./counter-slide-over";
|
|
7
8
|
import { FactsCard } from "./facts-card";
|
|
8
9
|
import { MatchCompatibilityCard } from "./match-compatibility-card";
|
|
9
10
|
import { NegotiationSection } from "./negotiation-section";
|
|
@@ -22,7 +23,31 @@ const DEFAULT_ORDER = [
|
|
|
22
23
|
"attachments",
|
|
23
24
|
"negotiation",
|
|
24
25
|
];
|
|
25
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Map the backend offer status enum onto the narrower FactsCardStatus
|
|
28
|
+
* surface the rail + facts strip render against. Unknown strings fall
|
|
29
|
+
* through to "proposed" so a partial payload still renders.
|
|
30
|
+
*/
|
|
31
|
+
function mapOfferStatus(raw) {
|
|
32
|
+
switch (raw) {
|
|
33
|
+
case "counter_pending":
|
|
34
|
+
return "counter_pending";
|
|
35
|
+
case "accepted":
|
|
36
|
+
return "accepted";
|
|
37
|
+
case "declined":
|
|
38
|
+
case "rejected":
|
|
39
|
+
return "declined";
|
|
40
|
+
case "expired":
|
|
41
|
+
return "expired";
|
|
42
|
+
case "withdrawn":
|
|
43
|
+
return "withdrawn";
|
|
44
|
+
// Negotiation "working" states — draft / submitted / sent /
|
|
45
|
+
// in_negotiation / proposed — all render as "proposed" to the rail.
|
|
46
|
+
default:
|
|
47
|
+
return "proposed";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function deriveRailActions(status, viewerInitiator) {
|
|
26
51
|
switch (status) {
|
|
27
52
|
case "proposed":
|
|
28
53
|
return viewerInitiator ? ["withdraw"] : ["counter", "accept", "decline"];
|
|
@@ -39,11 +64,6 @@ function producerCtas(status, viewerInitiator) {
|
|
|
39
64
|
return [];
|
|
40
65
|
}
|
|
41
66
|
}
|
|
42
|
-
// Blocker B9 — CTA aria-label composition. Screen-reader users should
|
|
43
|
-
// hear the full context ("Accept offer for Barolo DOCG 2020 from Fattoria
|
|
44
|
-
// San Marco") rather than a raw UUID ("Accept offer offer-1"). When the
|
|
45
|
-
// beverage or producer name is missing (defensive — this should not
|
|
46
|
-
// happen in practice), we fall back to the offer id segment.
|
|
47
67
|
const ACTION_VERB = {
|
|
48
68
|
counter: "Counter",
|
|
49
69
|
accept: "Accept",
|
|
@@ -54,23 +74,12 @@ const ACTION_VERB = {
|
|
|
54
74
|
};
|
|
55
75
|
function ctaAriaLabel(action, beverageName, producerName, offerId) {
|
|
56
76
|
const verb = ACTION_VERB[action];
|
|
57
|
-
if (beverageName && producerName)
|
|
77
|
+
if (beverageName && producerName)
|
|
58
78
|
return `${verb} offer for ${beverageName} from ${producerName}`;
|
|
59
|
-
}
|
|
60
79
|
if (beverageName)
|
|
61
80
|
return `${verb} offer for ${beverageName}`;
|
|
62
|
-
// Defensive fallback — should never fire because OfferDocumentProps
|
|
63
|
-
// requires `beverage.name` and `producer.name`, but keeps the aria-label
|
|
64
|
-
// non-empty even if a consumer passes an empty string.
|
|
65
81
|
return `${verb} offer ${offerId}`;
|
|
66
82
|
}
|
|
67
|
-
// Blocker B9 / spec §19 — Screen-reader announcement on offer state
|
|
68
|
-
// transitions. The OfferDocument rail exposes a dedicated
|
|
69
|
-
// `role="status"` live region separate from FactsCard's price-focused
|
|
70
|
-
// live region. It emits a composed sentence like
|
|
71
|
-
// "Offer accepted — no further counters possible"
|
|
72
|
-
// whenever the `status` prop changes. This is the region that the
|
|
73
|
-
// `StateTransitionAnnouncement` story asserts against.
|
|
74
83
|
const STATE_TRANSITION_SENTENCE = {
|
|
75
84
|
proposed: "Offer proposed — awaiting counterparty response",
|
|
76
85
|
counter_pending: "Counter pending — awaiting review",
|
|
@@ -79,7 +88,149 @@ const STATE_TRANSITION_SENTENCE = {
|
|
|
79
88
|
expired: "Offer expired — validity window closed",
|
|
80
89
|
withdrawn: "Offer withdrawn by initiator",
|
|
81
90
|
};
|
|
82
|
-
|
|
91
|
+
function numberOrNull(v) {
|
|
92
|
+
if (v == null)
|
|
93
|
+
return null;
|
|
94
|
+
const n = typeof v === "string" ? Number(v) : v;
|
|
95
|
+
return Number.isFinite(n) ? n : null;
|
|
96
|
+
}
|
|
97
|
+
function deriveTerms(offer) {
|
|
98
|
+
const price = numberOrNull(offer.price) ?? 0;
|
|
99
|
+
const volume = numberOrNull(offer.availableVolume ?? offer.volume) ?? 0;
|
|
100
|
+
const validUntil = typeof offer.validThrough === "string"
|
|
101
|
+
? offer.validThrough
|
|
102
|
+
: offer.validThrough instanceof Date
|
|
103
|
+
? offer.validThrough.toISOString()
|
|
104
|
+
: undefined;
|
|
105
|
+
return {
|
|
106
|
+
price,
|
|
107
|
+
currency: offer.currency ?? "EUR",
|
|
108
|
+
volume,
|
|
109
|
+
paymentTerms: offer.paymentTerms ?? undefined,
|
|
110
|
+
incoterms: offer.deliveryTerms ?? undefined,
|
|
111
|
+
validUntil,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function derivePreviousTerms(offer) {
|
|
115
|
+
const prev = offer.previousRoundTerms;
|
|
116
|
+
if (!prev || typeof prev !== "object")
|
|
117
|
+
return undefined;
|
|
118
|
+
const price = numberOrNull(prev.price);
|
|
119
|
+
const volume = numberOrNull(prev.volume);
|
|
120
|
+
if (price == null && volume == null)
|
|
121
|
+
return undefined;
|
|
122
|
+
return {
|
|
123
|
+
price: price ?? 0,
|
|
124
|
+
currency: prev.currency ?? offer.currency ?? "EUR",
|
|
125
|
+
volume: volume ?? 0,
|
|
126
|
+
paymentTerms: prev.paymentTerms,
|
|
127
|
+
incoterms: prev.incoterms,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function deriveProducer(offer, parties) {
|
|
131
|
+
const snap = (offer.orgSnapshot ?? {});
|
|
132
|
+
const region = typeof snap.region === "string" ? snap.region : undefined;
|
|
133
|
+
const city = typeof snap.city === "string" ? snap.city : undefined;
|
|
134
|
+
const country = parties.producer.country ?? (typeof snap.country === "string" ? snap.country : undefined);
|
|
135
|
+
const location = [city, region, country].filter(Boolean).join(", ") || undefined;
|
|
136
|
+
return {
|
|
137
|
+
orgId: parties.producer.orgId,
|
|
138
|
+
name: parties.producer.name ?? (typeof snap.name === "string" ? snap.name : "Producer"),
|
|
139
|
+
location,
|
|
140
|
+
logoUrl: parties.producer.logoUrl ?? (typeof snap.logoUrl === "string" ? snap.logoUrl : undefined),
|
|
141
|
+
primaryContactName: typeof snap.primaryContactName === "string" ? snap.primaryContactName : undefined,
|
|
142
|
+
primaryContactEmail: typeof snap.primaryContactEmail === "string" ? snap.primaryContactEmail : undefined,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function deriveImporter(parties) {
|
|
146
|
+
if (!parties.importer) {
|
|
147
|
+
// A declarable placeholder — PartiesCard tolerates "TBD" / empty name and
|
|
148
|
+
// rendering stays stable for draft / unsent offers that have no recipient yet.
|
|
149
|
+
return { orgId: "", name: "Pending recipient", location: undefined };
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
orgId: parties.importer.orgId,
|
|
153
|
+
name: parties.importer.name ?? "Importer",
|
|
154
|
+
location: parties.importer.country ?? undefined,
|
|
155
|
+
logoUrl: parties.importer.logoUrl ?? undefined,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function deriveOpportunity(offer) {
|
|
159
|
+
const snap = (offer.opportunitySnapshot ?? {});
|
|
160
|
+
const title = typeof snap.name === "string" ? snap.name : "Opportunity";
|
|
161
|
+
const deadlineIso = typeof snap.deadline === "string" ? snap.deadline : snap.deadline instanceof Date ? snap.deadline.toISOString() : null;
|
|
162
|
+
const closingDays = deadlineIso
|
|
163
|
+
? Math.max(0, Math.ceil((new Date(deadlineIso).getTime() - Date.now()) / (1000 * 60 * 60 * 24)))
|
|
164
|
+
: 0;
|
|
165
|
+
const priceMax = numberOrNull(snap.priceMax);
|
|
166
|
+
const volumeLiters = numberOrNull(snap.volumeLiters);
|
|
167
|
+
const requirements = [];
|
|
168
|
+
if (typeof snap.description === "string" && snap.description.trim())
|
|
169
|
+
requirements.push(snap.description);
|
|
170
|
+
if (Array.isArray(snap.certificateRequirements)) {
|
|
171
|
+
for (const c of snap.certificateRequirements) {
|
|
172
|
+
if (typeof c === "string")
|
|
173
|
+
requirements.push(`Certification: ${c}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
id: offer.opportunityId ?? "",
|
|
178
|
+
title,
|
|
179
|
+
closingDays,
|
|
180
|
+
priceCeilingEuro: priceMax ?? undefined,
|
|
181
|
+
volumeOptions: volumeLiters != null ? [volumeLiters] : undefined,
|
|
182
|
+
requirements: requirements.length ? requirements : undefined,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function deriveProduct(offer) {
|
|
186
|
+
const snap = (offer.variantSnapshot ?? {});
|
|
187
|
+
const bevType = (snap.beverageType ?? {});
|
|
188
|
+
const beverage = {
|
|
189
|
+
id: typeof snap.beverageId === "string" ? snap.beverageId : "",
|
|
190
|
+
name: typeof snap.beverageName === "string" ? snap.beverageName : "Product",
|
|
191
|
+
producer: typeof snap.producer === "string" ? snap.producer : undefined,
|
|
192
|
+
countryOfOrigin: typeof snap.countryOfOrigin === "string" ? snap.countryOfOrigin : undefined,
|
|
193
|
+
beverageType: {
|
|
194
|
+
category: typeof bevType.category === "string" ? bevType.category : undefined,
|
|
195
|
+
subtype: typeof bevType.subtype === "string" ? bevType.subtype : undefined,
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
const variant = {
|
|
199
|
+
id: typeof snap.variantId === "string"
|
|
200
|
+
? snap.variantId
|
|
201
|
+
: (offer.variantId ?? ""),
|
|
202
|
+
vintage: typeof snap.vintage === "number" ? snap.vintage : null,
|
|
203
|
+
packaging: typeof snap.packaging === "string" ? snap.packaging : undefined,
|
|
204
|
+
closure: typeof snap.closure === "string" ? snap.closure : undefined,
|
|
205
|
+
abv: numberOrNull(snap.abv),
|
|
206
|
+
residualSugar: numberOrNull(snap.residualSugar),
|
|
207
|
+
organic: Boolean(snap.organic),
|
|
208
|
+
fairtrade: Boolean(snap.fairtrade),
|
|
209
|
+
sustainable: Boolean(snap.sustainable),
|
|
210
|
+
imageUrl: typeof snap.imageUrl === "string" ? snap.imageUrl : null,
|
|
211
|
+
};
|
|
212
|
+
return { beverage, variant };
|
|
213
|
+
}
|
|
214
|
+
const NEUTRAL_EVALUATION = {
|
|
215
|
+
headline: "partial",
|
|
216
|
+
headlineSummary: "Match evaluation unavailable",
|
|
217
|
+
criteria: [],
|
|
218
|
+
freeTextFields: [],
|
|
219
|
+
hiddenReasons: [],
|
|
220
|
+
};
|
|
221
|
+
export function OfferDocument({ offer, matchEvaluation, counts, fx, presence, parties, timelineEvents, hasMoreTimeline: _hasMoreTimeline, onLoadOlderTimeline, perspective, viewerOrgId, tenderCurrency, onCounter, onAccept, onDecline, onWithdraw, onUploadAttachment, onReopen, onRenew, isReconnecting, sections, onOpenAttachment, className, }) {
|
|
222
|
+
const offerId = offer.offerId ?? offer.id ?? "";
|
|
223
|
+
const status = mapOfferStatus(offer.status);
|
|
224
|
+
const round = offer.currentRound ?? 1;
|
|
225
|
+
const terms = useMemo(() => deriveTerms(offer), [offer]);
|
|
226
|
+
const previousTerms = useMemo(() => derivePreviousTerms(offer), [offer]);
|
|
227
|
+
const producer = useMemo(() => deriveProducer(offer, parties), [offer, parties]);
|
|
228
|
+
const importer = useMemo(() => deriveImporter(parties), [parties]);
|
|
229
|
+
const opportunity = useMemo(() => deriveOpportunity(offer), [offer]);
|
|
230
|
+
const { beverage, variant } = useMemo(() => deriveProduct(offer), [offer]);
|
|
231
|
+
const evaluation = matchEvaluation ?? NEUTRAL_EVALUATION;
|
|
232
|
+
const attachments = offer.attachments ?? [];
|
|
233
|
+
const presenceList = presence ?? [];
|
|
83
234
|
const orderedIds = useMemo(() => {
|
|
84
235
|
const overrides = sections ?? {};
|
|
85
236
|
const active = DEFAULT_ORDER.filter((id) => !overrides[id]?.hidden);
|
|
@@ -90,36 +241,105 @@ export function OfferDocument({ offerId, status, round, perspective, viewerOrgId
|
|
|
90
241
|
});
|
|
91
242
|
}, [sections]);
|
|
92
243
|
const viewerInitiator = (status === "proposed" && viewerOrgId === producer.orgId) ||
|
|
93
|
-
(status === "counter_pending" &&
|
|
94
|
-
const
|
|
95
|
-
// Blocker B3 — viewerAdvantage is per-criterion and per-round. It must
|
|
96
|
-
// come from the backend evaluator (Plan 2) where each `MatchCriterion`
|
|
97
|
-
// carries its own `viewerAdvantage` scoped to the viewer. A flat
|
|
98
|
-
// page-level constant is wrong per spec §11: "Delta polarity: Producer:
|
|
99
|
-
// emerald · Importer: rose" describes a per-field rule, not a page-wide
|
|
100
|
-
// tone. We do NOT compute one here. Downstream cards that need the top-
|
|
101
|
-
// line viewer advantage (e.g. FactsCard price delta) derive it from the
|
|
102
|
-
// `price` criterion's own `viewerAdvantage`, with "neutral" as a safe
|
|
103
|
-
// fallback when the criterion is missing / FX-unavailable (§6.6).
|
|
244
|
+
(status === "counter_pending" && timelineEvents[timelineEvents.length - 1]?.actorOrgId === viewerOrgId);
|
|
245
|
+
const railActions = deriveRailActions(status, viewerInitiator);
|
|
104
246
|
const priceCriterion = evaluation.criteria.find((c) => c.id === "price");
|
|
105
247
|
const topLineAdvantage = priceCriterion?.viewerAdvantage ?? "neutral";
|
|
106
|
-
// Stable document-generation timestamp: captured once per mount, not on every re-render.
|
|
107
248
|
const printedAt = useMemo(() => new Date().toISOString(), []);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
249
|
+
/* ── Composer (CounterSlideOver) — owned internally ── */
|
|
250
|
+
const [composerOpen, setComposerOpen] = useState(false);
|
|
251
|
+
/**
|
|
252
|
+
* Mid-compose race banner: when the counterparty lands a new round while
|
|
253
|
+
* the composer is open, we surface a diff banner inside the composer and
|
|
254
|
+
* let the user re-pre-fill from the new round. The banner is driven by a
|
|
255
|
+
* latched `bannerRound` — if the prop `round` changes while the composer
|
|
256
|
+
* is open AND differs from the round we opened at, the banner fires.
|
|
257
|
+
*/
|
|
258
|
+
const openedAtRound = useRef(null);
|
|
259
|
+
const [composerBanner, setComposerBanner] = useState(undefined);
|
|
260
|
+
useEffect(() => {
|
|
261
|
+
if (!composerOpen)
|
|
262
|
+
return;
|
|
263
|
+
if (openedAtRound.current == null) {
|
|
264
|
+
openedAtRound.current = round;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (round !== openedAtRound.current) {
|
|
268
|
+
setComposerBanner({
|
|
269
|
+
kind: "incoming_counter",
|
|
270
|
+
roundN: round,
|
|
271
|
+
headline: "The counterparty sent a new counter while you were composing.",
|
|
272
|
+
onDismiss: () => setComposerBanner(undefined),
|
|
273
|
+
onReset: () => setComposerBanner(undefined),
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}, [composerOpen, round]);
|
|
277
|
+
useEffect(() => {
|
|
278
|
+
if (!composerOpen) {
|
|
279
|
+
openedAtRound.current = null;
|
|
280
|
+
setComposerBanner(undefined);
|
|
281
|
+
}
|
|
282
|
+
}, [composerOpen]);
|
|
283
|
+
const handleRailClick = async (a) => {
|
|
284
|
+
try {
|
|
285
|
+
switch (a) {
|
|
286
|
+
case "counter":
|
|
287
|
+
setComposerOpen(true);
|
|
288
|
+
return;
|
|
289
|
+
case "accept":
|
|
290
|
+
await onAccept();
|
|
291
|
+
return;
|
|
292
|
+
case "decline":
|
|
293
|
+
await onDecline();
|
|
294
|
+
return;
|
|
295
|
+
case "withdraw":
|
|
296
|
+
await onWithdraw();
|
|
297
|
+
return;
|
|
298
|
+
case "reopen":
|
|
299
|
+
await onReopen?.();
|
|
300
|
+
return;
|
|
301
|
+
case "renew":
|
|
302
|
+
await onRenew?.();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
/* Dashboard owns toast / retry — we stay silent here. */
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
const attachmentInputRef = useRef(null);
|
|
311
|
+
const handleAttachmentUpload = () => {
|
|
312
|
+
attachmentInputRef.current?.click();
|
|
313
|
+
};
|
|
314
|
+
const handleAttachmentFileChange = async (event) => {
|
|
315
|
+
const file = event.target.files?.[0];
|
|
316
|
+
event.target.value = ""; // reset so the same file can be re-selected
|
|
317
|
+
if (!file || !onUploadAttachment)
|
|
318
|
+
return;
|
|
319
|
+
try {
|
|
320
|
+
await onUploadAttachment(file);
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
/* Dashboard owns toast. */
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
return (_jsxs("div", { "data-offer-document": true, "data-offer-id": offerId, "data-printed-at": printedAt, className: cn("mx-auto w-full max-w-6xl space-y-4 p-4", className), children: [isReconnecting && (_jsx("div", { role: "status", "aria-live": "polite", className: "rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-50", children: "Reconnecting\u2026" })), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("nav", { "data-offer-nav-chrome": true, "aria-label": "breadcrumb", className: "text-xs text-muted-foreground", children: [perspective === "producer" ? "Sprint board" : "Offers", " / Offer ", offerId.slice(0, 8)] }), _jsx(OfferExportButton, { offerId: offerId })] }), _jsx("div", { role: "status", "aria-live": "polite", className: "sr-only", children: STATE_TRANSITION_SENTENCE[status] }), _jsx("div", { "data-offer-facts-card": true, children: _jsx(FactsCard, { status: status, round: round, terms: terms, previousPrice: previousTerms?.price, viewerAdvantage: topLineAdvantage, perspective: perspective, presence: presenceList, fx: fx ?? undefined, tenderCurrency: tenderCurrency, onExport: () => window.print() }) }), _jsxs("div", { className: "grid grid-cols-1 gap-4 lg:grid-cols-[minmax(0,1fr)_220px]", children: [_jsx("main", { className: "space-y-4", children: orderedIds.map((id) => (_jsxs("div", { "data-offer-section": true, "data-section-id": id, children: [id === "parties" && (_jsx(PartiesCard, { producer: producer, importer: importer, viewerOrgId: viewerOrgId, variant: sections?.parties?.defaultOpen ? "expanded" : "collapsed" })), id === "opportunity" && (_jsx(OpportunityCard, { opportunity: opportunity, variant: sections?.opportunity?.defaultOpen ? "expanded" : "collapsed" })), id === "product" && (_jsx(OfferProductCard, { variant: variant, beverage: beverage, variantDisplay: sections?.product?.defaultOpen === false ? "collapsed" : "expanded" })), id === "terms" && (_jsx(TermsCard, { terms: terms, previousTerms: previousTerms, variant: sections?.terms?.defaultOpen ? "expanded" : "collapsed", perspective: perspective })), id === "match" && _jsx(MatchCompatibilityCard, { evaluation: evaluation, perspective: perspective }), id === "notes" && _jsx(BuyerNotesCard, { notes: evaluation.freeTextFields }), id === "attachments" && (_jsx(AttachmentsCard, { attachments: attachments, onOpen: (a) => onOpenAttachment?.(a), onUpload: onUploadAttachment ? handleAttachmentUpload : undefined })), id === "negotiation" && (_jsx(NegotiationSection, { events: timelineEvents, viewerOrgId: viewerOrgId, viewerRole: perspective, onOpenComposer: () => setComposerOpen(true), onLoadOlder: onLoadOlderTimeline }))] }, id))) }), _jsx("aside", { "data-offer-rail": true, "aria-label": "Actions and meta", className: "hidden lg:block", children: _jsxs("div", { className: "sticky top-24 space-y-3", children: [_jsxs("div", { className: "rounded-xl border border-border/60 bg-card p-3", children: [_jsx("div", { className: "text-xs uppercase tracking-wide text-muted-foreground", children: "Actions" }), _jsxs("div", { className: "mt-2 flex flex-wrap gap-2", children: [railActions.length === 0 && _jsx("span", { className: "text-xs text-muted-foreground", children: "No actions available." }), railActions.map((a) => (_jsx(Button, { size: "sm", "aria-label": ctaAriaLabel(a, beverage.name, producer.name, offerId), onClick: () => void handleRailClick(a), children: ACTION_VERB[a] }, a)))] })] }), _jsxs("div", { className: "rounded-xl border border-border/60 bg-card p-3 text-xs", children: [_jsx("div", { className: "uppercase tracking-wide text-muted-foreground", children: "Status" }), _jsx("div", { className: "mt-1 font-medium capitalize", children: status.replace("_", " ") }), _jsxs("div", { className: "mt-1 text-muted-foreground", children: ["R", round, " of 4 max"] })] }), _jsxs("div", { className: "rounded-xl border border-border/60 bg-card p-3 text-xs", children: [_jsx("div", { className: "uppercase tracking-wide text-muted-foreground", children: "Offer" }), _jsx("div", { className: "mt-1 font-mono", children: offerId }), _jsxs("div", { className: "mt-1 text-muted-foreground", children: [(counts?.messages ?? timelineEvents.length), " events \u00B7 ", counts?.attachments ?? attachments.length, " files"] })] }), _jsxs("div", { className: "rounded-xl border border-border/60 bg-card p-3", children: [_jsx("div", { className: "text-xs uppercase tracking-wide text-muted-foreground", children: "Export" }), _jsx("div", { className: "mt-2", children: _jsx(OfferExportButton, { offerId: offerId }) })] })] }) })] }), _jsx("input", { ref: attachmentInputRef, type: "file", className: "sr-only", "aria-hidden": true, onChange: handleAttachmentFileChange }), _jsx(CounterSlideOver, { open: composerOpen, onClose: () => setComposerOpen(false), offerId: offerId, round: round, allowedIncoterms: ["EXW", "FCA", "CIF", "CIP", "DAP", "DDP"], baselineTerms: previousTerms ?? terms, initialMatchEvaluation: evaluation, onSubmit: async (draft) => {
|
|
327
|
+
const body = {
|
|
328
|
+
clientEventId: typeof crypto !== "undefined" && typeof crypto.randomUUID === "function"
|
|
329
|
+
? crypto.randomUUID()
|
|
330
|
+
: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
|
331
|
+
expectedRound: round,
|
|
332
|
+
price: draft.price ?? null,
|
|
333
|
+
volume: draft.volume ?? null,
|
|
334
|
+
incoterms: draft.incoterms ?? null,
|
|
335
|
+
payment: draft.paymentTerms ?? null,
|
|
336
|
+
delivery: draft.deliveryDate ?? null,
|
|
337
|
+
validUntil: draft.validUntil ?? null,
|
|
338
|
+
message: draft.message ?? null,
|
|
339
|
+
attachmentIds: draft.attachmentIds,
|
|
340
|
+
};
|
|
341
|
+
await onCounter(body);
|
|
342
|
+
setComposerOpen(false);
|
|
343
|
+
}, onEvaluateDraft: () => evaluation, banner: composerBanner })] }));
|
|
124
344
|
}
|
|
125
345
|
//# sourceMappingURL=offer-document.js.map
|