@axzydev/axzy_ui_system 1.2.6 → 1.2.7
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/index.cjs +246 -182
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +246 -182
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/grid/grid.tsx +7 -2
- package/src/components/layout/layout.tsx +14 -17
- package/src/components/navbar/navbar.tsx +51 -46
- package/src/components/page/page.props.ts +4 -0
- package/src/components/page/page.tsx +17 -7
- package/src/components/page-header/page-header.props.ts +2 -0
- package/src/components/page-header/page-header.stories.tsx +14 -0
- package/src/components/page-header/page-header.tsx +35 -15
- package/src/index.css +15 -0
- package/src/showcases/PageShowcases.tsx +465 -45
- package/src/showcases/StructureShowcases.tsx +205 -36
|
@@ -1,4 +1,33 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
FaUsers,
|
|
4
|
+
FaShoppingCart,
|
|
5
|
+
FaCog,
|
|
6
|
+
FaBoxOpen,
|
|
7
|
+
FaChartLine,
|
|
8
|
+
FaEdit,
|
|
9
|
+
FaTrash,
|
|
10
|
+
FaEye,
|
|
11
|
+
FaPlus,
|
|
12
|
+
FaDownload,
|
|
13
|
+
FaFilter,
|
|
14
|
+
FaSearch,
|
|
15
|
+
FaCheckCircle,
|
|
16
|
+
FaTimesCircle,
|
|
17
|
+
FaClock,
|
|
18
|
+
FaEnvelope,
|
|
19
|
+
FaPhone,
|
|
20
|
+
FaMapMarkerAlt,
|
|
21
|
+
FaBell,
|
|
22
|
+
FaSave,
|
|
23
|
+
FaSignOutAlt,
|
|
24
|
+
FaShieldAlt,
|
|
25
|
+
FaPalette,
|
|
26
|
+
FaLanguage,
|
|
27
|
+
FaDollarSign,
|
|
28
|
+
FaArrowUp,
|
|
29
|
+
FaArrowDown,
|
|
30
|
+
} from "react-icons/fa";
|
|
2
31
|
import ITPage from "../components/page/page";
|
|
3
32
|
import ITPageHeader from "../components/page-header/page-header";
|
|
4
33
|
import ITButton from "../components/button/button";
|
|
@@ -9,6 +38,7 @@ import ITStatCard from "../components/stat-card/stat-card";
|
|
|
9
38
|
import ITFlex from "../components/flex/flex";
|
|
10
39
|
import ITAvatar from "../components/avatar/avatar";
|
|
11
40
|
import ITSlideToggle from "../components/slide/slide";
|
|
41
|
+
import ITText from "@/components/text/text";
|
|
12
42
|
import { ShowcaseLayout } from "./ShowcaseLayout";
|
|
13
43
|
|
|
14
44
|
export const PageHeaderShowcase = () => {
|
|
@@ -16,10 +46,13 @@ export const PageHeaderShowcase = () => {
|
|
|
16
46
|
const [showBreadcrumbs, setShowBreadcrumbs] = useState(true);
|
|
17
47
|
const [showDescription, setShowDescription] = useState(true);
|
|
18
48
|
const [showActions, setShowActions] = useState(true);
|
|
49
|
+
const [showIcon, setShowIcon] = useState(true);
|
|
19
50
|
|
|
20
51
|
const code = `<ITPageHeader
|
|
21
52
|
title="Usuarios"
|
|
22
53
|
description="Gestiona los usuarios del sistema"
|
|
54
|
+
icon={<FaUsers size={20} />}
|
|
55
|
+
iconColor="#6366f1"
|
|
23
56
|
breadcrumbs={[
|
|
24
57
|
{ label: "Inicio", href: "#" },
|
|
25
58
|
{ label: "Usuarios" },
|
|
@@ -30,13 +63,15 @@ export const PageHeaderShowcase = () => {
|
|
|
30
63
|
return (
|
|
31
64
|
<ShowcaseLayout
|
|
32
65
|
title="ITPageHeader"
|
|
33
|
-
description="Encabezado estandarizado para pantallas. Incluye título, descripción, breadcrumbs, botón de volver y área de acciones."
|
|
66
|
+
description="Encabezado estandarizado para pantallas. Incluye título, descripción, icono, breadcrumbs, botón de volver y área de acciones."
|
|
34
67
|
code={code}
|
|
35
68
|
demo={
|
|
36
69
|
<div className="w-full border border-slate-200 dark:border-slate-700 rounded-xl p-6 bg-white dark:bg-slate-900/50">
|
|
37
70
|
<ITPageHeader
|
|
38
71
|
title="Usuarios"
|
|
39
72
|
description={showDescription ? "Gestiona los usuarios del sistema" : undefined}
|
|
73
|
+
icon={showIcon ? <FaUsers size={20} /> : undefined}
|
|
74
|
+
iconColor={showIcon ? "#6366f1" : undefined}
|
|
40
75
|
breadcrumbs={showBreadcrumbs ? [
|
|
41
76
|
{ label: "Inicio", href: "#" },
|
|
42
77
|
{ label: "Usuarios" },
|
|
@@ -60,6 +95,10 @@ export const PageHeaderShowcase = () => {
|
|
|
60
95
|
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Descripción</span>
|
|
61
96
|
<ITSlideToggle isOn={showDescription} onToggle={setShowDescription} size="sm" />
|
|
62
97
|
</ITFlex>
|
|
98
|
+
<ITFlex justify="between" align="center">
|
|
99
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Icono</span>
|
|
100
|
+
<ITSlideToggle isOn={showIcon} onToggle={setShowIcon} size="sm" />
|
|
101
|
+
</ITFlex>
|
|
63
102
|
<ITFlex justify="between" align="center">
|
|
64
103
|
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Acciones</span>
|
|
65
104
|
<ITSlideToggle isOn={showActions} onToggle={setShowActions} size="sm" />
|
|
@@ -110,6 +149,49 @@ export const PageHeaderShowcase = () => {
|
|
|
110
149
|
}
|
|
111
150
|
/>
|
|
112
151
|
</div>
|
|
152
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
|
|
153
|
+
<ITPageHeader
|
|
154
|
+
title="Usuarios"
|
|
155
|
+
description="Gestiona los usuarios del sistema"
|
|
156
|
+
icon={<FaUsers size={20} />}
|
|
157
|
+
iconColor="#6366f1"
|
|
158
|
+
/>
|
|
159
|
+
</div>
|
|
160
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
|
|
161
|
+
<ITPageHeader
|
|
162
|
+
title="Órdenes"
|
|
163
|
+
description="Listado de órdenes activas"
|
|
164
|
+
icon={<FaShoppingCart size={20} />}
|
|
165
|
+
iconColor="#f59e0b"
|
|
166
|
+
breadcrumbs={[
|
|
167
|
+
{ label: "Dashboard", href: "#" },
|
|
168
|
+
{ label: "Órdenes" },
|
|
169
|
+
]}
|
|
170
|
+
actions={<ITButton label="Nueva Orden" size="small" />}
|
|
171
|
+
/>
|
|
172
|
+
</div>
|
|
173
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
|
|
174
|
+
<ITPageHeader
|
|
175
|
+
title="Configuración"
|
|
176
|
+
description="Ajustes generales del sistema"
|
|
177
|
+
icon={<FaCog size={20} />}
|
|
178
|
+
iconColor="#10b981"
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
181
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
|
|
182
|
+
<ITPageHeader
|
|
183
|
+
title="Detalle del Producto"
|
|
184
|
+
description="Información completa del producto"
|
|
185
|
+
icon={<FaBoxOpen size={20} />}
|
|
186
|
+
iconColor="#ec4899"
|
|
187
|
+
backAction={() => {}}
|
|
188
|
+
breadcrumbs={[
|
|
189
|
+
{ label: "Productos", href: "#" },
|
|
190
|
+
{ label: "Detalle" },
|
|
191
|
+
]}
|
|
192
|
+
actions={<ITButton label="Editar" size="small" />}
|
|
193
|
+
/>
|
|
194
|
+
</div>
|
|
113
195
|
</ITStack>
|
|
114
196
|
}
|
|
115
197
|
/>
|
|
@@ -118,20 +200,20 @@ export const PageHeaderShowcase = () => {
|
|
|
118
200
|
|
|
119
201
|
export const PageShowcase = () => {
|
|
120
202
|
const [state, setState] = useState<"normal" | "loading" | "error" | "empty">("normal");
|
|
203
|
+
const [showIcon, setShowIcon] = useState(true);
|
|
121
204
|
|
|
122
205
|
const code = `<ITPage
|
|
123
206
|
title="Dashboard"
|
|
124
|
-
description="Resumen
|
|
125
|
-
|
|
207
|
+
description="Resumen general del sistema"
|
|
208
|
+
icon={<FaChartLine size={20} />}
|
|
209
|
+
iconColor="#6366f1"
|
|
210
|
+
breadcrumbs={[{ label: "Inicio", href: "#" }, { label: "Dashboard" }]}
|
|
126
211
|
loading={isLoading}
|
|
127
212
|
error={error}
|
|
213
|
+
empty={isEmpty}
|
|
128
214
|
onRetry={refetch}
|
|
129
215
|
>
|
|
130
|
-
|
|
131
|
-
<ITGrid item xs={12} sm={6} lg={3}>
|
|
132
|
-
<ITStatCard label="Usuarios" value="1,245" />
|
|
133
|
-
</ITGrid>
|
|
134
|
-
</ITGrid>
|
|
216
|
+
{/* KPIs, gráficos, listas, tablas... */}
|
|
135
217
|
</ITPage>`;
|
|
136
218
|
|
|
137
219
|
return (
|
|
@@ -140,67 +222,405 @@ export const PageShowcase = () => {
|
|
|
140
222
|
description="Template completo de página con estados: carga, error, vacío y contenido normal."
|
|
141
223
|
code={code}
|
|
142
224
|
demo={
|
|
143
|
-
<div className="w-full">
|
|
225
|
+
<div className="w-full border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
144
226
|
<ITPage
|
|
145
227
|
title="Dashboard"
|
|
146
|
-
description="Resumen
|
|
228
|
+
description="Resumen general del sistema en tiempo real"
|
|
229
|
+
icon={showIcon ? <FaChartLine size={20} /> : undefined}
|
|
230
|
+
iconColor={showIcon ? "#6366f1" : undefined}
|
|
147
231
|
breadcrumbs={[
|
|
232
|
+
{ label: "Inicio", href: "#" },
|
|
148
233
|
{ label: "Dashboard" },
|
|
149
234
|
]}
|
|
150
235
|
loading={state === "loading"}
|
|
151
|
-
error={state === "error" ? "
|
|
236
|
+
error={state === "error" ? "No se pudo conectar con el servidor. Verifica tu conexión a internet." : null}
|
|
237
|
+
errorTitle="Error de conexión"
|
|
152
238
|
onRetry={() => setState("normal")}
|
|
153
239
|
empty={state === "empty"}
|
|
154
|
-
emptyTitle="
|
|
155
|
-
emptyDescription="
|
|
240
|
+
emptyTitle="Aún no hay actividad"
|
|
241
|
+
emptyDescription="Cuando tus usuarios comiencen a generar actividad, verás las métricas aquí."
|
|
242
|
+
emptyAction={<ITButton label="Invitar usuarios" size="small" icon={<FaPlus />} />}
|
|
156
243
|
>
|
|
244
|
+
{/* KPIs */}
|
|
157
245
|
<ITGrid container spacing={3}>
|
|
158
246
|
<ITGrid item xs={12} sm={6} lg={3}>
|
|
159
|
-
<ITStatCard label="
|
|
247
|
+
<ITStatCard label="Ingresos del mes" value="$48,250" trend="+12.5%" trendDirection="up" />
|
|
160
248
|
</ITGrid>
|
|
161
249
|
<ITGrid item xs={12} sm={6} lg={3}>
|
|
162
|
-
<ITStatCard label="
|
|
250
|
+
<ITStatCard label="Usuarios activos" value="1,245" trend="+5.4%" trendDirection="up" color="bg-blue-50 dark:bg-blue-950/20" />
|
|
163
251
|
</ITGrid>
|
|
164
252
|
<ITGrid item xs={12} sm={6} lg={3}>
|
|
165
|
-
<ITStatCard label="Órdenes" value="89" trend="-2.1%" trendDirection="down" color="bg-amber-50 dark:bg-amber-950/20" />
|
|
253
|
+
<ITStatCard label="Órdenes pendientes" value="89" trend="-2.1%" trendDirection="down" color="bg-amber-50 dark:bg-amber-950/20" />
|
|
166
254
|
</ITGrid>
|
|
167
255
|
<ITGrid item xs={12} sm={6} lg={3}>
|
|
168
|
-
<ITStatCard label="Tickets" value="12" trend="-8%" trendDirection="down" color="bg-rose-50 dark:bg-rose-950/20" />
|
|
256
|
+
<ITStatCard label="Tickets abiertos" value="12" trend="-8%" trendDirection="down" color="bg-rose-50 dark:bg-rose-950/20" />
|
|
169
257
|
</ITGrid>
|
|
170
258
|
</ITGrid>
|
|
171
259
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
260
|
+
{/* Charts + Activity */}
|
|
261
|
+
<ITGrid container spacing={3}>
|
|
262
|
+
<ITGrid item xs={12} lg={8}>
|
|
263
|
+
<ITCard title="Ventas de los últimos 30 días">
|
|
264
|
+
<div className="h-48 flex items-end gap-2">
|
|
265
|
+
{[40, 65, 45, 80, 55, 90, 70, 85, 60, 95, 75, 50, 70, 85, 60, 90, 80, 95, 70, 85, 65, 90, 75, 88, 70, 92, 80, 96, 78, 90].map((h, i) => (
|
|
266
|
+
<div
|
|
267
|
+
key={i}
|
|
268
|
+
className="flex-1 bg-primary-500/60 dark:bg-primary-400/40 rounded-t-md hover:bg-primary-500 transition-all"
|
|
269
|
+
style={{ height: `${h}%` }}
|
|
270
|
+
/>
|
|
271
|
+
))}
|
|
272
|
+
</div>
|
|
273
|
+
<div className="flex items-center justify-between mt-4 pt-3 border-t border-slate-100 dark:border-slate-800">
|
|
274
|
+
<ITText className="text-xs text-slate-500">Total: $148,250</ITText>
|
|
275
|
+
<ITFlex gap={3} align="center">
|
|
276
|
+
<ITFlex gap={1.5} align="center">
|
|
277
|
+
<FaArrowUp className="text-emerald-500 text-xs" />
|
|
278
|
+
<span className="text-xs font-semibold text-emerald-600">+24.5%</span>
|
|
279
|
+
</ITFlex>
|
|
280
|
+
<span className="text-xs text-slate-400">vs mes anterior</span>
|
|
281
|
+
</ITFlex>
|
|
282
|
+
</div>
|
|
283
|
+
</ITCard>
|
|
284
|
+
</ITGrid>
|
|
285
|
+
<ITGrid item xs={12} lg={4}>
|
|
286
|
+
<ITCard title="Actividad reciente">
|
|
287
|
+
<ITStack spacing={3}>
|
|
288
|
+
{[
|
|
289
|
+
{ user: "Ana López", action: "creó un reporte", time: "hace 2 min", color: "bg-emerald-500" },
|
|
290
|
+
{ user: "Carlos Ruiz", action: "aprobó orden #1234", time: "hace 15 min", color: "bg-blue-500" },
|
|
291
|
+
{ user: "María García", action: "actualizó perfil", time: "hace 1 h", color: "bg-purple-500" },
|
|
292
|
+
{ user: "Pedro Martín", action: "subió documento", time: "hace 3 h", color: "bg-amber-500" },
|
|
293
|
+
].map((item, i) => (
|
|
294
|
+
<ITFlex key={i} gap={3} align="center">
|
|
295
|
+
<ITAvatar initials={item.user.split(" ").map(w => w[0]).join("")} size="sm" color={item.color} />
|
|
296
|
+
<div className="flex-1 min-w-0">
|
|
297
|
+
<p className="text-xs font-semibold text-slate-700 dark:text-slate-200 truncate">{item.user}</p>
|
|
298
|
+
<p className="text-[10px] text-slate-400 truncate">{item.action}</p>
|
|
299
|
+
</div>
|
|
300
|
+
<span className="text-[10px] text-slate-400 whitespace-nowrap">{item.time}</span>
|
|
301
|
+
</ITFlex>
|
|
302
|
+
))}
|
|
303
|
+
</ITStack>
|
|
304
|
+
</ITCard>
|
|
305
|
+
</ITGrid>
|
|
306
|
+
</ITGrid>
|
|
189
307
|
</ITPage>
|
|
190
308
|
</div>
|
|
191
309
|
}
|
|
192
310
|
controls={
|
|
193
|
-
<
|
|
194
|
-
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
311
|
+
<ITStack spacing={4}>
|
|
312
|
+
<div>
|
|
313
|
+
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">Estado de la página</p>
|
|
314
|
+
<ITFlex gap={2} wrap="wrap">
|
|
315
|
+
{(["normal", "loading", "error", "empty"] as const).map((s) => (
|
|
316
|
+
<ITButton
|
|
317
|
+
key={s}
|
|
318
|
+
label={s.charAt(0).toUpperCase() + s.slice(1)}
|
|
319
|
+
variant={state === s ? "filled" : "outlined"}
|
|
320
|
+
size="small"
|
|
321
|
+
onClick={() => setState(s)}
|
|
322
|
+
/>
|
|
323
|
+
))}
|
|
324
|
+
</ITFlex>
|
|
325
|
+
</div>
|
|
326
|
+
<ITFlex justify="between" align="center">
|
|
327
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Icono en header</span>
|
|
328
|
+
<ITSlideToggle isOn={showIcon} onToggle={setShowIcon} size="sm" />
|
|
329
|
+
</ITFlex>
|
|
330
|
+
</ITStack>
|
|
331
|
+
}
|
|
332
|
+
gallery={
|
|
333
|
+
<ITStack spacing={6}>
|
|
334
|
+
<div>
|
|
335
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Listado de Usuarios</h4>
|
|
336
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
337
|
+
<ITPage
|
|
338
|
+
title="Usuarios"
|
|
339
|
+
description="1,245 usuarios registrados · 38 activos hoy"
|
|
340
|
+
icon={<FaUsers size={20} />}
|
|
341
|
+
iconColor="#6366f1"
|
|
342
|
+
breadcrumbs={[{ label: "Inicio", href: "#" }, { label: "Usuarios" }]}
|
|
343
|
+
actions={
|
|
344
|
+
<>
|
|
345
|
+
<ITButton label="Exportar" variant="outlined" size="small" icon={<FaDownload />} />
|
|
346
|
+
<ITButton label="Nuevo usuario" size="small" icon={<FaPlus />} />
|
|
347
|
+
</>
|
|
348
|
+
}
|
|
349
|
+
>
|
|
350
|
+
<ITCard>
|
|
351
|
+
<ITFlex gap={3} className="mb-4">
|
|
352
|
+
<div className="flex-1 relative">
|
|
353
|
+
<FaSearch className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-sm" />
|
|
354
|
+
<input
|
|
355
|
+
type="text"
|
|
356
|
+
placeholder="Buscar por nombre o email..."
|
|
357
|
+
className="w-full pl-10 pr-4 py-2 text-sm border border-slate-200 dark:border-slate-700 rounded-lg bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500"
|
|
358
|
+
/>
|
|
359
|
+
</div>
|
|
360
|
+
<ITButton label="Filtros" variant="outlined" size="small" icon={<FaFilter />} />
|
|
361
|
+
</ITFlex>
|
|
362
|
+
<ITStack spacing={2}>
|
|
363
|
+
{[
|
|
364
|
+
{ name: "Ana López", email: "ana.lopez@axzy.dev", role: "Admin", status: "active", last: "Hace 2 min" },
|
|
365
|
+
{ name: "Carlos Ruiz", email: "carlos.ruiz@axzy.dev", role: "Editor", status: "active", last: "Hace 1 h" },
|
|
366
|
+
{ name: "María García", email: "maria.garcia@axzy.dev", role: "Viewer", status: "inactive", last: "Hace 3 días" },
|
|
367
|
+
{ name: "Pedro Martín", email: "pedro.martin@axzy.dev", role: "Admin", status: "active", last: "Hace 5 min" },
|
|
368
|
+
{ name: "Lucía Fernández", email: "lucia.fernandez@axzy.dev", role: "Editor", status: "pending", last: "Nunca" },
|
|
369
|
+
].map((u, i) => (
|
|
370
|
+
<div key={i} className="flex items-center gap-3 p-3 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors">
|
|
371
|
+
<ITAvatar initials={u.name.split(" ").map(w => w[0]).join("")} size="sm" color={u.status === "active" ? "bg-emerald-500" : u.status === "pending" ? "bg-amber-500" : "bg-slate-400"} />
|
|
372
|
+
<div className="flex-1 min-w-0">
|
|
373
|
+
<p className="text-sm font-semibold text-slate-800 dark:text-white truncate">{u.name}</p>
|
|
374
|
+
<p className="text-xs text-slate-500 truncate">{u.email}</p>
|
|
375
|
+
</div>
|
|
376
|
+
<span className={`px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider rounded-md ${
|
|
377
|
+
u.role === "Admin" ? "bg-primary-100 text-primary-700 dark:bg-primary-950/40 dark:text-primary-300" :
|
|
378
|
+
u.role === "Editor" ? "bg-blue-100 text-blue-700 dark:bg-blue-950/40 dark:text-blue-300" :
|
|
379
|
+
"bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-400"
|
|
380
|
+
}`}>{u.role}</span>
|
|
381
|
+
<ITFlex gap={1}>
|
|
382
|
+
<button className="p-1.5 rounded-md hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-500 hover:text-primary-600"><FaEye size={12} /></button>
|
|
383
|
+
<button className="p-1.5 rounded-md hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-500 hover:text-primary-600"><FaEdit size={12} /></button>
|
|
384
|
+
<button className="p-1.5 rounded-md hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-500 hover:text-rose-600"><FaTrash size={12} /></button>
|
|
385
|
+
</ITFlex>
|
|
386
|
+
</div>
|
|
387
|
+
))}
|
|
388
|
+
</ITStack>
|
|
389
|
+
</ITCard>
|
|
390
|
+
</ITPage>
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
393
|
+
|
|
394
|
+
<div>
|
|
395
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Detalle de Producto</h4>
|
|
396
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
397
|
+
<ITPage
|
|
398
|
+
title="MacBook Pro 16'' M3 Max"
|
|
399
|
+
description="SKU: MBP-16-M3MAX-2024 · Stock: 24 unidades"
|
|
400
|
+
icon={<FaBoxOpen size={20} />}
|
|
401
|
+
iconColor="#ec4899"
|
|
402
|
+
breadcrumbs={[
|
|
403
|
+
{ label: "Inicio", href: "#" },
|
|
404
|
+
{ label: "Productos", href: "#" },
|
|
405
|
+
{ label: "MacBook Pro 16" },
|
|
406
|
+
]}
|
|
407
|
+
backAction={() => {}}
|
|
408
|
+
actions={
|
|
409
|
+
<>
|
|
410
|
+
<ITButton label="Eliminar" variant="outlined" size="small" icon={<FaTrash />} />
|
|
411
|
+
<ITButton label="Editar" size="small" icon={<FaEdit />} />
|
|
412
|
+
</>
|
|
413
|
+
}
|
|
414
|
+
>
|
|
415
|
+
<ITGrid container spacing={3}>
|
|
416
|
+
<ITGrid item xs={12} md={5}>
|
|
417
|
+
<ITCard>
|
|
418
|
+
<div className="aspect-square bg-gradient-to-br from-slate-100 to-slate-200 dark:from-slate-800 dark:to-slate-900 rounded-xl flex items-center justify-center">
|
|
419
|
+
<FaBoxOpen className="text-6xl text-slate-400" />
|
|
420
|
+
</div>
|
|
421
|
+
<ITFlex gap={2} className="mt-3">
|
|
422
|
+
{[1,2,3,4].map(i => (
|
|
423
|
+
<div key={i} className="w-16 h-16 rounded-lg bg-slate-100 dark:bg-slate-800 border-2 border-transparent hover:border-primary-500 cursor-pointer" />
|
|
424
|
+
))}
|
|
425
|
+
</ITFlex>
|
|
426
|
+
</ITCard>
|
|
427
|
+
</ITGrid>
|
|
428
|
+
<ITGrid item xs={12} md={7}>
|
|
429
|
+
<ITCard title="Información general">
|
|
430
|
+
<ITStack spacing={4}>
|
|
431
|
+
<div>
|
|
432
|
+
<p className="text-xs font-bold uppercase text-slate-400 mb-1">Precio</p>
|
|
433
|
+
<ITFlex align="baseline" gap={2}>
|
|
434
|
+
<span className="text-3xl font-extrabold text-slate-800 dark:text-white">$3,499</span>
|
|
435
|
+
<span className="text-sm text-slate-400 line-through">$3,799</span>
|
|
436
|
+
<span className="text-xs font-bold text-emerald-600 bg-emerald-50 dark:bg-emerald-950/30 px-2 py-0.5 rounded-md">-8%</span>
|
|
437
|
+
</ITFlex>
|
|
438
|
+
</div>
|
|
439
|
+
<ITGrid container spacing={3}>
|
|
440
|
+
<ITGrid item xs={6}>
|
|
441
|
+
<p className="text-xs font-bold uppercase text-slate-400 mb-1">Categoría</p>
|
|
442
|
+
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">Laptops</p>
|
|
443
|
+
</ITGrid>
|
|
444
|
+
<ITGrid item xs={6}>
|
|
445
|
+
<p className="text-xs font-bold uppercase text-slate-400 mb-1">Estado</p>
|
|
446
|
+
<ITFlex gap={1.5} align="center">
|
|
447
|
+
<FaCheckCircle className="text-emerald-500 text-xs" />
|
|
448
|
+
<span className="text-sm font-semibold text-emerald-600">Activo</span>
|
|
449
|
+
</ITFlex>
|
|
450
|
+
</ITGrid>
|
|
451
|
+
<ITGrid item xs={6}>
|
|
452
|
+
<p className="text-xs font-bold uppercase text-slate-400 mb-1">Vendidos</p>
|
|
453
|
+
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">142 unidades</p>
|
|
454
|
+
</ITGrid>
|
|
455
|
+
<ITGrid item xs={6}>
|
|
456
|
+
<p className="text-xs font-bold uppercase text-slate-400 mb-1">Valoración</p>
|
|
457
|
+
<p className="text-sm font-semibold text-amber-600">★ 4.8 (89 reseñas)</p>
|
|
458
|
+
</ITGrid>
|
|
459
|
+
</ITGrid>
|
|
460
|
+
<div>
|
|
461
|
+
<p className="text-xs font-bold uppercase text-slate-400 mb-1">Descripción</p>
|
|
462
|
+
<p className="text-sm text-slate-600 dark:text-slate-300">
|
|
463
|
+
Potencia extrema para profesionales. Chip M3 Max con CPU de 16 núcleos, GPU de 40 núcleos y 64GB de memoria unificada.
|
|
464
|
+
</p>
|
|
465
|
+
</div>
|
|
466
|
+
</ITStack>
|
|
467
|
+
</ITCard>
|
|
468
|
+
</ITGrid>
|
|
469
|
+
</ITGrid>
|
|
470
|
+
</ITPage>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
|
|
474
|
+
<div>
|
|
475
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Editar / Formulario</h4>
|
|
476
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
477
|
+
<ITPage
|
|
478
|
+
title="Editar perfil"
|
|
479
|
+
description="Actualiza tu información personal y de contacto"
|
|
480
|
+
icon={<FaEdit size={20} />}
|
|
481
|
+
iconColor="#10b981"
|
|
482
|
+
breadcrumbs={[
|
|
483
|
+
{ label: "Inicio", href: "#" },
|
|
484
|
+
{ label: "Mi cuenta", href: "#" },
|
|
485
|
+
{ label: "Editar perfil" },
|
|
486
|
+
]}
|
|
487
|
+
backAction={() => {}}
|
|
488
|
+
actions={
|
|
489
|
+
<>
|
|
490
|
+
<ITButton label="Cancelar" variant="outlined" size="small" />
|
|
491
|
+
<ITButton label="Guardar cambios" size="small" icon={<FaSave />} />
|
|
492
|
+
</>
|
|
493
|
+
}
|
|
494
|
+
>
|
|
495
|
+
<ITGrid container spacing={3}>
|
|
496
|
+
<ITGrid item xs={12} md={4}>
|
|
497
|
+
<ITCard title="Foto de perfil">
|
|
498
|
+
<div className="flex flex-col items-center gap-4">
|
|
499
|
+
<ITAvatar initials="AL" size="xl" color="bg-primary-500" />
|
|
500
|
+
<div className="w-full">
|
|
501
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">URL de imagen</label>
|
|
502
|
+
<input type="text" placeholder="https://..." defaultValue="" className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
503
|
+
</div>
|
|
504
|
+
<ITButton label="Subir imagen" variant="outlined" size="small" />
|
|
505
|
+
</div>
|
|
506
|
+
</ITCard>
|
|
507
|
+
</ITGrid>
|
|
508
|
+
<ITGrid item xs={12} md={8}>
|
|
509
|
+
<ITCard title="Información personal">
|
|
510
|
+
<ITGrid container spacing={3}>
|
|
511
|
+
<ITGrid item xs={12} sm={6}>
|
|
512
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Nombre</label>
|
|
513
|
+
<input type="text" defaultValue="Ana" className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
514
|
+
</ITGrid>
|
|
515
|
+
<ITGrid item xs={12} sm={6}>
|
|
516
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Apellido</label>
|
|
517
|
+
<input type="text" defaultValue="López" className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
518
|
+
</ITGrid>
|
|
519
|
+
<ITGrid item xs={12}>
|
|
520
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Email</label>
|
|
521
|
+
<input type="email" defaultValue="ana.lopez@axzy.dev" className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
522
|
+
</ITGrid>
|
|
523
|
+
<ITGrid item xs={12} sm={6}>
|
|
524
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Teléfono</label>
|
|
525
|
+
<input type="text" placeholder="+52..." className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
526
|
+
</ITGrid>
|
|
527
|
+
<ITGrid item xs={12} sm={6}>
|
|
528
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Ubicación</label>
|
|
529
|
+
<input type="text" placeholder="Ciudad, País" className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
530
|
+
</ITGrid>
|
|
531
|
+
<ITGrid item xs={12}>
|
|
532
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Biografía</label>
|
|
533
|
+
<textarea
|
|
534
|
+
rows={3}
|
|
535
|
+
defaultValue="Diseñadora de producto enfocada en crear experiencias memorables."
|
|
536
|
+
className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500"
|
|
537
|
+
/>
|
|
538
|
+
</ITGrid>
|
|
539
|
+
</ITGrid>
|
|
540
|
+
</ITCard>
|
|
541
|
+
</ITGrid>
|
|
542
|
+
</ITGrid>
|
|
543
|
+
</ITPage>
|
|
544
|
+
</div>
|
|
545
|
+
</div>
|
|
546
|
+
|
|
547
|
+
<div>
|
|
548
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Configuración con tabs</h4>
|
|
549
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
550
|
+
<ITPage
|
|
551
|
+
title="Configuración"
|
|
552
|
+
description="Administra las preferencias de tu cuenta y del sistema"
|
|
553
|
+
icon={<FaCog size={20} />}
|
|
554
|
+
iconColor="#f59e0b"
|
|
555
|
+
breadcrumbs={[{ label: "Inicio", href: "#" }, { label: "Configuración" }]}
|
|
556
|
+
>
|
|
557
|
+
<ITGrid container spacing={3}>
|
|
558
|
+
<ITGrid item xs={12} md={4}>
|
|
559
|
+
<ITCard>
|
|
560
|
+
<ITStack spacing={1}>
|
|
561
|
+
{[
|
|
562
|
+
{ id: "general", label: "General", icon: <FaCog />, active: true },
|
|
563
|
+
{ id: "notif", label: "Notificaciones", icon: <FaBell /> },
|
|
564
|
+
{ id: "sec", label: "Seguridad", icon: <FaShieldAlt /> },
|
|
565
|
+
{ id: "apariencia", label: "Apariencia", icon: <FaPalette /> },
|
|
566
|
+
{ id: "lang", label: "Idioma", icon: <FaLanguage /> },
|
|
567
|
+
{ id: "billing", label: "Facturación", icon: <FaDollarSign /> },
|
|
568
|
+
].map(item => (
|
|
569
|
+
<button key={item.id} className={`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors ${item.active ? "bg-primary-50 text-primary-700 dark:bg-primary-950/30 dark:text-primary-300" : "text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-800"}`}>
|
|
570
|
+
<span className="text-base">{item.icon}</span>
|
|
571
|
+
{item.label}
|
|
572
|
+
</button>
|
|
573
|
+
))}
|
|
574
|
+
</ITStack>
|
|
575
|
+
</ITCard>
|
|
576
|
+
</ITGrid>
|
|
577
|
+
<ITGrid item xs={12} md={8}>
|
|
578
|
+
<ITCard title="Preferencias generales">
|
|
579
|
+
<ITStack spacing={4}>
|
|
580
|
+
<div>
|
|
581
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Nombre del sistema</label>
|
|
582
|
+
<input type="text" defaultValue="AXZY Console" className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
583
|
+
</div>
|
|
584
|
+
<div>
|
|
585
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Zona horaria</label>
|
|
586
|
+
<select className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500">
|
|
587
|
+
<option>América/México_City (GMT-6)</option>
|
|
588
|
+
<option>América/Bogotá (GMT-5)</option>
|
|
589
|
+
<option>América/Madrid (GMT+1)</option>
|
|
590
|
+
</select>
|
|
591
|
+
</div>
|
|
592
|
+
<div>
|
|
593
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Idioma por defecto</label>
|
|
594
|
+
<select className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500">
|
|
595
|
+
<option>Español (México)</option>
|
|
596
|
+
<option>Español (España)</option>
|
|
597
|
+
<option>English (US)</option>
|
|
598
|
+
</select>
|
|
599
|
+
</div>
|
|
600
|
+
<ITStack spacing={3} className="pt-2 border-t border-slate-100 dark:border-slate-800">
|
|
601
|
+
<ITFlex justify="between" align="center">
|
|
602
|
+
<div>
|
|
603
|
+
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">Modo oscuro automático</p>
|
|
604
|
+
<p className="text-xs text-slate-500">Sigue la configuración del sistema</p>
|
|
605
|
+
</div>
|
|
606
|
+
<ITSlideToggle isOn={true} onToggle={() => {}} size="sm" />
|
|
607
|
+
</ITFlex>
|
|
608
|
+
<ITFlex justify="between" align="center">
|
|
609
|
+
<div>
|
|
610
|
+
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">Notificaciones por email</p>
|
|
611
|
+
<p className="text-xs text-slate-500">Recibe alertas de actividad</p>
|
|
612
|
+
</div>
|
|
613
|
+
<ITSlideToggle isOn={false} onToggle={() => {}} size="sm" />
|
|
614
|
+
</ITFlex>
|
|
615
|
+
</ITStack>
|
|
616
|
+
</ITStack>
|
|
617
|
+
</ITCard>
|
|
618
|
+
</ITGrid>
|
|
619
|
+
</ITGrid>
|
|
620
|
+
</ITPage>
|
|
621
|
+
</div>
|
|
622
|
+
</div>
|
|
623
|
+
</ITStack>
|
|
204
624
|
}
|
|
205
625
|
/>
|
|
206
626
|
);
|