@fayz-ai/plugin-tables 0.10.3 → 0.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/ComandaSettingsView-ZB5RK7TP.js +176 -0
  2. package/dist/ComandaSettingsView-ZB5RK7TP.js.map +1 -0
  3. package/dist/TablesPage-VVDNK3GN.js +1145 -0
  4. package/dist/TablesPage-VVDNK3GN.js.map +1 -0
  5. package/dist/chunk-XHRPH676.js +12 -0
  6. package/dist/chunk-XHRPH676.js.map +1 -0
  7. package/dist/context.d.ts +10 -0
  8. package/dist/context.d.ts.map +1 -1
  9. package/dist/data/core-supabase.d.ts +32 -0
  10. package/dist/data/core-supabase.d.ts.map +1 -0
  11. package/dist/data/mock.d.ts.map +1 -1
  12. package/dist/data/registries.d.ts.map +1 -1
  13. package/dist/data/types.d.ts +39 -1
  14. package/dist/data/types.d.ts.map +1 -1
  15. package/dist/index.d.ts +7 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1234 -21
  18. package/dist/index.js.map +1 -1
  19. package/dist/locales/en.d.ts.map +1 -1
  20. package/dist/locales/pt-BR.d.ts.map +1 -1
  21. package/dist/migrations/index.d.ts +7 -0
  22. package/dist/migrations/index.d.ts.map +1 -0
  23. package/dist/store.d.ts +40 -1
  24. package/dist/store.d.ts.map +1 -1
  25. package/dist/types.d.ts +138 -0
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/views/ComandaActions.d.ts +63 -0
  28. package/dist/views/ComandaActions.d.ts.map +1 -0
  29. package/dist/views/ComandaSettingsView.d.ts +3 -0
  30. package/dist/views/ComandaSettingsView.d.ts.map +1 -0
  31. package/dist/views/FloorPlanView.d.ts.map +1 -1
  32. package/dist/views/TableRailPage.d.ts +3 -0
  33. package/dist/views/TableRailPage.d.ts.map +1 -0
  34. package/package.json +4 -4
  35. package/dist/TablesPage-GKTE4SD2.js +0 -274
  36. package/dist/TablesPage-GKTE4SD2.js.map +0 -1
