seat-editor 3.3.13 → 3.3.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/app/constant.d.ts +1 -0
- package/dist/app/constant.js +1 -0
- package/dist/app/layout.d.ts +6 -0
- package/dist/app/layout.jsx +27 -0
- package/dist/app/new-board/page.jsx +55 -0
- package/dist/app/old-board/page.d.ts +3 -0
- package/dist/app/old-board/page.jsx +510 -0
- package/dist/app/only-view/chair.d.ts +1 -0
- package/dist/app/only-view/chair.js +12 -0
- package/dist/app/only-view/constant.d.ts +60 -0
- package/dist/app/only-view/constant.js +1336 -0
- package/dist/app/only-view/page.jsx +248 -0
- package/dist/app/only-view/user.d.ts +1 -0
- package/dist/app/only-view/user.js +12 -0
- package/dist/app/page.d.ts +2 -0
- package/dist/app/page.jsx +13 -0
- package/dist/app/test/page.d.ts +2 -0
- package/dist/app/test/page.jsx +45 -0
- package/dist/app/v2/page.d.ts +2 -0
- package/dist/app/v2/page.jsx +13 -0
- package/dist/components/button-tools/index.d.ts +11 -0
- package/dist/components/button-tools/index.jsx +17 -0
- package/dist/components/form-tools/label.d.ts +2 -0
- package/dist/components/form-tools/label.jsx +63 -0
- package/dist/components/form-tools/shape.d.ts +8 -0
- package/dist/components/form-tools/shape.jsx +113 -0
- package/dist/components/input/number-indicator.d.ts +7 -0
- package/dist/components/input/number-indicator.jsx +36 -0
- package/dist/components/joystick/index.d.ts +12 -0
- package/dist/components/joystick/index.jsx +49 -0
- package/dist/components/layer/index.d.ts +19 -0
- package/dist/components/layer/index.jsx +383 -0
- package/dist/components/layer-v2/index.d.ts +19 -0
- package/dist/components/layer-v2/index.jsx +370 -0
- package/dist/components/layer-v3/index.d.ts +13 -0
- package/dist/components/layer-v3/index.jsx +631 -0
- package/dist/components/layer-v3/utils.d.ts +19 -0
- package/dist/components/layer-v3/utils.js +72 -0
- package/dist/components/layer-v4/constant.d.ts +60 -0
- package/dist/components/layer-v4/constant.js +93 -0
- package/dist/components/layer-v4/index.d.ts +24 -0
- package/dist/components/layer-v4/index.jsx +1046 -0
- package/dist/components/lib/index.d.ts +8 -0
- package/dist/components/lib/index.jsx +33 -0
- package/dist/components/modal-preview/index.d.ts +4 -0
- package/dist/components/modal-preview/index.jsx +11 -0
- package/dist/dto/event-handler.d.ts +1 -0
- package/dist/dto/event-handler.js +1 -0
- package/dist/dto/table.d.ts +80 -0
- package/dist/dto/table.js +1 -0
- package/dist/features/board/board-slice.d.ts +14 -0
- package/dist/features/board/board-slice.js +52 -0
- package/dist/features/board/index.d.ts +6 -0
- package/dist/features/board/index.jsx +725 -0
- package/dist/features/board-v2/board-slice.d.ts +14 -0
- package/dist/features/board-v2/board-slice.js +52 -0
- package/dist/features/board-v2/index.d.ts +8 -0
- package/dist/features/board-v2/index.jsx +869 -0
- package/dist/features/board-v3/board-slice.d.ts +19 -0
- package/dist/features/board-v3/board-slice.js +274 -0
- package/dist/features/board-v3/constant.d.ts +5 -0
- package/dist/features/board-v3/constant.js +5 -0
- package/dist/features/board-v3/history-slice.d.ts +27 -0
- package/dist/features/board-v3/history-slice.js +27 -0
- package/dist/features/board-v3/icons.d.ts +4 -0
- package/dist/features/board-v3/icons.jsx +100 -0
- package/dist/features/board-v3/index.d.ts +16 -0
- package/dist/features/board-v3/index.jsx +1678 -0
- package/dist/features/board-v3/polygon.d.ts +28 -0
- package/dist/features/board-v3/polygon.js +109 -0
- package/dist/features/board-v3/rect.d.ts +9 -0
- package/dist/features/board-v3/rect.js +152 -0
- package/dist/features/board-v3/resize-element.d.ts +12 -0
- package/dist/features/board-v3/resize-element.js +43 -0
- package/dist/features/board-v3/utils.d.ts +180 -0
- package/dist/features/board-v3/utils.js +1235 -0
- package/dist/features/navbar/index.d.ts +2 -0
- package/dist/features/navbar/index.jsx +5 -0
- package/dist/features/panel/index.d.ts +6 -0
- package/dist/features/panel/index.jsx +251 -0
- package/dist/features/panel/panel-slice.d.ts +23 -0
- package/dist/features/panel/panel-slice.js +46 -0
- package/dist/features/panel/select-tool.d.ts +6 -0
- package/dist/features/panel/select-tool.jsx +70 -0
- package/dist/features/panel/selected-group.d.ts +2 -0
- package/dist/features/panel/selected-group.jsx +93 -0
- package/dist/features/panel/square-circle-tool.d.ts +2 -0
- package/dist/features/panel/square-circle-tool.jsx +10 -0
- package/dist/features/panel/table-seat-circle.d.ts +2 -0
- package/dist/features/panel/table-seat-circle.jsx +36 -0
- package/dist/features/panel/table-seat-square.d.ts +2 -0
- package/dist/features/panel/table-seat-square.jsx +51 -0
- package/dist/features/panel/text-tool.d.ts +2 -0
- package/dist/features/panel/text-tool.jsx +57 -0
- package/dist/features/panel/upload-tool.d.ts +10 -0
- package/dist/features/panel/upload-tool.jsx +176 -0
- package/dist/features/panel/utils.d.ts +5 -0
- package/dist/features/panel/utils.js +47 -0
- package/dist/features/side-tool/index.d.ts +8 -0
- package/dist/features/side-tool/index.jsx +390 -0
- package/dist/features/side-tool/side-tool-slice.d.ts +16 -0
- package/dist/features/side-tool/side-tool-slice.js +28 -0
- package/dist/features/theme/theme-slice.d.ts +12 -0
- package/dist/features/theme/theme-slice.js +15 -0
- package/dist/features/view-only/index.d.ts +19 -0
- package/dist/features/view-only/index.jsx +205 -0
- package/dist/features/view-only-2/index.d.ts +19 -0
- package/dist/features/view-only-2/index.jsx +190 -0
- package/dist/features/view-only-3/index.d.ts +89 -0
- package/dist/features/view-only-3/index.jsx +590 -0
- package/dist/features/view-only-3/utils.d.ts +1 -0
- package/dist/features/view-only-3/utils.js +3 -0
- package/dist/hooks/use-redux.d.ts +4 -0
- package/dist/hooks/use-redux.js +3 -0
- package/dist/index.js +10 -0
- package/dist/libs/middleware.d.ts +2 -0
- package/dist/libs/middleware.js +5 -0
- package/dist/libs/rootReducer.d.ts +12 -0
- package/dist/libs/rootReducer.js +14 -0
- package/dist/libs/store.d.ts +18 -0
- package/dist/libs/store.js +19 -0
- package/dist/provider/antd-provider.d.ts +4 -0
- package/dist/provider/antd-provider.jsx +46 -0
- package/dist/provider/redux-provider.d.ts +3 -0
- package/dist/provider/redux-provider.jsx +6 -0
- package/dist/provider/store-provider.d.ts +4 -0
- package/dist/provider/store-provider.jsx +10 -0
- package/dist/utils/constant.d.ts +3 -0
- package/dist/utils/constant.js +13 -0
- package/dist/utils/format.d.ts +2 -0
- package/dist/utils/format.js +29 -0
- package/dist/utils/injectCss.d.ts +1 -0
- package/dist/utils/injectCss.js +13 -0
- package/dist/utils/regex.d.ts +3 -0
- package/dist/utils/regex.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import LayerView from "../../features/view-only-3";
|
|
3
|
+
import { useState, useRef } from "react";
|
|
4
|
+
import { data4, test1 } from "../constant";
|
|
5
|
+
import { ChairIcon } from "./chair";
|
|
6
|
+
import { UserIcon } from "./user";
|
|
7
|
+
import { Modal } from "antd";
|
|
8
|
+
import JsonView from "@uiw/react-json-view";
|
|
9
|
+
export const dummyImage = [
|
|
10
|
+
{
|
|
11
|
+
id: "1747388267450",
|
|
12
|
+
x: 368,
|
|
13
|
+
y: 77.54706573486328,
|
|
14
|
+
width: 751.9405198530717,
|
|
15
|
+
height: 812,
|
|
16
|
+
rotation: 0,
|
|
17
|
+
shape: "background",
|
|
18
|
+
src: "https://cdn.table.link/prod/5bf923de-2366-4a11-9b8b-e92de0afbf05/3a65cb36-7d85-4c38-9403-a15f94641920/68d45207-d66b-4bb5-92a2-4e5a87715e98/rsvp/1753965985769725756_BOI Reg.png",
|
|
19
|
+
fill: "#bca16a",
|
|
20
|
+
opacity: 1,
|
|
21
|
+
labels: [
|
|
22
|
+
{
|
|
23
|
+
label: "T22",
|
|
24
|
+
fontColor: "#0d0c0c",
|
|
25
|
+
x: 0,
|
|
26
|
+
fontSize: 16,
|
|
27
|
+
y: 8,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
// {
|
|
32
|
+
// x: 100,
|
|
33
|
+
// y: 520,
|
|
34
|
+
// labels: [
|
|
35
|
+
// {
|
|
36
|
+
// x: 0,
|
|
37
|
+
// y: 27,
|
|
38
|
+
// label: "New Table 5",
|
|
39
|
+
// fontSize: 12,
|
|
40
|
+
// fontColor: "#0d0c0c",
|
|
41
|
+
// },
|
|
42
|
+
// ],
|
|
43
|
+
// id: "1761194669729132000",
|
|
44
|
+
// stroke: "#347ADB", //warna border
|
|
45
|
+
// fill: "#E1F4FF", //warna latar belakang
|
|
46
|
+
// strokeWidth: 1,
|
|
47
|
+
// text: "",
|
|
48
|
+
// shape: "background",
|
|
49
|
+
// width: 100,
|
|
50
|
+
// height: 100,
|
|
51
|
+
// gapTags: 10, //gap antara tags secara vertical,
|
|
52
|
+
// tags: [
|
|
53
|
+
// {
|
|
54
|
+
// key: "table", //key untuk penamaan tag
|
|
55
|
+
// items: [
|
|
56
|
+
// {
|
|
57
|
+
// type: "text", //tipe text atau icon
|
|
58
|
+
// value: "V1", //value untuk text atau icon
|
|
59
|
+
// fontSize: 14,
|
|
60
|
+
// fontWeight: 600,
|
|
61
|
+
// fill: "#3F4254",
|
|
62
|
+
// },
|
|
63
|
+
// ],
|
|
64
|
+
// direction: "flex", // flex untuk horizontal dan column untuk vertikal
|
|
65
|
+
// gap: 2, //gap antara item
|
|
66
|
+
// offsetX: 0, //offset x antara item
|
|
67
|
+
// offsetY: 0, //offset y antara item
|
|
68
|
+
// },
|
|
69
|
+
// {
|
|
70
|
+
// key: "rsvp_time",
|
|
71
|
+
// items: [
|
|
72
|
+
// {
|
|
73
|
+
// value: "11:00",
|
|
74
|
+
// type: "text",
|
|
75
|
+
// fill: "#5E6278",
|
|
76
|
+
// fontSize: 11,
|
|
77
|
+
// fontWeight: 700,
|
|
78
|
+
// textDecoration: "underline",
|
|
79
|
+
// },
|
|
80
|
+
// {
|
|
81
|
+
// value: "20:00",
|
|
82
|
+
// type: "text",
|
|
83
|
+
// fill: "#5E6278",
|
|
84
|
+
// fontSize: 11,
|
|
85
|
+
// fontWeight: 400,
|
|
86
|
+
// },
|
|
87
|
+
// ],
|
|
88
|
+
// direction: "column",
|
|
89
|
+
// gap: 2,
|
|
90
|
+
// },
|
|
91
|
+
// {
|
|
92
|
+
// key: "rsvp_time",
|
|
93
|
+
// items: [
|
|
94
|
+
// {
|
|
95
|
+
// value: "01:00",
|
|
96
|
+
// type: "text",
|
|
97
|
+
// fill: "#5E6278",
|
|
98
|
+
// fontSize: 11,
|
|
99
|
+
// fontWeight: 400,
|
|
100
|
+
// symbol: {
|
|
101
|
+
// value: "+1",
|
|
102
|
+
// gap: 8,
|
|
103
|
+
// fontSize: 9,
|
|
104
|
+
// position: "right-top", // right | right-top | right-bottom | left | left-top | left-bottom | top | bottom
|
|
105
|
+
// },
|
|
106
|
+
// },
|
|
107
|
+
// ],
|
|
108
|
+
// direction: "flex",
|
|
109
|
+
// gap: 10,
|
|
110
|
+
// offsetX: -3,
|
|
111
|
+
// offsetY: -8,
|
|
112
|
+
// },
|
|
113
|
+
// ],
|
|
114
|
+
// opacity: 1,
|
|
115
|
+
// rotation: 90,
|
|
116
|
+
// seatCount: 10,
|
|
117
|
+
// openSpace: 0.3,
|
|
118
|
+
// seatFill: "#ed8989",
|
|
119
|
+
// seatPositions: {
|
|
120
|
+
// top: 3,
|
|
121
|
+
// bottom: 3,
|
|
122
|
+
// left: 3,
|
|
123
|
+
// right: 3,
|
|
124
|
+
// },
|
|
125
|
+
// },
|
|
126
|
+
];
|
|
127
|
+
const Card = (item) => {
|
|
128
|
+
const handleDragStart = (e) => {
|
|
129
|
+
// Jangan preventDefault di drag start
|
|
130
|
+
e.dataTransfer.setData("application/json", JSON.stringify(item));
|
|
131
|
+
e.dataTransfer.effectAllowed = "move";
|
|
132
|
+
};
|
|
133
|
+
return (<div className="h-40 bg-gray-400 shadow-lg rounded-lg p-4 m-4" data-table={JSON.stringify(item)} draggable onContextMenu={(e) => e.preventDefault()} onDragStart={handleDragStart} // ✅ ini yang benar
|
|
134
|
+
onClick={(e) => e.stopPropagation()} onPointerDown={(e) => e.stopPropagation()}>
|
|
135
|
+
<h2 className="text-lg font-semibold mb-2">Card Title</h2>
|
|
136
|
+
<p className="text-gray-600">{item === null || item === void 0 ? void 0 : item.name}</p>
|
|
137
|
+
</div>);
|
|
138
|
+
};
|
|
139
|
+
const TouchScrollDetect = () => {
|
|
140
|
+
const refLayer = useRef(null);
|
|
141
|
+
const [open, setOpen] = useState(false);
|
|
142
|
+
const [table, setTable] = useState(null);
|
|
143
|
+
const handleZoomIn = () => {
|
|
144
|
+
var _a, _b;
|
|
145
|
+
(_b = (_a = refLayer === null || refLayer === void 0 ? void 0 : refLayer.current) === null || _a === void 0 ? void 0 : _a.transformRef) === null || _b === void 0 ? void 0 : _b.zoomIn(0.1);
|
|
146
|
+
};
|
|
147
|
+
const handleZoomOut = () => {
|
|
148
|
+
var _a, _b;
|
|
149
|
+
(_b = (_a = refLayer === null || refLayer === void 0 ? void 0 : refLayer.current) === null || _a === void 0 ? void 0 : _a.transformRef) === null || _b === void 0 ? void 0 : _b.zoomOut();
|
|
150
|
+
};
|
|
151
|
+
const handleSwitch = (e, data) => {
|
|
152
|
+
console.log("hswith");
|
|
153
|
+
setOpen(!open);
|
|
154
|
+
setTable(data);
|
|
155
|
+
};
|
|
156
|
+
const handleDrop = (e, data) => {
|
|
157
|
+
var _a;
|
|
158
|
+
console.log("data drop", data);
|
|
159
|
+
const targetData = (_a = data === null || data === void 0 ? void 0 : data.targetTable) === null || _a === void 0 ? void 0 : _a.test;
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
setOpen(!open);
|
|
162
|
+
setTable(data);
|
|
163
|
+
};
|
|
164
|
+
const handleSelectTable = (item) => {
|
|
165
|
+
setOpen(!open);
|
|
166
|
+
setTable(item);
|
|
167
|
+
};
|
|
168
|
+
const renderModal = () => {
|
|
169
|
+
return (<Modal open={open} onCancel={() => setOpen(false)} width={700} title="Preview Board" centered footer={null}>
|
|
170
|
+
<div className="flex flex-col p-4 h-[500px] overflow-auto">
|
|
171
|
+
<JsonView value={table}/>
|
|
172
|
+
</div>
|
|
173
|
+
</Modal>);
|
|
174
|
+
};
|
|
175
|
+
return (<div className="w-full h-screen border-2 border-black overflow-auto" id="scroll-container">
|
|
176
|
+
{renderModal()}
|
|
177
|
+
<div className="flex">
|
|
178
|
+
<div className="h-screen bg-gray-500 w-1/3">
|
|
179
|
+
<div className="p-4">
|
|
180
|
+
{data4.map((item, index) => (<Card key={index} {...item}/>))}
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
<div className="h-screen w-2/3 relative">
|
|
184
|
+
<div className="absolute top-1 right-1 flex gap-4 z-[10]">
|
|
185
|
+
<button className="p-4 bg-gray-400" onClick={() => handleZoomIn()}>
|
|
186
|
+
+
|
|
187
|
+
</button>
|
|
188
|
+
<button className="p-4 bg-gray-400" onClick={() => handleZoomOut()}>
|
|
189
|
+
-
|
|
190
|
+
</button>
|
|
191
|
+
</div>
|
|
192
|
+
<LayerView refs={refLayer} statusKey="is_hold" privilegedTags={[
|
|
193
|
+
{
|
|
194
|
+
key: "table",
|
|
195
|
+
items: ["text", "icon"],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
key: "rsvp_time",
|
|
199
|
+
items: ["text", "icon"],
|
|
200
|
+
},
|
|
201
|
+
]} defaultBackground="#000000" mappingKey="properties" componentProps={test1} onDrop={(e, data) => handleDrop(e, data)} onSwitch={(e, data) => handleSwitch(e, data)} extraComponentProps={[]} onSelectComponent={(component) => {
|
|
202
|
+
handleSelectTable(component);
|
|
203
|
+
}}
|
|
204
|
+
// dragTableBlockKey={[
|
|
205
|
+
// {
|
|
206
|
+
// key: "is_lock",
|
|
207
|
+
// value: 1,
|
|
208
|
+
// },
|
|
209
|
+
// ]}
|
|
210
|
+
tableMatchKey={[
|
|
211
|
+
{
|
|
212
|
+
key: 0,
|
|
213
|
+
properties: { fill: "white" },
|
|
214
|
+
className: "blink-2",
|
|
215
|
+
},
|
|
216
|
+
]} eventMatchTable={[
|
|
217
|
+
{
|
|
218
|
+
event: "mouseenter",
|
|
219
|
+
properties: {
|
|
220
|
+
strokeWidth: 5,
|
|
221
|
+
filter: "drop-shadow(0px 0px 5px red)",
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
event: "dragenter",
|
|
226
|
+
properties: { strokeWidth: 5 },
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
event: "selected",
|
|
230
|
+
properties: { strokeWidth: 5 },
|
|
231
|
+
},
|
|
232
|
+
]} iconTags={[
|
|
233
|
+
{
|
|
234
|
+
icon: <ChairIcon />,
|
|
235
|
+
key: "chair",
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
icon: <UserIcon />,
|
|
239
|
+
key: "user",
|
|
240
|
+
},
|
|
241
|
+
]} viewStyles={{
|
|
242
|
+
paddingTop: 200,
|
|
243
|
+
}} disabled={false} transformProps={{}}/>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
</div>);
|
|
247
|
+
};
|
|
248
|
+
export default TouchScrollDetect;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function UserIcon(): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const UserIcon = () => {
|
|
2
|
+
return (<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M7.61992 10.1625C9.00754 10.1625 10.1324 9.03757 10.1324 7.64995C10.1324 6.26234 9.00754 5.13745 7.61992 5.13745C6.23231 5.13745 5.10742 6.26234 5.10742 7.64995C5.10742 9.03757 6.23231 10.1625 7.61992 10.1625Z" fill="#5E6278"/>
|
|
4
|
+
<path d="M7.62 14.9999C9.34313 14.9999 10.74 14.1168 10.74 13.0274C10.74 11.9381 9.34313 11.0549 7.62 11.0549C5.89687 11.0549 4.5 11.9381 4.5 13.0274C4.5 14.1168 5.89687 14.9999 7.62 14.9999Z" fill="#5E6278"/>
|
|
5
|
+
<path opacity="0.3" d="M11.595 4.23C12.7631 4.23 13.71 3.28308 13.71 2.115C13.71 0.946918 12.7631 0 11.595 0C10.4269 0 9.47998 0.946918 9.47998 2.115C9.47998 3.28308 10.4269 4.23 11.595 4.23Z" fill="#5E6278"/>
|
|
6
|
+
<path opacity="0.3" d="M3.62257 4.23C4.79065 4.23 5.73757 3.28308 5.73757 2.115C5.73757 0.946918 4.79065 0 3.62257 0C2.45449 0 1.50757 0.946918 1.50757 2.115C1.50757 3.28308 2.45449 4.23 3.62257 4.23Z" fill="#5E6278"/>
|
|
7
|
+
<g opacity="0.3">
|
|
8
|
+
<path d="M11.4749 5.87256C11.2349 5.87256 11.0024 5.87256 10.7699 5.91006C11.1229 6.52313 11.2825 7.22856 11.2276 7.93388C11.1727 8.63919 10.906 9.31147 10.4624 9.86256C10.7984 9.92909 11.1399 9.96424 11.4824 9.96756C13.3874 9.96756 14.9249 9.04506 14.9249 7.92006C14.9249 6.79506 13.3799 5.87256 11.4749 5.87256Z" fill="#5E6278"/>
|
|
9
|
+
<path d="M3.4499 6C3.6899 6 3.9224 6 4.1549 6.0375C3.80187 6.65057 3.64233 7.356 3.6972 8.06132C3.75208 8.76664 4.0188 9.43891 4.4624 9.99C4.12639 10.0565 3.78492 10.0917 3.4424 10.095C1.5374 10.095 -9.77516e-05 9.1725 -9.77516e-05 8.0475C-9.77516e-05 6.9225 1.5449 6 3.4499 6Z" fill="#5E6278"/>
|
|
10
|
+
</g>
|
|
11
|
+
</svg>);
|
|
12
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Board from "../features/board-v3";
|
|
2
|
+
import SideTool from "../features/side-tool";
|
|
3
|
+
import ControlPanels from "../features/panel";
|
|
4
|
+
const TableEditor = () => {
|
|
5
|
+
return (<>
|
|
6
|
+
<div className="w-full h-screen flex relative">
|
|
7
|
+
<SideTool />
|
|
8
|
+
<Board />
|
|
9
|
+
<ControlPanels />
|
|
10
|
+
</div>
|
|
11
|
+
</>);
|
|
12
|
+
};
|
|
13
|
+
export default TableEditor;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useRef, useState } from "react";
|
|
3
|
+
export default function DraggableRect() {
|
|
4
|
+
const rectRef = useRef(null);
|
|
5
|
+
const [pos, setPos] = useState({ x: 100, y: 100 });
|
|
6
|
+
const [dragging, setDragging] = useState(false);
|
|
7
|
+
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
8
|
+
const getCoords = (e) => {
|
|
9
|
+
if ("touches" in e) {
|
|
10
|
+
return {
|
|
11
|
+
x: e.touches[0].clientX,
|
|
12
|
+
y: e.touches[0].clientY,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
x: e.clientX,
|
|
17
|
+
y: e.clientY,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const handleStart = (e) => {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
const coords = getCoords(e);
|
|
23
|
+
setOffset({
|
|
24
|
+
x: coords.x - pos.x,
|
|
25
|
+
y: coords.y - pos.y,
|
|
26
|
+
});
|
|
27
|
+
setDragging(true);
|
|
28
|
+
};
|
|
29
|
+
const handleMove = (e) => {
|
|
30
|
+
if (!dragging)
|
|
31
|
+
return;
|
|
32
|
+
const coords = getCoords(e);
|
|
33
|
+
setPos({
|
|
34
|
+
x: coords.x - offset.x,
|
|
35
|
+
y: coords.y - offset.y,
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
const handleEnd = () => {
|
|
39
|
+
setDragging(false);
|
|
40
|
+
};
|
|
41
|
+
return (<svg width="100%" height="500" viewBox="0 0 800 600" style={{ border: "1px solid black", touchAction: "none" }} // important!
|
|
42
|
+
onMouseMove={handleMove} onMouseUp={handleEnd} onTouchMove={handleMove} onTouchEnd={handleEnd}>
|
|
43
|
+
<rect ref={rectRef} x={pos.x} y={pos.y} width="150" height="100" fill="tomato" onMouseDown={handleStart} onTouchStart={handleStart} style={{ cursor: "grab" }}/>
|
|
44
|
+
</svg>);
|
|
45
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Board from "../../features/board-v2";
|
|
2
|
+
import SideTool from "../../features/side-tool";
|
|
3
|
+
import ControlPanels from "../../features/panel";
|
|
4
|
+
const TableEditor = () => {
|
|
5
|
+
return (<>
|
|
6
|
+
<div className="w-full h-screen flex relative">
|
|
7
|
+
<SideTool />
|
|
8
|
+
<Board />
|
|
9
|
+
<ControlPanels />
|
|
10
|
+
</div>
|
|
11
|
+
</>);
|
|
12
|
+
};
|
|
13
|
+
export default TableEditor;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ButtonProps, PopoverProps } from "antd";
|
|
2
|
+
interface ButtonToolsProps {
|
|
3
|
+
buttonProps: ButtonProps;
|
|
4
|
+
items: Array<{
|
|
5
|
+
label: string;
|
|
6
|
+
onClick: () => void;
|
|
7
|
+
}>;
|
|
8
|
+
popoverProps?: PopoverProps;
|
|
9
|
+
}
|
|
10
|
+
declare const ButtonTools: (props: ButtonToolsProps) => import("react").JSX.Element;
|
|
11
|
+
export default ButtonTools;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button, Popover } from "antd";
|
|
3
|
+
const ButtonTools = (props) => {
|
|
4
|
+
const { buttonProps, items, popoverProps } = props;
|
|
5
|
+
if (items.length === 0) {
|
|
6
|
+
return (<Popover trigger="hover" {...popoverProps}>
|
|
7
|
+
<Button {...buttonProps}/>
|
|
8
|
+
</Popover>);
|
|
9
|
+
}
|
|
10
|
+
return (<Popover content={<div>
|
|
11
|
+
<Button>Button 1</Button>
|
|
12
|
+
<Button>Button 2</Button>
|
|
13
|
+
</div>} trigger="click">
|
|
14
|
+
<Button {...buttonProps}/>
|
|
15
|
+
</Popover>);
|
|
16
|
+
};
|
|
17
|
+
export default ButtonTools;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button, ColorPicker, Flex, Form, Input, InputNumber } from "antd";
|
|
3
|
+
const SectionLabel = () => {
|
|
4
|
+
return (<div className="py-2">
|
|
5
|
+
<h1 className="heading-s">Section Labeling</h1>
|
|
6
|
+
<Form.Item label="Labels in square" name={"labels"}>
|
|
7
|
+
<Form.List name="labels">
|
|
8
|
+
{(fields, { add, remove }) => (<>
|
|
9
|
+
{fields.map((field) => (<div key={field.key}>
|
|
10
|
+
<Flex gap={2}>
|
|
11
|
+
<Form.Item name={[field.name, "label"]} label="Text">
|
|
12
|
+
<Input />
|
|
13
|
+
</Form.Item>
|
|
14
|
+
<Form.Item name={[field.name, "fontColor"]} label="Color" getValueFromEvent={(color) => color.toHexString()}>
|
|
15
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
16
|
+
</Form.Item>
|
|
17
|
+
</Flex>
|
|
18
|
+
<Flex gap={2}>
|
|
19
|
+
<Form.Item name={[field.name, "x"]} label="X">
|
|
20
|
+
<InputNumber />
|
|
21
|
+
</Form.Item>
|
|
22
|
+
<Form.Item name={[field.name, "y"]} label="Y">
|
|
23
|
+
<InputNumber />
|
|
24
|
+
</Form.Item>
|
|
25
|
+
</Flex>
|
|
26
|
+
<Flex gap={2}>
|
|
27
|
+
<Form.Item name={[field.name, "fontSize"]} label="Size">
|
|
28
|
+
<InputNumber suffix="px"/>
|
|
29
|
+
</Form.Item>
|
|
30
|
+
<Form.Item name={[field.name, "rotation"]} label="Rotation">
|
|
31
|
+
<InputNumber suffix="°" min={0} max={360} parser={(value) => {
|
|
32
|
+
if (!value)
|
|
33
|
+
return 0;
|
|
34
|
+
const num = Number(value.replace(/\D/g, ""));
|
|
35
|
+
if (Number.isNaN(num))
|
|
36
|
+
return 0;
|
|
37
|
+
return Math.min(360, Math.max(0, num));
|
|
38
|
+
}}/>
|
|
39
|
+
</Form.Item>
|
|
40
|
+
</Flex>
|
|
41
|
+
</div>))}
|
|
42
|
+
<Flex gap={2}>
|
|
43
|
+
<Button type="primary" onClick={() => add({
|
|
44
|
+
label: "",
|
|
45
|
+
fontColor: "#000000",
|
|
46
|
+
x: 0,
|
|
47
|
+
y: 0,
|
|
48
|
+
fontSize: 12,
|
|
49
|
+
rotation: 0
|
|
50
|
+
})} className="btn btn-primary">
|
|
51
|
+
Add
|
|
52
|
+
</Button>
|
|
53
|
+
<Button type="primary" onClick={() => remove(fields.length - 1)} className="btn btn-primary">
|
|
54
|
+
Remove
|
|
55
|
+
</Button>
|
|
56
|
+
</Flex>
|
|
57
|
+
</>)}
|
|
58
|
+
</Form.List>
|
|
59
|
+
</Form.Item>
|
|
60
|
+
<div className="divider-dashed"/>
|
|
61
|
+
</div>);
|
|
62
|
+
};
|
|
63
|
+
export default SectionLabel;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ColorPicker, Flex, Form, InputNumber, Select } from "antd";
|
|
3
|
+
export const optionsShape = [
|
|
4
|
+
{
|
|
5
|
+
value: "circle",
|
|
6
|
+
label: "Circle",
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
value: "square",
|
|
10
|
+
label: "Square",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
value: "table-seat-circle",
|
|
14
|
+
label: "Type 1",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
value: "table-seat-square",
|
|
18
|
+
label: "Type 2",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
value: "table-seat-half-square",
|
|
22
|
+
label: "Type 3",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
value: "table-seat-rect-square",
|
|
26
|
+
label: "Type 4",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
value: "table-seat-rect-circle",
|
|
30
|
+
label: "Type 5",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
label: "Image Table",
|
|
34
|
+
value: "image-table",
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
const SectionShape = ({ allowChangeShape = true, }) => {
|
|
38
|
+
const shape = Form.useWatch("shape");
|
|
39
|
+
return (<div className="py-2">
|
|
40
|
+
<h1 className="heading-s">Shape</h1>
|
|
41
|
+
{allowChangeShape && (<Flex gap={2} className="w-full">
|
|
42
|
+
<Form.Item label="Name" name="shape" className="w-full">
|
|
43
|
+
<Select options={optionsShape} className="w-full"/>
|
|
44
|
+
</Form.Item>
|
|
45
|
+
</Flex>)}
|
|
46
|
+
<Flex gap={2} className="w-full">
|
|
47
|
+
<Form.Item label="Width" name="width" className="w-full">
|
|
48
|
+
<InputNumber suffix="px" controls parser={(value) => {
|
|
49
|
+
var _a;
|
|
50
|
+
const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
|
|
51
|
+
return onlyNumber === "" ? 1 : Math.max(1, Number(onlyNumber));
|
|
52
|
+
}}/>
|
|
53
|
+
</Form.Item>
|
|
54
|
+
<Form.Item label="Height" name="height" className="w-full">
|
|
55
|
+
<InputNumber suffix="px" parser={(value) => {
|
|
56
|
+
var _a;
|
|
57
|
+
const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
|
|
58
|
+
return onlyNumber === "" ? 1 : Math.max(1, Number(onlyNumber));
|
|
59
|
+
}}/>
|
|
60
|
+
</Form.Item>
|
|
61
|
+
</Flex>
|
|
62
|
+
<Flex gap={2}>
|
|
63
|
+
<Form.Item label="Position X" name="x" className="w-full">
|
|
64
|
+
<InputNumber />
|
|
65
|
+
</Form.Item>
|
|
66
|
+
<Form.Item label="Position Y" name="y" className="w-full">
|
|
67
|
+
<InputNumber />
|
|
68
|
+
</Form.Item>
|
|
69
|
+
<Form.Item label="Rotation" name="rotation" className="w-full">
|
|
70
|
+
<InputNumber suffix="°" min={0} max={360} parser={(value) => {
|
|
71
|
+
if (!value)
|
|
72
|
+
return 0;
|
|
73
|
+
const num = Number(value.replace(/\D/g, ""));
|
|
74
|
+
if (Number.isNaN(num))
|
|
75
|
+
return 0;
|
|
76
|
+
return Math.min(360, Math.max(0, num));
|
|
77
|
+
}}/>
|
|
78
|
+
</Form.Item>
|
|
79
|
+
</Flex>
|
|
80
|
+
<Flex gap={2}>
|
|
81
|
+
<Form.Item label="Fill" name={"fill"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
|
|
82
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
83
|
+
</Form.Item>
|
|
84
|
+
<Form.Item label="Stroke" name={"stroke"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
|
|
85
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
86
|
+
</Form.Item>
|
|
87
|
+
</Flex>
|
|
88
|
+
<Flex>
|
|
89
|
+
<Form.Item label="Stroke" name={"strokeWidth"} className="w-full">
|
|
90
|
+
<InputNumber />
|
|
91
|
+
</Form.Item>
|
|
92
|
+
{!(shape === null || shape === void 0 ? void 0 : shape.includes("circle")) && (<Form.Item label="Radius" name="radius" className="w-full">
|
|
93
|
+
<InputNumber suffix="px" parser={(value) => {
|
|
94
|
+
var _a;
|
|
95
|
+
const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
|
|
96
|
+
return onlyNumber === "" ? 1 : Math.max(1, Number(onlyNumber));
|
|
97
|
+
}}/>
|
|
98
|
+
</Form.Item>)}
|
|
99
|
+
<Form.Item label="opacity" name={"opacity"} className="w-full">
|
|
100
|
+
<InputNumber step={0.1} max={1} min={0} parser={(value) => {
|
|
101
|
+
if (value === undefined || value === null || value === "")
|
|
102
|
+
return null;
|
|
103
|
+
const cleaned = value.replace(/[^0-9.]/g, "");
|
|
104
|
+
const num = Number(cleaned);
|
|
105
|
+
if (Number.isNaN(num))
|
|
106
|
+
return null;
|
|
107
|
+
return Math.min(1, Math.max(0, num));
|
|
108
|
+
}}/>
|
|
109
|
+
</Form.Item>
|
|
110
|
+
</Flex>
|
|
111
|
+
</div>);
|
|
112
|
+
};
|
|
113
|
+
export default SectionShape;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface NumberIndicatorProps {
|
|
2
|
+
name: string;
|
|
3
|
+
defaultValue?: number;
|
|
4
|
+
onChange: (value: number) => void;
|
|
5
|
+
}
|
|
6
|
+
declare const NumberIndicator: ({ name, defaultValue, onChange }: NumberIndicatorProps) => import("react").JSX.Element;
|
|
7
|
+
export default NumberIndicator;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { Input, Button, Flex, Form } from "antd";
|
|
4
|
+
import { ArrowRight, ArrowLeft } from "lucide-react";
|
|
5
|
+
const NumberIndicator = ({ name, defaultValue, onChange }) => {
|
|
6
|
+
const [value, setValue] = useState(0);
|
|
7
|
+
const form = Form.useFormInstance();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (defaultValue) {
|
|
10
|
+
setValue(defaultValue);
|
|
11
|
+
form.setFieldsValue({ [name]: defaultValue });
|
|
12
|
+
}
|
|
13
|
+
}, [defaultValue]);
|
|
14
|
+
const handlePrev = () => {
|
|
15
|
+
setValue(value - 1);
|
|
16
|
+
form.setFieldsValue({ [name]: value - 1 });
|
|
17
|
+
onChange(value - 1);
|
|
18
|
+
};
|
|
19
|
+
const handleNext = () => {
|
|
20
|
+
setValue(value + 1);
|
|
21
|
+
form.setFieldsValue({ [name]: value + 1 });
|
|
22
|
+
onChange(value + 1);
|
|
23
|
+
};
|
|
24
|
+
return (<Flex gap={2}>
|
|
25
|
+
<Button onClick={handlePrev}>
|
|
26
|
+
<ArrowLeft />
|
|
27
|
+
</Button>
|
|
28
|
+
<Form.Item name={name} noStyle>
|
|
29
|
+
<Input className="flex text-center" type="number" value={value} name={name} onChange={(e) => setValue(parseInt(e.target.value))}/>
|
|
30
|
+
</Form.Item>
|
|
31
|
+
<Button onClick={handleNext}>
|
|
32
|
+
<ArrowRight />
|
|
33
|
+
</Button>
|
|
34
|
+
</Flex>);
|
|
35
|
+
};
|
|
36
|
+
export default NumberIndicator;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
type JoystickPosition = {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
};
|
|
6
|
+
type JoystickProps = {
|
|
7
|
+
size?: number;
|
|
8
|
+
onMove?: (pos: JoystickPosition) => void;
|
|
9
|
+
onEnd?: () => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const Joystick: ({ size, onMove, onEnd, }: JoystickProps) => React.JSX.Element;
|
|
12
|
+
export {};
|