@cellarnode/ui 0.8.7 → 0.8.9

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 (65) hide show
  1. package/dist/components/attachment-row.d.ts +23 -0
  2. package/dist/components/attachment-row.d.ts.map +1 -0
  3. package/dist/components/attachment-row.js +61 -0
  4. package/dist/components/attachment-row.js.map +1 -0
  5. package/dist/components/attachment-row.stories.d.ts +9 -0
  6. package/dist/components/attachment-row.stories.d.ts.map +1 -0
  7. package/dist/components/attachment-row.stories.js +65 -0
  8. package/dist/components/attachment-row.stories.js.map +1 -0
  9. package/dist/components/certification-upload-card.d.ts +19 -0
  10. package/dist/components/certification-upload-card.d.ts.map +1 -0
  11. package/dist/components/certification-upload-card.js +74 -0
  12. package/dist/components/certification-upload-card.js.map +1 -0
  13. package/dist/components/certification-upload-card.stories.d.ts +9 -0
  14. package/dist/components/certification-upload-card.stories.d.ts.map +1 -0
  15. package/dist/components/certification-upload-card.stories.js +44 -0
  16. package/dist/components/certification-upload-card.stories.js.map +1 -0
  17. package/dist/components/composition-editor.d.ts +29 -0
  18. package/dist/components/composition-editor.d.ts.map +1 -0
  19. package/dist/components/composition-editor.js +60 -0
  20. package/dist/components/composition-editor.js.map +1 -0
  21. package/dist/components/composition-editor.stories.d.ts +15 -0
  22. package/dist/components/composition-editor.stories.d.ts.map +1 -0
  23. package/dist/components/composition-editor.stories.js +51 -0
  24. package/dist/components/composition-editor.stories.js.map +1 -0
  25. package/dist/components/confirmation-dialog.d.ts.map +1 -1
  26. package/dist/components/confirmation-dialog.js +1 -0
  27. package/dist/components/confirmation-dialog.js.map +1 -1
  28. package/dist/components/contact-person-select.d.ts +16 -0
  29. package/dist/components/contact-person-select.d.ts.map +1 -0
  30. package/dist/components/contact-person-select.js +19 -0
  31. package/dist/components/contact-person-select.js.map +1 -0
  32. package/dist/components/contact-person-select.stories.d.ts +16 -0
  33. package/dist/components/contact-person-select.stories.d.ts.map +1 -0
  34. package/dist/components/contact-person-select.stories.js +56 -0
  35. package/dist/components/contact-person-select.stories.js.map +1 -0
  36. package/dist/components/price-comparison.d.ts +13 -0
  37. package/dist/components/price-comparison.d.ts.map +1 -0
  38. package/dist/components/price-comparison.js +60 -0
  39. package/dist/components/price-comparison.js.map +1 -0
  40. package/dist/components/price-comparison.stories.d.ts +11 -0
  41. package/dist/components/price-comparison.stories.d.ts.map +1 -0
  42. package/dist/components/price-comparison.stories.js +56 -0
  43. package/dist/components/price-comparison.stories.js.map +1 -0
  44. package/dist/components/variant-picker-dialog.d.ts.map +1 -1
  45. package/dist/components/variant-picker-dialog.js +1 -0
  46. package/dist/components/variant-picker-dialog.js.map +1 -1
  47. package/dist/globe/globe-canvas.d.ts.map +1 -1
  48. package/dist/globe/globe-canvas.js +1 -0
  49. package/dist/globe/globe-canvas.js.map +1 -1
  50. package/dist/globe/globe-tooltip.d.ts.map +1 -1
  51. package/dist/globe/globe-tooltip.js +58 -18
  52. package/dist/globe/globe-tooltip.js.map +1 -1
  53. package/dist/globe/globe-types.d.ts +4 -0
  54. package/dist/globe/globe-types.d.ts.map +1 -1
  55. package/dist/globe/globe-view.d.ts.map +1 -1
  56. package/dist/globe/globe-view.js +29 -13
  57. package/dist/globe/globe-view.js.map +1 -1
  58. package/dist/index.d.ts +10 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +5 -0
  61. package/dist/index.js.map +1 -1
  62. package/dist/org/invite-member-dialog.d.ts.map +1 -1
  63. package/dist/org/invite-member-dialog.js +2 -0
  64. package/dist/org/invite-member-dialog.js.map +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ export interface AttachmentRowFile {
2
+ id: string;
3
+ fileName: string;
4
+ name?: string | null;
5
+ mimeType: string;
6
+ fileSize: number;
7
+ type?: string;
8
+ }
9
+ export interface AttachmentRowProps {
10
+ file: AttachmentRowFile;
11
+ typeOptions: Array<{
12
+ value: string;
13
+ label: string;
14
+ }>;
15
+ autoAttached?: boolean;
16
+ onRename?: (id: string, newName: string) => void;
17
+ onTypeChange?: (id: string, newType: string) => void;
18
+ onRemove?: (id: string) => void;
19
+ onDownload?: (id: string) => void;
20
+ className?: string;
21
+ }
22
+ export declare function AttachmentRow({ file, typeOptions, autoAttached, onRename, onTypeChange, onRemove, onDownload, className, }: AttachmentRowProps): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=attachment-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-row.d.ts","sourceRoot":"","sources":["../../src/components/attachment-row.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC;IACxB,WAAW,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,SAAS,GACV,EAAE,kBAAkB,2CA2HpB"}
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cn } from "../lib/utils";
4
+ function formatFileSize(bytes) {
5
+ if (bytes < 1024)
6
+ return `${bytes} B`;
7
+ if (bytes < 1024 * 1024)
8
+ return `${Math.round(bytes / 1024)} KB`;
9
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
10
+ }
11
+ function getFileIcon(mimeType) {
12
+ if (mimeType === "application/pdf") {
13
+ return { label: "PDF", bgClass: "bg-red-500/15 text-red-600 dark:bg-red-500/20 dark:text-red-400" };
14
+ }
15
+ if (mimeType.startsWith("image/")) {
16
+ return { label: "IMG", bgClass: "bg-sky-500/15 text-sky-600 dark:bg-sky-500/20 dark:text-sky-400" };
17
+ }
18
+ return { label: "FILE", bgClass: "bg-muted text-muted-foreground" };
19
+ }
20
+ export function AttachmentRow({ file, typeOptions, autoAttached, onRename, onTypeChange, onRemove, onDownload, className, }) {
21
+ const [editing, setEditing] = React.useState(false);
22
+ const [editValue, setEditValue] = React.useState("");
23
+ const inputRef = React.useRef(null);
24
+ const displayName = file.name ?? file.fileName;
25
+ const icon = getFileIcon(file.mimeType);
26
+ React.useEffect(() => {
27
+ if (editing && inputRef.current) {
28
+ inputRef.current.focus();
29
+ inputRef.current.select();
30
+ }
31
+ }, [editing]);
32
+ function startEditing() {
33
+ if (!onRename)
34
+ return;
35
+ setEditValue(displayName);
36
+ setEditing(true);
37
+ }
38
+ function commitEdit() {
39
+ const trimmed = editValue.trim();
40
+ if (trimmed && trimmed !== displayName) {
41
+ onRename?.(file.id, trimmed);
42
+ }
43
+ setEditing(false);
44
+ }
45
+ function cancelEdit() {
46
+ setEditing(false);
47
+ }
48
+ function handleKeyDown(e) {
49
+ if (e.key === "Enter") {
50
+ e.preventDefault();
51
+ commitEdit();
52
+ }
53
+ else if (e.key === "Escape") {
54
+ e.preventDefault();
55
+ cancelEdit();
56
+ }
57
+ }
58
+ return (_jsxs("div", { className: cn("flex items-center gap-3 rounded-xl border border-border bg-background px-3.5 py-2.5", className), children: [_jsx("div", { className: cn("flex size-9 shrink-0 items-center justify-center rounded-lg text-xs font-bold", icon.bgClass), children: icon.label }), _jsxs("div", { className: "min-w-0 flex-1", children: [editing ? (_jsx("input", { ref: inputRef, type: "text", value: editValue, onChange: (e) => setEditValue(e.target.value), onBlur: commitEdit, onKeyDown: handleKeyDown, className: "w-full border-b border-dashed border-primary bg-transparent text-sm font-medium text-foreground outline-none" })) : (_jsx("button", { type: "button", onClick: onRename ? startEditing : onDownload ? () => onDownload(file.id) : undefined, className: cn("truncate text-left text-sm font-medium text-foreground", onRename &&
59
+ "cursor-text border-b border-dashed border-transparent hover:border-primary/40", !onRename && onDownload && "cursor-pointer hover:underline", !onRename && !onDownload && "cursor-default"), children: displayName })), _jsxs("p", { className: "text-[10px] text-muted-foreground", children: [formatFileSize(file.fileSize), autoAttached && (_jsx("span", { className: "ml-1.5", children: "\u00B7 Auto-attached from portfolio" }))] })] }), _jsx("select", { value: file.type ?? "generic", onChange: (e) => onTypeChange?.(file.id, e.target.value), className: "shrink-0 rounded-lg border border-border bg-background px-2 py-1 text-[11px] text-foreground", children: typeOptions.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) }), onRemove && (_jsx("button", { type: "button", onClick: () => onRemove(file.id), className: "shrink-0 text-sm text-muted-foreground transition-colors hover:text-red-500", "aria-label": "Remove attachment", children: "\u00D7" }))] }));
60
+ }
61
+ //# sourceMappingURL=attachment-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-row.js","sourceRoot":"","sources":["../../src/components/attachment-row.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { AttachmentRow } from "./attachment-row";
3
+ declare const meta: Meta<typeof AttachmentRow>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const Default: Story;
7
+ export declare const AutoAttached: Story;
8
+ export declare const WithEditableName: Story;
9
+ //# sourceMappingURL=attachment-row.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-row.stories.d.ts","sourceRoot":"","sources":["../../src/components/attachment-row.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAQjD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAOpC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAcrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAe1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAgB9B,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AttachmentRow } from "./attachment-row";
3
+ const typeOptions = [
4
+ { value: "product_image", label: "Product Image" },
5
+ { value: "technical_sheet", label: "Technical Sheet" },
6
+ { value: "generic", label: "Other Document" },
7
+ ];
8
+ const meta = {
9
+ title: "Components/AttachmentRow",
10
+ component: AttachmentRow,
11
+ tags: ["autodocs"],
12
+ parameters: { layout: "padded" },
13
+ args: { typeOptions },
14
+ decorators: [(Story) => _jsx("div", { className: "max-w-lg", children: _jsx(Story, {}) })],
15
+ };
16
+ export default meta;
17
+ export const Default = {
18
+ args: {
19
+ file: {
20
+ id: "1",
21
+ fileName: "product-spec-2026.pdf",
22
+ mimeType: "application/pdf",
23
+ fileSize: 245_760,
24
+ type: "technical_sheet",
25
+ },
26
+ /* eslint-disable no-console */
27
+ onRemove: (id) => console.log("remove", id),
28
+ onTypeChange: (id, type) => console.log("type change", id, type),
29
+ /* eslint-enable no-console */
30
+ },
31
+ };
32
+ export const AutoAttached = {
33
+ args: {
34
+ file: {
35
+ id: "2",
36
+ fileName: "chateau-reserve-front.jpg",
37
+ mimeType: "image/jpeg",
38
+ fileSize: 1_832_960,
39
+ type: "product_image",
40
+ },
41
+ autoAttached: true,
42
+ /* eslint-disable no-console */
43
+ onRemove: (id) => console.log("remove", id),
44
+ onTypeChange: (id, type) => console.log("type change", id, type),
45
+ /* eslint-enable no-console */
46
+ },
47
+ };
48
+ export const WithEditableName = {
49
+ args: {
50
+ file: {
51
+ id: "3",
52
+ fileName: "compliance-report-final.pdf",
53
+ name: "Compliance Report",
54
+ mimeType: "application/pdf",
55
+ fileSize: 524_288,
56
+ type: "generic",
57
+ },
58
+ /* eslint-disable no-console */
59
+ onRename: (id, name) => console.log("rename", id, name),
60
+ onRemove: (id) => console.log("remove", id),
61
+ onTypeChange: (id, type) => console.log("type change", id, type),
62
+ /* eslint-enable no-console */
63
+ },
64
+ };
65
+ //# sourceMappingURL=attachment-row.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-row.stories.js","sourceRoot":"","sources":["../../src/components/attachment-row.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,GAAG;IAClB,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE;IAClD,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACtD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,EAAE;CAC9C,CAAC;AAEF,MAAM,IAAI,GAA+B;IACvC,KAAK,EAAE,0BAA0B;IACjC,SAAS,EAAE,aAAa;IACxB,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;IAChC,IAAI,EAAE,EAAE,WAAW,EAAE;IACrB,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAK,SAAS,EAAC,UAAU,YAAC,KAAC,KAAK,KAAG,GAAM,CAAC;CACnE,CAAC;AAEF,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE;YACJ,EAAE,EAAE,GAAG;YACP,QAAQ,EAAE,uBAAuB;YACjC,QAAQ,EAAE,iBAAiB;YAC3B,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,iBAAiB;SACxB;QACD,+BAA+B;QAC/B,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC3C,YAAY,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,CAAC;QAChE,8BAA8B;KAC/B;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAU;IACjC,IAAI,EAAE;QACJ,IAAI,EAAE;YACJ,EAAE,EAAE,GAAG;YACP,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,YAAY;YACtB,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,eAAe;SACtB;QACD,YAAY,EAAE,IAAI;QAClB,+BAA+B;QAC/B,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC3C,YAAY,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,CAAC;QAChE,8BAA8B;KAC/B;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAU;IACrC,IAAI,EAAE;QACJ,IAAI,EAAE;YACJ,EAAE,EAAE,GAAG;YACP,QAAQ,EAAE,6BAA6B;YACvC,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,iBAAiB;YAC3B,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,SAAS;SAChB;QACD,+BAA+B;QAC/B,QAAQ,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC;QACvD,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC3C,YAAY,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,CAAC;QAChE,8BAA8B;KAC/B;CACF,CAAC"}
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ export type CertStatus = "required" | "filled" | "optional";
3
+ export interface CertificationUploadCardProps {
4
+ type: string;
5
+ label: string;
6
+ icon: React.ReactNode;
7
+ status: CertStatus;
8
+ file?: {
9
+ name: string;
10
+ size?: number;
11
+ } | null;
12
+ autoAttached?: boolean;
13
+ onUpload: (file: File) => void;
14
+ onRemove?: () => void;
15
+ onReplace?: () => void;
16
+ className?: string;
17
+ }
18
+ export declare function CertificationUploadCard({ label, icon, status, file, autoAttached, onUpload, onRemove, onReplace, className, }: CertificationUploadCardProps): import("react/jsx-runtime").JSX.Element;
19
+ //# sourceMappingURL=certification-upload-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certification-upload-card.d.ts","sourceRoot":"","sources":["../../src/components/certification-upload-card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE5D,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuCD,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,GACV,EAAE,4BAA4B,2CA4J9B"}
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cn } from "../lib/utils";
4
+ const ACCEPTED_TYPES = ".pdf,.jpg,.jpeg,.png,.webp";
5
+ const containerStyles = {
6
+ filled: "border border-emerald-200 bg-emerald-50/60 dark:border-emerald-500/20 dark:bg-emerald-950/20",
7
+ required: "border border-dashed border-amber-300 bg-amber-50/40 dark:border-amber-500/20 dark:bg-amber-950/20",
8
+ optional: "border border-dashed border-border/60 bg-muted/30 opacity-70",
9
+ };
10
+ const iconStyles = {
11
+ filled: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300",
12
+ required: "bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300",
13
+ optional: "bg-muted text-muted-foreground",
14
+ };
15
+ const labelStyles = {
16
+ filled: "text-emerald-700 dark:text-emerald-300",
17
+ required: "text-amber-700 dark:text-amber-300",
18
+ optional: "text-muted-foreground",
19
+ };
20
+ const dropZoneBorderStyles = {
21
+ required: "border-amber-300 text-amber-700 hover:bg-amber-50 dark:border-amber-500/30 dark:text-amber-300 dark:hover:bg-amber-950/30",
22
+ optional: "border-border/60 text-muted-foreground hover:bg-muted/40 dark:hover:bg-muted/20",
23
+ };
24
+ function formatFileSize(bytes) {
25
+ if (bytes < 1024)
26
+ return `${bytes} B`;
27
+ if (bytes < 1024 * 1024)
28
+ return `${(bytes / 1024).toFixed(1)} KB`;
29
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
30
+ }
31
+ export function CertificationUploadCard({ label, icon, status, file, autoAttached, onUpload, onRemove, onReplace, className, }) {
32
+ const inputRef = React.useRef(null);
33
+ const [dragOver, setDragOver] = React.useState(false);
34
+ const handleFileChange = (e) => {
35
+ const selected = e.target.files?.[0];
36
+ if (selected) {
37
+ onUpload(selected);
38
+ // Reset input so the same file can be re-selected
39
+ e.target.value = "";
40
+ }
41
+ };
42
+ const handleDragOver = (e) => {
43
+ e.preventDefault();
44
+ e.stopPropagation();
45
+ setDragOver(true);
46
+ };
47
+ const handleDragLeave = (e) => {
48
+ e.preventDefault();
49
+ e.stopPropagation();
50
+ setDragOver(false);
51
+ };
52
+ const handleDrop = (e) => {
53
+ e.preventDefault();
54
+ e.stopPropagation();
55
+ setDragOver(false);
56
+ const droppedFile = e.dataTransfer.files[0];
57
+ if (droppedFile) {
58
+ onUpload(droppedFile);
59
+ }
60
+ };
61
+ const handleDropZoneClick = () => {
62
+ inputRef.current?.click();
63
+ };
64
+ const handleReplaceClick = () => {
65
+ if (onReplace) {
66
+ onReplace();
67
+ }
68
+ else {
69
+ inputRef.current?.click();
70
+ }
71
+ };
72
+ return (_jsxs("div", { className: cn("relative flex flex-col items-center rounded-xl p-4 text-center transition-all", containerStyles[status], dragOver && "ring-2 ring-primary/40", className), onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [status === "filled" && autoAttached && (_jsx("span", { className: "absolute -top-2 right-2 rounded-full bg-emerald-600 px-2 py-0.5 text-[9px] font-bold text-white", children: "AUTO" })), _jsx("div", { className: cn("mb-2 flex size-9 items-center justify-center rounded-lg", iconStyles[status]), children: icon }), _jsx("span", { className: cn("text-[11px] font-bold uppercase tracking-[0.06em]", labelStyles[status]), children: label }), status === "filled" && file ? (_jsxs("div", { className: "mt-2 w-full", children: [_jsxs("div", { className: "inline-flex items-center gap-1.5 rounded-full bg-emerald-100/80 px-2.5 py-1 dark:bg-emerald-900/30", children: [_jsx("span", { className: "max-w-[120px] truncate text-[11px] font-medium text-emerald-800 dark:text-emerald-200", children: file.name }), file.size != null && (_jsx("span", { className: "text-[10px] text-emerald-600 dark:text-emerald-400", children: formatFileSize(file.size) }))] }), _jsxs("div", { className: "mt-1.5 flex items-center justify-center gap-2", children: [_jsx("button", { type: "button", onClick: handleReplaceClick, className: "text-[10px] font-medium text-emerald-700 underline-offset-2 hover:underline dark:text-emerald-300", children: "Replace" }), onRemove && (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-emerald-300 dark:text-emerald-700", children: "|" }), _jsx("button", { type: "button", onClick: onRemove, className: "text-[10px] font-medium text-red-600 underline-offset-2 hover:underline dark:text-red-400", children: "Remove" })] }))] })] })) : (_jsxs("div", { className: "mt-2 w-full", children: [status === "required" && (_jsx("p", { className: "mb-1.5 text-[10px] text-amber-600 dark:text-amber-400", children: "Required \u00B7 Not uploaded" })), _jsx("button", { type: "button", onClick: handleDropZoneClick, className: cn("w-full cursor-pointer rounded-lg border border-dashed px-3 py-1.5 text-[11px] font-medium transition-colors", dropZoneBorderStyles[status === "required" ? "required" : "optional"]), children: "Drop file or click" })] })), _jsx("input", { ref: inputRef, type: "file", accept: ACCEPTED_TYPES, className: "hidden", onChange: handleFileChange, tabIndex: -1 })] }));
73
+ }
74
+ //# sourceMappingURL=certification-upload-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certification-upload-card.js","sourceRoot":"","sources":["../../src/components/certification-upload-card.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { CertificationUploadCard } from "./certification-upload-card";
3
+ declare const meta: Meta<typeof CertificationUploadCard>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const Required: Story;
7
+ export declare const Filled: Story;
8
+ export declare const Optional: Story;
9
+ //# sourceMappingURL=certification-upload-card.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certification-upload-card.stories.d.ts","sourceRoot":"","sources":["../../src/components/certification-upload-card.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,uBAAuB,CAM9C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAmBnC,eAAO,MAAM,QAAQ,EAAE,KAQtB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,KAYpB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAQtB,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CertificationUploadCard } from "./certification-upload-card";
3
+ const meta = {
4
+ title: "Components/CertificationUploadCard",
5
+ component: CertificationUploadCard,
6
+ tags: ["autodocs"],
7
+ parameters: { layout: "padded" },
8
+ decorators: [(Story) => _jsx("div", { className: "w-48", children: _jsx(Story, {}) })],
9
+ };
10
+ export default meta;
11
+ /** Inline leaf icon — avoids importing lucide into the ui package */
12
+ const LeafIcon = () => (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "size-5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M11 20A7 7 0 0 1 9.8 6.9C15.5 4.9 17 3.5 19 2c1 2 2 4.5 2 8 0 5.5-4.78 10-10 10Z" }), _jsx("path", { d: "M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12" })] }));
13
+ export const Required = {
14
+ args: {
15
+ type: "organic",
16
+ label: "Organic",
17
+ icon: _jsx(LeafIcon, {}),
18
+ status: "required",
19
+ onUpload: (file) => console.warn("Upload:", file.name),
20
+ },
21
+ };
22
+ export const Filled = {
23
+ args: {
24
+ type: "organic",
25
+ label: "Organic",
26
+ icon: _jsx(LeafIcon, {}),
27
+ status: "filled",
28
+ file: { name: "organic-cert-2026.pdf", size: 245_000 },
29
+ autoAttached: true,
30
+ onUpload: (file) => console.warn("Upload:", file.name),
31
+ onRemove: () => console.warn("Remove"),
32
+ onReplace: () => console.warn("Replace"),
33
+ },
34
+ };
35
+ export const Optional = {
36
+ args: {
37
+ type: "sustainable",
38
+ label: "Sustainable",
39
+ icon: _jsx(LeafIcon, {}),
40
+ status: "optional",
41
+ onUpload: (file) => console.warn("Upload:", file.name),
42
+ },
43
+ };
44
+ //# sourceMappingURL=certification-upload-card.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certification-upload-card.stories.js","sourceRoot":"","sources":["../../src/components/certification-upload-card.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,MAAM,IAAI,GAAyC;IACjD,KAAK,EAAE,oCAAoC;IAC3C,SAAS,EAAE,uBAAuB;IAClC,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAK,SAAS,EAAC,MAAM,YAAC,KAAC,KAAK,KAAG,GAAM,CAAC;CAC/D,CAAC;AAEF,eAAe,IAAI,CAAC;AAGpB,qEAAqE;AACrE,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,CACrB,eACE,KAAK,EAAC,4BAA4B,EAClC,SAAS,EAAC,QAAQ,EAClB,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAE,GAAG,EAChB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,aAEtB,eAAM,CAAC,EAAC,kFAAkF,GAAG,EAC7F,eAAM,CAAC,EAAC,kDAAkD,GAAG,IACzD,CACP,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAU;IAC7B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,KAAC,QAAQ,KAAG;QAClB,MAAM,EAAE,UAAU;QAClB,QAAQ,EAAE,CAAC,IAAU,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC;KAC7D;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAU;IAC3B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,KAAC,QAAQ,KAAG;QAClB,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,OAAO,EAAE;QACtD,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,CAAC,IAAU,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC;QAC5D,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;QACtC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;KACzC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAU;IAC7B,IAAI,EAAE;QACJ,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,KAAC,QAAQ,KAAG;QAClB,MAAM,EAAE,UAAU;QAClB,QAAQ,EAAE,CAAC,IAAU,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC;KAC7D;CACF,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface CompositionEntry {
2
+ name: string;
3
+ percentage?: number | null;
4
+ }
5
+ export interface CompositionEditorProps {
6
+ /** Current entries */
7
+ value: CompositionEntry[];
8
+ /** Called when entries change */
9
+ onChange: (entries: CompositionEntry[]) => void;
10
+ /** Label for the name column */
11
+ nameLabel?: string;
12
+ /** Placeholder for the name input */
13
+ namePlaceholder?: string;
14
+ /** Whether percentage column is shown (default true) */
15
+ showPercentage?: boolean;
16
+ /** Whether the editor is read-only */
17
+ readOnly?: boolean;
18
+ /** Max number of entries (default 20) */
19
+ maxEntries?: number;
20
+ /** Label for the add button (defaults to "Add {nameLabel}") */
21
+ addLabel?: string;
22
+ className?: string;
23
+ }
24
+ export declare function CompositionEditor({ value, onChange, nameLabel, namePlaceholder, showPercentage, readOnly, maxEntries, addLabel, className, }: CompositionEditorProps): import("react/jsx-runtime").JSX.Element;
25
+ /** Serialize entries to a display string (e.g., "60% Pinot Noir, 40% Grenache") */
26
+ export declare function serializeComposition(entries: CompositionEntry[]): string;
27
+ /** Parse a comma-separated string back to entries */
28
+ export declare function parseCompositionString(str: string): CompositionEntry[];
29
+ //# sourceMappingURL=composition-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-editor.d.ts","sourceRoot":"","sources":["../../src/components/composition-editor.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,sBAAsB;IACtB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,iCAAiC;IACjC,QAAQ,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAChD,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,QAAQ,EACR,SAAwB,EACxB,eAAwB,EACxB,cAAqB,EACrB,QAAgB,EAChB,UAAe,EACf,QAAQ,EACR,SAAS,GACV,EAAE,sBAAsB,2CAiJxB;AAID,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,MAAM,CASxE;AAED,qDAAqD;AACrD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAatE"}
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback } from "react";
3
+ import { cn } from "../lib/utils";
4
+ // ─── Component ──────────────────────────────────────────────────────────────
5
+ export function CompositionEditor({ value, onChange, nameLabel = "Ingredient", namePlaceholder = "Name", showPercentage = true, readOnly = false, maxEntries = 20, addLabel, className, }) {
6
+ const totalPct = value.reduce((sum, e) => sum + (e.percentage ?? 0), 0);
7
+ const hasPercentages = value.some((e) => e.percentage != null && e.percentage > 0);
8
+ const pctWarning = hasPercentages && Math.abs(totalPct - 100) > 0.5;
9
+ const updateEntry = useCallback((index, field, rawValue) => {
10
+ const next = [...value];
11
+ if (field === "name") {
12
+ next[index] = { ...next[index], name: rawValue };
13
+ }
14
+ else {
15
+ const num = rawValue === "" ? null : Number(rawValue);
16
+ next[index] = { ...next[index], percentage: num != null && !isNaN(num) ? num : null };
17
+ }
18
+ onChange(next);
19
+ }, [value, onChange]);
20
+ const addEntry = useCallback(() => {
21
+ if (value.length >= maxEntries)
22
+ return;
23
+ onChange([...value, { name: "", percentage: null }]);
24
+ }, [value, onChange, maxEntries]);
25
+ const removeEntry = useCallback((index) => {
26
+ onChange(value.filter((_, i) => i !== index));
27
+ }, [value, onChange]);
28
+ const btnLabel = addLabel ?? `Add ${nameLabel.toLowerCase()}`;
29
+ return (_jsxs("div", { className: cn("space-y-2", className), children: [value.length > 0 && (_jsxs("div", { className: "flex items-center gap-2 px-1", children: [_jsx("div", { className: "flex-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground", children: nameLabel }), showPercentage && (_jsx("div", { className: "w-20 text-right text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground", children: "%" })), !readOnly && _jsx("div", { className: "w-7" })] })), value.map((entry, i) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: entry.name, onChange: (e) => updateEntry(i, "name", e.target.value), placeholder: namePlaceholder, readOnly: readOnly, className: cn("flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground/50", "focus:border-primary/30 focus:ring-2 focus:ring-primary/10", readOnly && "cursor-default bg-muted/30") }), showPercentage && (_jsxs("div", { className: "relative w-20", children: [_jsx("input", { type: "text", inputMode: "decimal", value: entry.percentage != null ? String(entry.percentage) : "", onChange: (e) => updateEntry(i, "percentage", e.target.value), placeholder: "\u2014", readOnly: readOnly, className: cn("w-full rounded-lg border border-border bg-background py-2 pl-3 pr-7 text-right text-sm tabular-nums text-foreground outline-none transition-colors placeholder:text-muted-foreground/40", "focus:border-primary/30 focus:ring-2 focus:ring-primary/10", readOnly && "cursor-default bg-muted/30") }), _jsx("span", { className: "pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 text-xs text-muted-foreground/50", children: "%" })] })), !readOnly && (_jsx("button", { type: "button", onClick: () => removeEntry(i), className: "flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/60 transition-colors hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-950/30 dark:hover:text-red-400", title: "Remove", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", className: "size-3.5", children: _jsx("path", { d: "M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z" }) }) }))] }, i))), _jsxs("div", { className: "flex items-center justify-between pt-1", children: [!readOnly && value.length < maxEntries ? (_jsxs("button", { type: "button", onClick: addEntry, className: "inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-[11px] font-semibold text-primary transition-colors hover:bg-primary/5", children: [_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", className: "size-3", children: _jsx("path", { d: "M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z" }) }), btnLabel] })) : (_jsx("div", {})), showPercentage && hasPercentages && (_jsxs("div", { className: cn("rounded-md px-2 py-0.5 text-[10px] font-semibold tabular-nums", pctWarning
30
+ ? "bg-amber-50 text-amber-700 dark:bg-amber-950/30 dark:text-amber-300"
31
+ : "bg-emerald-50 text-emerald-700 dark:bg-emerald-950/30 dark:text-emerald-300"), children: ["Total: ", totalPct.toFixed(0), "%"] }))] }), value.length === 0 && !readOnly && (_jsxs("button", { type: "button", onClick: addEntry, className: "w-full rounded-xl border border-dashed border-border/60 bg-muted/20 px-4 py-4 text-center text-xs text-muted-foreground transition-colors hover:border-primary/30 hover:bg-primary/[0.02]", children: ["+ ", btnLabel] })), value.length === 0 && readOnly && (_jsx("div", { className: "px-1 text-sm text-muted-foreground/60", children: "No data" }))] }));
32
+ }
33
+ // ─── Serialization helpers ──────────────────────────────────────────────────
34
+ /** Serialize entries to a display string (e.g., "60% Pinot Noir, 40% Grenache") */
35
+ export function serializeComposition(entries) {
36
+ if (!entries || entries.length === 0)
37
+ return "";
38
+ return entries
39
+ .map((e) => e.percentage != null ? `${e.percentage}% ${e.name ?? ""}`.trim() : (e.name ?? ""))
40
+ .map((s) => s.trim())
41
+ .filter(Boolean)
42
+ .join(", ");
43
+ }
44
+ /** Parse a comma-separated string back to entries */
45
+ export function parseCompositionString(str) {
46
+ if (!str.trim())
47
+ return [];
48
+ return str
49
+ .split(",")
50
+ .map((part) => {
51
+ const trimmed = part.trim();
52
+ const match = trimmed.match(/^(\d+(?:\.\d+)?)\s*%?\s*(.*)$/);
53
+ if (match) {
54
+ return { name: match[2].trim(), percentage: Number(match[1]) };
55
+ }
56
+ return { name: trimmed, percentage: null };
57
+ })
58
+ .filter((e) => e.name.length > 0);
59
+ }
60
+ //# sourceMappingURL=composition-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-editor.js","sourceRoot":"","sources":["../../src/components/composition-editor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { StoryObj } from "@storybook/react-vite";
2
+ import { CompositionEditor } from "./composition-editor";
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof CompositionEditor;
6
+ tags: string[];
7
+ };
8
+ export default meta;
9
+ type Story = StoryObj<typeof meta>;
10
+ export declare const Wine: Story;
11
+ export declare const Beer: Story;
12
+ export declare const Cider: Story;
13
+ export declare const Empty: Story;
14
+ export declare const ReadOnly: Story;
15
+ //# sourceMappingURL=composition-editor.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-editor.stories.d.ts","sourceRoot":"","sources":["../../src/components/composition-editor.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAyB,MAAM,sBAAsB,CAAC;AAEhF,QAAA,MAAM,IAAI;;;;CAIgC,CAAC;AAE3C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AA2BnC,eAAO,MAAM,IAAI,EAAE,KAclB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAalB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAanB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAKnB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { CompositionEditor } from "./composition-editor";
4
+ const meta = {
5
+ title: "Components/CompositionEditor",
6
+ component: CompositionEditor,
7
+ tags: ["autodocs"],
8
+ };
9
+ export default meta;
10
+ function InteractiveEditor({ initial, nameLabel, namePlaceholder, addLabel, }) {
11
+ const [value, setValue] = useState(initial);
12
+ return (_jsx("div", { className: "max-w-lg", children: _jsx(CompositionEditor, { value: value, onChange: setValue, nameLabel: nameLabel, namePlaceholder: namePlaceholder, addLabel: addLabel }) }));
13
+ }
14
+ export const Wine = {
15
+ render: () => (_jsx(InteractiveEditor, { initial: [
16
+ { name: "Pinot Noir", percentage: 60 },
17
+ { name: "Grenache", percentage: 30 },
18
+ { name: "Syrah", percentage: 10 },
19
+ ], nameLabel: "Grape variety", namePlaceholder: "e.g., Pinot Noir", addLabel: "Add grape variety" })),
20
+ args: {},
21
+ };
22
+ export const Beer = {
23
+ render: () => (_jsx(InteractiveEditor, { initial: [
24
+ { name: "Pilsner Malt", percentage: 80 },
25
+ { name: "Cascade Hops", percentage: null },
26
+ ], nameLabel: "Ingredient", namePlaceholder: "e.g., Pilsner Malt", addLabel: "Add ingredient" })),
27
+ args: {},
28
+ };
29
+ export const Cider = {
30
+ render: () => (_jsx(InteractiveEditor, { initial: [
31
+ { name: "Bramley Apple", percentage: 70 },
32
+ { name: "Conference Pear", percentage: 30 },
33
+ ], nameLabel: "Fruit variety", namePlaceholder: "e.g., Bramley Apple", addLabel: "Add fruit variety" })),
34
+ args: {},
35
+ };
36
+ export const Empty = {
37
+ render: () => (_jsx(InteractiveEditor, { initial: [], nameLabel: "Ingredient", addLabel: "Add ingredient" })),
38
+ args: {},
39
+ };
40
+ export const ReadOnly = {
41
+ args: {
42
+ value: [
43
+ { name: "Cabernet Sauvignon", percentage: 55 },
44
+ { name: "Merlot", percentage: 45 },
45
+ ],
46
+ onChange: () => { },
47
+ nameLabel: "Grape variety",
48
+ readOnly: true,
49
+ },
50
+ };
51
+ //# sourceMappingURL=composition-editor.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition-editor.stories.js","sourceRoot":"","sources":["../../src/components/composition-editor.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAyB,MAAM,sBAAsB,CAAC;AAEhF,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,8BAA8B;IACrC,SAAS,EAAE,iBAAiB;IAC5B,IAAI,EAAE,CAAC,UAAU,CAAC;CACsB,CAAC;AAE3C,eAAe,IAAI,CAAC;AAGpB,SAAS,iBAAiB,CAAC,EACzB,OAAO,EACP,SAAS,EACT,eAAe,EACf,QAAQ,GAMT;IACC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB,OAAO,CAAC,CAAC;IAChE,OAAO,CACL,cAAK,SAAS,EAAC,UAAU,YACvB,KAAC,iBAAiB,IAChB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,QAAQ,GAClB,GACE,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAU;IACzB,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,KAAC,iBAAiB,IAChB,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,EAAE;YACtC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE;YACpC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE;SAClC,EACD,SAAS,EAAC,eAAe,EACzB,eAAe,EAAC,kBAAkB,EAClC,QAAQ,EAAC,mBAAmB,GAC5B,CACH;IACD,IAAI,EAAE,EAAS;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,IAAI,GAAU;IACzB,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,KAAC,iBAAiB,IAChB,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,EAAE;YACxC,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,EAAE;SAC3C,EACD,SAAS,EAAC,YAAY,EACtB,eAAe,EAAC,oBAAoB,EACpC,QAAQ,EAAC,gBAAgB,GACzB,CACH;IACD,IAAI,EAAE,EAAS;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,KAAC,iBAAiB,IAChB,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,EAAE,EAAE;YACzC,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,EAAE,EAAE;SAC5C,EACD,SAAS,EAAC,eAAe,EACzB,eAAe,EAAC,qBAAqB,EACrC,QAAQ,EAAC,mBAAmB,GAC5B,CACH;IACD,IAAI,EAAE,EAAS;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,KAAC,iBAAiB,IAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAC,YAAY,EAAC,QAAQ,EAAC,gBAAgB,GAAG,CACpF;IACD,IAAI,EAAE,EAAS;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAU;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,EAAE,EAAE;YAC9C,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;SACnC;QACD,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;QAClB,SAAS,EAAE,eAAe;QAC1B,QAAQ,EAAE,IAAI;KACf;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"confirmation-dialog.d.ts","sourceRoot":"","sources":["../../src/components/confirmation-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAEnE,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,0EAA0E;IAC1E,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,2FAA2F;IAC3F,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,wFAAwF;IACxF,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AA8FD,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,OAAO,EACP,SAAS,EACT,KAAK,EACL,WAAW,EACX,OAAO,EACP,IAAe,EACf,IAAI,EACJ,YAAwB,EACxB,WAAsB,EACtB,SAAS,EAAE,eAAuB,EAClC,QAAQ,GACT,EAAE,uBAAuB,2CAuEzB"}
1
+ {"version":3,"file":"confirmation-dialog.d.ts","sourceRoot":"","sources":["../../src/components/confirmation-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAEnE,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,0EAA0E;IAC1E,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,2FAA2F;IAC3F,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,wFAAwF;IACxF,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AA8FD,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,OAAO,EACP,SAAS,EACT,KAAK,EACL,WAAW,EACX,OAAO,EACP,IAAe,EACf,IAAI,EACJ,YAAwB,EACxB,WAAsB,EACtB,SAAS,EAAE,eAAuB,EAClC,QAAQ,GACT,EAAE,uBAAuB,2CAwEzB"}
@@ -62,6 +62,7 @@ export function ConfirmationDialog({ open, onClose, onConfirm, title, descriptio
62
62
  };
63
63
  // Reset submitting state when dialog closes
64
64
  React.useEffect(() => {
65
+ // eslint-disable-next-line @eslint-react/set-state-in-effect -- intentional reset on prop change
65
66
  if (!open)
66
67
  setSubmitting(false);
67
68
  }, [open]);
@@ -1 +1 @@
1
- {"version":3,"file":"confirmation-dialog.js","sourceRoot":"","sources":["../../src/components/confirmation-dialog.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"confirmation-dialog.js","sourceRoot":"","sources":["../../src/components/confirmation-dialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface ContactPerson {
2
+ id: string;
3
+ name?: string | null;
4
+ email?: string | null;
5
+ role?: string | null;
6
+ }
7
+ export interface ContactPersonSelectProps {
8
+ members: ContactPerson[];
9
+ selectedId: string | null;
10
+ onSelect: (id: string) => void;
11
+ label?: string;
12
+ placeholder?: string;
13
+ className?: string;
14
+ }
15
+ export declare function ContactPersonSelect({ members, selectedId, onSelect, label, placeholder, className, }: ContactPersonSelectProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=contact-person-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-person-select.d.ts","sourceRoot":"","sources":["../../src/components/contact-person-select.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,UAAU,EACV,QAAQ,EACR,KAAwB,EACxB,WAAmC,EACnC,SAAS,GACV,EAAE,wBAAwB,2CA2F1B"}