@@ -0,0 +1,176 @@
1
+ import { useTablesStore } from './chunk-XHRPH676.js';
2
+ import React from 'react';
3
+ import { Plus, Trash2 } from 'lucide-react';
4
+ import { Input, Switch, Button, Card } from '@fayz-ai/ui';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ function Section({ title, description, children }) {
8
+ return /* @__PURE__ */ jsxs(Card, { className: "p-4", children: [
9
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: title }),
10
+ description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }),
11
+ /* @__PURE__ */ jsx("div", { className: "mt-3", children })
12
+ ] });
13
+ }
14
+ function ComandaSettingsView() {
15
+ const settings = useTablesStore((s) => s.settings);
16
+ const fetchSettings = useTablesStore((s) => s.fetchSettings);
17
+ const saveSettings = useTablesStore((s) => s.saveSettings);
18
+ const reasons = useTablesStore((s) => s.cancelReasons);
19
+ const fetchCancelReasons = useTablesStore((s) => s.fetchCancelReasons);
20
+ const addCancelReason = useTablesStore((s) => s.addCancelReason);
21
+ const updateCancelReason = useTablesStore((s) => s.updateCancelReason);
22
+ const deleteCancelReason = useTablesStore((s) => s.deleteCancelReason);
23
+ const [percent, setPercent] = React.useState("");
24
+ const [pin, setPin] = React.useState(false);
25
+ const [dayStart, setDayStart] = React.useState("06:00");
26
+ const [newReason, setNewReason] = React.useState("");
27
+ const [saving, setSaving] = React.useState(false);
28
+ React.useEffect(() => {
29
+ void fetchSettings();
30
+ void fetchCancelReasons();
31
+ }, [fetchSettings, fetchCancelReasons]);
32
+ React.useEffect(() => {
33
+ if (!settings) return;
34
+ setPercent(String(settings.serviceChargePercent));
35
+ setPin(settings.cancelRequiresPin);
36
+ setDayStart(settings.operationalDayStart.slice(0, 5));
37
+ }, [settings]);
38
+ const parsed = Number(percent.replace(",", "."));
39
+ const valid = Number.isFinite(parsed) && parsed >= 0 && parsed <= 100;
40
+ const dirty = settings != null && (parsed !== settings.serviceChargePercent || pin !== settings.cancelRequiresPin || dayStart !== settings.operationalDayStart.slice(0, 5));
41
+ async function save() {
42
+ setSaving(true);
43
+ try {
44
+ await saveSettings({
45
+ serviceChargePercent: parsed,
46
+ cancelRequiresPin: pin,
47
+ operationalDayStart: dayStart
48
+ });
49
+ } finally {
50
+ setSaving(false);
51
+ }
52
+ }
53
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
54
+ /* @__PURE__ */ jsxs(
55
+ Section,
56
+ {
57
+ title: "Taxa de servi\xE7o",
58
+ description: "A taxa da casa. Cada mesa e cada participante podem ter a sua, e o que estiver em branco herda desta.",
59
+ children: [
60
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
61
+ /* @__PURE__ */ jsx("span", { className: "w-28 shrink-0", children: /* @__PURE__ */ jsx(
62
+ Input,
63
+ {
64
+ value: percent,
65
+ onChange: (e) => setPercent(e.target.value),
66
+ inputMode: "decimal",
67
+ "aria-label": "Taxa de servi\xE7o da casa"
68
+ }
69
+ ) }),
70
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "%" })
71
+ ] }),
72
+ !valid && percent !== "" && /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-xs text-destructive", children: "Informe um n\xFAmero entre 0 e 100." }),
73
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: "Entra na comanda e na fatura levantada no fechamento." })
74
+ ]
75
+ }
76
+ ),
77
+ /* @__PURE__ */ jsx(
78
+ Section,
79
+ {
80
+ title: "Cancelamento",
81
+ description: "Quem pode cancelar item vem do perfil de acesso. Aqui fica o que a tela pergunta na hora.",
82
+ children: /* @__PURE__ */ jsxs("label", { className: "flex items-start gap-3", children: [
83
+ /* @__PURE__ */ jsx(Switch, { checked: pin, onCheckedChange: setPin, "aria-label": "Exigir PIN para cancelar" }),
84
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
85
+ /* @__PURE__ */ jsx("span", { className: "block text-sm", children: "Exigir PIN para cancelar" }),
86
+ /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: "O terminal do sal\xE3o fica logado a noite inteira, e nem sempre quem cancela \xE9 quem est\xE1 logado. Ligado, o cancelamento pede o PIN de algu\xE9m com permiss\xE3o." })
87
+ ] })
88
+ ] })
89
+ }
90
+ ),
91
+ /* @__PURE__ */ jsxs(
92
+ Section,
93
+ {
94
+ title: "Motivos de cancelamento",
95
+ description: "O que aparece na hora de tirar um item da comanda \u2014 e o que alimenta o ranking do que a cozinha mais devolveu.",
96
+ children: [
97
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
98
+ /* @__PURE__ */ jsx(
99
+ Input,
100
+ {
101
+ value: newReason,
102
+ onChange: (e) => setNewReason(e.target.value),
103
+ onKeyDown: (e) => {
104
+ if (e.key === "Enter" && newReason.trim()) {
105
+ void addCancelReason(newReason.trim());
106
+ setNewReason("");
107
+ }
108
+ },
109
+ placeholder: "Ex.: saiu errado da cozinha, cliente trocou o pedido\u2026"
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsx(
113
+ Button,
114
+ {
115
+ variant: "outline",
116
+ disabled: !newReason.trim(),
117
+ onClick: () => {
118
+ void addCancelReason(newReason.trim());
119
+ setNewReason("");
120
+ },
121
+ children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" })
122
+ }
123
+ )
124
+ ] }),
125
+ /* @__PURE__ */ jsxs("ul", { className: "mt-3 space-y-1", children: [
126
+ reasons.map((r) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2 rounded px-2 py-1.5 hover:bg-muted/50", children: [
127
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm", children: r.label }),
128
+ /* @__PURE__ */ jsx(
129
+ "button",
130
+ {
131
+ type: "button",
132
+ onClick: () => void updateCancelReason(r.id, { isActive: !r.isActive }),
133
+ className: `rounded-full border px-2 py-0.5 text-xs transition-colors ${r.isActive ? "border-success/40 bg-success/10 text-success" : "border-border text-muted-foreground"}`,
134
+ children: r.isActive ? "Ativo" : "Inativo"
135
+ }
136
+ ),
137
+ /* @__PURE__ */ jsx(
138
+ Button,
139
+ {
140
+ variant: "ghost",
141
+ size: "icon",
142
+ className: "h-7 w-7",
143
+ "aria-label": `Excluir ${r.label}`,
144
+ onClick: () => void deleteCancelReason(r.id),
145
+ children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5 text-destructive" })
146
+ }
147
+ )
148
+ ] }, r.id)),
149
+ reasons.length === 0 && /* @__PURE__ */ jsx("li", { className: "py-3 text-sm text-muted-foreground", children: "Nenhum motivo cadastrado. Sem eles, quem cancela escreve o motivo \xE0 m\xE3o." })
150
+ ] })
151
+ ]
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsx(
155
+ Section,
156
+ {
157
+ title: "Dia operacional",
158
+ description: "O dia do restaurante n\xE3o \xE9 o dia do calend\xE1rio: come\xE7ar de madrugada mant\xE9m a virada no turno a que ela pertence.",
159
+ children: /* @__PURE__ */ jsx("span", { className: "inline-block w-32", children: /* @__PURE__ */ jsx(
160
+ Input,
161
+ {
162
+ type: "time",
163
+ value: dayStart,
164
+ onChange: (e) => setDayStart(e.target.value),
165
+ "aria-label": "In\xEDcio do dia operacional"
166
+ }
167
+ ) })
168
+ }
169
+ ),
170
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(Button, { onClick: save, disabled: !dirty || !valid || saving, children: saving ? "Salvando\u2026" : "Salvar" }) })
171
+ ] });
172
+ }
173
+
174
+ export { ComandaSettingsView };
175
+ //# sourceMappingURL=ComandaSettingsView-ZB5RK7TP.js.map
176
+ //# sourceMappingURL=ComandaSettingsView-ZB5RK7TP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/views/ComandaSettingsView.tsx"],"names":[],"mappings":"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","file":"ComandaSettingsView-ZB5RK7TP.js","sourcesContent":["import React from 'react'\nimport { Plus, Trash2 } from 'lucide-react'\nimport { Button, Input, Switch, Card } from '@fayz-ai/ui'\nimport { useTablesStore } from '../context'\n\n// ---------------------------------------------------------------------------\n// Configurações da comanda.\n//\n// Três lições do V1 que esta tela não repete:\n//\n// 1. TEM Salvar, e ele aparece. As \"Chamadas de Garçom\" do V1 gravam ao\n// mudar, sem nenhum aviso — numa tela de configuração é o oposto do que o\n// resto do produto faz, e a pessoa que muda o número e fecha a aba não\n// sabe se gravou.\n// 2. Entrar pela URL funciona. As \"Regras de Cancelamento\" abertas por link\n// direto vêm com a lista PERMANENTEMENTE vazia (V1-048), com 103 pessoas\n// no banco.\n// 3. O selo é botão ou não é selo. O \"Ativa\" do Salão é decorativo (V1-037)\n// e o de Chamadas alterna de verdade; um dos dois ensina errado.\n// ---------------------------------------------------------------------------\n\nfunction Section({ title, description, children }: {\n title: string\n description?: string\n children: React.ReactNode\n}) {\n return (\n <Card className=\"p-4\">\n <h3 className=\"text-sm font-semibold\">{title}</h3>\n {description && <p className=\"mt-0.5 text-xs text-muted-foreground\">{description}</p>}\n <div className=\"mt-3\">{children}</div>\n </Card>\n )\n}\n\nexport function ComandaSettingsView() {\n const settings = useTablesStore((s) => s.settings)\n const fetchSettings = useTablesStore((s) => s.fetchSettings)\n const saveSettings = useTablesStore((s) => s.saveSettings)\n const reasons = useTablesStore((s) => s.cancelReasons)\n const fetchCancelReasons = useTablesStore((s) => s.fetchCancelReasons)\n const addCancelReason = useTablesStore((s) => s.addCancelReason)\n const updateCancelReason = useTablesStore((s) => s.updateCancelReason)\n const deleteCancelReason = useTablesStore((s) => s.deleteCancelReason)\n\n const [percent, setPercent] = React.useState('')\n const [pin, setPin] = React.useState(false)\n const [dayStart, setDayStart] = React.useState('06:00')\n const [newReason, setNewReason] = React.useState('')\n const [saving, setSaving] = React.useState(false)\n\n React.useEffect(() => {\n void fetchSettings()\n void fetchCancelReasons()\n }, [fetchSettings, fetchCancelReasons])\n\n React.useEffect(() => {\n if (!settings) return\n setPercent(String(settings.serviceChargePercent))\n setPin(settings.cancelRequiresPin)\n setDayStart(settings.operationalDayStart.slice(0, 5))\n }, [settings])\n\n const parsed = Number(percent.replace(',', '.'))\n const valid = Number.isFinite(parsed) && parsed >= 0 && parsed <= 100\n const dirty = settings != null && (\n parsed !== settings.serviceChargePercent\n || pin !== settings.cancelRequiresPin\n || dayStart !== settings.operationalDayStart.slice(0, 5)\n )\n\n async function save() {\n setSaving(true)\n try {\n await saveSettings({\n serviceChargePercent: parsed,\n cancelRequiresPin: pin,\n operationalDayStart: dayStart,\n })\n } finally { setSaving(false) }\n }\n\n return (\n <div className=\"space-y-4\">\n <Section\n title=\"Taxa de serviço\"\n description=\"A taxa da casa. Cada mesa e cada participante podem ter a sua, e o que estiver em branco herda desta.\"\n >\n <div className=\"flex items-center gap-2\">\n {/* Largura no INVÓLUCRO: o `Input` se desenha dentro de um `div.w-full`\n próprio, e sem isto o \"%\" era empurrado para o outro lado da tela. */}\n <span className=\"w-28 shrink-0\">\n <Input value={percent} onChange={(e) => setPercent(e.target.value)}\n inputMode=\"decimal\" aria-label=\"Taxa de serviço da casa\" />\n </span>\n <span className=\"text-sm text-muted-foreground\">%</span>\n </div>\n {!valid && percent !== '' && (\n <p className=\"mt-1.5 text-xs text-destructive\">Informe um número entre 0 e 100.</p>\n )}\n {/* O porquê de isto existir: até aqui a taxa era uma constante no código\n do app, desenhada só no rodapé do painel — a fatura levantada no\n fechamento não a via. */}\n <p className=\"mt-2 text-xs text-muted-foreground\">\n Entra na comanda e na fatura levantada no fechamento.\n </p>\n </Section>\n\n <Section\n title=\"Cancelamento\"\n description=\"Quem pode cancelar item vem do perfil de acesso. Aqui fica o que a tela pergunta na hora.\"\n >\n <label className=\"flex items-start gap-3\">\n <Switch checked={pin} onCheckedChange={setPin} aria-label=\"Exigir PIN para cancelar\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm\">Exigir PIN para cancelar</span>\n {/* Desligado por padrão de propósito: o V1 exige senha de 6 dígitos\n sempre, criada em OUTRA tela por OUTRA pessoa, e quem esquece\n descobre no meio do serviço. */}\n <span className=\"block text-xs text-muted-foreground\">\n O terminal do salão fica logado a noite inteira, e nem sempre quem\n cancela é quem está logado. Ligado, o cancelamento pede o PIN de\n alguém com permissão.\n </span>\n </span>\n </label>\n </Section>\n\n <Section\n title=\"Motivos de cancelamento\"\n description=\"O que aparece na hora de tirar um item da comanda — e o que alimenta o ranking do que a cozinha mais devolveu.\"\n >\n <div className=\"flex gap-2\">\n <Input\n value={newReason}\n onChange={(e) => setNewReason(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && newReason.trim()) {\n void addCancelReason(newReason.trim()); setNewReason('')\n }\n }}\n placeholder=\"Ex.: saiu errado da cozinha, cliente trocou o pedido…\"\n />\n <Button variant=\"outline\" disabled={!newReason.trim()}\n onClick={() => { void addCancelReason(newReason.trim()); setNewReason('') }}>\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n\n <ul className=\"mt-3 space-y-1\">\n {reasons.map((r) => (\n <li key={r.id} className=\"flex items-center gap-2 rounded px-2 py-1.5 hover:bg-muted/50\">\n <span className=\"min-w-0 flex-1 truncate text-sm\">{r.label}</span>\n {/* O selo É botão. Desativar preserva o histórico e tira o motivo\n da vista; a lixeira apaga. */}\n <button\n type=\"button\"\n onClick={() => void updateCancelReason(r.id, { isActive: !r.isActive })}\n className={`rounded-full border px-2 py-0.5 text-xs transition-colors ${\n r.isActive\n ? 'border-success/40 bg-success/10 text-success'\n : 'border-border text-muted-foreground'\n }`}\n >\n {r.isActive ? 'Ativo' : 'Inativo'}\n </button>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-7 w-7\"\n aria-label={`Excluir ${r.label}`} onClick={() => void deleteCancelReason(r.id)}>\n <Trash2 className=\"h-3.5 w-3.5 text-destructive\" />\n </Button>\n </li>\n ))}\n {reasons.length === 0 && (\n <li className=\"py-3 text-sm text-muted-foreground\">\n Nenhum motivo cadastrado. Sem eles, quem cancela escreve o motivo à mão.\n </li>\n )}\n </ul>\n </Section>\n\n <Section\n title=\"Dia operacional\"\n description=\"O dia do restaurante não é o dia do calendário: começar de madrugada mantém a virada no turno a que ela pertence.\"\n >\n <span className=\"inline-block w-32\">\n <Input type=\"time\" value={dayStart} onChange={(e) => setDayStart(e.target.value)}\n aria-label=\"Início do dia operacional\" />\n </span>\n </Section>\n\n <div className=\"flex justify-end\">\n <Button onClick={save} disabled={!dirty || !valid || saving}>\n {saving ? 'Salvando…' : 'Salvar'}\n </Button>\n </div>\n </div>\n )\n}\n"]}