@zauru-sdk/components 2.0.119 → 2.0.121

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.
@@ -1,28 +1,46 @@
1
- import React, { useState } from "react";
1
+ import React, { useState, useRef } from "react";
2
2
  import { createRoot } from "react-dom/client";
3
3
 
4
4
  // Tipos de datos
5
5
  type Item = {
6
+ item_id: string;
6
7
  name: string;
7
8
  code: string;
8
9
  unitPrice: number;
9
10
  stock: number;
10
11
  currencyPrefix: string;
11
12
  imageUrl: string;
13
+ quantity: number;
14
+ flexiblePrice: boolean;
15
+ priceText: string;
12
16
  };
13
17
 
14
- type ItemCategory = { name: string; items: Item[] };
18
+ export type ItemModalCategory = { name: string; items: Item[] };
19
+
20
+ type OnCloseType = (selectedItem: Item | null) => void;
15
21
 
16
22
  type ItemModalProps = {
17
- itemList: ItemCategory[];
18
- onClose: (selectedItem: Item | null) => void;
19
- config?: { itemSize: { width: string; height: string } }; // Tamaño configurable
23
+ itemList: ItemModalCategory[];
24
+ onClose: OnCloseType;
25
+ config?: {
26
+ itemSize?: {
27
+ width: string;
28
+ height: string;
29
+ };
30
+ };
31
+ /**
32
+ * Controla cómo se muestran las categorías.
33
+ * - "text": Estilo por defecto (un simple título con flecha).
34
+ * - "card": Tarjeta más grande y ancha, útil para pantallas táctiles (tablet).
35
+ */
36
+ categoryViewMode?: "text" | "card";
20
37
  };
21
38
 
