@infinitech.maps/st-map 1.0.18 → 1.0.19
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/README.md +226 -0
- package/dist/index.js +17898 -17457
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# @infinitech.maps/st-map
|
|
2
|
+
|
|
3
|
+
SDK de React para renderizar mapas interactivos de SmartTicket con selección de asientos, mesas y secciones.
|
|
4
|
+
|
|
5
|
+
## Instalación
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @infinitech.maps/st-map
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Peer dependencies:** `react >=18` y `react-dom >=18`.
|
|
12
|
+
|
|
13
|
+
## Uso básico
|
|
14
|
+
|
|
15
|
+
```jsx
|
|
16
|
+
import { STMap } from "@infinitech.maps/st-map";
|
|
17
|
+
|
|
18
|
+
function App() {
|
|
19
|
+
return (
|
|
20
|
+
<STMap
|
|
21
|
+
map={mapData}
|
|
22
|
+
onSeatClick={(seat, shape, event) => {
|
|
23
|
+
console.log(seat, shape);
|
|
24
|
+
}}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Props
|
|
31
|
+
|
|
32
|
+
| Prop | Tipo | Descripción |
|
|
33
|
+
|------|------|-------------|
|
|
34
|
+
| `map` | `object` | **Requerido.** Objeto JSON del mapa (formato v2 o legacy). |
|
|
35
|
+
| `onSeatClick` | `(seat, shape, event) => void` | Callback al hacer clic en un asiento, silla o mesa. |
|
|
36
|
+
| `onSectionClick` | `(shape, event) => void` | Callback al hacer clic en una sección/categoría completa. |
|
|
37
|
+
| `prices` | `Record<string, number>` | Mapa de precios por UUID (ver sección de precios). |
|
|
38
|
+
| `selectedSeats` | `string[]` | Lista de UUIDs seleccionados (modo controlado). |
|
|
39
|
+
| `reservedSeats` | `string[]` | Lista de UUIDs de asientos reservados. |
|
|
40
|
+
| `selectedSeatColor` | `string` | Color de asientos seleccionados. Default: `"#01FFFF"`. |
|
|
41
|
+
| `reservedSeatColor` | `string` | Color de asientos reservados. Default: `"#FF0000"`. |
|
|
42
|
+
| `purchasedSeatColor` | `string` | Color de asientos comprados. Default: `"#000000"`. |
|
|
43
|
+
| `hoverColor` | `string` | Color al pasar el cursor. Default: `"#444"`. |
|
|
44
|
+
| `hoverTransition` | `number` | Duración de la transición hover en ms. Default: `0`. |
|
|
45
|
+
| `onReady` | `() => void` | Callback cuando el mapa termina de renderizar. |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Obtener el UUID y precio de un elemento
|
|
50
|
+
|
|
51
|
+
Al hacer clic en cualquier elemento reservable (asiento, silla o mesa), el SDK invoca el callback `onSeatClick` con tres argumentos. El **UUID** y el **precio** se obtienen del primer argumento (`seat`):
|
|
52
|
+
|
|
53
|
+
### `onSeatClick(seat, shape, event)`
|
|
54
|
+
|
|
55
|
+
| Argumento | Descripción |
|
|
56
|
+
|-----------|-------------|
|
|
57
|
+
| `seat` | Objeto del asiento/mesa seleccionado. Contiene `id` (UUID) y `price` (si hay precio asignado). |
|
|
58
|
+
| `shape` | Objeto de la forma padre (fila, mesa, sector). Contiene metadatos como `category`, `section`, `sectorName`, etc. |
|
|
59
|
+
| `event` | Evento de Konva (canvas). |
|
|
60
|
+
|
|
61
|
+
#### Propiedades clave de `seat`
|
|
62
|
+
|
|
63
|
+
| Propiedad | Tipo | Descripción |
|
|
64
|
+
|-----------|------|-------------|
|
|
65
|
+
| `seat.id` | `string` | **UUID** único del elemento seleccionado. |
|
|
66
|
+
| `seat.price` | `number \| undefined` | **Precio** resuelto. Presente solo si se pasó la prop `prices` y existe un precio para este elemento. Si no hay precio, esta propiedad **no existe**. |
|
|
67
|
+
| `seat.name` | `string` | Nombre visible del asiento (ej. `"A01"`). |
|
|
68
|
+
| `seat.row` | `string \| number` | Fila del asiento. |
|
|
69
|
+
| `seat.column` | `number` | Columna del asiento. |
|
|
70
|
+
| `seat.status` | `string` | Estado: `"vacant"`, `"reserved"`, `"purchased"`. |
|
|
71
|
+
| `seat.isTable` | `boolean` | `true` cuando se selecciona una mesa completa (modo mesa). |
|
|
72
|
+
| `seat.tableName` | `string` | Nombre de la mesa (solo si `isTable` es `true`). |
|
|
73
|
+
| `seat.chairs` | `array` | Lista de sillas de la mesa (solo si `isTable` es `true`). |
|
|
74
|
+
| `seat.totalChairs` | `number` | Total de sillas en la mesa (solo si `isTable` es `true`). |
|
|
75
|
+
|
|
76
|
+
### Ejemplo: obtener UUID y precio
|
|
77
|
+
|
|
78
|
+
```jsx
|
|
79
|
+
import { STMap } from "@infinitech.maps/st-map";
|
|
80
|
+
|
|
81
|
+
function MapView({ mapData }) {
|
|
82
|
+
const prices = {
|
|
83
|
+
// UUID de categoría, sector o asiento individual → precio
|
|
84
|
+
"d5195a0a-2e6f-4167-a930-b26440d1e072": 150, // Categoría "VIP"
|
|
85
|
+
"702fdfc0-3a10-48a5-861c-0ddddac1bf7f": 50, // Categoría "General"
|
|
86
|
+
"58a5497e-eb75-445a-a89c-dc0fbe652d38": 500, // Asiento específico
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const handleSeatClick = (seat, shape, event) => {
|
|
90
|
+
// UUID del elemento
|
|
91
|
+
const uuid = seat.id;
|
|
92
|
+
|
|
93
|
+
// Precio (puede ser undefined si no se configuró)
|
|
94
|
+
const precio = seat.price;
|
|
95
|
+
|
|
96
|
+
console.log("UUID:", uuid);
|
|
97
|
+
console.log("Precio:", precio !== undefined ? precio : "Sin precio asignado");
|
|
98
|
+
|
|
99
|
+
// Ejemplo: agregar al carrito
|
|
100
|
+
if (seat.isTable) {
|
|
101
|
+
console.log(`Mesa "${seat.tableName}" con ${seat.totalChairs} sillas`);
|
|
102
|
+
} else {
|
|
103
|
+
console.log(`Asiento ${seat.name}, fila ${seat.row}`);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<STMap
|
|
109
|
+
map={mapData}
|
|
110
|
+
prices={prices}
|
|
111
|
+
onSeatClick={handleSeatClick}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### `onSectionClick(shape, event)`
|
|
118
|
+
|
|
119
|
+
Para secciones/categorías completas (formas geométricas sin asientos individuales):
|
|
120
|
+
|
|
121
|
+
| Propiedad | Tipo | Descripción |
|
|
122
|
+
|-----------|------|-------------|
|
|
123
|
+
| `shape.id` | `string` | **UUID** de la sección. |
|
|
124
|
+
| `shape.price` | `number \| undefined` | **Precio** resuelto (si existe). |
|
|
125
|
+
| `shape.category` | `string` | ID de la categoría. |
|
|
126
|
+
| `shape.categoryName` | `string` | Nombre de la categoría. |
|
|
127
|
+
| `shape.section` | `string` | ID del sector. |
|
|
128
|
+
| `shape.sectorName` | `string` | Nombre del sector. |
|
|
129
|
+
|
|
130
|
+
```jsx
|
|
131
|
+
const handleSectionClick = (shape, event) => {
|
|
132
|
+
console.log("UUID sección:", shape.id);
|
|
133
|
+
console.log("Precio:", shape.price !== undefined ? shape.price : "Sin precio");
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
<STMap
|
|
137
|
+
map={mapData}
|
|
138
|
+
prices={prices}
|
|
139
|
+
onSeatClick={handleSeatClick}
|
|
140
|
+
onSectionClick={handleSectionClick}
|
|
141
|
+
/>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Resolución jerárquica de precios
|
|
147
|
+
|
|
148
|
+
Cuando se pasa la prop `prices`, el SDK resuelve el precio de forma jerárquica buscando en este orden:
|
|
149
|
+
|
|
150
|
+
1. **Asiento individual** → `prices[seat.id]`
|
|
151
|
+
2. **Sector** → `prices[shape.section]`
|
|
152
|
+
3. **Categoría** → `prices[shape.category]`
|
|
153
|
+
|
|
154
|
+
El primer match encontrado se asigna como `seat.price` (o `shape.price` en secciones).
|
|
155
|
+
|
|
156
|
+
Si se proporcionan `prices` pero no se encuentra precio en ningún nivel, el SDK muestra una alerta y **no permite la selección** del elemento.
|
|
157
|
+
|
|
158
|
+
Si **no** se pasa la prop `prices`, no hay validación de precio y todos los elementos son seleccionables.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Console log integrado
|
|
163
|
+
|
|
164
|
+
El SDK incluye un log automático en la consola del navegador cada vez que se hace clic en un elemento reservable:
|
|
165
|
+
|
|
166
|
+
Para **asientos/mesas** (`onSeatClick`):
|
|
167
|
+
```js
|
|
168
|
+
[ST-Map] Seat click {
|
|
169
|
+
uuid: "58a5497e-eb75-445a-a89c-dc0fbe652d38",
|
|
170
|
+
price: 500,
|
|
171
|
+
row: "A",
|
|
172
|
+
column: 1,
|
|
173
|
+
category: "VIP",
|
|
174
|
+
section: "Sector 1"
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Para **secciones** (`onSectionClick`):
|
|
179
|
+
```js
|
|
180
|
+
[ST-Map] Section click {
|
|
181
|
+
uuid: "3b1633c9-57d0-4438-b952-95c213f98e29",
|
|
182
|
+
price: 200,
|
|
183
|
+
category: "General",
|
|
184
|
+
section: "Sector 2"
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Si un campo no existe en el elemento (ej. fila/columna en mesas), se muestra `"N/A"`. Si no hay precio, se muestra `"sin precio"`.
|
|
189
|
+
|
|
190
|
+
Esto facilita la depuración durante el desarrollo.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Selección controlada
|
|
195
|
+
|
|
196
|
+
Por defecto el SDK gestiona la selección internamente. Para controlarla externamente, pasa `selectedSeats`:
|
|
197
|
+
|
|
198
|
+
```jsx
|
|
199
|
+
const [selected, setSelected] = useState([]);
|
|
200
|
+
|
|
201
|
+
const handleSeatClick = (seat) => {
|
|
202
|
+
setSelected((prev) =>
|
|
203
|
+
prev.includes(seat.id)
|
|
204
|
+
? prev.filter((id) => id !== seat.id)
|
|
205
|
+
: [...prev, seat.id]
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
<STMap
|
|
210
|
+
map={mapData}
|
|
211
|
+
selectedSeats={selected}
|
|
212
|
+
onSeatClick={handleSeatClick}
|
|
213
|
+
/>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## STMapClient
|
|
219
|
+
|
|
220
|
+
Cliente HTTP para interactuar con la API de gestión de asientos:
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
import { STMapClient } from "@infinitech.maps/st-map";
|
|
224
|
+
|
|
225
|
+
const client = new STMapClient({ baseUrl: "https://api.example.com" });
|
|
226
|
+
```
|