@fayz-ai/plugin-forms 0.15.13 → 0.15.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CustomFormsSettingsTab-EI4WKOYR.js +314 -0
- package/dist/CustomFormsSettingsTab-EI4WKOYR.js.map +1 -0
- package/dist/{FormBuilder-Q2Q42HAT.js → FormBuilder-7UXCXUOF.js} +7 -3
- package/dist/FormBuilder-7UXCXUOF.js.map +1 -0
- package/dist/PersonAnswerAlerts-MDBBY63K.js +98 -0
- package/dist/PersonAnswerAlerts-MDBBY63K.js.map +1 -0
- package/dist/PersonDocumentsWidget-RGN4UHS3.js +977 -0
- package/dist/PersonDocumentsWidget-RGN4UHS3.js.map +1 -0
- package/dist/chunk-5WW6FTNG.js +113 -0
- package/dist/chunk-5WW6FTNG.js.map +1 -0
- package/dist/chunk-66C3L4RE.js +17 -0
- package/dist/chunk-66C3L4RE.js.map +1 -0
- package/dist/chunk-BFXJLPKA.js +55 -0
- package/dist/chunk-BFXJLPKA.js.map +1 -0
- package/dist/chunk-RB7UYZLA.js +824 -0
- package/dist/chunk-RB7UYZLA.js.map +1 -0
- package/dist/chunk-X6CU44B4.js +223 -0
- package/dist/chunk-X6CU44B4.js.map +1 -0
- package/dist/chunk-YOFFKQD4.js +584 -0
- package/dist/chunk-YOFFKQD4.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -1507
- package/dist/index.js.map +1 -1
- package/dist/views/CustomFormsSettingsTab.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/FormBuilder-Q2Q42HAT.js.map +0 -1
- package/dist/chunk-JRR7A5HN.js +0 -1678
- package/dist/chunk-JRR7A5HN.js.map +0 -1
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { CustomFormsProvider } from './chunk-66C3L4RE.js';
|
|
2
|
+
import React2, { useState, useCallback, useMemo, useEffect } from 'react';
|
|
3
|
+
import { navigateApp, onAppPathChange, currentAppPath, useTranslation, getActiveTenantId, useDataVersion } from '@fayz-ai/core';
|
|
4
|
+
import { FORM_TEMPLATE_EVENT } from '@fayz-ai/forms/store';
|
|
5
|
+
import { Plus, WandSparkles, Pencil, Archive, FileText, Search } from 'lucide-react';
|
|
6
|
+
import { Badge, Switch, RowActions, Button, PageHeaderActions, Card, Input, DataTable } from '@fayz-ai/ui';
|
|
7
|
+
import { askAI, PermissionGate, PageActions } from '@fayz-ai/admin';
|
|
8
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
var CATEGORY_COLORS = {
|
|
11
|
+
anamnesis: "bg-info-soft text-info-soft-foreground",
|
|
12
|
+
evaluation: "bg-info-soft text-info-soft-foreground",
|
|
13
|
+
photos: "bg-muted text-muted-foreground",
|
|
14
|
+
evolution: "bg-success-soft text-success-soft-foreground",
|
|
15
|
+
report: "bg-magic-soft text-magic-soft-foreground",
|
|
16
|
+
contract: "bg-warning-soft text-warning-soft-foreground",
|
|
17
|
+
general: "bg-muted text-muted-foreground"
|
|
18
|
+
};
|
|
19
|
+
function TemplateListView({ store, config, onEdit, onNew }) {
|
|
20
|
+
const t = useTranslation();
|
|
21
|
+
const [search, setSearch] = useState("");
|
|
22
|
+
const templates = store((s) => s.templates);
|
|
23
|
+
const loading = store((s) => s.templatesLoading);
|
|
24
|
+
const usage = store((s) => s.templateUsage);
|
|
25
|
+
const orgId = getActiveTenantId();
|
|
26
|
+
const createActions = useMemo(() => {
|
|
27
|
+
const permission = { feature: "custom_forms", action: "create" };
|
|
28
|
+
return [
|
|
29
|
+
{
|
|
30
|
+
id: "new",
|
|
31
|
+
label: t("customForms.newTemplate"),
|
|
32
|
+
description: t("customForms.newByHandHint"),
|
|
33
|
+
icon: Plus,
|
|
34
|
+
intent: "primary",
|
|
35
|
+
creates: true,
|
|
36
|
+
onSelect: onNew,
|
|
37
|
+
permission
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "ai",
|
|
41
|
+
label: t("assistant.askAI"),
|
|
42
|
+
description: t("customForms.newWithAIHint"),
|
|
43
|
+
icon: WandSparkles,
|
|
44
|
+
ai: true,
|
|
45
|
+
intent: "secondary",
|
|
46
|
+
creates: true,
|
|
47
|
+
onSelect: () => askAI({
|
|
48
|
+
hint: t("customForms.askPlaceholder"),
|
|
49
|
+
intro: {
|
|
50
|
+
role: "setup",
|
|
51
|
+
persona: t("customForms.askPersona"),
|
|
52
|
+
pitch: t("customForms.askPitch"),
|
|
53
|
+
description: t("customForms.askDescription"),
|
|
54
|
+
suggestions: [0, 1, 2].map((i) => ({ label: t(`customForms.askSuggestion.${i}`) }))
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
permission
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
}, [t, onNew]);
|
|
61
|
+
const version = useDataVersion(`${FORM_TEMPLATE_EVENT}*`);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!orgId) return;
|
|
64
|
+
const timer = setTimeout(() => {
|
|
65
|
+
store.getState().fetchTemplates({ search: search || void 0 });
|
|
66
|
+
}, 50);
|
|
67
|
+
return () => clearTimeout(timer);
|
|
68
|
+
}, [orgId, search, version]);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (!orgId) return;
|
|
71
|
+
void store.getState().fetchTemplateUsage();
|
|
72
|
+
}, [orgId]);
|
|
73
|
+
const handleArchive = useCallback(async (template) => {
|
|
74
|
+
if (!window.confirm(t("customForms.archiveTemplateConfirm"))) return;
|
|
75
|
+
await store.getState().updateTemplate(template.id, { isActive: false });
|
|
76
|
+
}, [store, t]);
|
|
77
|
+
const visibleTemplates = templates.filter((tpl) => tpl.isActive !== false);
|
|
78
|
+
const categoryLabel = (cat) => t(`customForms.category.${cat}`);
|
|
79
|
+
const columns = useMemo(() => [
|
|
80
|
+
{
|
|
81
|
+
id: "name",
|
|
82
|
+
header: t("customForms.template"),
|
|
83
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
84
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: row.original.name }),
|
|
85
|
+
row.original.description && /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-muted-foreground", children: row.original.description })
|
|
86
|
+
] })
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "category",
|
|
90
|
+
header: t("customForms.categoryColumn"),
|
|
91
|
+
cell: ({ row }) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: `text-[10px] ${CATEGORY_COLORS[row.original.category]}`, children: categoryLabel(row.original.category) })
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "fields",
|
|
95
|
+
header: t("customForms.builder.fields"),
|
|
96
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs("span", { className: "tabular-nums text-muted-foreground", children: [
|
|
97
|
+
row.original.schema.fields.length,
|
|
98
|
+
row.original.version > 1 && /* @__PURE__ */ jsxs("span", { className: "ml-2", children: [
|
|
99
|
+
"v",
|
|
100
|
+
row.original.version
|
|
101
|
+
] })
|
|
102
|
+
] })
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "required",
|
|
106
|
+
header: "Exigido",
|
|
107
|
+
// A PORTA da migration 001. Sem ela as duas colunas novas ficam no banco
|
|
108
|
+
// e o aviso de formulário pendente nunca acende para ninguém — código
|
|
109
|
+
// pronto sem consumidor é o mesmo que código ausente.
|
|
110
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
Switch,
|
|
113
|
+
{
|
|
114
|
+
size: "sm",
|
|
115
|
+
checked: row.original.requiredOnAttendance,
|
|
116
|
+
onCheckedChange: (on) => {
|
|
117
|
+
void store.getState().updateTemplate(row.original.id, {
|
|
118
|
+
requiredOnAttendance: on,
|
|
119
|
+
// Seis meses é o que o V1 usa na anamnese, e é o padrão que faz
|
|
120
|
+
// a validade existir sem pedir mais uma decisão na hora de
|
|
121
|
+
// ligar. Zero validade é o mesmo que "vale para sempre", que
|
|
122
|
+
// deixa uma anamnese de 2019 contando como preenchida.
|
|
123
|
+
validityDays: on ? row.original.validityDays ?? 180 : null
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
"aria-label": `Exigir ${row.original.name} de todo cliente`
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
row.original.requiredOnAttendance && /* @__PURE__ */ jsxs("span", { className: "text-[11px] text-muted-foreground", children: [
|
|
130
|
+
"vale ",
|
|
131
|
+
row.original.validityDays ?? "\u221E",
|
|
132
|
+
" dias"
|
|
133
|
+
] })
|
|
134
|
+
] })
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "alert",
|
|
138
|
+
header: "Alerta",
|
|
139
|
+
// A SEGUNDA PERGUNTA DO V1, e ela é outra pergunta mesmo: exigir põe a
|
|
140
|
+
// bola no checklist do atendimento — trabalho a fazer com a pessoa na
|
|
141
|
+
// cadeira; alertar leva a falta para a FRENTE, na faixa âmbar do
|
|
142
|
+
// agendamento e da ficha. Uma casa exige anamnese e não quer a faixa
|
|
143
|
+
// toda vez que marca horário, e o V1 respeita isso desligado.
|
|
144
|
+
cell: ({ row }) => /* @__PURE__ */ jsx(
|
|
145
|
+
Switch,
|
|
146
|
+
{
|
|
147
|
+
size: "sm",
|
|
148
|
+
disabled: !row.original.requiredOnAttendance,
|
|
149
|
+
checked: row.original.requiredOnAttendance && row.original.alertWhenMissing,
|
|
150
|
+
onCheckedChange: (on) => {
|
|
151
|
+
void store.getState().updateTemplate(row.original.id, { alertWhenMissing: on });
|
|
152
|
+
},
|
|
153
|
+
"aria-label": `Alertar quando ${row.original.name} estiver faltando`
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: "usage",
|
|
159
|
+
header: t("customForms.usageColumn"),
|
|
160
|
+
// "0 preenchimentos" é informação, não ausência dela: é o que separa um
|
|
161
|
+
// formulário que o salão usa todo dia de um que sobrou de uma importação.
|
|
162
|
+
cell: ({ row }) => {
|
|
163
|
+
const u = usage[row.original.id];
|
|
164
|
+
return /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
165
|
+
t("customForms.usageCount", { count: String(u?.documentCount ?? 0) }),
|
|
166
|
+
u?.lastDocumentAt && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
167
|
+
/* @__PURE__ */ jsx("span", { className: "px-1", children: "\xB7" }),
|
|
168
|
+
t("customForms.usageLast", { date: new Date(u.lastDocumentAt).toLocaleDateString() })
|
|
169
|
+
] })
|
|
170
|
+
] });
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: "actions",
|
|
175
|
+
header: "",
|
|
176
|
+
// RowActions is the one renderer for what can be done to a single row —
|
|
177
|
+
// it owns the sizing, the accessible name and the rule that keeps a
|
|
178
|
+
// destructive action off the row itself.
|
|
179
|
+
cell: ({ row }) => /* @__PURE__ */ jsx(
|
|
180
|
+
RowActions,
|
|
181
|
+
{
|
|
182
|
+
actions: [
|
|
183
|
+
{
|
|
184
|
+
id: "edit",
|
|
185
|
+
label: t("common.edit"),
|
|
186
|
+
icon: Pencil,
|
|
187
|
+
onSelect: () => onEdit(row.original)
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: "archive",
|
|
191
|
+
label: t("customForms.archive"),
|
|
192
|
+
icon: Archive,
|
|
193
|
+
intent: "danger",
|
|
194
|
+
onSelect: () => {
|
|
195
|
+
void handleArchive(row.original);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
], [t, usage, onEdit, handleArchive]);
|
|
203
|
+
const emptyState = /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-6 text-center", children: [
|
|
204
|
+
/* @__PURE__ */ jsx("div", { className: "mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx(FileText, { className: "h-5 w-5 text-muted-foreground" }) }),
|
|
205
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-foreground", children: t("customForms.noTemplates") }),
|
|
206
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: t("customForms.noTemplatesDescription") }),
|
|
207
|
+
/* @__PURE__ */ jsx(PermissionGate, { feature: "custom_forms", action: "create", children: /* @__PURE__ */ jsxs(Button, { onClick: onNew, size: "sm", className: "mt-4", children: [
|
|
208
|
+
/* @__PURE__ */ jsx(Plus, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
209
|
+
t("customForms.newTemplate")
|
|
210
|
+
] }) })
|
|
211
|
+
] });
|
|
212
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
213
|
+
/* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsx(PageActions, { actions: createActions }) }),
|
|
214
|
+
/* @__PURE__ */ jsxs(Card, { className: "overflow-hidden", children: [
|
|
215
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2 border-b border-border px-3 py-2", children: /* @__PURE__ */ jsxs("div", { className: "relative min-w-[10rem] flex-1", children: [
|
|
216
|
+
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
217
|
+
/* @__PURE__ */ jsx(
|
|
218
|
+
Input,
|
|
219
|
+
{
|
|
220
|
+
value: search,
|
|
221
|
+
onChange: (e) => setSearch(e.target.value),
|
|
222
|
+
placeholder: t("common.search"),
|
|
223
|
+
className: "h-auto rounded-none border-0 bg-transparent py-1.5 pl-8 pr-3 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0"
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
] }) }),
|
|
227
|
+
/* @__PURE__ */ jsx(
|
|
228
|
+
DataTable,
|
|
229
|
+
{
|
|
230
|
+
variant: "bare",
|
|
231
|
+
columns,
|
|
232
|
+
data: loading ? [] : visibleTemplates,
|
|
233
|
+
loading,
|
|
234
|
+
skeletonRows: 3,
|
|
235
|
+
emptyMessage: emptyState,
|
|
236
|
+
onRowClick: (row) => onEdit(row)
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
] })
|
|
240
|
+
] });
|
|
241
|
+
}
|
|
242
|
+
var ROUTE_BASE = "/settings/custom_forms";
|
|
243
|
+
function readBuilderIdFromHash() {
|
|
244
|
+
const hash = currentAppPath();
|
|
245
|
+
const m = hash.match(/\/settings\/custom_forms\/templates\/([^/]+)/);
|
|
246
|
+
if (!m) return null;
|
|
247
|
+
return m[1] === "new" ? "__new__" : m[1];
|
|
248
|
+
}
|
|
249
|
+
function CustomFormsSettingsTab({ config, provider, store }) {
|
|
250
|
+
const [builderTemplateId, setBuilderTemplateId] = useState(readBuilderIdFromHash);
|
|
251
|
+
const handleNew = useCallback(() => {
|
|
252
|
+
navigateApp(`#${ROUTE_BASE}/templates/new`);
|
|
253
|
+
}, []);
|
|
254
|
+
const handleEdit = useCallback((template) => {
|
|
255
|
+
navigateApp(`#${ROUTE_BASE}/templates/${template.id}`);
|
|
256
|
+
}, []);
|
|
257
|
+
const handleBackFromBuilder = useCallback(() => {
|
|
258
|
+
navigateApp(`#${ROUTE_BASE}/forms`);
|
|
259
|
+
store.getState().fetchTemplates();
|
|
260
|
+
}, [store]);
|
|
261
|
+
React2.useEffect(() => {
|
|
262
|
+
const sync = () => setBuilderTemplateId(readBuilderIdFromHash());
|
|
263
|
+
return onAppPathChange(sync);
|
|
264
|
+
}, []);
|
|
265
|
+
return builderTemplateId ? /* @__PURE__ */ jsx(
|
|
266
|
+
BuilderWrapper,
|
|
267
|
+
{
|
|
268
|
+
templateId: builderTemplateId === "__new__" ? void 0 : builderTemplateId,
|
|
269
|
+
store,
|
|
270
|
+
provider,
|
|
271
|
+
config,
|
|
272
|
+
onBack: handleBackFromBuilder
|
|
273
|
+
}
|
|
274
|
+
) : /* @__PURE__ */ jsx(
|
|
275
|
+
TemplateListView,
|
|
276
|
+
{
|
|
277
|
+
store,
|
|
278
|
+
config,
|
|
279
|
+
onEdit: handleEdit,
|
|
280
|
+
onNew: handleNew
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
function BuilderWrapper({
|
|
285
|
+
templateId,
|
|
286
|
+
store,
|
|
287
|
+
provider,
|
|
288
|
+
config,
|
|
289
|
+
onBack
|
|
290
|
+
}) {
|
|
291
|
+
const FormBuilderLazy = React2.lazy(
|
|
292
|
+
() => import('./FormBuilder-7UXCXUOF.js').then((m) => ({ default: m.FormBuilder }))
|
|
293
|
+
);
|
|
294
|
+
return /* @__PURE__ */ jsx(CustomFormsProvider, { value: { config, provider, store }, children: /* @__PURE__ */ jsx(
|
|
295
|
+
React2.Suspense,
|
|
296
|
+
{
|
|
297
|
+
fallback: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx("div", { className: "h-6 w-6 border-2 border-primary border-t-transparent animate-spin rounded-full" }) }),
|
|
298
|
+
children: /* @__PURE__ */ jsx(
|
|
299
|
+
FormBuilderLazy,
|
|
300
|
+
{
|
|
301
|
+
templateId,
|
|
302
|
+
store,
|
|
303
|
+
provider,
|
|
304
|
+
config,
|
|
305
|
+
onBack
|
|
306
|
+
}
|
|
307
|
+
)
|
|
308
|
+
}
|
|
309
|
+
) });
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export { CustomFormsSettingsTab };
|
|
313
|
+
//# sourceMappingURL=CustomFormsSettingsTab-EI4WKOYR.js.map
|
|
314
|
+
//# sourceMappingURL=CustomFormsSettingsTab-EI4WKOYR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/views/TemplateListView.tsx","../src/views/CustomFormsSettingsTab.tsx"],"names":["useState","useCallback","React","jsx"],"mappings":"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","file":"CustomFormsSettingsTab-EI4WKOYR.js","sourcesContent":["import React, { useEffect, useState, useCallback, useMemo } from 'react'\nimport { getActiveTenantId, useDataVersion } from '@fayz-ai/core'\nimport { FORM_TEMPLATE_EVENT } from '@fayz-ai/forms/store'\nimport { Plus, Pencil, Archive, FileText, Search, WandSparkles } from 'lucide-react'\nimport { Button, Card, Input, Badge, DataTable, PageHeaderActions, RowActions, type DataTableProps, Switch } from '@fayz-ai/ui'\nimport { PageActions, askAI, type PageAction } from '@fayz-ai/admin'\nimport { PermissionGate } from '@fayz-ai/admin'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { FormsStore } from '@fayz-ai/forms/store'\nimport type { CustomFormsConfig } from '../config'\nimport type { FormTemplate, TemplateCategory } from '@fayz-ai/forms/domain/template'\n\ninterface TemplateListViewProps {\n store: FormsStore\n config: CustomFormsConfig\n onEdit: (template: FormTemplate) => void\n onNew: () => void\n}\n\nconst CATEGORY_COLORS: Record<TemplateCategory, string> = {\n anamnesis: 'bg-info-soft text-info-soft-foreground',\n evaluation: 'bg-info-soft text-info-soft-foreground',\n photos: 'bg-muted text-muted-foreground',\n evolution: 'bg-success-soft text-success-soft-foreground',\n report: 'bg-magic-soft text-magic-soft-foreground',\n contract: 'bg-warning-soft text-warning-soft-foreground',\n general: 'bg-muted text-muted-foreground',\n}\n\nexport function TemplateListView({ store, config, onEdit, onNew }: TemplateListViewProps) {\n const t = useTranslation()\n const [search, setSearch] = useState('')\n\n // Subscribe to zustand store reactively\n const templates = store((s) => s.templates)\n const loading = store((s) => s.templatesLoading)\n const usage = store((s) => s.templateUsage)\n\n const orgId = getActiveTenantId()\n\n // Declared, not drawn: the shell renders this as the button in the header bar\n // on a desktop and as the round \"+\" in the thumb's corner on a phone, and it\n // resolves the create permission that used to be a gate wrapped around here.\n const createActions = useMemo<PageAction[]>(() => {\n const permission = { feature: 'custom_forms', action: 'create' as const }\n return [\n {\n id: 'new',\n label: t('customForms.newTemplate'),\n description: t('customForms.newByHandHint'),\n icon: Plus,\n intent: 'primary' as const,\n creates: true,\n onSelect: onNew,\n permission,\n },\n {\n id: 'ai',\n label: t('assistant.askAI'),\n description: t('customForms.newWithAIHint'),\n icon: WandSparkles,\n ai: true,\n intent: 'secondary' as const,\n creates: true,\n onSelect: () => askAI({\n hint: t('customForms.askPlaceholder'),\n intro: {\n role: 'setup',\n persona: t('customForms.askPersona'),\n pitch: t('customForms.askPitch'),\n description: t('customForms.askDescription'),\n suggestions: [0, 1, 2].map((i) => ({ label: t(`customForms.askSuggestion.${i}`) })),\n },\n }),\n permission,\n },\n ]\n }, [t, onNew])\n\n // Um modelo criado em outro lugar — pelo assistente, por outra aba, pelo\n // construtor — não passa por este store, e a lista ficava mostrando o mundo\n // de antes até alguém recarregar a página.\n const version = useDataVersion(`${FORM_TEMPLATE_EVENT}*`)\n\n // Fetch when org is ready or search changes — debounce to avoid Strict Mode double-fire\n useEffect(() => {\n if (!orgId) return\n const timer = setTimeout(() => {\n store.getState().fetchTemplates({ search: search || undefined })\n }, 50)\n return () => clearTimeout(timer)\n }, [orgId, search, version])\n\n // O uso não depende da busca — é o mesmo mapa para todos os modelos do tenant,\n // e reagregá-lo a cada tecla digitada seria uma consulta por letra.\n useEffect(() => {\n if (!orgId) return\n void store.getState().fetchTemplateUsage()\n }, [orgId])\n\n // Archive, not delete: deactivate the template so it drops out of the list\n // and the \"add document\" picker, without destroying it or its documents.\n const handleArchive = useCallback(async (template: FormTemplate) => {\n if (!window.confirm(t('customForms.archiveTemplateConfirm'))) return\n await store.getState().updateTemplate(template.id, { isActive: false })\n }, [store, t])\n\n // Archived (isActive=false) templates stay in the store but leave the view.\n const visibleTemplates = templates.filter((tpl) => tpl.isActive !== false)\n\n const categoryLabel = (cat: TemplateCategory) => t(`customForms.category.${cat}`)\n\n const columns = useMemo<DataTableProps<FormTemplate, unknown>['columns']>(() => [\n {\n id: 'name',\n header: t('customForms.template'),\n cell: ({ row }) => (\n <div className=\"min-w-0\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.description && (\n <p className=\"truncate text-xs text-muted-foreground\">{row.original.description}</p>\n )}\n </div>\n ),\n },\n {\n id: 'category',\n header: t('customForms.categoryColumn'),\n cell: ({ row }) => (\n <Badge variant=\"secondary\" className={`text-[10px] ${CATEGORY_COLORS[row.original.category]}`}>\n {categoryLabel(row.original.category)}\n </Badge>\n ),\n },\n {\n id: 'fields',\n header: t('customForms.builder.fields'),\n cell: ({ row }) => (\n <span className=\"tabular-nums text-muted-foreground\">\n {row.original.schema.fields.length}\n {row.original.version > 1 && <span className=\"ml-2\">v{row.original.version}</span>}\n </span>\n ),\n },\n {\n id: 'required',\n header: 'Exigido',\n // A PORTA da migration 001. Sem ela as duas colunas novas ficam no banco\n // e o aviso de formulário pendente nunca acende para ninguém — código\n // pronto sem consumidor é o mesmo que código ausente.\n cell: ({ row }) => (\n <div className=\"flex items-center gap-2\">\n <Switch\n size=\"sm\"\n checked={row.original.requiredOnAttendance}\n onCheckedChange={(on) => {\n void store.getState().updateTemplate(row.original.id, {\n requiredOnAttendance: on,\n // Seis meses é o que o V1 usa na anamnese, e é o padrão que faz\n // a validade existir sem pedir mais uma decisão na hora de\n // ligar. Zero validade é o mesmo que \"vale para sempre\", que\n // deixa uma anamnese de 2019 contando como preenchida.\n validityDays: on ? (row.original.validityDays ?? 180) : null,\n })\n }}\n aria-label={`Exigir ${row.original.name} de todo cliente`}\n />\n {row.original.requiredOnAttendance && (\n <span className=\"text-[11px] text-muted-foreground\">\n vale {row.original.validityDays ?? '∞'} dias\n </span>\n )}\n </div>\n ),\n },\n {\n id: 'alert',\n header: 'Alerta',\n // A SEGUNDA PERGUNTA DO V1, e ela é outra pergunta mesmo: exigir põe a\n // bola no checklist do atendimento — trabalho a fazer com a pessoa na\n // cadeira; alertar leva a falta para a FRENTE, na faixa âmbar do\n // agendamento e da ficha. Uma casa exige anamnese e não quer a faixa\n // toda vez que marca horário, e o V1 respeita isso desligado.\n cell: ({ row }) => (\n <Switch\n size=\"sm\"\n disabled={!row.original.requiredOnAttendance}\n checked={row.original.requiredOnAttendance && row.original.alertWhenMissing}\n onCheckedChange={(on) => {\n void store.getState().updateTemplate(row.original.id, { alertWhenMissing: on })\n }}\n aria-label={`Alertar quando ${row.original.name} estiver faltando`}\n />\n ),\n },\n {\n id: 'usage',\n header: t('customForms.usageColumn'),\n // \"0 preenchimentos\" é informação, não ausência dela: é o que separa um\n // formulário que o salão usa todo dia de um que sobrou de uma importação.\n cell: ({ row }) => {\n const u = usage[row.original.id]\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t('customForms.usageCount', { count: String(u?.documentCount ?? 0) })}\n {u?.lastDocumentAt && (\n <>\n <span className=\"px-1\">·</span>\n {t('customForms.usageLast', { date: new Date(u.lastDocumentAt).toLocaleDateString() })}\n </>\n )}\n </span>\n )\n },\n },\n {\n id: 'actions',\n header: '',\n // RowActions is the one renderer for what can be done to a single row —\n // it owns the sizing, the accessible name and the rule that keeps a\n // destructive action off the row itself.\n cell: ({ row }) => (\n <RowActions\n actions={[\n {\n id: 'edit',\n label: t('common.edit'),\n icon: Pencil,\n onSelect: () => onEdit(row.original),\n },\n {\n id: 'archive',\n label: t('customForms.archive'),\n icon: Archive,\n intent: 'danger' as const,\n onSelect: () => { void handleArchive(row.original) },\n },\n ]}\n />\n ),\n },\n ], [t, usage, onEdit, handleArchive])\n\n const emptyState = (\n <div className=\"flex flex-col items-center justify-center py-6 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <FileText className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium text-foreground\">{t('customForms.noTemplates')}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">\n {t('customForms.noTemplatesDescription')}\n </p>\n <PermissionGate feature=\"custom_forms\" action=\"create\">\n <Button onClick={onNew} size=\"sm\" className=\"mt-4\">\n <Plus className=\"mr-1.5 h-3.5 w-3.5\" />\n {t('customForms.newTemplate')}\n </Button>\n </PermissionGate>\n </div>\n )\n\n return (\n <div className=\"space-y-4\">\n {/* O \"Novo modelo\" vai para a barra da shell, onde mora a ação principal\n de toda lista do produto — desenhá-lo aqui gastava uma fileira do corpo\n para pôr o botão num canto diferente do de todas as outras telas. */}\n <PageHeaderActions>\n {/* Duas portas para o mesmo modelo, e a de IA vem junto: montar uma\n anamnese campo a campo é meia hora de cliques, e descrevê-la é uma\n frase. A ferramenta atrás dela é `createOrUpdateForm`, que é\n server-plane e já existia — aqui só se abre a porta. */}\n <PageActions actions={createActions} />\n </PageHeaderActions>\n\n {/* Busca e tabela são UMA superfície, como em qualquer lista de CRUD: elas\n agem sobre as mesmas linhas. */}\n <Card className=\"overflow-hidden\">\n <div className=\"flex flex-wrap items-center gap-2 border-b border-border px-3 py-2\">\n <div className=\"relative min-w-[10rem] flex-1\">\n <Search className=\"pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={t('common.search')}\n className=\"h-auto rounded-none border-0 bg-transparent py-1.5 pl-8 pr-3 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n </div>\n </div>\n <DataTable\n variant=\"bare\"\n columns={columns}\n data={loading ? [] : visibleTemplates}\n loading={loading}\n skeletonRows={3}\n emptyMessage={emptyState}\n onRowClick={(row) => onEdit(row)}\n />\n </Card>\n </div>\n )\n}\n","import React, { useState, useCallback } from 'react'\nimport { TemplateListView } from './TemplateListView'\nimport { CustomFormsProvider } from '../context'\nimport type { CustomFormsConfig } from '../config'\nimport type { FormsDataProvider } from '@fayz-ai/forms/data/provider'\nimport type { FormsStore } from '@fayz-ai/forms/store'\nimport type { FormTemplate } from '@fayz-ai/forms/domain/template'\nimport { navigateApp, currentAppPath, onAppPathChange } from '@fayz-ai/core'\n\ninterface CustomFormsSettingsTabProps {\n config: CustomFormsConfig\n provider: FormsDataProvider\n store: FormsStore\n}\n\nconst ROUTE_BASE = '/settings/custom_forms'\n\n/** Read the currently-open template id from the URL hash (the source of truth,\n * so deep links and browser back/forward work like any CRUD detail page). */\nfunction readBuilderIdFromHash(): string | null {\n const hash = currentAppPath()\n const m = hash.match(/\\/settings\\/custom_forms\\/templates\\/([^/]+)/)\n if (!m) return null\n return m[1] === 'new' ? '__new__' : m[1]\n}\n\nexport function CustomFormsSettingsTab({ config, provider, store }: CustomFormsSettingsTabProps) {\n // URL is the source of truth — opening/closing a template updates the hash,\n // so the record id shows in the URL just like opening a CRUD record.\n const [builderTemplateId, setBuilderTemplateId] = useState<string | null>(readBuilderIdFromHash)\n\n const handleNew = useCallback(() => {\n navigateApp(`#${ROUTE_BASE}/templates/new`)\n }, [])\n\n const handleEdit = useCallback((template: FormTemplate) => {\n navigateApp(`#${ROUTE_BASE}/templates/${template.id}`)\n }, [])\n\n const handleBackFromBuilder = useCallback(() => {\n // Return to the list route and re-fetch templates to reflect any saves.\n navigateApp(`#${ROUTE_BASE}/forms`)\n store.getState().fetchTemplates()\n }, [store])\n\n // Keep local state in sync with the URL (deep links, back/forward, and our\n // own hash writes above all flow through here).\n React.useEffect(() => {\n const sync = () => setBuilderTemplateId(readBuilderIdFromHash())\n return onAppPathChange(sync)\n }, [])\n\n return builderTemplateId ? (\n <BuilderWrapper\n templateId={builderTemplateId === '__new__' ? undefined : builderTemplateId}\n store={store}\n provider={provider}\n config={config}\n onBack={handleBackFromBuilder}\n />\n ) : (\n <TemplateListView\n store={store}\n config={config}\n onEdit={handleEdit}\n onNew={handleNew}\n />\n )\n}\n\n/** Lazy-loads the FormBuilder to avoid pulling @dnd-kit into the initial bundle */\nfunction BuilderWrapper({\n templateId,\n store,\n provider,\n config,\n onBack,\n}: {\n templateId?: string\n store: FormsStore\n provider: FormsDataProvider\n config: CustomFormsConfig\n onBack: () => void\n}) {\n const FormBuilderLazy = React.lazy(() =>\n import('../components/FormBuilder').then((m) => ({ default: m.FormBuilder })),\n )\n\n // Field previews and property panels upload and sign media through the context.\n return (\n <CustomFormsProvider value={{ config, provider, store }}>\n <React.Suspense\n fallback={\n <div className=\"flex items-center justify-center py-12\">\n <div className=\"h-6 w-6 border-2 border-primary border-t-transparent animate-spin rounded-full\" />\n </div>\n }\n >\n <FormBuilderLazy\n templateId={templateId}\n store={store}\n provider={provider}\n config={config}\n onBack={onBack}\n />\n </React.Suspense>\n </CustomFormsProvider>\n )\n}\n"]}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import { FORM_BUILDER_INSTRUCTIONS
|
|
1
|
+
import { FORM_BUILDER_INSTRUCTIONS } from './chunk-BFXJLPKA.js';
|
|
2
|
+
import { buildPrintHtml, PERSON_FIELD_OPTIONS } from './chunk-X6CU44B4.js';
|
|
3
|
+
import { FormRenderer } from './chunk-RB7UYZLA.js';
|
|
4
|
+
import { useMediaUpload, MediaImage } from './chunk-YOFFKQD4.js';
|
|
5
|
+
import './chunk-66C3L4RE.js';
|
|
2
6
|
import React, { useState, useEffect, useCallback } from 'react';
|
|
3
7
|
import { useSensors, useSensor, PointerSensor, DndContext, pointerWithin, DragOverlay, useDroppable, useDraggable } from '@dnd-kit/core';
|
|
4
8
|
import { arrayMove, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
@@ -871,5 +875,5 @@ function FormBuilder({ templateId, store, provider, config, onBack }) {
|
|
|
871
875
|
}
|
|
872
876
|
|
|
873
877
|
export { FormBuilder };
|
|
874
|
-
//# sourceMappingURL=FormBuilder-
|
|
875
|
-
//# sourceMappingURL=FormBuilder-
|
|
878
|
+
//# sourceMappingURL=FormBuilder-7UXCXUOF.js.map
|
|
879
|
+
//# sourceMappingURL=FormBuilder-7UXCXUOF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/FieldPalette.tsx","../src/components/BuilderField.tsx","../src/components/BuilderCanvas.tsx","../src/components/fields/FieldTypeSettings.tsx","../src/components/FieldConfigDialog.tsx","../src/components/FormBuilder.tsx"],"names":["useTranslation","jsxs","jsx","Button","Input","Checkbox","Trash2","useState","useEffect","React","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Fragment"],"mappings":"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","file":"FormBuilder-7UXCXUOF.js","sourcesContent":["import React from 'react'\nimport { useDraggable } from '@dnd-kit/core'\nimport {\n Heading, Type, AlignLeft, FileEdit, CalendarDays,\n ChevronDown, CircleDot, Tags, CheckSquare,\n Image, GalleryHorizontalEnd, Receipt, ToggleLeft, MessageSquareText, ScanFace, Sparkles, PenLine,\n} from 'lucide-react'\nimport { useTranslation } from '@fayz-ai/core'\nimport { Button } from '@fayz-ai/ui'\nimport type { FormFieldType } from '@fayz-ai/forms/domain/template'\n\nexport interface FieldTypeItem {\n type: FormFieldType\n icon: React.ElementType\n}\n\nexport const DEFAULT_COL_SPAN: Record<string, number> = {\n title: 12,\n memo: 12,\n richtext: 12,\n gallery: 12,\n budget: 12,\n image: 6,\n text: 6,\n date: 4,\n select: 6,\n radio: 6,\n tags: 8,\n checkbox: 4,\n yes_no: 6,\n yes_no_text: 6,\n stencil_photo: 4,\n recommendation: 12,\n signature: 12,\n}\n\nexport const FIELD_TYPES: FieldTypeItem[] = [\n { type: 'title', icon: Heading },\n { type: 'text', icon: Type },\n { type: 'memo', icon: AlignLeft },\n { type: 'richtext', icon: FileEdit },\n { type: 'date', icon: CalendarDays },\n { type: 'select', icon: ChevronDown },\n { type: 'radio', icon: CircleDot },\n { type: 'tags', icon: Tags },\n { type: 'checkbox', icon: CheckSquare },\n { type: 'yes_no', icon: ToggleLeft },\n { type: 'yes_no_text', icon: MessageSquareText },\n { type: 'image', icon: Image },\n { type: 'stencil_photo', icon: ScanFace },\n { type: 'gallery', icon: GalleryHorizontalEnd },\n { type: 'recommendation', icon: Sparkles },\n { type: 'budget', icon: Receipt },\n { type: 'signature', icon: PenLine },\n]\n\nfunction DraggableFieldType({ item }: { item: FieldTypeItem }) {\n const t = useTranslation()\n const { attributes, listeners, setNodeRef, isDragging } = useDraggable({\n id: `palette-${item.type}`,\n data: { source: 'palette', fieldType: item.type },\n })\n\n const Icon = item.icon\n\n return (\n <Button variant=\"bare\" size=\"bare\"\n ref={setNodeRef}\n {...listeners}\n {...attributes}\n className={`justify-start flex items-center gap-2 w-full px-3 py-2 rounded-lg border bg-card text-sm font-medium transition-all hover:shadow-sm hover:border-primary/30 cursor-grab active:cursor-grabbing ${isDragging ? 'opacity-30' : ''}`}\n >\n <Icon className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n <span className=\"truncate\">{t(`customForms.fieldType.${item.type}`)}</span>\n </Button>\n )\n}\n\nexport function FieldPalette() {\n const t = useTranslation()\n\n return (\n <div className=\"w-44 shrink-0 space-y-1.5\">\n <p className=\"text-[10px] font-semibold uppercase tracking-wider text-muted-foreground px-1 mb-2\">\n {t('customForms.builder.fields')}\n </p>\n {FIELD_TYPES.map((item) => (\n <DraggableFieldType key={item.type} item={item} />\n ))}\n </div>\n )\n}\n","import React from 'react'\nimport { useSortable } from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\nimport { GripVertical, X } from 'lucide-react'\nimport { useTranslation } from '@fayz-ai/core'\nimport { Button } from '@fayz-ai/ui'\nimport type { FormFieldDef } from '@fayz-ai/forms/domain/template'\nimport { FIELD_TYPES } from './FieldPalette'\n\ninterface BuilderFieldProps {\n field: FormFieldDef\n onSelect: (field: FormFieldDef) => void\n onRemove: (fieldId: string) => void\n isSelected: boolean\n}\n\nexport function BuilderField({ field, onSelect, onRemove, isSelected }: BuilderFieldProps) {\n const t = useTranslation()\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: field.id })\n\n const style: React.CSSProperties = {\n transform: CSS.Transform.toString(transform),\n transition,\n gridColumn: `span ${field.colSpan}`,\n opacity: isDragging ? 0.5 : 1,\n }\n\n const fieldTypeDef = FIELD_TYPES.find((ft) => ft.type === field.type)\n const Icon = fieldTypeDef?.icon\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={`group relative flex items-start gap-2 rounded-lg border-2 bg-card p-3 transition-colors cursor-pointer ${\n isSelected\n ? 'border-primary ring-1 ring-primary/20'\n : 'border-border hover:border-primary/30'\n }`}\n onClick={() => onSelect(field)}\n >\n {/* Drag handle */}\n <Button variant=\"bare\" size=\"bare\"\n {...attributes}\n {...listeners}\n className=\"mt-0.5 cursor-grab active:cursor-grabbing text-muted-foreground/50 hover:text-muted-foreground\"\n onClick={(e) => e.stopPropagation()}\n >\n <GripVertical className=\"h-4 w-4\" />\n </Button>\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n {Icon && <Icon className=\"h-3.5 w-3.5 text-muted-foreground shrink-0\" />}\n <span className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n {t(`customForms.fieldType.${field.type}`)}\n </span>\n </div>\n <p className=\"text-sm font-medium mt-0.5 truncate\">{field.label}</p>\n {field.required && (\n <span className=\"text-[10px] text-destructive\">*</span>\n )}\n </div>\n\n {/* Remove button */}\n <Button variant=\"bare\" size=\"bare\"\n onClick={(e) => { e.stopPropagation(); onRemove(field.id) }}\n className=\"absolute top-1.5 right-1.5 p-1 rounded-md opacity-0 group-hover:opacity-100 hover:bg-destructive/10 transition-opacity\"\n >\n <X className=\"h-3 w-3 text-destructive\" />\n </Button>\n </div>\n )\n}\n","import React from 'react'\nimport { useDroppable } from '@dnd-kit/core'\nimport { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { FormFieldDef, FormFieldType } from '@fayz-ai/forms/domain/template'\nimport { BuilderField } from './BuilderField'\nimport { FIELD_TYPES, DEFAULT_COL_SPAN } from './FieldPalette'\n\ninterface BuilderCanvasProps {\n fields: FormFieldDef[]\n selectedFieldId: string | null\n onSelectField: (field: FormFieldDef) => void\n onRemoveField: (fieldId: string) => void\n draggingFieldType: FormFieldType | null\n}\n\nfunction DropPreview({ fieldType }: { fieldType: FormFieldType }) {\n const t = useTranslation()\n const def = FIELD_TYPES.find((ft) => ft.type === fieldType)\n if (!def) return null\n const Icon = def.icon\n\n return (\n <div\n className=\"flex items-center gap-2 rounded-lg border-2 border-dashed border-primary/40 bg-primary/5 p-3\"\n style={{ gridColumn: `span ${DEFAULT_COL_SPAN[fieldType] ?? 12}` }}\n >\n <Icon className=\"h-4 w-4 text-primary/50\" />\n <span className=\"text-sm text-primary/50 font-medium\">\n {t(`customForms.fieldType.${fieldType}`)}\n </span>\n </div>\n )\n}\n\nexport function BuilderCanvas({\n fields,\n selectedFieldId,\n onSelectField,\n onRemoveField,\n draggingFieldType,\n}: BuilderCanvasProps) {\n const t = useTranslation()\n const { setNodeRef, isOver } = useDroppable({ id: 'builder-canvas' })\n\n const sortedFields = [...fields].sort((a, b) => a.row - b.row || a.col - b.col)\n const showPreview = isOver && draggingFieldType !== null\n\n return (\n <div\n ref={setNodeRef}\n className={`flex-1 min-h-[400px] rounded-xl border-2 border-dashed p-4 transition-colors ${\n isOver ? 'border-primary/50 bg-primary/5' : 'border-border bg-muted/20'\n }`}\n style={{\n backgroundImage:\n 'repeating-linear-gradient(90deg, transparent, transparent calc(8.333% - 1px), hsl(var(--border) / 0.3) calc(8.333% - 1px), hsl(var(--border) / 0.3) 8.333%)',\n backgroundSize: '100% 100%',\n }}\n >\n {fields.length === 0 && !showPreview && (\n <div className=\"flex items-center justify-center h-full text-muted-foreground text-sm\">\n {t('customForms.builder.emptyCanvas')}\n </div>\n )}\n\n <SortableContext items={sortedFields.map((f) => f.id)} strategy={verticalListSortingStrategy}>\n <div\n className=\"grid gap-3\"\n style={{ gridTemplateColumns: 'repeat(12, 1fr)' }}\n >\n {sortedFields.map((field) => (\n <BuilderField\n key={field.id}\n field={field}\n isSelected={field.id === selectedFieldId}\n onSelect={onSelectField}\n onRemove={onRemoveField}\n />\n ))}\n\n {showPreview && <DropPreview fieldType={draggingFieldType!} />}\n </div>\n </SortableContext>\n </div>\n )\n}\n","import React from 'react'\nimport { ImageUp, Trash2 } from 'lucide-react'\nimport { Button, Input, SegmentedControl, Checkbox } from '@fayz-ai/ui'\nimport type { AnswerAlertConfig, FormFieldDef, GalleryConfig, StencilConfig } from '@fayz-ai/forms/domain/template'\nimport { useMediaUpload } from './media'\nimport { MediaImage } from './media'\nimport { describeError } from '@fayz-ai/core'\n\ntype Config = Record<string, unknown>\n\nfunction Row({ label, children, hint }: { label: string; children: React.ReactNode; hint?: string }) {\n return (\n <div className=\"space-y-1.5\">\n <label className=\"block text-xs font-medium\">{label}</label>\n {children}\n {hint && <p className=\"text-[10px] text-muted-foreground\">{hint}</p>}\n </div>\n )\n}\n\nfunction Check({ checked, onChange, label }: { checked: boolean; onChange: (v: boolean) => void; label: string }) {\n const id = React.useId()\n return (\n <div className=\"flex items-center gap-2\">\n <Checkbox id={id} checked={checked} onChange={onChange} />\n <label htmlFor={id} className=\"cursor-pointer text-sm\">{label}</label>\n </div>\n )\n}\n\n/** Per-type properties of the V1 FieldPropertiesPanel: stencil, gallery and answer alert. */\nexport function FieldTypeSettings({ field, config, onChange }: {\n field: FormFieldDef\n config: Config\n onChange: (c: Config) => void\n}) {\n const upload = useMediaUpload()\n const [sending, setSending] = React.useState(false)\n const [erro, setErro] = React.useState<string | null>(null)\n\n if (field.type === 'stencil_photo') {\n const st = (config.stencil as StencilConfig) ?? {}\n const set = (p: Partial<StencilConfig>) => onChange({ ...config, stencil: { ...st, ...p } })\n async function sendOverlay(file: File | undefined) {\n if (!file || !upload) return\n setSending(true); setErro(null)\n try {\n const { path } = await upload(file, `templates/${field.id}`, file.name)\n set({ overlayPath: path })\n } catch (e) {\n setErro(describeError(e, 'Não foi possível enviar o gabarito.'))\n } finally { setSending(false) }\n }\n return (\n <div className=\"space-y-4 border-t pt-4\">\n <Row label=\"Gabarito (imagem sobre a câmera)\" hint=\"PNG com fundo transparente, desenhado na proporção da foto.\">\n {st.overlayPath ? (\n <div className=\"flex items-start gap-3\">\n <MediaImage value={st.overlayPath} alt=\"Gabarito\" className=\"h-24 w-20 rounded-md border bg-muted object-contain\" />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"h-8 gap-1 text-xs\" onClick={() => set({ overlayPath: undefined })}>\n <Trash2 className=\"h-3 w-3\" /> Remover\n </Button>\n </div>\n ) : (\n <label className={`flex cursor-pointer items-center justify-center gap-2 rounded-lg border-2 border-dashed py-4 text-xs text-muted-foreground hover:border-primary hover:text-primary ${sending ? 'pointer-events-none opacity-60' : ''}`}>\n <ImageUp className=\"h-4 w-4\" /> {sending ? 'Enviando…' : 'Enviar imagem'}\n <input type=\"file\" accept=\"image/png,image/webp,image/svg+xml\" className=\"hidden\" onChange={(e) => sendOverlay(e.target.files?.[0])} />\n </label>\n )}\n {erro && <p className=\"text-xs text-destructive\">{erro}</p>}\n </Row>\n <Row label={`Opacidade do gabarito · ${Math.round((st.opacity ?? 0.6) * 100)}%`}>\n <input type=\"range\" min={10} max={100} step={5} value={Math.round((st.opacity ?? 0.6) * 100)}\n onChange={(e) => set({ opacity: Number(e.target.value) / 100 })} className=\"w-full accent-primary\" />\n </Row>\n <Row label=\"Proporção\">\n <SegmentedControl value={st.aspect ?? '3:4'} onChange={(v) => set({ aspect: v as StencilConfig['aspect'] })}\n options={[{ value: '3:4', label: 'Retrato 3:4' }, { value: '1:1', label: 'Quadrada' }, { value: '4:3', label: 'Paisagem' }]} />\n </Row>\n <Row label=\"Câmera\">\n <SegmentedControl value={st.camera ?? 'environment'} onChange={(v) => set({ camera: v as StencilConfig['camera'] })}\n options={[{ value: 'environment', label: 'Traseira' }, { value: 'user', label: 'Frontal' }]} />\n </Row>\n <Check checked={!!st.burnOverlay} onChange={(v) => set({ burnOverlay: v })} label=\"Gravar o gabarito na foto\" />\n <Row label=\"Instrução para quem fotografa\">\n <Input value={st.description ?? ''} onChange={(e) => set({ description: e.target.value })} className=\"h-9 text-sm\"\n placeholder=\"Tocar para abrir câmera\" />\n </Row>\n </div>\n )\n }\n\n if (field.type === 'gallery') {\n const g = (config.gallery as GalleryConfig) ?? {}\n const set = (p: Partial<GalleryConfig>) => onChange({ ...config, gallery: { ...g, ...p } })\n return (\n <div className=\"space-y-2 border-t pt-4\">\n <Check checked={g.allowPhoto ?? true} onChange={(v) => set({ allowPhoto: v })} label=\"Permite fotos\" />\n <Check checked={g.allowVideo ?? true} onChange={(v) => set({ allowVideo: v })} label=\"Permite vídeos\" />\n </div>\n )\n }\n\n if (field.type === 'yes_no' || field.type === 'yes_no_text') {\n const a = (config.alert as AnswerAlertConfig) ?? {}\n const set = (p: Partial<AnswerAlertConfig>) => onChange({ ...config, alert: { ...a, ...p } })\n return (\n <div className=\"space-y-4 border-t pt-4\">\n <Row label=\"Alerta na ficha do cliente\" hint=\"A resposta escolhida aparece como alerta na ficha e no atendimento.\">\n <SegmentedControl value={a.trigger ?? 'never'} onChange={(v) => set({ trigger: v as AnswerAlertConfig['trigger'] })}\n options={[{ value: 'never', label: 'Nunca' }, { value: 'sim', label: 'Quando Sim' }, { value: 'nao', label: 'Quando Não' }]} />\n </Row>\n {a.trigger && a.trigger !== 'never' && (\n <>\n <Row label=\"Gravidade\">\n <SegmentedControl value={a.severity ?? 'danger'} onChange={(v) => set({ severity: v as AnswerAlertConfig['severity'] })}\n options={[{ value: 'danger', label: 'Crítico' }, { value: 'warning', label: 'Atenção' }, { value: 'info', label: 'Informativo' }]} />\n </Row>\n <Row label=\"Mensagem (opcional)\">\n <Input value={a.message ?? ''} onChange={(e) => set({ message: e.target.value })} className=\"h-9 text-sm\"\n placeholder={field.label} />\n </Row>\n </>\n )}\n </div>\n )\n }\n\n return null\n}\n","import React, { useState, useEffect } from 'react'\nimport { Plus, Trash2 } from 'lucide-react'\nimport {\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetBody,\n SheetFooter,\n} from '@fayz-ai/ui'\nimport { Button, Checkbox } from '@fayz-ai/ui'\nimport { Input } from '@fayz-ai/ui'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { FormFieldDef } from '@fayz-ai/forms/domain/template'\nimport { FIELD_TYPES } from './FieldPalette'\nimport { PERSON_FIELD_OPTIONS } from '../lib/person-fields'\nimport { FieldTypeSettings } from './fields/FieldTypeSettings'\n\n/** Field types that can be auto-filled from a person record. */\nconst MAPPABLE_TYPES = ['text', 'memo', 'richtext', 'date']\nconst MAP_NONE = '__none__'\n\nconst SIZE_OPTIONS = [\n { span: 3, label: '1/4' },\n { span: 4, label: '1/3' },\n { span: 6, label: '1/2' },\n { span: 8, label: '2/3' },\n { span: 9, label: '3/4' },\n { span: 12, label: 'Full' },\n]\n\ninterface FieldConfigDrawerProps {\n field: FormFieldDef | null\n onSave: (updated: FormFieldDef) => void\n /** Live update without closing — used for visual changes like colSpan */\n onUpdate?: (updated: FormFieldDef) => void\n onClose: () => void\n}\n\nexport function FieldConfigDrawer({ field, onSave, onUpdate, onClose }: FieldConfigDrawerProps) {\n const t = useTranslation()\n const [label, setLabel] = useState('')\n const [placeholder, setPlaceholder] = useState('')\n const [required, setRequired] = useState(false)\n const [colSpan, setColSpan] = useState(12)\n const [options, setOptions] = useState<Array<{ label: string; value: string }>>([])\n const [map, setMap] = useState<string>('')\n const [config, setConfig] = useState<Record<string, unknown>>({})\n\n // Sync state when field changes\n useEffect(() => {\n if (!field) return\n setLabel(field.label)\n setPlaceholder(field.placeholder ?? '')\n setRequired(field.required ?? false)\n setColSpan(field.colSpan)\n setOptions(field.options ?? [])\n setMap(field.map ?? '')\n setConfig(field.config ?? {})\n }, [field?.id])\n\n if (!field) return null\n\n const hasOptions = ['select', 'radio', 'tags'].includes(field.type)\n const canMap = MAPPABLE_TYPES.includes(field.type)\n const fieldTypeDef = FIELD_TYPES.find((ft) => ft.type === field.type)\n const Icon = fieldTypeDef?.icon\n\n const handleSave = () => {\n onSave({\n ...field,\n label,\n placeholder: placeholder || undefined,\n required,\n colSpan: Math.max(1, Math.min(12, colSpan)),\n options: hasOptions ? options.filter((o) => o.label.trim()) : field.options,\n map: canMap && map ? map : undefined,\n config: Object.keys(config).length ? config : field.config,\n })\n }\n\n const addOption = () => {\n setOptions([...options, { label: '', value: '' }])\n }\n\n const updateOption = (index: number, newLabel: string) => {\n const updated = [...options]\n updated[index] = { label: newLabel, value: newLabel.toLowerCase().replace(/\\s+/g, '_') }\n setOptions(updated)\n }\n\n const removeOption = (index: number) => {\n setOptions(options.filter((_, i) => i !== index))\n }\n\n return (\n <Sheet open={!!field} onOpenChange={(open) => { if (!open) onClose() }}>\n <SheetContent className=\"w-80 sm:w-96\" overlay=\"none\">\n <SheetHeader>\n <SheetTitle className=\"flex items-center gap-2 text-sm\">\n {Icon && <Icon className=\"h-4 w-4 text-muted-foreground\" />}\n {t(`customForms.fieldType.${field.type}`)}\n </SheetTitle>\n </SheetHeader>\n\n <SheetBody className=\"space-y-4 py-4\">\n {/* Label */}\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium\">{t('customForms.builder.fieldLabel')}</label>\n <Input\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n className=\"h-9 text-sm\"\n autoFocus\n />\n </div>\n\n {/* Placeholder */}\n {!['title', 'checkbox', 'image', 'gallery', 'stencil_photo', 'recommendation', 'signature', 'yes_no'].includes(field.type) && (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium\">{t('customForms.builder.fieldPlaceholder')}</label>\n <Input\n value={placeholder}\n onChange={(e) => setPlaceholder(e.target.value)}\n className=\"h-9 text-sm\"\n />\n </div>\n )}\n\n {/* Column span — visual skeleton selector */}\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium\">{t('customForms.builder.colSpan')}</label>\n <div className=\"grid grid-cols-3 gap-2\">\n {SIZE_OPTIONS.map((opt) => (\n <Button variant=\"bare\" size=\"bare\"\n key={opt.span}\n onClick={() => {\n setColSpan(opt.span)\n if (onUpdate && field) {\n onUpdate({ ...field, colSpan: opt.span })\n }\n }}\n className={`block font-normal group relative rounded-lg border-2 p-2 transition-all ${\n colSpan === opt.span\n ? 'border-primary bg-primary/5'\n : 'border-border hover:border-primary/30'\n }`}\n >\n {/* Mini 12-col skeleton preview */}\n <div className=\"flex gap-px h-3 mb-1.5\">\n <div\n className={`rounded-sm ${colSpan === opt.span ? 'bg-primary/60' : 'bg-muted-foreground/30 group-hover:bg-primary/30'}`}\n style={{ width: `${(opt.span / 12) * 100}%` }}\n />\n {opt.span < 12 && (\n <div\n className=\"rounded-sm bg-muted/60\"\n style={{ width: `${((12 - opt.span) / 12) * 100}%` }}\n />\n )}\n </div>\n <span className={`text-[10px] font-medium ${colSpan === opt.span ? 'text-primary' : 'text-muted-foreground'}`}>\n {opt.label}\n </span>\n </Button>\n ))}\n </div>\n </div>\n\n {/* Required */}\n {field.type !== 'title' && (\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <Checkbox checked={required} onChange={setRequired} />\n <span className=\"text-sm\">{t('customForms.builder.fieldRequired')}</span>\n </label>\n )}\n\n {/* Auto-fill from person record */}\n {canMap && (\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium\">{t('customForms.builder.mapToPerson')}</label>\n <Select\n value={map || MAP_NONE}\n onValueChange={(v) => setMap(v === MAP_NONE ? '' : v)}\n >\n <SelectTrigger className=\"h-9 text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={MAP_NONE}>{t('customForms.builder.mapNone')}</SelectItem>\n {PERSON_FIELD_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {t(opt.labelKey)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-[10px] text-muted-foreground\">{t('customForms.builder.mapHint')}</p>\n </div>\n )}\n\n {/* Options */}\n {hasOptions && (\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium\">{t('customForms.builder.fieldOptions')}</label>\n {options.map((opt, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <Input\n value={opt.label}\n onChange={(e) => updateOption(i, e.target.value)}\n placeholder={`Option ${i + 1}`}\n className=\"h-8 text-sm flex-1\"\n />\n <Button variant=\"bare\" size=\"bare\" onClick={() => removeOption(i)} className=\"p-1 hover:bg-destructive/10 rounded\">\n <Trash2 className=\"h-3.5 w-3.5 text-destructive\" />\n </Button>\n </div>\n ))}\n <Button variant=\"outline\" size=\"sm\" onClick={addOption} className=\"h-8 text-xs w-full\">\n <Plus className=\"h-3 w-3 mr-1\" />\n {t('customForms.builder.addOption')}\n </Button>\n </div>\n )}\n <FieldTypeSettings field={field} config={config} onChange={setConfig} />\n </SheetBody>\n\n <SheetFooter className=\"pt-4 border-t\">\n <Button size=\"sm\" onClick={handleSave} className=\"w-full\">\n OK\n </Button>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n )\n}\n","import React, { useState, useCallback, useEffect } from 'react'\nimport {\n DndContext,\n DragEndEvent,\n DragOverlay,\n DragStartEvent,\n PointerSensor,\n pointerWithin,\n useSensor,\n useSensors,\n} from '@dnd-kit/core'\nimport { arrayMove } from '@dnd-kit/sortable'\nimport { snapCenterToCursor } from '@dnd-kit/modifiers'\nimport { ArrowLeft, Eye, Pencil, Printer } from 'lucide-react'\nimport { Button, useSaveBar, toast } from '@fayz-ai/ui'\nimport { Input } from '@fayz-ai/ui'\nimport { Card, CardContent } from '@fayz-ai/ui'\nimport { Badge } from '@fayz-ai/ui'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport { useLimitGuard, invalidateLimit, useAgentSurface, type AgentSurfaceContribution } from '@fayz-ai/admin'\nimport type { FormsStore } from '@fayz-ai/forms/store'\nimport type { FormsDataProvider } from '@fayz-ai/forms/data/provider'\nimport type { CustomFormsConfig } from '../config'\nimport type { FormFieldDef, FormFieldType, FormSchema, TemplateCategory } from '@fayz-ai/forms/domain/template'\nimport { FieldPalette, FIELD_TYPES, DEFAULT_COL_SPAN } from './FieldPalette'\nimport { BuilderCanvas } from './BuilderCanvas'\nimport { FieldConfigDrawer } from './FieldConfigDialog'\nimport { createPortal } from 'react-dom'\nimport { FormRenderer } from './FormRenderer'\nimport { buildPrintHtml } from '../lib/print'\nimport { FORM_BUILDER_INSTRUCTIONS } from '../lib/agent-tools'\n\nconst TEMPLATE_CATEGORIES: TemplateCategory[] = ['anamnesis', 'evaluation', 'photos', 'evolution', 'report', 'contract', 'general']\n\ninterface FormBuilderProps {\n templateId?: string\n store: FormsStore\n provider: FormsDataProvider\n config: CustomFormsConfig\n onBack: () => void\n}\n\nexport function FormBuilder({ templateId, store, provider, config, onBack }: FormBuilderProps) {\n const t = useTranslation()\n const guardTemplates = useLimitGuard('form_templates')\n\n const [name, setName] = useState('')\n const [description, setDescription] = useState('')\n const [category, setCategory] = useState<TemplateCategory>('general')\n const [fields, setFields] = useState<FormFieldDef[]>([])\n const [selectedFieldId, setSelectedFieldId] = useState<string | null>(null)\n const [saving, setSaving] = useState(false)\n const [showPreview, setShowPreview] = useState(false)\n const [previewMode, setPreviewMode] = useState<'editor' | 'print'>('editor')\n const [previewData, setPreviewData] = useState<Record<string, unknown>>({})\n const [draggingFieldType, setDraggingFieldType] = useState<FormFieldType | null>(null)\n const [templateName, setTemplateName] = useState<string | null>(null)\n\n // Load existing template\n useEffect(() => {\n if (!templateId) return\n let cancelled = false\n provider.getTemplateById(templateId).then((tpl) => {\n if (cancelled || !tpl) return\n setName(tpl.name)\n setTemplateName(tpl.name)\n setDescription(tpl.description ?? '')\n setCategory(tpl.category)\n setFields(tpl.schema.fields)\n })\n return () => { cancelled = true }\n }, [templateId, provider])\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n )\n\n const handleDragStart = useCallback((event: DragStartEvent) => {\n const data = event.active.data.current\n if (data?.source === 'palette') {\n setDraggingFieldType(data.fieldType)\n }\n }, [])\n\n const handleDragEnd = useCallback((event: DragEndEvent) => {\n setDraggingFieldType(null)\n const { active, over } = event\n\n // Dropped from palette onto canvas\n if (active.data.current?.source === 'palette' && over) {\n const fieldType = active.data.current.fieldType\n const typeDef = FIELD_TYPES.find((ft) => ft.type === fieldType)\n if (!typeDef) return\n\n const newField: FormFieldDef = {\n id: crypto.randomUUID(),\n type: fieldType,\n label: t(`customForms.fieldType.${fieldType}`),\n col: 0,\n row: fields.length,\n colSpan: DEFAULT_COL_SPAN[fieldType] ?? 12,\n }\n\n if (['select', 'radio', 'tags'].includes(fieldType)) {\n newField.options = [\n { label: 'Option 1', value: 'option_1' },\n { label: 'Option 2', value: 'option_2' },\n ]\n }\n\n setFields((prev) => [...prev, newField])\n return\n }\n\n // Reorder within canvas\n if (active.id !== over?.id && over) {\n setFields((prev) => {\n const oldIndex = prev.findIndex((f) => f.id === active.id)\n const newIndex = prev.findIndex((f) => f.id === over.id)\n if (oldIndex === -1 || newIndex === -1) return prev\n const reordered = arrayMove(prev, oldIndex, newIndex)\n return reordered.map((f, i) => ({ ...f, row: i }))\n })\n }\n }, [fields, t])\n\n const handleSelectField = useCallback((field: FormFieldDef) => {\n setSelectedFieldId(field.id)\n }, [])\n\n const handleRemoveField = useCallback((fieldId: string) => {\n setFields((prev) => prev.filter((f) => f.id !== fieldId).map((f, i) => ({ ...f, row: i })))\n if (selectedFieldId === fieldId) setSelectedFieldId(null)\n }, [selectedFieldId])\n\n const handleFieldUpdate = useCallback((updated: FormFieldDef) => {\n setFields((prev) => prev.map((f) => (f.id === updated.id ? updated : f)))\n }, [])\n\n // --- Assistant surface: publish WHAT THE USER IS EDITING as context --------\n // The build action is the server-plane createOrUpdateForm tool (a pool RPC),\n // which works from any page. This surface only tells the model which template\n // is open and its current fields+ids, so \"add an allergies field to THIS\n // form\" resolves to the right templateId. No client-side mutation here.\n const surfaceStateRef = React.useRef({ templateId, name, description, category, fields })\n surfaceStateRef.current = { templateId, name, description, category, fields }\n\n const agentSurface = React.useMemo<AgentSurfaceContribution>(\n () => ({\n id: 'custom_forms.builder',\n pluginId: 'custom_forms',\n instructions: FORM_BUILDER_INSTRUCTIONS,\n describe: () => {\n const o = surfaceStateRef.current\n return {\n title: `Construtor de formulário — ${o.name?.trim() || 'novo modelo'}`,\n state: {\n // Pass this as `templateId` to createOrUpdateForm when editing THIS\n // form. Null = an unsaved new form (create, then it gets an id).\n templateId: o.templateId ?? null,\n unsaved: !o.templateId,\n name: o.name ?? '',\n category: o.category ?? 'general',\n description: o.description ?? '',\n fieldCount: o.fields.length,\n fields: o.fields.map((f) => ({\n id: f.id,\n type: f.type,\n label: f.label,\n required: !!f.required,\n ...(f.options?.length ? { options: f.options.map((x) => x.label) } : {}),\n })),\n },\n }\n },\n }),\n [],\n )\n useAgentSurface(agentSurface)\n // ---------------------------------------------------------------------------\n\n const handleFieldConfigSave = useCallback((updated: FormFieldDef) => {\n handleFieldUpdate(updated)\n setSelectedFieldId(null)\n }, [handleFieldUpdate])\n\n const handleSave = useCallback(async () => {\n if (!name.trim()) { toast.error(t('common.formIncomplete')); return }\n // Plan quantity guard (client-side, before the provider call) — only on\n // create. Opens the global UpgradeModal and aborts when the cap is reached.\n if (!templateId && (await guardTemplates()) === 'blocked') return\n setSaving(true)\n try {\n const schema: FormSchema = { fields, layout: { columns: 12 } }\n\n if (templateId) {\n await store.getState().updateTemplate(templateId, { name, description, category, schema })\n } else {\n await store.getState().createTemplate({ name, description, category, schema })\n invalidateLimit('form_templates')\n }\n onBack()\n } finally {\n setSaving(false)\n }\n }, [templateId, name, description, category, fields, store, onBack, guardTemplates])\n\n // Dirty detection — snapshot editable fields once async load settles\n const currentFields = { name, description, category, fields }\n const snapshot = React.useRef<string | null>(null)\n const loaded = !templateId || templateName !== null\n useEffect(() => {\n if (loaded && snapshot.current === null) snapshot.current = JSON.stringify(currentFields)\n }, [loaded])\n const dirty = snapshot.current !== null && JSON.stringify(currentFields) !== snapshot.current\n\n useSaveBar({\n dirty,\n saving,\n onSave: () => { void handleSave() },\n onDiscard: () => onBack(),\n saveLabel: t('customForms.builder.save'),\n })\n\n const selectedField = selectedFieldId\n ? fields.find((f) => f.id === selectedFieldId) ?? null\n : null\n\n const isNew = !templateId\n const breadcrumbLabel = isNew\n ? t('customForms.newTemplate')\n : templateName ?? t('customForms.editTemplate')\n\n return (\n <div className=\"space-y-4\">\n {/* Breadcrumb */}\n <div className=\"flex items-center gap-1.5 text-sm\">\n <Button variant=\"bare\" size=\"bare\"\n onClick={onBack}\n className=\"flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors font-normal\"\n >\n <ArrowLeft className=\"h-3.5 w-3.5\" />\n {t('customForms.templates')}\n </Button>\n <span className=\"text-muted-foreground\">/</span>\n <span className=\"font-medium\">{breadcrumbLabel}</span>\n </div>\n\n {/* Form meta — card layout matching CRUD form */}\n <Card>\n <CardContent className=\"p-5 space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">\n {t('customForms.templateName')} <span className=\"text-destructive\">*</span>\n </label>\n <Input\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={t('customForms.templateName')}\n className=\"h-9 text-sm\"\n autoFocus={isNew}\n />\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">{t('customForms.templateCategory')}</label>\n <Select value={category} onValueChange={(v) => setCategory(v as TemplateCategory)}>\n <SelectTrigger className=\"h-9 text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {TEMPLATE_CATEGORIES.map((cat) => (\n <SelectItem key={cat} value={cat}>\n {t(`customForms.category.${cat}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">{t('customForms.templateDescription')}</label>\n <Input\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t('customForms.templateDescription')}\n className=\"h-9 text-sm\"\n />\n </div>\n </CardContent>\n </Card>\n\n {/* Builder section header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-semibold\">{t('customForms.builder.fields')}</h3>\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {t('customForms.builder.fieldCount', { count: String(fields.length) })}\n </Badge>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-9\"\n disabled={fields.length === 0}\n onClick={() => { setPreviewData({}); setPreviewMode('editor'); setShowPreview(true) }}\n >\n <Eye className=\"h-3.5 w-3.5 mr-1.5\" />\n Preview\n </Button>\n </div>\n </div>\n\n {/* Builder body — drag palette + canvas */}\n <DndContext sensors={sensors} collisionDetection={pointerWithin} onDragStart={handleDragStart} onDragEnd={handleDragEnd}>\n <div className=\"flex gap-4\">\n <FieldPalette />\n <BuilderCanvas\n fields={fields}\n selectedFieldId={selectedFieldId}\n onSelectField={handleSelectField}\n onRemoveField={handleRemoveField}\n draggingFieldType={draggingFieldType}\n />\n </div>\n\n <DragOverlay dropAnimation={null} modifiers={[snapCenterToCursor]}>\n {draggingFieldType ? (\n <div className=\"flex items-center gap-2 px-3 py-2 rounded-lg border bg-card shadow-xl text-sm font-medium opacity-90 pointer-events-none\">\n {(() => {\n const def = FIELD_TYPES.find((ft) => ft.type === draggingFieldType)\n if (!def) return null\n const Icon = def.icon\n return (\n <>\n <Icon className=\"h-4 w-4 text-primary\" />\n {t(`customForms.fieldType.${draggingFieldType}`)}\n </>\n )\n })()}\n </div>\n ) : null}\n </DragOverlay>\n </DndContext>\n\n {/* Field config drawer (right side) */}\n <FieldConfigDrawer\n field={selectedField}\n onSave={handleFieldConfigSave}\n onUpdate={handleFieldUpdate}\n onClose={() => setSelectedFieldId(null)}\n />\n\n {/* Preview — A4 paper overlay (portaled to body) */}\n {showPreview && createPortal(\n <div className=\"fixed inset-0 z-[100] flex items-start justify-center bg-black/60 overflow-y-auto py-10 px-4\" onClick={() => setShowPreview(false)}>\n <div\n className=\"relative w-full max-w-3xl bg-white rounded-modal shadow-lg\"\n style={{ minHeight: '80vh' }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Toggle Editor ⟷ Impressão (centered) + close, on a sticky top bar. */}\n <div className=\"sticky top-0 z-10 flex items-center justify-center border-b bg-white/95 backdrop-blur px-4 py-2.5 rounded-t-modal\">\n <div className=\"inline-flex rounded-lg border p-0.5 text-xs\">\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => setPreviewMode('editor')}\n className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-md font-medium transition-colors ${previewMode === 'editor' ? 'bg-neutral-900 text-white' : 'text-neutral-500 hover:text-neutral-800'}`}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n {t('customForms.preview.editor')}\n </Button>\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => setPreviewMode('print')}\n className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-md font-medium transition-colors ${previewMode === 'print' ? 'bg-neutral-900 text-white' : 'text-neutral-500 hover:text-neutral-800'}`}\n >\n <Printer className=\"h-3.5 w-3.5\" />\n {t('customForms.preview.print')}\n </Button>\n </div>\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => setShowPreview(false)}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full text-neutral-400 hover:bg-neutral-100 hover:text-neutral-700 transition-colors font-normal\"\n >\n <span className=\"text-lg\">✕</span>\n </Button>\n </div>\n\n {previewMode === 'editor' ? (\n /* Editor — fillable form (same renderer used on the person's ficha) */\n <div className=\"px-10 py-8 sm:px-14 sm:py-10 text-neutral-900\">\n <h1 className=\"text-2xl font-bold mb-1\">{name || t('customForms.newTemplate')}</h1>\n {description && <p className=\"text-sm text-neutral-500 mb-8\">{description}</p>}\n {!description && <div className=\"mb-8\" />}\n\n <FormRenderer\n schema={{ fields, layout: { columns: 12 } }}\n data={previewData}\n onChange={setPreviewData}\n />\n </div>\n ) : (\n /* Impressão — exact print/PDF output rendered in an isolated iframe */\n <iframe\n title=\"print-preview\"\n className=\"w-full rounded-b-modal\"\n style={{ height: '75vh', border: 'none' }}\n srcDoc={buildPrintHtml(\n { id: 'preview', name: name || t('customForms.newTemplate'), schema: { fields, layout: { columns: 12 } } } as any,\n { title: name || t('customForms.newTemplate'), createdAt: new Date().toISOString(), status: 'draft', data: previewData } as any,\n )}\n />\n )}\n </div>\n </div>,\n document.body,\n )}\n </div>\n )\n}\n"]}
|