22
39
  const ItemSelectionModal: React.FC<ItemModalProps> = ({
23
40
  itemList,
24
41
  onClose,
25
42
  config,
43
+ categoryViewMode = "text",
26
44
  }) => {
27
45
  const defaultConfig = {
28
46
  itemSize: {
@@ -35,17 +53,12 @@ const ItemSelectionModal: React.FC<ItemModalProps> = ({
35
53
  const [expandedCategories, setExpandedCategories] = useState<{
36
54
  [key: string]: boolean;
37
55
  }>({});
56
+ const [selectedItem, setSelectedItem] = useState<Item | null>(null);
57
+ const [quantity, setQuantity] = useState<number>(1);
58
+ const [customPrice, setCustomPrice] = useState<number | null>(null);
38
59
 
39
- const toggleCategory = (categoryName: string) => {
40
- setExpandedCategories((prev) => ({
41
- ...prev,
42
- [categoryName]: !prev[categoryName],
43
- }));
44
- };
45
-
46
- const handleItemClick = (item: Item) => {
47
- onClose(item);
48
- };
60
+ // Ref para forzar el scroll al tope cuando seleccionamos un ítem
61
+ const modalContentRef = useRef<HTMLDivElement>(null);
49
62
 
50
63
  const filteredList = itemList
51
64
  .map((category) => ({
@@ -60,96 +73,336 @@ const ItemSelectionModal: React.FC<ItemModalProps> = ({
60
73
  category.items.length > 0
61
74
  );
62
75
 
76
+ const toggleCategory = (categoryName: string) => {
77
+ setExpandedCategories((prev) => ({
78
+ ...prev,
79
+ [categoryName]: !prev[categoryName],
80
+ }));
81
+ };
82
+
83
+ const handleItemClick = (item: Item) => {
84
+ setSelectedItem(item);
85
+ setQuantity(1);
86
+ // Si el ítem tiene precio flexible, inicializamos el customPrice con su precio actual
87
+ setCustomPrice(item.flexiblePrice ? item.unitPrice : null);
88
+
89
+ // Forzar scroll a la parte superior del contenido, ya que antes se iniciaba el scroll desde donde se había quedado.
90
+ if (modalContentRef.current) {
91
+ modalContentRef.current.scrollTo({ top: 0, behavior: "smooth" });
92
+ }
93
+ };
94
+
95
+ const handleConfirmQuantity = () => {
96
+ if (selectedItem) {
97
+ // (5) Devolver el precio correcto
98
+ const finalPrice = selectedItem.flexiblePrice
99
+ ? // si el precio es flexible, tomar lo que el usuario haya ingresado (o fallback al precio original)
100
+ customPrice ?? selectedItem.unitPrice
101
+ : // si NO es flexible, solo usamos el precio que ya tenía
102
+ selectedItem.unitPrice;
103
+
104
+ onClose({
105
+ ...selectedItem,
106
+ quantity,
107
+ unitPrice: finalPrice,
108
+ });
109
+ }
110
+ };
111
+
112
+ const handleCancelQuantity = () => {
113
+ setSelectedItem(null);
114
+ setQuantity(1);
115
+ setCustomPrice(null);
116
+ };
117
+
118
+ const handleCloseModal = () => {
119
+ onClose(null);
120
+ };
121
+
63
122
  return (
64
- <div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50">
65
- <div className="bg-white p-4 rounded-lg shadow-lg w-11/12 max-w-4xl h-5/6 overflow-y-auto">
123
+ <div
124
+ className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50"
125
+ onClick={handleCloseModal}
126
+ >
127
+ <div
128
+ //Le ponemos ref para poder scrollear al tope
129
+ ref={modalContentRef}
130
+ className="bg-white p-4 rounded-lg shadow-lg w-11/12 max-w-4xl h-5/6 overflow-y-auto"
131
+ onClick={(e) => e.stopPropagation()}
132
+ >
66
133
  {/* Header */}
67
- <div className="flex flex-col mb-4">
68
- <div className="flex justify-between items-center mb-4">
69
- <h2 className="text-2xl font-bold">Seleccionar un Ítem</h2>
70
- <button
71
- className="text-gray-500 hover:text-gray-800"
72
- onClick={() => onClose(null)}
73
- >
74
- &times;
75
- </button>
76
- </div>
77
- {/* Barra de búsqueda */}
78
- <input
79
- type="text"
80
- placeholder="Buscar por nombre o categoría..."
81
- value={searchTerm}
82
- onChange={(e) => setSearchTerm(e.target.value)}
83
- className="p-2 border rounded-lg w-full"
84
- />
134
+ <div className="flex justify-between items-center mb-4">
135
+ <h2 className="text-2xl font-bold">
136
+ {selectedItem ? "Confirmar selección" : "Seleccionar un Ítem"}
137
+ </h2>
138
+ <button
139
+ className="text-gray-500 hover:text-gray-800 text-3xl"
140
+ onClick={handleCloseModal}
141
+ >
142
+ &times;
143
+ </button>
85
144
  </div>
86
145
 
87
- {/* Lista de categorías e ítems */}
88
- {filteredList.length === 0 ? (
89
- <p className="text-gray-500 text-center">
90
- No se encontraron resultados.
91
- </p>
92
- ) : (
93
- filteredList.map((category) => (
94
- <div key={category.name} className="mb-4">
95
- <h3
96
- className="text-lg font-semibold mb-2 cursor-pointer flex justify-between items-center hover:text-blue-600"
97
- onClick={() => toggleCategory(category.name)}
98
- >
99
- <span>
100
- {category.name}{" "}
101
- <span className="text-gray-500">
102
- ({category.items.length})
103
- </span>
104
- </span>
105
- <span
106
- className={`transform transition-transform duration-200 ${
107
- expandedCategories[category.name] ? "rotate-90" : ""
108
- }`}
109
- >
110
-
111
- </span>
112
- </h3>
113
- {expandedCategories[category.name] && (
114
- <div
115
- className="grid gap-5"
116
- style={{
117
- gridTemplateColumns: `repeat(auto-fit, minmax(${defaultConfig.itemSize.width}, 1fr))`,
118
- }}
146
+ {/*
147
+ Render condicional:
148
+ - Si NO hay item seleccionado => mostramos la búsqueda + listado de ítems.
149
+ - Si YA hay un item seleccionado => mostramos selector de cantidad y (si aplica) selector de precio.
150
+ */}
151
+ {!selectedItem ? (
152
+ /* ==============================
153
+ PASO 1: SELECCIONAR ÍTEM
154
+ ============================== */
155
+ <>
156
+ {/* Barra de búsqueda */}
157
+ <div className="relative mb-4">
158
+ <input
159
+ type="text"
160
+ placeholder="Buscar por nombre o categoría..."
161
+ value={searchTerm}
162
+ onChange={(e) => setSearchTerm(e.target.value)}
163
+ className="p-2 border rounded-lg w-full"
164
+ />
165
+ {searchTerm && (
166
+ <button
167
+ className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-800"
168
+ onClick={() => setSearchTerm("")}
119
169
  >
120
- {category.items.map((item) => (
170
+ &times;
171
+ </button>
172
+ )}
173
+ </div>
174
+
175
+ {/* Lista de categorías e ítems */}
176
+ {filteredList.length === 0 ? (
177
+ <p className="text-gray-500 text-center">
178
+ No se encontraron resultados.
179
+ </p>
180
+ ) : (
181
+ filteredList.map((category) => {
182
+ const isExpanded = expandedCategories[category.name];
183
+
184
+ // Estilos condicionales para "text" vs. "card"
185
+ const categoryContainerClasses =
186
+ categoryViewMode === "card"
187
+ ? "w-full mb-2 px-4 py-3 bg-blue-50 rounded-md flex justify-between items-center cursor-pointer hover:bg-blue-100"
188
+ : "text-lg font-semibold mb-2 cursor-pointer flex justify-between items-center hover:text-blue-600";
189
+
190
+ return (
191
+ <div key={category.name} className="mb-4">
192
+ {/* Cabecera de la categoría (texto o card) */}
121
193
  <div
122
- key={item.code}
123
- className="border rounded-lg shadow-lg hover:shadow-xl cursor-pointer relative"
124
- onClick={() => handleItemClick(item)}
125
- style={{
126
- backgroundImage: `url(${item.imageUrl})`,
127
- backgroundSize: "cover",
128
- backgroundPosition: "center",
129
- width: defaultConfig.itemSize.width,
130
- height: defaultConfig.itemSize.height,
131
- }}
194
+ className={categoryContainerClasses}
195
+ onClick={() => toggleCategory(category.name)}
132
196
  >
133
- <div className="bg-white bg-opacity-80 p-2 rounded absolute top-0 left-0 right-0">
134
- <h4 className="font-bold text-sm text-center">
135
- {item.name}
136
- </h4>
137
- </div>
138
- <div className="absolute bottom-0 left-0 bg-white bg-opacity-80 p-2 rounded">
139
- <span className="text-xs">Stock: {item.stock}</span>
140
- </div>
141
- <div className="absolute bottom-0 right-0 bg-white bg-opacity-80 p-2 rounded">
142
- <span className="text-xs">
143
- {item.currencyPrefix}
144
- {item.unitPrice}
197
+ <span>
198
+ {category.name}{" "}
199
+ <span className="text-gray-500">
200
+ ({category.items.length})
145
201
  </span>
146
- </div>
202
+ </span>
203
+ <span
204
+ className={`transform transition-transform duration-200 ${
205
+ isExpanded ? "rotate-90" : ""
206
+ }`}
207
+ >
208
+
209
+ </span>
147
210
  </div>
148
- ))}
211
+
212
+ {/* Ítems dentro de la categoría */}
213
+ {isExpanded && (
214
+ <div
215
+ className="grid gap-5"
216
+ style={{
217
+ gridTemplateColumns: `repeat(auto-fit, minmax(${defaultConfig.itemSize.width}, 1fr))`,
218
+ }}
219
+ >
220
+ {category.items.map((item) => {
221
+ // Verificamos si es un "paquete" usando item_id
222
+ const isPackage = item.item_id.startsWith("b");
223
+
224
+ return (
225
+ <div
226
+ key={item.code}
227
+ onClick={() => handleItemClick(item)}
228
+ className={`border rounded-lg shadow-lg hover:shadow-xl cursor-pointer relative ${
229
+ isPackage ? "bg-yellow-50" : ""
230
+ }`}
231
+ style={{
232
+ backgroundImage: `url(${item.imageUrl})`,
233
+ backgroundSize: "cover",
234
+ backgroundPosition: "center",
235
+ width: defaultConfig.itemSize.width,
236
+ height: defaultConfig.itemSize.height,
237
+ }}
238
+ >
239
+ {/* Franja superior (nombre) */}
240
+ <div
241
+ className={`p-2 rounded absolute top-0 left-0 right-0 ${
242
+ isPackage
243
+ ? "bg-yellow-300 text-black"
244
+ : "bg-white bg-opacity-80"
245
+ }`}
246
+ >
247
+ <h4 className="font-semibold text-sm text-center">
248
+ {item.name}
249
+ </h4>
250
+ </div>
251
+ <div
252
+ className={`absolute bottom-0 left-0 p-2 rounded ${
253
+ isPackage
254
+ ? "bg-yellow-300"
255
+ : "bg-white bg-opacity-80"
256
+ }`}
257
+ >
258
+ <span className="text-xs font-normal">
259
+ Stock: {item.stock}
260
+ </span>
261
+ </div>
262
+ <div
263
+ className={`absolute bottom-0 right-0 p-2 rounded ${
264
+ isPackage
265
+ ? "bg-yellow-300"
266
+ : "bg-white bg-opacity-80"
267
+ }`}
268
+ >
269
+ <span className="text-xs font-normal">
270
+ {item.currencyPrefix}
271
+ {item.priceText}
272
+ </span>
273
+ </div>
274
+ </div>
275
+ );
276
+ })}
277
+ </div>
278
+ )}
279
+ </div>
280
+ );
281
+ })
282
+ )}
283
+ </>
284
+ ) : (
285
+ /* ==============================
286
+ PASO 2: CONFIRMAR SELECCIÓN
287
+ ============================== */
288
+ <div className="flex flex-col items-center justify-center">
289
+ <img
290
+ src={selectedItem.imageUrl}
291
+ alt={selectedItem.name}
292
+ className="w-40 h-40 object-cover rounded mb-4 shadow-md"
293
+ />
294
+ <p className="mb-2 text-xl font-bold">{selectedItem.name}</p>
295
+ <p className="mb-2 text-base font-semibold text-gray-700">
296
+ Stock disponible:
297
+ <span className="ml-1 font-normal text-gray-800">
298
+ {selectedItem.stock}
299
+ </span>
300
+ </p>
301
+
302
+ {/* Si el ítem NO es flexible, mostramos el precio fijo */}
303
+ {!selectedItem.flexiblePrice && (
304
+ <p className="mb-4 text-base font-semibold text-gray-700">
305
+ Precio unitario:
306
+ <span className="ml-1 font-normal text-gray-800">
307
+ {selectedItem.currencyPrefix}
308
+ {selectedItem.priceText}
309
+ </span>
310
+ </p>
311
+ )}
312
+
313
+ {/*
314
+ Selector de cantidad
315
+ */}
316
+ <div className="mb-4 w-full max-w-sm flex flex-col items-center">
317
+ <p className="text-base font-semibold text-gray-700 mb-2">
318
+ Seleccionar cantidad
319
+ </p>
320
+ <div className="flex items-center space-x-4">
321
+ <button
322
+ className="bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400"
323
+ onClick={() =>
324
+ setQuantity((prev) => (prev > 1 ? prev - 1 : 1))
325
+ }
326
+ >
327
+ -
328
+ </button>
329
+ <input
330
+ className="w-16 text-center border rounded text-lg"
331
+ type="number"
332
+ min={1}
333
+ value={quantity}
334
+ onChange={(e) => {
335
+ const val = parseInt(e.target.value, 10);
336
+ setQuantity(isNaN(val) || val < 1 ? 1 : val);
337
+ }}
338
+ />
339
+ <button
340
+ className="bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400"
341
+ onClick={() => setQuantity((prev) => prev + 1)}
342
+ >
343
+ +
344
+ </button>
345
+ </div>
346
+ </div>
347
+
348
+ {/*
349
+ Si el ítem SÍ es flexible, ponemos un selector de precio
350
+ */}
351
+ {selectedItem.flexiblePrice && (
352
+ <div className="mb-4 w-full max-w-sm flex flex-col items-center">
353
+ <p className="text-base font-semibold text-gray-700 mb-2">
354
+ Seleccionar precio
355
+ </p>
356
+ <div className="flex items-center space-x-4">
357
+ <button
358
+ className="bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400"
359
+ onClick={() =>
360
+ setCustomPrice((prev) => {
361
+ const newVal = (prev ?? 0) - 1;
362
+ return newVal < 0 ? 0 : newVal;
363
+ })
364
+ }
365
+ >
366
+ -
367
+ </button>
368
+ <input
369
+ className="w-16 text-center border rounded text-lg"
370
+ type="number"
371
+ min={0}
372
+ value={customPrice ?? 0}
373
+ onChange={(e) => {
374
+ const val = parseInt(e.target.value, 10);
375
+ setCustomPrice(isNaN(val) || val < 0 ? 0 : val);
376
+ }}
377
+ />
378
+ <button
379
+ className="bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400"
380
+ onClick={() =>
381
+ setCustomPrice((prev) => (prev == null ? 1 : prev + 1))
382
+ }
383
+ >
384
+ +
385
+ </button>
149
386
  </div>
150
- )}
387
+ </div>
388
+ )}
389
+
390
+ {/* Botones de Confirmar y Volver */}
391
+ <div className="flex space-x-4 mt-6">
392
+ <button
393
+ className="bg-gray-300 px-4 py-2 rounded hover:bg-gray-400"
394
+ onClick={handleCancelQuantity}
395
+ >
396
+ Volver
397
+ </button>
398
+ <button
399
+ className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
400
+ onClick={handleConfirmQuantity}
401
+ >
402
+ Confirmar
403
+ </button>
151
404
  </div>
152
- ))
405
+ </div>
153
406
  )}
154
407
  </div>
155
408
  </div>
@@ -158,8 +411,9 @@ const ItemSelectionModal: React.FC<ItemModalProps> = ({
158
411
 
159
412
  // Función para crear el modal
160
413
  export const createItemModal = (
161
- itemList: ItemCategory[],
162
- config?: ItemModalProps["config"]
414
+ itemList: ItemModalCategory[],
415
+ config?: ItemModalProps["config"],
416
+ categoryViewMode?: ItemModalProps["categoryViewMode"]
163
417
  ): Promise<Item | null> => {
164
418
  return new Promise((resolve) => {
165
419
  const handleClose = (selectedItem: Item | null) => {
@@ -180,6 +434,7 @@ export const createItemModal = (
180
434
  itemList={itemList}
181
435
  onClose={handleClose}
182
436
  config={config}
437
+ categoryViewMode={categoryViewMode}
183
438
  />
184
439
  );
185
440
  });
@@ -12,7 +12,7 @@ import type {
12
12
  NavBarItem,
13
13
  NavBarProps,
14
14
  } from "./NavBar.types.js";
15
- import { Link, useNavigate } from "@remix-run/react";
15
+ import { Link, useNavigate, useLocation } from "@remix-run/react";
16
16
  import { useAppSelector } from "@zauru-sdk/redux";
17
17
 
18
18
  const OptionsDropDownButton = ({ color, options, name }: EntityProps) => {
@@ -52,6 +52,9 @@ const NavItem = ({
52
52
  childrens = [],
53
53
  reduxNotificationBadge,
54
54
  }: NavBarItem) => {
55
+ const location = useLocation();
56
+ const isActive = location.pathname === link;
57
+
55
58
  const specialColor: ColorInterface = selectedColor
56
59
  ? COLORS[selectedColor]
57
60
  : COLORS["slate"];
@@ -69,43 +72,51 @@ const NavItem = ({
69
72
  setNotificationBadge(relevantState);
70
73
  }, [relevantState]);
71
74
 
72
- return (
73
- <li className="nav-item relative">
74
- {childrens.length > 0 ? (
75
- <OptionsDropDownButton
76
- name={name}
77
- color={specialColor}
78
- options={childrens.map((x, index) => (
79
- <Link
80
- key={index}
81
- to={x.link}
82
- className={`block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`}
83
- >
84
- {x.name}
85
- </Link>
86
- ))}
87
- />
88
- ) : (
89
- <div
90
- className={`${specialColor.bg700} container text-white w-full sm:w-auto h-10 text-sm py-1 uppercase shadow hover:shadow-lg outline-none rounded-full focus:outline-none my-auto sm:my-0 sm:mr-1 mb-1 ease-linear transition-all duration-150`}
91
- >
75
+ // Si este NavItem tiene elementos hijos, renderiza el botón desplegable:
76
+ if (childrens.length > 0) {
77
+ return (
78
+ <OptionsDropDownButton
79
+ name={name}
80
+ color={specialColor}
81
+ options={childrens.map((x, index) => (
92
82
  <Link
93
- className="px-3 flex items-center text-xs leading-snug text-white uppercase hover:opacity-75 relative"
94
- to={link}
83
+ key={index}
84
+ to={x.link}
85
+ className={`block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`}
95
86
  >
96
- <div className="mx-auto pt-2">
97
- {icon}
98
- <span>{name}</span>
99
- </div>
100
- {/* Badge de notificaciones */}
101
- {notificationBadge !== undefined && (
102
- <span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center w-5 h-5">
103
- {notificationBadge}
104
- </span>
105
- )}
87
+ {x.name}
106
88
  </Link>
107
- </div>
108
- )}
89
+ ))}
90
+ />
91
+ );
92
+ }
93
+
94
+ // Si NO tiene elementos hijos, se renderiza como un ítem simple:
95
+ return (
96
+ <li className="nav-item relative">
97
+ <div
98
+ // Si está activo, usamos color de fondo más oscuro (bg900)
99
+ // De lo contrario, usamos el color normal (bg700)
100
+ className={`${
101
+ isActive ? specialColor.bg900 : specialColor.bg700
102
+ } container text-white w-full sm:w-auto h-10 text-sm py-1 uppercase shadow hover:shadow-lg outline-none rounded-full focus:outline-none my-auto sm:my-0 sm:mr-1 mb-1 ease-linear transition-all duration-150`}
103
+ >
104
+ <Link
105
+ className="px-3 flex items-center text-xs leading-snug text-white uppercase hover:opacity-75 relative"
106
+ to={link}
107
+ >
108
+ <div className="mx-auto pt-2">
109
+ {icon}
110
+ <span>{name}</span>
111
+ </div>
112
+ {/* Badge de notificaciones */}
113
+ {notificationBadge !== undefined && (
114
+ <span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center w-5 h-5">
115
+ {notificationBadge}
116
+ </span>
117
+ )}
118
+ </Link>
119
+ </div>
109
120
  </li>
110
121
  );
111
122
  };
@@ -165,6 +176,7 @@ export const NavBar = ({
165
176
  color={color}
166
177
  options={[
167
178
  <Link
179
+ key="cerrar-sesion"
168
180
  className={`block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`}
169
181
  to="/logout"
170
182
  >
@@ -187,19 +199,12 @@ export const NavBar = ({
187
199
  <Link
188
200
  className="text-sm font-bold leading-relaxed inline-block mr-4 py-2 whitespace-nowrap uppercase text-white"
189
201
  to={"/home"}
190
- children={
191
- <>
192
- <div className="inline-block mr-2 mb-2 align-middle">
193
- <img
194
- className="w-auto h-7"
195
- src="/logo.png"
196
- alt="logo-zauru"
197
- />
198
- </div>
199
- {title}
200
- </>
201
- }
202
- />
202
+ >
203
+ <div className="inline-block mr-2 mb-2 align-middle">
204
+ <img className="w-auto h-7" src="/logo.png" alt="logo-zauru" />
205
+ </div>
206
+ {title}
207
+ </Link>
203
208
  {version !== currentVersion && (
204
209
  <button
205
210
  className={`ml-2 px-2 py-1 text-xs text-white ${color.bg700} rounded-full hover:${color.bg900} transition-colors duration-200`}
@@ -3,7 +3,14 @@ export type NavBarItem = {
3
3
  link: string;
4
4
  loggedIn: boolean;
5
5
  icon?: any;
6
- selectedColor?: "green";
6
+ selectedColor?:
7
+ | "pink"
8
+ | "purple"
9
+ | "slate"
10
+ | "green"
11
+ | "yellow"
12
+ | "red"
13
+ | "sky";
7
14
  color?: ColorInterface;
8
15
  childrens?: Exclude<NavBarItem, "loggedIn">[];
9
16
  reduxNotificationBadge?: (state: any) => string | number;
@@ -35,6 +42,7 @@ export type ColorInterface = {
35
42
  bg700: string;
36
43
  bg600: string;
37
44
  bg500: string;
45
+ bg200: string;
38
46
  ring600: string;
39
47
  ring500: string;
40
48
  };