@squaredr/fieldcraft-pro 1.7.0 → 1.8.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.
- package/LICENSE.txt +51 -51
- package/README.md +139 -139
- package/dist/{chunk-4TN6YJDF.mjs → chunk-CYXJGOQH.mjs} +903 -205
- package/dist/{chunk-J5V6OVZO.mjs → chunk-GXKQCXIB.mjs} +344 -174
- package/dist/{chunk-VEP3DOCQ.mjs → chunk-IW654Z3M.mjs} +13 -16
- package/dist/{chunk-GZIV2XAD.mjs → chunk-MLP5EDWP.mjs} +166 -177
- package/dist/form-builder/index.d.mts +1 -1
- package/dist/form-builder/index.d.ts +1 -1
- package/dist/form-builder/index.js +480 -290
- package/dist/form-builder/index.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1967 -893
- package/dist/index.mjs +326 -121
- package/dist/response-viewer/index.d.mts +1 -1
- package/dist/response-viewer/index.d.ts +1 -1
- package/dist/response-viewer/index.js +165 -177
- package/dist/response-viewer/index.mjs +1 -1
- package/dist/styles.css +1 -1
- package/dist/templates/index.js +13 -16
- package/dist/templates/index.mjs +1 -1
- package/dist/theme-editor/index.d.mts +11 -5
- package/dist/theme-editor/index.d.ts +11 -5
- package/dist/theme-editor/index.js +903 -205
- package/dist/theme-editor/index.mjs +1 -1
- package/package.json +18 -7
- package/theme-editor/styles.css +468 -466
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { cn } from './chunk-QQ4JZGTD.mjs';
|
|
2
2
|
import { requireLicense } from './chunk-4MMKB2EW.mjs';
|
|
3
|
+
import * as React from 'react';
|
|
3
4
|
import { forwardRef, lazy, memo, createContext, Component, useState, useRef, useEffect, useCallback, useMemo, Suspense, useContext } from 'react';
|
|
4
5
|
import { DndContext, DragOverlay, useSensors, useSensor, MouseSensor, TouchSensor, useDraggable, useDroppable } from '@dnd-kit/core';
|
|
5
|
-
import { ChevronDown, Undo2, Redo2, PencilRuler, Eye, Code, GitBranch, LayoutTemplate, Upload, Download, Save, X, PanelLeft, PanelRight, Search, ChevronRight, Plus, Settings, FileText, Layers, ZoomOut, ZoomIn, Maximize, Copy, Trash2, HelpCircle, MoveVertical, Minus, Video, Image, PartyPopper, Hand, ShieldCheck, SeparatorHorizontal, Info, Heading, Trophy, EyeOff, Calculator, CreditCard, MapPin, Repeat, Grid3X3, Camera, PenTool, Paperclip, CalendarCheck, CalendarRange, Clock, Calendar, ArrowUpDown, Globe, ToggleLeft, CheckSquare, CircleDot, ListOrdered, TrendingUp, BarChart3, Star, SlidersHorizontal, Hash, UserCheck, Link, PhoneCall, Phone, Mail, AlignLeft, Type, GripVertical } from 'lucide-react';
|
|
6
|
+
import { ChevronDown, ChevronUp, Check, Undo2, Redo2, PencilRuler, Eye, Code, GitBranch, LayoutTemplate, Upload, Download, Save, X, PanelLeft, PanelRight, Search, ChevronRight, Plus, Settings, FileText, Layers, ZoomOut, ZoomIn, Maximize, Copy, Trash2, HelpCircle, MoveVertical, Minus, Video, Image, PartyPopper, Hand, ShieldCheck, SeparatorHorizontal, Info, Heading, Trophy, EyeOff, Calculator, CreditCard, MapPin, Repeat, Grid3X3, Camera, PenTool, Paperclip, CalendarCheck, CalendarRange, Clock, Calendar, ArrowUpDown, Globe, ToggleLeft, CheckSquare, CircleDot, ListOrdered, TrendingUp, BarChart3, Star, SlidersHorizontal, Hash, UserCheck, Link, PhoneCall, Phone, Mail, AlignLeft, Type, GripVertical } from 'lucide-react';
|
|
6
7
|
import { Button, Separator, FormEngineRenderer, Input, Badge, Textarea, Label, Switch } from '@squaredr/fieldcraft-react';
|
|
7
8
|
import { validateSchema, FormEngineSchemaError } from '@squaredr/fieldcraft-core';
|
|
8
9
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
|
+
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
9
11
|
import { MarkerType, Handle, Position, getBezierPath, BaseEdge, EdgeLabelRenderer, useNodesState, useEdgesState, ReactFlowProvider, useReactFlow, ReactFlow, Background, MiniMap } from '@xyflow/react';
|
|
10
12
|
import '@xyflow/react/dist/style.css';
|
|
11
13
|
|
|
@@ -13,20 +15,23 @@ var MAX_HISTORY = 50;
|
|
|
13
15
|
function useUndoRedo(currentSchema, setSchema) {
|
|
14
16
|
const historyRef = useRef([currentSchema]);
|
|
15
17
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
18
|
+
const currentIndexRef = useRef(currentIndex);
|
|
19
|
+
currentIndexRef.current = currentIndex;
|
|
16
20
|
const canUndo = currentIndex > 0;
|
|
17
21
|
const canRedo = currentIndex < historyRef.current.length - 1;
|
|
18
22
|
const push = useCallback(
|
|
19
23
|
(schema) => {
|
|
20
|
-
|
|
24
|
+
const idx = currentIndexRef.current;
|
|
25
|
+
historyRef.current = historyRef.current.slice(0, idx + 1);
|
|
21
26
|
historyRef.current.push(schema);
|
|
22
27
|
if (historyRef.current.length > MAX_HISTORY) {
|
|
23
28
|
historyRef.current.shift();
|
|
24
29
|
setCurrentIndex(historyRef.current.length - 1);
|
|
25
30
|
} else {
|
|
26
|
-
setCurrentIndex(
|
|
31
|
+
setCurrentIndex(idx + 1);
|
|
27
32
|
}
|
|
28
33
|
},
|
|
29
|
-
[
|
|
34
|
+
[]
|
|
30
35
|
);
|
|
31
36
|
const undo = useCallback(() => {
|
|
32
37
|
if (currentIndex > 0) {
|
|
@@ -644,7 +649,7 @@ var QUESTION_TYPE_INFO = {
|
|
|
644
649
|
category: "advanced",
|
|
645
650
|
icon: "ListPlus",
|
|
646
651
|
description: "Repeatable group of fields",
|
|
647
|
-
defaultConfig: { type: "repeater", fields: [],
|
|
652
|
+
defaultConfig: { type: "repeater", fields: [], minEntries: 1, maxEntries: 10 }
|
|
648
653
|
},
|
|
649
654
|
likert: {
|
|
650
655
|
type: "likert",
|
|
@@ -655,13 +660,7 @@ var QUESTION_TYPE_INFO = {
|
|
|
655
660
|
requiresOptions: true,
|
|
656
661
|
defaultConfig: {
|
|
657
662
|
type: "likert",
|
|
658
|
-
|
|
659
|
-
{ label: "Strongly Disagree", value: "1" },
|
|
660
|
-
{ label: "Disagree", value: "2" },
|
|
661
|
-
{ label: "Neutral", value: "3" },
|
|
662
|
-
{ label: "Agree", value: "4" },
|
|
663
|
-
{ label: "Strongly Agree", value: "5" }
|
|
664
|
-
]
|
|
663
|
+
labels: ["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]
|
|
665
664
|
}
|
|
666
665
|
},
|
|
667
666
|
scoring: {
|
|
@@ -714,7 +713,7 @@ var QUESTION_TYPE_INFO = {
|
|
|
714
713
|
category: "advanced",
|
|
715
714
|
icon: "CreditCard",
|
|
716
715
|
description: "Collect payment via Stripe",
|
|
717
|
-
defaultConfig: { type: "payment", provider: "stripe", publicKey: "", currency: "USD" }
|
|
716
|
+
defaultConfig: { type: "payment", provider: "stripe", publicKey: "", currency: "USD", serverUrl: "" }
|
|
718
717
|
},
|
|
719
718
|
// ── Structural ──
|
|
720
719
|
section_header: {
|
|
@@ -1509,30 +1508,71 @@ function FormCanvas({ builderState }) {
|
|
|
1509
1508
|
] })
|
|
1510
1509
|
] }) });
|
|
1511
1510
|
}
|
|
1512
|
-
var
|
|
1513
|
-
|
|
1514
|
-
|
|
1511
|
+
var Select = SelectPrimitive.Root;
|
|
1512
|
+
var SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
1513
|
+
SelectPrimitive.Trigger,
|
|
1514
|
+
{
|
|
1515
|
+
ref,
|
|
1516
|
+
className: cn(
|
|
1517
|
+
"flex h-9 w-full items-center justify-between rounded-md border border-input bg-card px-3 py-1 text-sm shadow-xs transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
1518
|
+
className
|
|
1519
|
+
),
|
|
1520
|
+
...props,
|
|
1521
|
+
children: [
|
|
1522
|
+
children,
|
|
1523
|
+
/* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 text-muted-foreground" }) })
|
|
1524
|
+
]
|
|
1525
|
+
}
|
|
1526
|
+
));
|
|
1527
|
+
SelectTrigger.displayName = "SelectTrigger";
|
|
1528
|
+
var SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
1529
|
+
SelectPrimitive.Content,
|
|
1530
|
+
{
|
|
1531
|
+
ref,
|
|
1532
|
+
className: cn(
|
|
1533
|
+
"relative z-50 max-h-64 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
1534
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
1535
|
+
className
|
|
1536
|
+
),
|
|
1537
|
+
position,
|
|
1538
|
+
...props,
|
|
1539
|
+
children: [
|
|
1540
|
+
/* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-4" }) }),
|
|
1515
1541
|
/* @__PURE__ */ jsx(
|
|
1516
|
-
|
|
1542
|
+
SelectPrimitive.Viewport,
|
|
1517
1543
|
{
|
|
1518
|
-
ref,
|
|
1519
1544
|
className: cn(
|
|
1520
|
-
"
|
|
1521
|
-
|
|
1545
|
+
"p-1",
|
|
1546
|
+
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
|
1522
1547
|
),
|
|
1523
|
-
...props,
|
|
1524
1548
|
children
|
|
1525
1549
|
}
|
|
1526
1550
|
),
|
|
1527
|
-
/* @__PURE__ */ jsx(
|
|
1528
|
-
]
|
|
1551
|
+
/* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4" }) })
|
|
1552
|
+
]
|
|
1529
1553
|
}
|
|
1530
|
-
);
|
|
1531
|
-
|
|
1554
|
+
) }));
|
|
1555
|
+
SelectContent.displayName = "SelectContent";
|
|
1556
|
+
var SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
1557
|
+
SelectPrimitive.Item,
|
|
1558
|
+
{
|
|
1559
|
+
ref,
|
|
1560
|
+
className: cn(
|
|
1561
|
+
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
1562
|
+
className
|
|
1563
|
+
),
|
|
1564
|
+
...props,
|
|
1565
|
+
children: [
|
|
1566
|
+
/* @__PURE__ */ jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "size-4" }) }) }),
|
|
1567
|
+
/* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
|
|
1568
|
+
]
|
|
1569
|
+
}
|
|
1570
|
+
));
|
|
1571
|
+
SelectItem.displayName = "SelectItem";
|
|
1532
1572
|
function useConfigUpdater(question, onUpdate) {
|
|
1533
|
-
return (
|
|
1573
|
+
return (updates) => {
|
|
1534
1574
|
const current = question.config ?? {};
|
|
1535
|
-
onUpdate({ config: { ...current, type: question.type,
|
|
1575
|
+
onUpdate({ config: { ...current, type: question.type, ...updates } });
|
|
1536
1576
|
};
|
|
1537
1577
|
}
|
|
1538
1578
|
function QuestionConfigEditor({ question, onUpdate }) {
|
|
@@ -1542,226 +1582,274 @@ function QuestionConfigEditor({ question, onUpdate }) {
|
|
|
1542
1582
|
// ── Text ──
|
|
1543
1583
|
case "short_text":
|
|
1544
1584
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Text Settings", children: [
|
|
1545
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "255", onChange: (v) => updateConfig(
|
|
1546
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Input Type", value: config.inputType ?? "text", options: [{ label: "Text", value: "text" }, { label: "Password", value: "password" }], onChange: (v) => updateConfig(
|
|
1547
|
-
/* @__PURE__ */ jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig(
|
|
1548
|
-
/* @__PURE__ */ jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. USD", onChange: (v) => updateConfig(
|
|
1585
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "255", onChange: (v) => updateConfig({ maxLength: v }) }),
|
|
1586
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Input Type", value: config.inputType ?? "text", options: [{ label: "Text", value: "text" }, { label: "Password", value: "password" }], onChange: (v) => updateConfig({ inputType: v }) }),
|
|
1587
|
+
/* @__PURE__ */ jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig({ prefix: v }) }),
|
|
1588
|
+
/* @__PURE__ */ jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. USD", onChange: (v) => updateConfig({ suffix: v }) })
|
|
1549
1589
|
] });
|
|
1550
1590
|
case "long_text":
|
|
1551
1591
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Text Settings", children: [
|
|
1552
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "No limit", onChange: (v) => updateConfig(
|
|
1553
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Rows", value: config.rows, placeholder: "4", onChange: (v) => updateConfig(
|
|
1554
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Character Count", checked: !!config.showCharCount, onChange: (v) => updateConfig(
|
|
1592
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "No limit", onChange: (v) => updateConfig({ maxLength: v }) }),
|
|
1593
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Rows", value: config.rows, placeholder: "4", onChange: (v) => updateConfig({ rows: v }) }),
|
|
1594
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Character Count", checked: !!config.showCharCount, onChange: (v) => updateConfig({ showCharCount: v }) })
|
|
1555
1595
|
] });
|
|
1556
1596
|
case "legal_name":
|
|
1557
1597
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Name Fields", children: [
|
|
1558
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Middle Name", checked: !!config.showMiddleName, onChange: (v) => updateConfig(
|
|
1559
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Suffix", checked: !!config.showSuffix, onChange: (v) => updateConfig(
|
|
1598
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Middle Name", checked: !!config.showMiddleName, onChange: (v) => updateConfig({ showMiddleName: v }) }),
|
|
1599
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Suffix", checked: !!config.showSuffix, onChange: (v) => updateConfig({ showSuffix: v }) })
|
|
1560
1600
|
] });
|
|
1561
1601
|
// ── Numeric ──
|
|
1562
1602
|
case "number":
|
|
1563
1603
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Number Settings", children: [
|
|
1564
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Min", value: config.min, onChange: (v) => updateConfig(
|
|
1565
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max", value: config.max, onChange: (v) => updateConfig(
|
|
1566
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig(
|
|
1567
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "0", onChange: (v) => updateConfig(
|
|
1568
|
-
/* @__PURE__ */ jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig(
|
|
1569
|
-
/* @__PURE__ */ jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. kg", onChange: (v) => updateConfig(
|
|
1604
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Min", value: config.min, onChange: (v) => updateConfig({ min: v }) }),
|
|
1605
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max", value: config.max, onChange: (v) => updateConfig({ max: v }) }),
|
|
1606
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig({ step: v }) }),
|
|
1607
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "0", onChange: (v) => updateConfig({ decimalPlaces: v }) }),
|
|
1608
|
+
/* @__PURE__ */ jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig({ prefix: v }) }),
|
|
1609
|
+
/* @__PURE__ */ jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. kg", onChange: (v) => updateConfig({ suffix: v }) })
|
|
1570
1610
|
] });
|
|
1571
1611
|
case "slider":
|
|
1572
1612
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Slider Settings", children: [
|
|
1573
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Min", value: config.min, placeholder: "0", onChange: (v) => updateConfig(
|
|
1574
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max", value: config.max, placeholder: "100", onChange: (v) => updateConfig(
|
|
1575
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig(
|
|
1576
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Value", checked: !!config.showValue, onChange: (v) => updateConfig(
|
|
1577
|
-
/* @__PURE__ */ jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig(
|
|
1578
|
-
/* @__PURE__ */ jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig(
|
|
1613
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Min", value: config.min, placeholder: "0", onChange: (v) => updateConfig({ min: v }) }),
|
|
1614
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max", value: config.max, placeholder: "100", onChange: (v) => updateConfig({ max: v }) }),
|
|
1615
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig({ step: v }) }),
|
|
1616
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Value", checked: !!config.showValue, onChange: (v) => updateConfig({ showValue: v }) }),
|
|
1617
|
+
/* @__PURE__ */ jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig({ minLabel: v }) }),
|
|
1618
|
+
/* @__PURE__ */ jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig({ maxLabel: v }) })
|
|
1579
1619
|
] });
|
|
1580
1620
|
case "rating":
|
|
1581
1621
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Rating Settings", children: [
|
|
1582
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Stars", value: config.max, placeholder: "5", onChange: (v) => updateConfig(
|
|
1583
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Icon", value: config.icon ?? "star", options: [{ label: "Star", value: "star" }, { label: "Heart", value: "heart" }, { label: "Circle", value: "circle" }], onChange: (v) => updateConfig(
|
|
1584
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Labels", checked: !!config.showLabels, onChange: (v) => updateConfig(
|
|
1622
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Stars", value: config.max, placeholder: "5", onChange: (v) => updateConfig({ max: v }) }),
|
|
1623
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Icon", value: config.icon ?? "star", options: [{ label: "Star", value: "star" }, { label: "Heart", value: "heart" }, { label: "Circle", value: "circle" }], onChange: (v) => updateConfig({ icon: v }) }),
|
|
1624
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Labels", checked: !!config.showLabels, onChange: (v) => updateConfig({ showLabels: v }) })
|
|
1585
1625
|
] });
|
|
1586
1626
|
case "nps":
|
|
1587
1627
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "NPS Settings", children: [
|
|
1588
|
-
/* @__PURE__ */ jsx(TextField, { label: "Low Label", value: config.lowLabel ?? "Not likely", onChange: (v) => updateConfig(
|
|
1589
|
-
/* @__PURE__ */ jsx(TextField, { label: "High Label", value: config.highLabel ?? "Very likely", onChange: (v) => updateConfig(
|
|
1628
|
+
/* @__PURE__ */ jsx(TextField, { label: "Low Label", value: config.lowLabel ?? "Not likely", onChange: (v) => updateConfig({ lowLabel: v }) }),
|
|
1629
|
+
/* @__PURE__ */ jsx(TextField, { label: "High Label", value: config.highLabel ?? "Very likely", onChange: (v) => updateConfig({ highLabel: v }) })
|
|
1590
1630
|
] });
|
|
1591
1631
|
case "opinion_scale":
|
|
1592
1632
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Scale Settings", children: [
|
|
1593
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Min", value: config.min, placeholder: "1", onChange: (v) => updateConfig(
|
|
1594
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max", value: config.max, placeholder: "5", onChange: (v) => updateConfig(
|
|
1595
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig(
|
|
1596
|
-
/* @__PURE__ */ jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig(
|
|
1597
|
-
/* @__PURE__ */ jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig(
|
|
1633
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Min", value: config.min, placeholder: "1", onChange: (v) => updateConfig({ min: v }) }),
|
|
1634
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max", value: config.max, placeholder: "5", onChange: (v) => updateConfig({ max: v }) }),
|
|
1635
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig({ step: v }) }),
|
|
1636
|
+
/* @__PURE__ */ jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig({ minLabel: v }) }),
|
|
1637
|
+
/* @__PURE__ */ jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig({ maxLabel: v }) })
|
|
1598
1638
|
] });
|
|
1599
1639
|
case "likert":
|
|
1600
|
-
return /* @__PURE__ */ jsx(ConfigSection, { title: "Likert Settings", children: /* @__PURE__ */ jsx(LikertLabelsEditor, { labels: config.labels ?? ["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"], onChange: (v) => updateConfig(
|
|
1640
|
+
return /* @__PURE__ */ jsx(ConfigSection, { title: "Likert Settings", children: /* @__PURE__ */ jsx(LikertLabelsEditor, { labels: config.labels ?? ["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"], onChange: (v) => updateConfig({ labels: v }) }) });
|
|
1601
1641
|
// ── Selection ──
|
|
1602
1642
|
case "single_select":
|
|
1603
1643
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Select Settings", children: [
|
|
1604
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig(
|
|
1605
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig(
|
|
1606
|
-
!!config.allowOther && /* @__PURE__ */ jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig(
|
|
1644
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig({ layout: v }) }),
|
|
1645
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => v ? updateConfig({ allowOther: true }) : updateConfig({ allowOther: false, otherLabel: void 0 }) }),
|
|
1646
|
+
!!config.allowOther && /* @__PURE__ */ jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig({ otherLabel: v }) })
|
|
1607
1647
|
] });
|
|
1608
1648
|
case "multi_select":
|
|
1609
1649
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Multi-Select Settings", children: [
|
|
1610
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig(
|
|
1611
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Min Selections", value: config.minSelections, onChange: (v) => updateConfig(
|
|
1612
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Selections", value: config.maxSelections, onChange: (v) => updateConfig(
|
|
1613
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig(
|
|
1614
|
-
!!config.allowOther && /* @__PURE__ */ jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig(
|
|
1650
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig({ layout: v }) }),
|
|
1651
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Min Selections", value: config.minSelections, onChange: (v) => updateConfig({ minSelections: v }) }),
|
|
1652
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Selections", value: config.maxSelections, onChange: (v) => updateConfig({ maxSelections: v }) }),
|
|
1653
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => v ? updateConfig({ allowOther: true }) : updateConfig({ allowOther: false, otherLabel: void 0 }) }),
|
|
1654
|
+
!!config.allowOther && /* @__PURE__ */ jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig({ otherLabel: v }) })
|
|
1615
1655
|
] });
|
|
1616
1656
|
case "dropdown":
|
|
1617
1657
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Dropdown Settings", children: [
|
|
1618
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Searchable", checked: !!config.searchable, onChange: (v) => updateConfig(
|
|
1619
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig(
|
|
1620
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Multiple", checked: !!config.multiple, onChange: (v) => updateConfig(
|
|
1658
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Searchable", checked: !!config.searchable, onChange: (v) => updateConfig({ searchable: v }) }),
|
|
1659
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig({ allowOther: v }) }),
|
|
1660
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Multiple", checked: !!config.multiple, onChange: (v) => updateConfig({ multiple: v }) })
|
|
1621
1661
|
] });
|
|
1622
1662
|
case "boolean":
|
|
1623
1663
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Yes/No Settings", children: [
|
|
1624
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Style", value: config.style ?? "toggle", options: [{ label: "Toggle", value: "toggle" }, { label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }], onChange: (v) => updateConfig(
|
|
1625
|
-
/* @__PURE__ */ jsx(TextField, { label: "True Label", value: config.trueLabel ?? "Yes", onChange: (v) => updateConfig(
|
|
1626
|
-
/* @__PURE__ */ jsx(TextField, { label: "False Label", value: config.falseLabel ?? "No", onChange: (v) => updateConfig(
|
|
1664
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Style", value: config.style ?? "toggle", options: [{ label: "Toggle", value: "toggle" }, { label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }], onChange: (v) => updateConfig({ style: v }) }),
|
|
1665
|
+
/* @__PURE__ */ jsx(TextField, { label: "True Label", value: config.trueLabel ?? "Yes", onChange: (v) => updateConfig({ trueLabel: v }) }),
|
|
1666
|
+
/* @__PURE__ */ jsx(TextField, { label: "False Label", value: config.falseLabel ?? "No", onChange: (v) => updateConfig({ falseLabel: v }) })
|
|
1627
1667
|
] });
|
|
1628
1668
|
case "country_select":
|
|
1629
1669
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Country Settings", children: [
|
|
1630
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Flags", checked: config.showFlags !== false, onChange: (v) => updateConfig(
|
|
1631
|
-
/* @__PURE__ */ jsx(TextField, { label: "Priority Countries", value: config.priorityCountries?.join(", "), placeholder: "e.g. US, GB, CA", onChange: (v) => updateConfig(
|
|
1632
|
-
/* @__PURE__ */ jsx(TextField, { label: "Exclude Countries", value: config.excludeCountries?.join(", "), placeholder: "e.g. XX, YY", onChange: (v) => updateConfig(
|
|
1670
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Flags", checked: config.showFlags !== false, onChange: (v) => updateConfig({ showFlags: v }) }),
|
|
1671
|
+
/* @__PURE__ */ jsx(TextField, { label: "Priority Countries", value: config.priorityCountries?.join(", "), placeholder: "e.g. US, GB, CA", onChange: (v) => updateConfig({ priorityCountries: v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0 }) }),
|
|
1672
|
+
/* @__PURE__ */ jsx(TextField, { label: "Exclude Countries", value: config.excludeCountries?.join(", "), placeholder: "e.g. XX, YY", onChange: (v) => updateConfig({ excludeCountries: v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0 }) })
|
|
1633
1673
|
] });
|
|
1634
1674
|
// ── Date/Time ──
|
|
1635
1675
|
case "date":
|
|
1636
1676
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Date Settings", children: [
|
|
1637
|
-
/* @__PURE__ */ jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig(
|
|
1638
|
-
/* @__PURE__ */ jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig(
|
|
1639
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Disable Past Dates", checked: !!config.disablePast, onChange: (v) => updateConfig(
|
|
1640
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Disable Future Dates", checked: !!config.disableFuture, onChange: (v) => updateConfig(
|
|
1641
|
-
/* @__PURE__ */ jsx(TextField, { label: "Format", value: config.format, placeholder: "e.g. MM/DD/YYYY", onChange: (v) => updateConfig(
|
|
1677
|
+
/* @__PURE__ */ jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ minDate: v }) }),
|
|
1678
|
+
/* @__PURE__ */ jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ maxDate: v }) }),
|
|
1679
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Disable Past Dates", checked: !!config.disablePast, onChange: (v) => updateConfig({ disablePast: v }) }),
|
|
1680
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Disable Future Dates", checked: !!config.disableFuture, onChange: (v) => updateConfig({ disableFuture: v }) }),
|
|
1681
|
+
/* @__PURE__ */ jsx(TextField, { label: "Format", value: config.format, placeholder: "e.g. MM/DD/YYYY", onChange: (v) => updateConfig({ format: v }) })
|
|
1642
1682
|
] });
|
|
1643
1683
|
case "time":
|
|
1644
1684
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Time Settings", children: [
|
|
1645
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Format", value: config.format ?? "12h", options: [{ label: "12 Hour", value: "12h" }, { label: "24 Hour", value: "24h" }], onChange: (v) => updateConfig(
|
|
1646
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Minute Step", value: config.minuteStep, placeholder: "1", onChange: (v) => updateConfig(
|
|
1685
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Format", value: config.format ?? "12h", options: [{ label: "12 Hour", value: "12h" }, { label: "24 Hour", value: "24h" }], onChange: (v) => updateConfig({ format: v }) }),
|
|
1686
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Minute Step", value: config.minuteStep, placeholder: "1", onChange: (v) => updateConfig({ minuteStep: v }) })
|
|
1647
1687
|
] });
|
|
1648
1688
|
case "date_range":
|
|
1649
1689
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Date Range Settings", children: [
|
|
1650
|
-
/* @__PURE__ */ jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig(
|
|
1651
|
-
/* @__PURE__ */ jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig(
|
|
1652
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Range (days)", value: config.maxRangeDays, onChange: (v) => updateConfig(
|
|
1690
|
+
/* @__PURE__ */ jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ minDate: v }) }),
|
|
1691
|
+
/* @__PURE__ */ jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ maxDate: v }) }),
|
|
1692
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Range (days)", value: config.maxRangeDays, onChange: (v) => updateConfig({ maxRangeDays: v }) })
|
|
1653
1693
|
] });
|
|
1654
|
-
case "appointment":
|
|
1694
|
+
case "appointment": {
|
|
1695
|
+
const appointmentMode = typeof config.embedUrl === "string" ? "embed" : typeof config.slotsUrl === "string" ? "url" : "static";
|
|
1655
1696
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Appointment Settings", children: [
|
|
1656
|
-
/* @__PURE__ */ jsx(
|
|
1657
|
-
|
|
1658
|
-
|
|
1697
|
+
/* @__PURE__ */ jsx(
|
|
1698
|
+
SelectField,
|
|
1699
|
+
{
|
|
1700
|
+
label: "Mode",
|
|
1701
|
+
value: appointmentMode,
|
|
1702
|
+
options: [
|
|
1703
|
+
{ label: "Static Slots", value: "static" },
|
|
1704
|
+
{ label: "API Endpoint", value: "url" },
|
|
1705
|
+
{ label: "Embed (Calendly / Cal.com)", value: "embed" }
|
|
1706
|
+
],
|
|
1707
|
+
onChange: (v) => {
|
|
1708
|
+
if (v === "static") {
|
|
1709
|
+
updateConfig({ slotsUrl: void 0, embedUrl: void 0, embedProvider: void 0 });
|
|
1710
|
+
} else if (v === "url") {
|
|
1711
|
+
updateConfig({ slotsUrl: "", embedUrl: void 0, embedProvider: void 0, slots: void 0 });
|
|
1712
|
+
} else if (v === "embed") {
|
|
1713
|
+
updateConfig({ embedUrl: "", slotsUrl: void 0, slots: void 0 });
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
),
|
|
1718
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Duration (min)", value: config.duration ?? 30, onChange: (v) => updateConfig({ duration: v }) }),
|
|
1719
|
+
/* @__PURE__ */ jsx(TextField, { label: "Timezone", value: config.timezone, placeholder: "e.g. America/New_York", onChange: (v) => updateConfig({ timezone: v }) }),
|
|
1720
|
+
/* @__PURE__ */ jsx(TextField, { label: "Timezone Field", value: config.timezoneField, placeholder: "Field ID for dynamic timezone", onChange: (v) => updateConfig({ timezoneField: v }) }),
|
|
1721
|
+
/* @__PURE__ */ jsx(TextField, { label: "Date Format", value: config.dateFormat, placeholder: "Locale-aware (default)", onChange: (v) => updateConfig({ dateFormat: v }) }),
|
|
1722
|
+
appointmentMode === "url" && /* @__PURE__ */ jsx(TextField, { label: "Slots URL", value: config.slotsUrl, placeholder: "https://api.example.com/slots", onChange: (v) => updateConfig({ slotsUrl: v }) }),
|
|
1723
|
+
appointmentMode === "embed" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1724
|
+
/* @__PURE__ */ jsx(TextField, { label: "Embed URL", value: config.embedUrl, placeholder: "https://calendly.com/your-name/30min", onChange: (v) => updateConfig({ embedUrl: v }) }),
|
|
1725
|
+
/* @__PURE__ */ jsx(
|
|
1726
|
+
SelectField,
|
|
1727
|
+
{
|
|
1728
|
+
label: "Embed Provider",
|
|
1729
|
+
value: config.embedProvider ?? "custom",
|
|
1730
|
+
options: [
|
|
1731
|
+
{ label: "Calendly", value: "calendly" },
|
|
1732
|
+
{ label: "Cal.com", value: "cal_com" },
|
|
1733
|
+
{ label: "Custom", value: "custom" }
|
|
1734
|
+
],
|
|
1735
|
+
onChange: (v) => updateConfig({ embedProvider: v })
|
|
1736
|
+
}
|
|
1737
|
+
)
|
|
1738
|
+
] }),
|
|
1739
|
+
appointmentMode === "static" && /* @__PURE__ */ jsx(
|
|
1740
|
+
AppointmentSlotsEditor,
|
|
1741
|
+
{
|
|
1742
|
+
slots: config.slots ?? [],
|
|
1743
|
+
onChange: (v) => updateConfig({ slots: v })
|
|
1744
|
+
}
|
|
1745
|
+
)
|
|
1659
1746
|
] });
|
|
1747
|
+
}
|
|
1660
1748
|
// ── Media ──
|
|
1661
1749
|
case "file_upload":
|
|
1662
1750
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Upload Settings", children: [
|
|
1663
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Files", value: config.maxFiles ?? 1, onChange: (v) => updateConfig(
|
|
1664
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb ?? 10, onChange: (v) => updateConfig(
|
|
1665
|
-
/* @__PURE__ */ jsx(TextField, { label: "Accepted Types", value: config.accept?.join(", "), placeholder: "e.g. .pdf, .jpg, .png", onChange: (v) => updateConfig(
|
|
1666
|
-
/* @__PURE__ */ jsx(TextField, { label: "Upload URL", value: config.uploadUrl, placeholder: "Server upload endpoint", onChange: (v) => updateConfig(
|
|
1751
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Files", value: config.maxFiles ?? 1, onChange: (v) => updateConfig({ maxFiles: v }) }),
|
|
1752
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb ?? 10, onChange: (v) => updateConfig({ maxSizeMb: v }) }),
|
|
1753
|
+
/* @__PURE__ */ jsx(TextField, { label: "Accepted Types", value: config.accept?.join(", "), placeholder: "e.g. .pdf, .jpg, .png", onChange: (v) => updateConfig({ accept: v ? v.split(",").map((s) => s.trim()) : void 0 }) }),
|
|
1754
|
+
/* @__PURE__ */ jsx(TextField, { label: "Upload URL", value: config.uploadUrl, placeholder: "Server upload endpoint", onChange: (v) => updateConfig({ uploadUrl: v }) })
|
|
1667
1755
|
] });
|
|
1668
1756
|
case "signature":
|
|
1669
1757
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Signature Settings", children: [
|
|
1670
|
-
/* @__PURE__ */ jsx(TextField, { label: "Pen Color", value: config.penColor, placeholder: "#000000", onChange: (v) => updateConfig(
|
|
1671
|
-
/* @__PURE__ */ jsx(TextField, { label: "Background", value: config.backgroundColor, placeholder: "#ffffff", onChange: (v) => updateConfig(
|
|
1672
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Width (px)", value: config.width, onChange: (v) => updateConfig(
|
|
1673
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Height (px)", value: config.height, onChange: (v) => updateConfig(
|
|
1758
|
+
/* @__PURE__ */ jsx(TextField, { label: "Pen Color", value: config.penColor, placeholder: "#000000", onChange: (v) => updateConfig({ penColor: v }) }),
|
|
1759
|
+
/* @__PURE__ */ jsx(TextField, { label: "Background", value: config.backgroundColor, placeholder: "#ffffff", onChange: (v) => updateConfig({ backgroundColor: v }) }),
|
|
1760
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Width (px)", value: config.width, onChange: (v) => updateConfig({ width: v }) }),
|
|
1761
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Height (px)", value: config.height, onChange: (v) => updateConfig({ height: v }) })
|
|
1674
1762
|
] });
|
|
1675
1763
|
case "image_capture":
|
|
1676
1764
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Camera Settings", children: [
|
|
1677
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Camera", value: config.camera ?? "any", options: [{ label: "Any", value: "any" }, { label: "Front", value: "front" }, { label: "Back", value: "back" }], onChange: (v) => updateConfig(
|
|
1678
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb, onChange: (v) => updateConfig(
|
|
1679
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Gallery", checked: config.allowGallery !== false, onChange: (v) => updateConfig(
|
|
1765
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Camera", value: config.camera ?? "any", options: [{ label: "Any", value: "any" }, { label: "Front", value: "front" }, { label: "Back", value: "back" }], onChange: (v) => updateConfig({ camera: v }) }),
|
|
1766
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb, onChange: (v) => updateConfig({ maxSizeMb: v }) }),
|
|
1767
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Allow Gallery", checked: config.allowGallery !== false, onChange: (v) => updateConfig({ allowGallery: v }) })
|
|
1680
1768
|
] });
|
|
1681
1769
|
// ── Content & Visual ──
|
|
1682
1770
|
case "welcome-screen":
|
|
1683
1771
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Welcome Screen", children: [
|
|
1684
|
-
/* @__PURE__ */ jsx(TextField, { label: "Heading", value: config.heading ?? "Welcome", onChange: (v) => updateConfig(
|
|
1685
|
-
/* @__PURE__ */ jsx(TextareaField, { label: "Description", value: config.description, onChange: (v) => updateConfig(
|
|
1686
|
-
/* @__PURE__ */ jsx(TextField, { label: "Button Text", value: config.buttonText ?? "Start", onChange: (v) => updateConfig(
|
|
1687
|
-
/* @__PURE__ */ jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig(
|
|
1688
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig(
|
|
1772
|
+
/* @__PURE__ */ jsx(TextField, { label: "Heading", value: config.heading ?? "Welcome", onChange: (v) => updateConfig({ heading: v }) }),
|
|
1773
|
+
/* @__PURE__ */ jsx(TextareaField, { label: "Description", value: config.description, onChange: (v) => updateConfig({ description: v }) }),
|
|
1774
|
+
/* @__PURE__ */ jsx(TextField, { label: "Button Text", value: config.buttonText ?? "Start", onChange: (v) => updateConfig({ buttonText: v }) }),
|
|
1775
|
+
/* @__PURE__ */ jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig({ imageUrl: v }) }),
|
|
1776
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig({ alignment: v }) })
|
|
1689
1777
|
] });
|
|
1690
1778
|
case "thank-you-screen":
|
|
1691
1779
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Thank You Screen", children: [
|
|
1692
|
-
/* @__PURE__ */ jsx(TextField, { label: "Heading", value: config.heading ?? "Thank You!", onChange: (v) => updateConfig(
|
|
1693
|
-
/* @__PURE__ */ jsx(TextareaField, { label: "Description", value: config.description ?? "", onChange: (v) => updateConfig(
|
|
1694
|
-
/* @__PURE__ */ jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig(
|
|
1695
|
-
/* @__PURE__ */ jsx(TextField, { label: "Redirect URL", value: config.redirectUrl, placeholder: "https://...", onChange: (v) => updateConfig(
|
|
1696
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Redirect Delay (s)", value: config.redirectDelay, placeholder: "0", onChange: (v) => updateConfig(
|
|
1697
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Response Summary", checked: !!config.showSummary, onChange: (v) => updateConfig(
|
|
1780
|
+
/* @__PURE__ */ jsx(TextField, { label: "Heading", value: config.heading ?? "Thank You!", onChange: (v) => updateConfig({ heading: v }) }),
|
|
1781
|
+
/* @__PURE__ */ jsx(TextareaField, { label: "Description", value: config.description ?? "", onChange: (v) => updateConfig({ description: v }) }),
|
|
1782
|
+
/* @__PURE__ */ jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig({ imageUrl: v }) }),
|
|
1783
|
+
/* @__PURE__ */ jsx(TextField, { label: "Redirect URL", value: config.redirectUrl, placeholder: "https://...", onChange: (v) => updateConfig({ redirectUrl: v }) }),
|
|
1784
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Redirect Delay (s)", value: config.redirectDelay, placeholder: "0", onChange: (v) => updateConfig({ redirectDelay: v }) }),
|
|
1785
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Response Summary", checked: !!config.showSummary, onChange: (v) => updateConfig({ showSummary: v }) })
|
|
1698
1786
|
] });
|
|
1699
1787
|
case "rich-text":
|
|
1700
1788
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Rich Text", children: [
|
|
1701
|
-
/* @__PURE__ */ jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 6, onChange: (v) => updateConfig(
|
|
1702
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Format", value: config.format ?? "html", options: [{ label: "HTML", value: "html" }, { label: "Markdown", value: "markdown" }], onChange: (v) => updateConfig(
|
|
1789
|
+
/* @__PURE__ */ jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 6, onChange: (v) => updateConfig({ content: v }) }),
|
|
1790
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Format", value: config.format ?? "html", options: [{ label: "HTML", value: "html" }, { label: "Markdown", value: "markdown" }], onChange: (v) => updateConfig({ format: v }) })
|
|
1703
1791
|
] });
|
|
1704
1792
|
case "image":
|
|
1705
1793
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Image Settings", children: [
|
|
1706
|
-
/* @__PURE__ */ jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "https://...", onChange: (v) => updateConfig(
|
|
1707
|
-
/* @__PURE__ */ jsx(TextField, { label: "Alt Text", value: config.alt ?? "", onChange: (v) => updateConfig(
|
|
1708
|
-
/* @__PURE__ */ jsx(TextField, { label: "Caption", value: config.caption, onChange: (v) => updateConfig(
|
|
1709
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig(
|
|
1710
|
-
/* @__PURE__ */ jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 300px", onChange: (v) => updateConfig(
|
|
1711
|
-
/* @__PURE__ */ jsx(TextField, { label: "Link URL", value: config.link, placeholder: "Click opens this URL", onChange: (v) => updateConfig(
|
|
1794
|
+
/* @__PURE__ */ jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "https://...", onChange: (v) => updateConfig({ src: v }) }),
|
|
1795
|
+
/* @__PURE__ */ jsx(TextField, { label: "Alt Text", value: config.alt ?? "", onChange: (v) => updateConfig({ alt: v }) }),
|
|
1796
|
+
/* @__PURE__ */ jsx(TextField, { label: "Caption", value: config.caption, onChange: (v) => updateConfig({ caption: v }) }),
|
|
1797
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig({ alignment: v }) }),
|
|
1798
|
+
/* @__PURE__ */ jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 300px", onChange: (v) => updateConfig({ width: v }) }),
|
|
1799
|
+
/* @__PURE__ */ jsx(TextField, { label: "Link URL", value: config.link, placeholder: "Click opens this URL", onChange: (v) => updateConfig({ link: v }) })
|
|
1712
1800
|
] });
|
|
1713
1801
|
case "video":
|
|
1714
1802
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Video Settings", children: [
|
|
1715
|
-
/* @__PURE__ */ jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "YouTube/Vimeo URL", onChange: (v) => updateConfig(
|
|
1716
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Provider", value: config.provider ?? "youtube", options: [{ label: "YouTube", value: "youtube" }, { label: "Vimeo", value: "vimeo" }, { label: "Direct URL", value: "url" }], onChange: (v) => updateConfig(
|
|
1717
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Autoplay", checked: !!config.autoplay, onChange: (v) => updateConfig(
|
|
1718
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Muted", checked: !!config.muted, onChange: (v) => updateConfig(
|
|
1719
|
-
/* @__PURE__ */ jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 640px", onChange: (v) => updateConfig(
|
|
1720
|
-
/* @__PURE__ */ jsx(TextField, { label: "Height", value: config.height, placeholder: "e.g. 360px", onChange: (v) => updateConfig(
|
|
1803
|
+
/* @__PURE__ */ jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "YouTube/Vimeo URL", onChange: (v) => updateConfig({ src: v }) }),
|
|
1804
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Provider", value: config.provider ?? "youtube", options: [{ label: "YouTube", value: "youtube" }, { label: "Vimeo", value: "vimeo" }, { label: "Direct URL", value: "url" }], onChange: (v) => updateConfig({ provider: v }) }),
|
|
1805
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Autoplay", checked: !!config.autoplay, onChange: (v) => updateConfig({ autoplay: v }) }),
|
|
1806
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Muted", checked: !!config.muted, onChange: (v) => updateConfig({ muted: v }) }),
|
|
1807
|
+
/* @__PURE__ */ jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 640px", onChange: (v) => updateConfig({ width: v }) }),
|
|
1808
|
+
/* @__PURE__ */ jsx(TextField, { label: "Height", value: config.height, placeholder: "e.g. 360px", onChange: (v) => updateConfig({ height: v }) })
|
|
1721
1809
|
] });
|
|
1722
1810
|
case "divider":
|
|
1723
1811
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Divider Settings", children: [
|
|
1724
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Style", value: config.style ?? "solid", options: [{ label: "Solid", value: "solid" }, { label: "Dashed", value: "dashed" }, { label: "Dotted", value: "dotted" }], onChange: (v) => updateConfig(
|
|
1725
|
-
/* @__PURE__ */ jsx(TextField, { label: "Color", value: config.color, placeholder: "#e5e7eb", onChange: (v) => updateConfig(
|
|
1726
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Thickness (px)", value: config.thickness, placeholder: "1", onChange: (v) => updateConfig(
|
|
1727
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Spacing (px)", value: config.spacing, placeholder: "16", onChange: (v) => updateConfig(
|
|
1812
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Style", value: config.style ?? "solid", options: [{ label: "Solid", value: "solid" }, { label: "Dashed", value: "dashed" }, { label: "Dotted", value: "dotted" }], onChange: (v) => updateConfig({ style: v }) }),
|
|
1813
|
+
/* @__PURE__ */ jsx(TextField, { label: "Color", value: config.color, placeholder: "#e5e7eb", onChange: (v) => updateConfig({ color: v }) }),
|
|
1814
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Thickness (px)", value: config.thickness, placeholder: "1", onChange: (v) => updateConfig({ thickness: v }) }),
|
|
1815
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Spacing (px)", value: config.spacing, placeholder: "16", onChange: (v) => updateConfig({ spacing: v }) })
|
|
1728
1816
|
] });
|
|
1729
1817
|
case "spacer":
|
|
1730
|
-
return /* @__PURE__ */ jsx(ConfigSection, { title: "Spacer Settings", children: /* @__PURE__ */ jsx(NumberField, { label: "Height (px)", value: config.height ?? 32, onChange: (v) => updateConfig(
|
|
1818
|
+
return /* @__PURE__ */ jsx(ConfigSection, { title: "Spacer Settings", children: /* @__PURE__ */ jsx(NumberField, { label: "Height (px)", value: config.height ?? 32, onChange: (v) => updateConfig({ height: v }) }) });
|
|
1731
1819
|
// ── Structural ──
|
|
1732
1820
|
case "section_header":
|
|
1733
1821
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Header Settings", children: [
|
|
1734
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Level", value: config.level ?? "h3", options: [{ label: "H2", value: "h2" }, { label: "H3", value: "h3" }, { label: "H4", value: "h4" }], onChange: (v) => updateConfig(
|
|
1735
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Divider", checked: !!config.showDivider, onChange: (v) => updateConfig(
|
|
1822
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Level", value: config.level ?? "h3", options: [{ label: "H2", value: "h2" }, { label: "H3", value: "h3" }, { label: "H4", value: "h4" }], onChange: (v) => updateConfig({ level: v }) }),
|
|
1823
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Divider", checked: !!config.showDivider, onChange: (v) => updateConfig({ showDivider: v }) })
|
|
1736
1824
|
] });
|
|
1737
1825
|
case "info_block":
|
|
1738
1826
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Info Block", children: [
|
|
1739
|
-
/* @__PURE__ */ jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 4, onChange: (v) => updateConfig(
|
|
1740
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Variant", value: config.variant ?? "info", options: [{ label: "Info", value: "info" }, { label: "Warning", value: "warning" }, { label: "Success", value: "success" }, { label: "Error", value: "error" }], onChange: (v) => updateConfig(
|
|
1827
|
+
/* @__PURE__ */ jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 4, onChange: (v) => updateConfig({ content: v }) }),
|
|
1828
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Variant", value: config.variant ?? "info", options: [{ label: "Info", value: "info" }, { label: "Warning", value: "warning" }, { label: "Success", value: "success" }, { label: "Error", value: "error" }], onChange: (v) => updateConfig({ variant: v }) })
|
|
1741
1829
|
] });
|
|
1742
1830
|
case "page_break":
|
|
1743
|
-
return /* @__PURE__ */ jsx(ConfigSection, { title: "Page Break", children: /* @__PURE__ */ jsx(TextField, { label: "Label", value: config.label, placeholder: "Next page label", onChange: (v) => updateConfig(
|
|
1831
|
+
return /* @__PURE__ */ jsx(ConfigSection, { title: "Page Break", children: /* @__PURE__ */ jsx(TextField, { label: "Label", value: config.label, placeholder: "Next page label", onChange: (v) => updateConfig({ label: v }) }) });
|
|
1744
1832
|
case "consent":
|
|
1745
1833
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Consent Settings", children: [
|
|
1746
|
-
/* @__PURE__ */ jsx(TextareaField, { label: "Consent Text", value: config.text ?? "", rows: 4, onChange: (v) => updateConfig(
|
|
1747
|
-
/* @__PURE__ */ jsx(TextField, { label: "Checkbox Label", value: config.checkboxLabel ?? "I agree", onChange: (v) => updateConfig(
|
|
1748
|
-
/* @__PURE__ */ jsx(TextareaField, { label: "Expandable Text", value: config.expandableText, rows: 3, placeholder: "Additional text shown on expand", onChange: (v) => updateConfig(
|
|
1834
|
+
/* @__PURE__ */ jsx(TextareaField, { label: "Consent Text", value: config.text ?? "", rows: 4, onChange: (v) => updateConfig({ text: v }) }),
|
|
1835
|
+
/* @__PURE__ */ jsx(TextField, { label: "Checkbox Label", value: config.checkboxLabel ?? "I agree", onChange: (v) => updateConfig({ checkboxLabel: v }) }),
|
|
1836
|
+
/* @__PURE__ */ jsx(TextareaField, { label: "Expandable Text", value: config.expandableText, rows: 3, placeholder: "Additional text shown on expand", onChange: (v) => updateConfig({ expandableText: v }) })
|
|
1749
1837
|
] });
|
|
1750
1838
|
// ── Advanced ──
|
|
1751
1839
|
case "matrix":
|
|
1752
1840
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Matrix Settings", children: [
|
|
1753
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Input Type", value: config.inputType ?? "radio", options: [{ label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }, { label: "Text", value: "text" }, { label: "Number", value: "number" }], onChange: (v) => updateConfig(
|
|
1754
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Required", value: config.required ?? "none", options: [{ label: "All rows", value: "all" }, { label: "Any row", value: "any" }, { label: "None", value: "none" }], onChange: (v) => updateConfig(
|
|
1755
|
-
/* @__PURE__ */ jsx(MatrixItemsEditor, { label: "Rows", items: config.rows ?? [], onChange: (v) => updateConfig(
|
|
1756
|
-
/* @__PURE__ */ jsx(MatrixItemsEditor, { label: "Columns", items: config.columns ?? [], onChange: (v) => updateConfig(
|
|
1841
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Input Type", value: config.inputType ?? "radio", options: [{ label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }, { label: "Text", value: "text" }, { label: "Number", value: "number" }], onChange: (v) => updateConfig({ inputType: v }) }),
|
|
1842
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Required", value: config.required ?? "none", options: [{ label: "All rows", value: "all" }, { label: "Any row", value: "any" }, { label: "None", value: "none" }], onChange: (v) => updateConfig({ required: v }) }),
|
|
1843
|
+
/* @__PURE__ */ jsx(MatrixItemsEditor, { label: "Rows", items: config.rows ?? [], onChange: (v) => updateConfig({ rows: v }) }),
|
|
1844
|
+
/* @__PURE__ */ jsx(MatrixItemsEditor, { label: "Columns", items: config.columns ?? [], onChange: (v) => updateConfig({ columns: v }) })
|
|
1757
1845
|
] });
|
|
1758
1846
|
case "repeater":
|
|
1759
1847
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Repeater Settings", children: [
|
|
1760
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Min Entries", value: config.minEntries, placeholder: "1", onChange: (v) => updateConfig(
|
|
1761
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Max Entries", value: config.maxEntries, onChange: (v) => updateConfig(
|
|
1762
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Default Entries", value: config.defaultEntries, placeholder: "1", onChange: (v) => updateConfig(
|
|
1763
|
-
/* @__PURE__ */ jsx(TextField, { label: "Add Button Label", value: config.addLabel, placeholder: "Add Entry", onChange: (v) => updateConfig(
|
|
1764
|
-
/* @__PURE__ */ jsx(TextField, { label: "Remove Button Label", value: config.removeLabel, placeholder: "Remove", onChange: (v) => updateConfig(
|
|
1848
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Min Entries", value: config.minEntries, placeholder: "1", onChange: (v) => updateConfig({ minEntries: v }) }),
|
|
1849
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Max Entries", value: config.maxEntries, onChange: (v) => updateConfig({ maxEntries: v }) }),
|
|
1850
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Default Entries", value: config.defaultEntries, placeholder: "1", onChange: (v) => updateConfig({ defaultEntries: v }) }),
|
|
1851
|
+
/* @__PURE__ */ jsx(TextField, { label: "Add Button Label", value: config.addLabel, placeholder: "Add Entry", onChange: (v) => updateConfig({ addLabel: v }) }),
|
|
1852
|
+
/* @__PURE__ */ jsx(TextField, { label: "Remove Button Label", value: config.removeLabel, placeholder: "Remove", onChange: (v) => updateConfig({ removeLabel: v }) }),
|
|
1765
1853
|
/* @__PURE__ */ jsx("div", { className: "mt-1 text-[11px] text-muted-foreground leading-relaxed", children: "Sub-fields for each repeater entry are configured by nesting questions inside the repeater in the schema JSON." })
|
|
1766
1854
|
] });
|
|
1767
1855
|
case "address": {
|
|
@@ -1775,9 +1863,9 @@ function QuestionConfigEditor({ question, onUpdate }) {
|
|
|
1775
1863
|
];
|
|
1776
1864
|
const activeFields = config.fields ?? ["street", "city", "state", "zip", "country"];
|
|
1777
1865
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Address Settings", children: [
|
|
1778
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Provider", value: config.provider ?? "none", options: [{ label: "None", value: "none" }, { label: "Google", value: "google" }, { label: "Mapbox", value: "mapbox" }], onChange: (v) => updateConfig(
|
|
1779
|
-
config.provider !== "none" && /* @__PURE__ */ jsx(TextField, { label: "API Key", value: config.apiKey, placeholder: "Provider API key", onChange: (v) => updateConfig(
|
|
1780
|
-
/* @__PURE__ */ jsx(TextField, { label: "Default Country", value: config.defaultCountry, placeholder: "e.g. US", onChange: (v) => updateConfig(
|
|
1866
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Provider", value: config.provider ?? "none", options: [{ label: "None", value: "none" }, { label: "Google", value: "google" }, { label: "Mapbox", value: "mapbox" }], onChange: (v) => updateConfig({ provider: v }) }),
|
|
1867
|
+
config.provider !== "none" && /* @__PURE__ */ jsx(TextField, { label: "API Key", value: config.apiKey, placeholder: "Provider API key", onChange: (v) => updateConfig({ apiKey: v }) }),
|
|
1868
|
+
/* @__PURE__ */ jsx(TextField, { label: "Default Country", value: config.defaultCountry, placeholder: "e.g. US", onChange: (v) => updateConfig({ defaultCountry: v }) }),
|
|
1781
1869
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1782
1870
|
/* @__PURE__ */ jsx(Label, { className: "text-xs text-muted-foreground mb-2 block", children: "Fields" }),
|
|
1783
1871
|
/* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: ADDRESS_FIELDS.map((f) => /* @__PURE__ */ jsx(
|
|
@@ -1787,7 +1875,7 @@ function QuestionConfigEditor({ question, onUpdate }) {
|
|
|
1787
1875
|
checked: activeFields.includes(f.value),
|
|
1788
1876
|
onChange: (checked) => {
|
|
1789
1877
|
const next = checked ? [...activeFields, f.value] : activeFields.filter((v) => v !== f.value);
|
|
1790
|
-
updateConfig(
|
|
1878
|
+
updateConfig({ fields: next.length > 0 ? next : void 0 });
|
|
1791
1879
|
}
|
|
1792
1880
|
},
|
|
1793
1881
|
f.value
|
|
@@ -1797,41 +1885,47 @@ function QuestionConfigEditor({ question, onUpdate }) {
|
|
|
1797
1885
|
}
|
|
1798
1886
|
case "payment":
|
|
1799
1887
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Payment Settings", children: [
|
|
1800
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Provider", value: config.provider ?? "stripe", options: [{ label: "Stripe", value: "stripe" }, { label: "PayPal", value: "paypal" }], onChange: (v) => updateConfig(
|
|
1801
|
-
/* @__PURE__ */ jsx(TextField, { label: "Public Key", value: config.publicKey ?? "", placeholder: "Provider public/client key", onChange: (v) => updateConfig(
|
|
1802
|
-
/* @__PURE__ */ jsx(
|
|
1803
|
-
/* @__PURE__ */ jsx(TextField, { label: "
|
|
1804
|
-
/* @__PURE__ */ jsx(
|
|
1805
|
-
/* @__PURE__ */ jsx(TextField, { label: "
|
|
1888
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Provider", value: config.provider ?? "stripe", options: [{ label: "Stripe", value: "stripe" }, { label: "PayPal", value: "paypal" }], onChange: (v) => updateConfig({ provider: v }) }),
|
|
1889
|
+
/* @__PURE__ */ jsx(TextField, { label: "Public Key", value: config.publicKey ?? "", placeholder: "Provider public/client key", onChange: (v) => updateConfig({ publicKey: v }) }),
|
|
1890
|
+
/* @__PURE__ */ jsx(TextField, { label: "Server URL", value: config.serverUrl ?? "", placeholder: "https://api.example.com/create-intent", onChange: (v) => updateConfig({ serverUrl: v || void 0 }) }),
|
|
1891
|
+
/* @__PURE__ */ jsx(TextField, { label: "Client Secret Path", value: config.responseMapping?.clientSecretPath ?? "", placeholder: "clientSecret", onChange: (v) => updateConfig({ responseMapping: v ? { clientSecretPath: v } : void 0 }) }),
|
|
1892
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Amount", value: config.amount, onChange: (v) => updateConfig({ amount: v }) }),
|
|
1893
|
+
/* @__PURE__ */ jsx(TextField, { label: "Amount Field", value: config.amountField, placeholder: "Field ID for dynamic amount", onChange: (v) => updateConfig({ amountField: v }) }),
|
|
1894
|
+
/* @__PURE__ */ jsx(TextField, { label: "Currency", value: config.currency, placeholder: "USD", onChange: (v) => updateConfig({ currency: v }) }),
|
|
1895
|
+
/* @__PURE__ */ jsx(TextField, { label: "Description", value: config.description, onChange: (v) => updateConfig({ description: v }) })
|
|
1806
1896
|
] });
|
|
1807
1897
|
case "calculated":
|
|
1808
1898
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Calculated Field", children: [
|
|
1809
|
-
/* @__PURE__ */ jsx(TextField, { label: "Expression", value: config.expression ?? "", placeholder: "e.g. {q1} + {q2}", onChange: (v) => updateConfig(
|
|
1810
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Format", value: config.format ?? "number", options: [{ label: "Number", value: "number" }, { label: "Currency", value: "currency" }, { label: "Percentage", value: "percentage" }], onChange: (v) => updateConfig(
|
|
1811
|
-
/* @__PURE__ */ jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "2", onChange: (v) => updateConfig(
|
|
1812
|
-
/* @__PURE__ */ jsx(TextField, { label: "Prefix", value: config.prefix, onChange: (v) => updateConfig(
|
|
1813
|
-
/* @__PURE__ */ jsx(TextField, { label: "Suffix", value: config.suffix, onChange: (v) => updateConfig(
|
|
1814
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Visible to User", checked: config.visible !== false, onChange: (v) => updateConfig(
|
|
1899
|
+
/* @__PURE__ */ jsx(TextField, { label: "Expression", value: config.expression ?? "", placeholder: "e.g. {q1} + {q2}", onChange: (v) => updateConfig({ expression: v }) }),
|
|
1900
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Format", value: config.format ?? "number", options: [{ label: "Number", value: "number" }, { label: "Currency", value: "currency" }, { label: "Percentage", value: "percentage" }], onChange: (v) => updateConfig({ format: v }) }),
|
|
1901
|
+
/* @__PURE__ */ jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "2", onChange: (v) => updateConfig({ decimalPlaces: v }) }),
|
|
1902
|
+
/* @__PURE__ */ jsx(TextField, { label: "Prefix", value: config.prefix, onChange: (v) => updateConfig({ prefix: v }) }),
|
|
1903
|
+
/* @__PURE__ */ jsx(TextField, { label: "Suffix", value: config.suffix, onChange: (v) => updateConfig({ suffix: v }) }),
|
|
1904
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Visible to User", checked: config.visible !== false, onChange: (v) => updateConfig({ visible: v }) })
|
|
1815
1905
|
] });
|
|
1816
1906
|
case "hidden":
|
|
1817
1907
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Hidden Field", children: [
|
|
1818
|
-
/* @__PURE__ */ jsx(SelectField, { label: "Source", value: config.source ?? "static", options: [{ label: "Static Value", value: "static" }, { label: "URL Parameter", value: "url_param" }, { label: "Cookie", value: "cookie" }, { label: "Referrer", value: "referrer" }], onChange: (v) => updateConfig(
|
|
1819
|
-
config.source === "static" && /* @__PURE__ */ jsx(TextField, { label: "Default Value", value: config.defaultValue, onChange: (v) => updateConfig(
|
|
1820
|
-
config.source === "url_param" && /* @__PURE__ */ jsx(TextField, { label: "Parameter Name", value: config.paramName, placeholder: "e.g. utm_source", onChange: (v) => updateConfig(
|
|
1821
|
-
config.source === "cookie" && /* @__PURE__ */ jsx(TextField, { label: "Cookie Name", value: config.cookieName, onChange: (v) => updateConfig(
|
|
1908
|
+
/* @__PURE__ */ jsx(SelectField, { label: "Source", value: config.source ?? "static", options: [{ label: "Static Value", value: "static" }, { label: "URL Parameter", value: "url_param" }, { label: "Cookie", value: "cookie" }, { label: "Referrer", value: "referrer" }], onChange: (v) => updateConfig({ source: v }) }),
|
|
1909
|
+
config.source === "static" && /* @__PURE__ */ jsx(TextField, { label: "Default Value", value: config.defaultValue, onChange: (v) => updateConfig({ defaultValue: v }) }),
|
|
1910
|
+
config.source === "url_param" && /* @__PURE__ */ jsx(TextField, { label: "Parameter Name", value: config.paramName, placeholder: "e.g. utm_source", onChange: (v) => updateConfig({ paramName: v }) }),
|
|
1911
|
+
config.source === "cookie" && /* @__PURE__ */ jsx(TextField, { label: "Cookie Name", value: config.cookieName, onChange: (v) => updateConfig({ cookieName: v }) })
|
|
1822
1912
|
] });
|
|
1823
1913
|
case "scoring":
|
|
1824
1914
|
return /* @__PURE__ */ jsxs(ConfigSection, { title: "Scoring Settings", children: [
|
|
1825
|
-
/* @__PURE__ */ jsx(ToggleField, { label: "Show Score", checked: !!config.showScore, onChange: (v) => updateConfig(
|
|
1826
|
-
/* @__PURE__ */ jsx(ScoringOptionsEditor, { options: config.options ?? [], onChange: (v) => updateConfig(
|
|
1827
|
-
/* @__PURE__ */ jsx(ScoreRangesEditor, { ranges: config.scoreRanges ?? [], onChange: (v) => updateConfig(
|
|
1915
|
+
/* @__PURE__ */ jsx(ToggleField, { label: "Show Score", checked: !!config.showScore, onChange: (v) => updateConfig({ showScore: v }) }),
|
|
1916
|
+
/* @__PURE__ */ jsx(ScoringOptionsEditor, { options: config.options ?? [], onChange: (v) => updateConfig({ options: v }) }),
|
|
1917
|
+
/* @__PURE__ */ jsx(ScoreRangesEditor, { ranges: config.scoreRanges ?? [], onChange: (v) => updateConfig({ scoreRanges: v }) })
|
|
1828
1918
|
] });
|
|
1829
1919
|
case "ranking":
|
|
1830
|
-
return /* @__PURE__ */ jsx(ConfigSection, { title: "Ranking Settings", children: /* @__PURE__ */ jsx(MatrixItemsEditor, { label: "Items", items: config.items ?? [], onChange: (v) => updateConfig(
|
|
1920
|
+
return /* @__PURE__ */ jsx(ConfigSection, { title: "Ranking Settings", children: /* @__PURE__ */ jsx(MatrixItemsEditor, { label: "Items", items: config.items ?? [], onChange: (v) => updateConfig({ items: v }) }) });
|
|
1921
|
+
case "phone_international":
|
|
1922
|
+
return /* @__PURE__ */ jsxs(ConfigSection, { title: "International Phone Settings", children: [
|
|
1923
|
+
/* @__PURE__ */ jsx(TextField, { label: "Default Country", value: config.defaultCountry ?? "US", placeholder: "e.g. US", onChange: (v) => updateConfig({ defaultCountry: v }) }),
|
|
1924
|
+
/* @__PURE__ */ jsx(TextField, { label: "Priority Countries", value: config.priorityCountries?.join(", "), placeholder: "e.g. US, GB, CA", onChange: (v) => updateConfig({ priorityCountries: v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0 }) })
|
|
1925
|
+
] });
|
|
1831
1926
|
// Types with no additional config
|
|
1832
1927
|
case "email":
|
|
1833
1928
|
case "phone":
|
|
1834
|
-
case "phone_international":
|
|
1835
1929
|
case "url":
|
|
1836
1930
|
return null;
|
|
1837
1931
|
default:
|
|
@@ -1923,7 +2017,10 @@ function SelectField({
|
|
|
1923
2017
|
}) {
|
|
1924
2018
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
1925
2019
|
/* @__PURE__ */ jsx(Label, { className: "text-xs text-muted-foreground mb-1", children: label }),
|
|
1926
|
-
/* @__PURE__ */
|
|
2020
|
+
/* @__PURE__ */ jsxs(Select, { value, onValueChange: onChange, children: [
|
|
2021
|
+
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx("span", { children: options.find((o) => o.value === value)?.label ?? value }) }),
|
|
2022
|
+
/* @__PURE__ */ jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
|
|
2023
|
+
] })
|
|
1927
2024
|
] });
|
|
1928
2025
|
}
|
|
1929
2026
|
function LikertLabelsEditor({
|
|
@@ -2069,6 +2166,59 @@ function ScoringOptionsEditor({
|
|
|
2069
2166
|
] }, index)) })
|
|
2070
2167
|
] });
|
|
2071
2168
|
}
|
|
2169
|
+
function AppointmentSlotsEditor({
|
|
2170
|
+
slots,
|
|
2171
|
+
onChange
|
|
2172
|
+
}) {
|
|
2173
|
+
const handleDateChange = (index, date) => {
|
|
2174
|
+
const updated = slots.map((s, i) => i === index ? { ...s, date } : s);
|
|
2175
|
+
onChange(updated);
|
|
2176
|
+
};
|
|
2177
|
+
const handleTimesChange = (index, timesStr) => {
|
|
2178
|
+
const times = timesStr.split(",").map((t) => t.trim()).filter(Boolean);
|
|
2179
|
+
const updated = slots.map((s, i) => i === index ? { ...s, times } : s);
|
|
2180
|
+
onChange(updated);
|
|
2181
|
+
};
|
|
2182
|
+
const handleAdd = () => {
|
|
2183
|
+
const tomorrow = /* @__PURE__ */ new Date();
|
|
2184
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
2185
|
+
const dateStr = tomorrow.toISOString().split("T")[0];
|
|
2186
|
+
onChange([...slots, { date: dateStr, times: ["09:00", "10:00", "11:00", "14:00", "15:00"] }]);
|
|
2187
|
+
};
|
|
2188
|
+
const handleRemove = (index) => {
|
|
2189
|
+
onChange(slots.filter((_, i) => i !== index));
|
|
2190
|
+
};
|
|
2191
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
2192
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
|
|
2193
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs text-muted-foreground", children: "Slots" }),
|
|
2194
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "xs", onClick: handleAdd, className: "px-0", children: "+ Add Date" })
|
|
2195
|
+
] }),
|
|
2196
|
+
slots.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground", children: "No slots configured. Add a date to get started." }),
|
|
2197
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: slots.map((slot, index) => /* @__PURE__ */ jsxs("div", { className: "p-2 rounded-md border border-border space-y-1.5 group", children: [
|
|
2198
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
2199
|
+
/* @__PURE__ */ jsx(
|
|
2200
|
+
Input,
|
|
2201
|
+
{
|
|
2202
|
+
type: "date",
|
|
2203
|
+
value: slot.date,
|
|
2204
|
+
onChange: (e) => handleDateChange(index, e.target.value),
|
|
2205
|
+
className: "h-7 text-xs flex-1"
|
|
2206
|
+
}
|
|
2207
|
+
),
|
|
2208
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", onClick: () => handleRemove(index), className: "text-destructive opacity-0 group-hover:opacity-100 transition-opacity", children: "x" })
|
|
2209
|
+
] }),
|
|
2210
|
+
/* @__PURE__ */ jsx(
|
|
2211
|
+
Input,
|
|
2212
|
+
{
|
|
2213
|
+
value: slot.times.join(", "),
|
|
2214
|
+
onChange: (e) => handleTimesChange(index, e.target.value),
|
|
2215
|
+
className: "h-7 text-xs",
|
|
2216
|
+
placeholder: "09:00, 10:00, 14:00, 15:00"
|
|
2217
|
+
}
|
|
2218
|
+
)
|
|
2219
|
+
] }, index)) })
|
|
2220
|
+
] });
|
|
2221
|
+
}
|
|
2072
2222
|
function ScoreRangesEditor({
|
|
2073
2223
|
ranges,
|
|
2074
2224
|
onChange
|
|
@@ -2101,6 +2251,26 @@ function ScoreRangesEditor({
|
|
|
2101
2251
|
] }, index)) })
|
|
2102
2252
|
] });
|
|
2103
2253
|
}
|
|
2254
|
+
var NativeSelect = forwardRef(
|
|
2255
|
+
({ className, wrapperClassName, children, ...props }, ref) => {
|
|
2256
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative", wrapperClassName), children: [
|
|
2257
|
+
/* @__PURE__ */ jsx(
|
|
2258
|
+
"select",
|
|
2259
|
+
{
|
|
2260
|
+
ref,
|
|
2261
|
+
className: cn(
|
|
2262
|
+
"flex h-9 w-full appearance-none rounded-md border border-input bg-card px-3 py-1 pr-8 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring text-foreground cursor-pointer",
|
|
2263
|
+
className
|
|
2264
|
+
),
|
|
2265
|
+
...props,
|
|
2266
|
+
children
|
|
2267
|
+
}
|
|
2268
|
+
),
|
|
2269
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" })
|
|
2270
|
+
] });
|
|
2271
|
+
}
|
|
2272
|
+
);
|
|
2273
|
+
NativeSelect.displayName = "NativeSelect";
|
|
2104
2274
|
var RULE_TYPES = [
|
|
2105
2275
|
{ value: "minLength", label: "Min Length", description: "Minimum character count" },
|
|
2106
2276
|
{ value: "maxLength", label: "Max Length", description: "Maximum character count" },
|