@axzydev/axzy_ui_system 1.2.6 → 1.2.8
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 +777 -535
- 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 +1470 -87
- package/dist/index.d.ts +1470 -87
- package/dist/index.js +799 -555
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/App.tsx +19 -54
- package/src/components/alert/alert.doc.mdx +48 -0
- package/src/components/alert/alert.props.ts +7 -0
- package/src/components/alert/alert.tsx +8 -0
- package/src/components/avatar/avatar.doc.mdx +48 -0
- package/src/components/avatar/avatar.props.ts +8 -0
- package/src/components/avatar/avatar.tsx +25 -5
- package/src/components/badget/badget.doc.mdx +46 -0
- package/src/components/badget/badget.props.ts +6 -0
- package/src/components/badget/badget.tsx +11 -0
- package/src/components/breadcrumbs/breadcrumbs.doc.mdx +57 -0
- package/src/components/breadcrumbs/breadcrumbs.props.ts +6 -0
- package/src/components/breadcrumbs/breadcrumbs.tsx +12 -0
- package/src/components/button/button.doc.mdx +59 -0
- package/src/components/button/button.props.ts +12 -0
- package/src/components/button/button.tsx +11 -0
- package/src/components/calendar/calendar.doc.mdx +75 -0
- package/src/components/calendar/calendar.props.ts +27 -7
- package/src/components/calendar/calendar.tsx +13 -0
- package/src/components/card/card.doc.mdx +54 -0
- package/src/components/card/card.props.ts +11 -0
- package/src/components/card/card.tsx +13 -0
- package/src/components/checkbox/checkbox.doc.mdx +54 -0
- package/src/components/checkbox/checkbox.props.ts +7 -0
- package/src/components/checkbox/checkbox.tsx +9 -0
- package/src/components/confirm-dialog/confirm-dialog.doc.mdx +60 -0
- package/src/components/confirm-dialog/confirm-dialog.props.ts +9 -0
- package/src/components/confirm-dialog/confirm-dialog.tsx +19 -0
- package/src/components/data-table/ITDataTable.doc.mdx +59 -0
- package/src/components/data-table/dataTable.props.ts +15 -0
- package/src/components/data-table/dataTable.tsx +178 -73
- package/src/components/date-picker/date-picker.doc.mdx +65 -0
- package/src/components/date-picker/date-picker.props.ts +17 -0
- package/src/components/date-picker/datePicker.tsx +31 -1
- package/src/components/dialog/dialog.doc.mdx +54 -0
- package/src/components/dialog/dialog.props.ts +7 -0
- package/src/components/dialog/dialog.tsx +26 -0
- package/src/components/divider/divider.doc.mdx +42 -0
- package/src/components/divider/divider.props.ts +5 -0
- package/src/components/divider/divider.tsx +16 -0
- package/src/components/drawer/drawer.doc.mdx +59 -0
- package/src/components/drawer/drawer.props.ts +9 -0
- package/src/components/drawer/drawer.tsx +20 -0
- package/src/components/dropfile/dropfile.doc.mdx +59 -0
- package/src/components/dropfile/dropfile.props.ts +41 -0
- package/src/components/dropfile/dropfile.tsx +21 -33
- package/src/components/empty-state/empty-state.doc.mdx +50 -0
- package/src/components/empty-state/empty-state.props.ts +5 -0
- package/src/components/empty-state/empty-state.tsx +16 -0
- package/src/components/flex/flex.doc.mdx +59 -0
- package/src/components/flex/flex.props.ts +13 -0
- package/src/components/flex/flex.tsx +15 -0
- package/src/components/form-builder/fieldRenderer.tsx +52 -2
- package/src/components/form-builder/formBuilder.doc.mdx +124 -0
- package/src/components/form-builder/formBuilder.props.ts +12 -2
- package/src/components/form-builder/formBuilder.tsx +31 -0
- package/src/components/form-header/form-header.doc.mdx +38 -0
- package/src/components/form-header/form-header.props.ts +3 -0
- package/src/components/form-header/form-header.stories.tsx +53 -0
- package/src/components/form-header/form-header.tsx +11 -0
- package/src/components/grid/grid.doc.mdx +54 -0
- package/src/components/grid/grid.props.ts +13 -0
- package/src/components/grid/grid.tsx +26 -2
- package/src/components/image/image.doc.mdx +44 -0
- package/src/components/image/image.props.ts +5 -0
- package/src/components/image/image.stories.tsx +49 -0
- package/src/components/image/image.tsx +19 -0
- package/src/components/input/input.doc.mdx +70 -0
- package/src/components/input/input.props.ts +34 -2
- package/src/components/input/input.tsx +29 -0
- package/src/components/layout/layout.doc.mdx +51 -0
- package/src/components/layout/layout.props.ts +5 -0
- package/src/components/layout/layout.tsx +41 -17
- package/src/components/loader/loader.doc.mdx +43 -0
- package/src/components/loader/loader.props.ts +4 -0
- package/src/components/loader/loader.tsx +17 -0
- package/src/components/navbar/navbar.doc.mdx +77 -0
- package/src/components/navbar/navbar.props.ts +37 -1
- package/src/components/navbar/navbar.stories.tsx +84 -0
- package/src/components/navbar/navbar.tsx +78 -46
- package/src/components/page/page.doc.mdx +80 -0
- package/src/components/page/page.props.ts +25 -0
- package/src/components/page/page.tsx +35 -7
- package/src/components/page-header/page-header.doc.mdx +54 -0
- package/src/components/page-header/page-header.props.ts +11 -0
- package/src/components/page-header/page-header.stories.tsx +14 -0
- package/src/components/page-header/page-header.tsx +50 -15
- package/src/components/pagination/pagination.doc.mdx +62 -0
- package/src/components/pagination/pagination.props.ts +11 -32
- package/src/components/pagination/pagination.tsx +17 -0
- package/src/components/popover/popover.doc.mdx +53 -0
- package/src/components/popover/popover.props.ts +8 -0
- package/src/components/popover/popover.tsx +13 -0
- package/src/components/progress/progress.doc.mdx +48 -0
- package/src/components/progress/progress.props.ts +8 -0
- package/src/components/progress/progress.tsx +9 -0
- package/src/components/radio/radio.doc.mdx +62 -0
- package/src/components/radio/radio.props.ts +11 -0
- package/src/components/radio/radio.tsx +18 -0
- package/src/components/search-select/search-select.doc.mdx +72 -0
- package/src/components/search-select/search-select.props.ts +23 -18
- package/src/components/search-select/search-select.tsx +27 -2
- package/src/components/searchTable/searchTable.doc.mdx +79 -0
- package/src/components/searchTable/searchTable.props.ts +42 -3
- package/src/components/searchTable/searchTable.stories.tsx +74 -0
- package/src/components/searchTable/searchTable.tsx +23 -0
- package/src/components/segmented-control/segmented-control.doc.mdx +60 -0
- package/src/components/segmented-control/segmented-control.props.ts +12 -0
- package/src/components/segmented-control/segmented-control.tsx +15 -0
- package/src/components/select/select.doc.mdx +75 -0
- package/src/components/select/select.props.ts +22 -0
- package/src/components/select/select.tsx +2 -5
- package/src/components/sidebar/sidebar.doc.mdx +86 -0
- package/src/components/sidebar/sidebar.props.ts +22 -0
- package/src/components/sidebar/sidebar.tsx +22 -0
- package/src/components/skeleton/skeleton.doc.mdx +43 -0
- package/src/components/skeleton/skeleton.props.ts +8 -0
- package/src/components/skeleton/skeleton.tsx +10 -0
- package/src/components/slide/slide.doc.mdx +46 -0
- package/src/components/slide/slide.props.ts +11 -24
- package/src/components/slide/slide.tsx +10 -1
- package/src/components/slider/slider.doc.mdx +49 -0
- package/src/components/slider/slider.props.ts +9 -0
- package/src/components/slider/slider.tsx +15 -0
- package/src/components/stack/stack.doc.mdx +126 -0
- package/src/components/stack/stack.props.ts +18 -0
- package/src/components/stack/stack.stories.tsx +221 -16
- package/src/components/stack/stack.tsx +21 -0
- package/src/components/stat-card/stat-card.doc.mdx +48 -0
- package/src/components/stat-card/stat-card.props.ts +9 -0
- package/src/components/stat-card/stat-card.tsx +10 -0
- package/src/components/stepper/stepper.doc.mdx +54 -0
- package/src/components/stepper/stepper.props.ts +11 -1
- package/src/components/stepper/stepper.tsx +15 -0
- package/src/components/table/table.doc.mdx +58 -0
- package/src/components/table/table.props.ts +17 -0
- package/src/components/table/table.tsx +199 -84
- package/src/components/tabs/tabs.doc.mdx +52 -0
- package/src/components/tabs/tabs.props.ts +11 -0
- package/src/components/tabs/tabs.tsx +14 -0
- package/src/components/text/text.doc.mdx +41 -0
- package/src/components/text/text.props.ts +5 -0
- package/src/components/text/text.stories.tsx +67 -0
- package/src/components/text/text.tsx +10 -0
- package/src/components/textarea/textarea.doc.mdx +64 -0
- package/src/components/textarea/textarea.props.ts +11 -0
- package/src/components/textarea/textarea.tsx +16 -0
- package/src/components/theme-provider/themeProvider.doc.mdx +75 -0
- package/src/components/theme-provider/themeProvider.props.ts +3 -0
- package/src/components/theme-provider/themeProvider.stories.tsx +59 -0
- package/src/components/theme-provider/themeProvider.tsx +14 -0
- package/src/components/time-picker/timePicker.doc.mdx +68 -0
- package/src/components/time-picker/timePicker.props.ts +14 -0
- package/src/components/time-picker/timePicker.tsx +22 -1
- package/src/components/toast/toast.doc.mdx +50 -0
- package/src/components/toast/toast.props.ts +5 -0
- package/src/components/toast/toast.tsx +21 -0
- package/src/components/tooltip/tooltip.doc.mdx +47 -0
- package/src/components/tooltip/tooltip.props.ts +6 -0
- package/src/components/tooltip/tooltip.tsx +19 -0
- package/src/components/topbar/topbar.doc.mdx +69 -0
- package/src/components/topbar/topbar.props.ts +15 -0
- package/src/components/topbar/topbar.tsx +38 -0
- package/src/components/triple-filter/tripleFilter.doc.mdx +62 -0
- package/src/components/triple-filter/tripleFilter.props.ts +7 -0
- package/src/components/triple-filter/tripleFilter.tsx +32 -0
- package/src/index.css +17 -0
- package/src/showcases/DataShowcases.tsx +529 -45
- package/src/showcases/FormShowcases.tsx +399 -29
- package/src/showcases/HomeShowcase.tsx +252 -272
- package/src/showcases/LayoutPrimitivesShowcases.tsx +1224 -248
- package/src/showcases/PageShowcases.tsx +868 -151
- package/src/showcases/ShowcaseLayout.tsx +237 -73
- package/src/showcases/StructureShowcases.tsx +1039 -97
- package/src/types/table.types.ts +1 -1
- package/src/utils/styles.ts +2 -1
|
@@ -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,106 +38,354 @@ 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";
|
|
42
|
+
import ITTable from "@/components/table/table";
|
|
43
|
+
import type { Column } from "@/components/table/table.props";
|
|
12
44
|
import { ShowcaseLayout } from "./ShowcaseLayout";
|
|
13
45
|
|
|
14
46
|
export const PageHeaderShowcase = () => {
|
|
15
47
|
const [showBack, setShowBack] = useState(true);
|
|
16
48
|
const [showBreadcrumbs, setShowBreadcrumbs] = useState(true);
|
|
17
|
-
const [
|
|
18
|
-
const [
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
49
|
+
const [showIcon, setShowIcon] = useState(true);
|
|
50
|
+
const [iconColor, setIconColor] = useState("#6366f1");
|
|
51
|
+
const [showDesc, setShowDesc] = useState(true);
|
|
52
|
+
const [actionsVariant, setActionsVariant] = useState<"none" | "single" | "double" | "full">("double");
|
|
53
|
+
const [showFilters, setShowFilters] = useState(true);
|
|
54
|
+
|
|
55
|
+
const buildCode = () => {
|
|
56
|
+
const lines = [`<ITPageHeader`];
|
|
57
|
+
lines.push(` title="Team members"`);
|
|
58
|
+
if (showDesc) lines.push(` description="Manage invitations, roles and permissions…"`);
|
|
59
|
+
if (showIcon) lines.push(` icon={<FaUsers size={20} />}`);
|
|
60
|
+
if (showBreadcrumbs) lines.push(` breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Team" }]}`);
|
|
61
|
+
if (showBack) lines.push(` backAction={() => history.back()}`);
|
|
62
|
+
if (actionsVariant !== "none") {
|
|
63
|
+
const acts = [];
|
|
64
|
+
acts.push(`<ITButton label="Add member" variant="filled" color="primary" size="small" />`);
|
|
65
|
+
if (actionsVariant === "double" || actionsVariant === "full") acts.push(`<ITButton label="Export" variant="outlined" color="gray" size="small" />`);
|
|
66
|
+
lines.push(` actions={<>${acts.join("")}</>}`);
|
|
67
|
+
}
|
|
68
|
+
lines.push(`/>`);
|
|
69
|
+
return lines.join("\n");
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const actionEl =
|
|
73
|
+
actionsVariant === "none" ? undefined : (
|
|
74
|
+
<ITFlex gap={2}>
|
|
75
|
+
<ITButton label="Add member" variant="filled" color="primary" size="small" />
|
|
76
|
+
{(actionsVariant === "double" || actionsVariant === "full") && (
|
|
77
|
+
<ITButton label="Export" variant="outlined" color="gray" size="small" />
|
|
78
|
+
)}
|
|
79
|
+
</ITFlex>
|
|
80
|
+
);
|
|
29
81
|
|
|
30
82
|
return (
|
|
31
83
|
<ShowcaseLayout
|
|
32
84
|
title="ITPageHeader"
|
|
33
|
-
description="Encabezado estandarizado para pantallas. Incluye título, descripción, breadcrumbs, botón de volver y área de acciones."
|
|
34
|
-
code={
|
|
85
|
+
description="Encabezado estandarizado para pantallas. Incluye título, descripción, icono, breadcrumbs, botón de volver y área de acciones."
|
|
86
|
+
code={buildCode()}
|
|
35
87
|
demo={
|
|
36
|
-
<div className="w-full
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
88
|
+
<div className="w-full flex flex-col">
|
|
89
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl bg-white dark:bg-slate-900/50 overflow-hidden">
|
|
90
|
+
<div className="p-6 pb-4">
|
|
91
|
+
<ITPageHeader
|
|
92
|
+
title="Team members"
|
|
93
|
+
description={showDesc ? "Manage invitations, roles and permissions for your organization workspace." : undefined}
|
|
94
|
+
icon={showIcon ? <FaUsers size={20} /> : undefined}
|
|
95
|
+
iconColor={showIcon ? iconColor : undefined}
|
|
96
|
+
breadcrumbs={showBreadcrumbs ? [
|
|
97
|
+
{ label: "Admin", href: "#" },
|
|
98
|
+
{ label: "Team" },
|
|
99
|
+
] : undefined}
|
|
100
|
+
backAction={showBack ? () => {} : undefined}
|
|
101
|
+
actions={actionEl}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
{/* Filter bar below header */}
|
|
106
|
+
{showFilters && (
|
|
107
|
+
<div className="px-6 pb-4">
|
|
108
|
+
<ITFlex gap={3} align="center" wrap="wrap">
|
|
109
|
+
<div className="flex-1 min-w-[200px] relative">
|
|
110
|
+
<FaSearch size={12} className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
|
|
111
|
+
<input
|
|
112
|
+
type="text"
|
|
113
|
+
placeholder="Search by name or email..."
|
|
114
|
+
className="w-full pl-9 pr-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500"
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
<select
|
|
118
|
+
value="all"
|
|
119
|
+
onChange={() => {}}
|
|
120
|
+
className="px-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-700 dark:text-slate-200 outline-none focus:ring-2 focus:ring-primary-500"
|
|
121
|
+
>
|
|
122
|
+
<option value="all">All roles</option>
|
|
123
|
+
<option value="admin">Admin</option>
|
|
124
|
+
<option value="editor">Editor</option>
|
|
125
|
+
<option value="viewer">Viewer</option>
|
|
126
|
+
</select>
|
|
127
|
+
<select
|
|
128
|
+
value="all"
|
|
129
|
+
onChange={() => {}}
|
|
130
|
+
className="px-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-700 dark:text-slate-200 outline-none focus:ring-2 focus:ring-primary-500"
|
|
131
|
+
>
|
|
132
|
+
<option value="all">All status</option>
|
|
133
|
+
<option value="active">Active</option>
|
|
134
|
+
<option value="pending">Pending</option>
|
|
135
|
+
<option value="inactive">Inactive</option>
|
|
136
|
+
</select>
|
|
137
|
+
<ITButton label="Clear" variant="text" color="gray" size="small" />
|
|
138
|
+
</ITFlex>
|
|
139
|
+
</div>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
{/* Fixed footer with active-property badges */}
|
|
144
|
+
<div className="sticky bottom-0 mt-4 -mx-6 -mb-6 px-6 py-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-t border-slate-200 dark:border-slate-700 flex items-center flex-wrap gap-1.5 text-[10px] font-mono">
|
|
145
|
+
<span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
|
|
146
|
+
{showBack && <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">back</span>}
|
|
147
|
+
{showBreadcrumbs && <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">breadcrumbs</span>}
|
|
148
|
+
{showIcon && <span className="px-2 py-0.5 rounded-md bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300">icon</span>}
|
|
149
|
+
{showDesc && <span className="px-2 py-0.5 rounded-md bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">description</span>}
|
|
150
|
+
{actionsVariant !== "none" && <span className="px-2 py-0.5 rounded-md bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300">actions ({actionsVariant})</span>}
|
|
151
|
+
{showFilters && <span className="px-2 py-0.5 rounded-md bg-cyan-100 dark:bg-cyan-900/30 text-cyan-700 dark:text-cyan-300">filters</span>}
|
|
152
|
+
</div>
|
|
47
153
|
</div>
|
|
48
154
|
}
|
|
49
155
|
controls={
|
|
50
156
|
<ITStack spacing={4}>
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
157
|
+
<div>
|
|
158
|
+
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">Header elements</p>
|
|
159
|
+
<ITFlex direction="column" gap={3}>
|
|
160
|
+
<ITFlex justify="between" align="center">
|
|
161
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Back button</span>
|
|
162
|
+
<ITSlideToggle isOn={showBack} onToggle={setShowBack} size="sm" />
|
|
163
|
+
</ITFlex>
|
|
164
|
+
<ITFlex justify="between" align="center">
|
|
165
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Breadcrumbs</span>
|
|
166
|
+
<ITSlideToggle isOn={showBreadcrumbs} onToggle={setShowBreadcrumbs} size="sm" />
|
|
167
|
+
</ITFlex>
|
|
168
|
+
<ITFlex justify="between" align="center">
|
|
169
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Icon</span>
|
|
170
|
+
<ITSlideToggle isOn={showIcon} onToggle={setShowIcon} size="sm" />
|
|
171
|
+
</ITFlex>
|
|
172
|
+
{showIcon && (
|
|
173
|
+
<ITFlex gap={2} align="center">
|
|
174
|
+
{["#6366f1", "#8b5cf6", "#10b981", "#f59e0b", "#ec4899"].map((c) => (
|
|
175
|
+
<button
|
|
176
|
+
key={c}
|
|
177
|
+
onClick={() => setIconColor(c)}
|
|
178
|
+
className={`w-6 h-6 rounded-full border-2 transition-all ${
|
|
179
|
+
iconColor === c ? "border-slate-900 dark:border-white scale-125" : "border-transparent"
|
|
180
|
+
}`}
|
|
181
|
+
style={{ backgroundColor: c }}
|
|
182
|
+
/>
|
|
183
|
+
))}
|
|
184
|
+
</ITFlex>
|
|
185
|
+
)}
|
|
186
|
+
<ITFlex justify="between" align="center">
|
|
187
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Description</span>
|
|
188
|
+
<ITSlideToggle isOn={showDesc} onToggle={setShowDesc} size="sm" />
|
|
189
|
+
</ITFlex>
|
|
190
|
+
</ITFlex>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div>
|
|
194
|
+
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">Actions</p>
|
|
195
|
+
<ITFlex gap={2} wrap="wrap">
|
|
196
|
+
{(["none", "single", "double", "full"] as const).map((v) => (
|
|
197
|
+
<ITButton
|
|
198
|
+
key={v}
|
|
199
|
+
label={v.charAt(0).toUpperCase() + v.slice(1)}
|
|
200
|
+
variant={actionsVariant === v ? "filled" : "outlined"}
|
|
201
|
+
color="primary"
|
|
202
|
+
size="small"
|
|
203
|
+
onClick={() => setActionsVariant(v)}
|
|
204
|
+
/>
|
|
205
|
+
))}
|
|
206
|
+
</ITFlex>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
<div>
|
|
210
|
+
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">Filters</p>
|
|
211
|
+
<ITFlex justify="between" align="center">
|
|
212
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Show filter bar</span>
|
|
213
|
+
<ITSlideToggle isOn={showFilters} onToggle={setShowFilters} size="sm" />
|
|
214
|
+
</ITFlex>
|
|
215
|
+
</div>
|
|
67
216
|
</ITStack>
|
|
68
217
|
}
|
|
69
218
|
gallery={
|
|
70
|
-
<ITStack spacing={
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
219
|
+
<ITStack spacing={6}>
|
|
220
|
+
{/* 1. Team management — full header + search + filter bar + user rows */}
|
|
221
|
+
<div>
|
|
222
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Team management</h4>
|
|
223
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
224
|
+
<div className="p-5 pb-3">
|
|
225
|
+
<ITPageHeader
|
|
226
|
+
title="Team members"
|
|
227
|
+
description="Manage invitations, roles and permissions for your organization workspace."
|
|
228
|
+
icon={<FaUsers size={20} />}
|
|
229
|
+
iconColor="#6366f1"
|
|
230
|
+
breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Team" }]}
|
|
231
|
+
backAction={() => {}}
|
|
232
|
+
actions={
|
|
233
|
+
<ITFlex gap={2}>
|
|
234
|
+
<ITButton label="Export" variant="outlined" color="gray" size="small" />
|
|
235
|
+
<ITButton label="Add member" variant="filled" color="primary" size="small" />
|
|
236
|
+
</ITFlex>
|
|
237
|
+
}
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
<ITFlex gap={3} align="center" wrap="wrap" className="px-5 pb-3">
|
|
241
|
+
<div className="flex-1 min-w-[180px] relative">
|
|
242
|
+
<FaSearch size={12} className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
|
|
243
|
+
<input type="text" placeholder="Search..." className="w-full pl-9 pr-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 outline-none focus:ring-2 focus:ring-primary-500 text-slate-800 dark:text-white" />
|
|
244
|
+
</div>
|
|
245
|
+
<select className="px-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-700 dark:text-slate-200 outline-none">
|
|
246
|
+
<option>All roles</option>
|
|
247
|
+
<option>Admin</option>
|
|
248
|
+
<option>Editor</option>
|
|
249
|
+
</select>
|
|
250
|
+
<select className="px-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-700 dark:text-slate-200 outline-none">
|
|
251
|
+
<option>All status</option>
|
|
252
|
+
<option>Active</option>
|
|
253
|
+
<option>Pending</option>
|
|
254
|
+
</select>
|
|
255
|
+
</ITFlex>
|
|
256
|
+
<ITStack spacing={1} className="px-5 pb-5">
|
|
257
|
+
{[
|
|
258
|
+
{ name: "Sofía Castillo", email: "sofia@axzy.dev", role: "Admin", status: "active" },
|
|
259
|
+
{ name: "Daniela Klein", email: "daniela@axzy.dev", role: "Editor", status: "active" },
|
|
260
|
+
{ name: "Mariana Reyes", email: "mariana@axzy.dev", role: "Viewer", status: "inactive" },
|
|
261
|
+
].map((u, i) => (
|
|
262
|
+
<ITFlex key={i} align="center" gap={3} className="p-2.5 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors">
|
|
263
|
+
<ITAvatar initials={u.name.split(" ").map(w => w[0]).join("")} size="sm" color={u.status === "active" ? "bg-primary-700" : "bg-slate-400"} />
|
|
264
|
+
<div className="flex-1 min-w-0">
|
|
265
|
+
<p className="text-sm font-semibold text-slate-800 dark:text-white truncate">{u.name}</p>
|
|
266
|
+
<p className="text-xs text-slate-500 truncate">{u.email}</p>
|
|
267
|
+
</div>
|
|
268
|
+
<span className={`px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider rounded-md ${
|
|
269
|
+
u.role === "Admin" ? "bg-primary-100 text-primary-700 dark:bg-primary-950/40 dark:text-primary-300" :
|
|
270
|
+
u.role === "Editor" ? "bg-blue-100 text-blue-700 dark:bg-blue-950/40 dark:text-blue-300" :
|
|
271
|
+
"bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-400"
|
|
272
|
+
}`}>{u.role}</span>
|
|
273
|
+
<ITFlex gap={1}>
|
|
274
|
+
<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>
|
|
275
|
+
<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>
|
|
276
|
+
</ITFlex>
|
|
277
|
+
</ITFlex>
|
|
278
|
+
))}
|
|
279
|
+
</ITStack>
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
{/* 2. Detail page — back + breadcrumbs + back button + save/cancel */}
|
|
284
|
+
<div>
|
|
285
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Detail / Edit form</h4>
|
|
286
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
287
|
+
<div className="p-5 pb-3">
|
|
288
|
+
<ITPageHeader
|
|
289
|
+
title="Edit product"
|
|
290
|
+
description="Update product details, pricing and inventory information."
|
|
291
|
+
icon={<FaBoxOpen size={20} />}
|
|
292
|
+
iconColor="#ec4899"
|
|
293
|
+
breadcrumbs={[{ label: "Products", href: "#" }, { label: "MacBook Pro 16", href: "#" }, { label: "Edit" }]}
|
|
294
|
+
backAction={() => {}}
|
|
295
|
+
actions={
|
|
296
|
+
<ITFlex gap={2}>
|
|
297
|
+
<ITButton label="Cancel" variant="outlined" color="gray" size="small" />
|
|
298
|
+
<ITButton label="Save changes" variant="filled" color="primary" size="small" />
|
|
299
|
+
</ITFlex>
|
|
300
|
+
}
|
|
301
|
+
/>
|
|
302
|
+
</div>
|
|
303
|
+
<ITGrid container spacing={3} className="px-5 pb-5">
|
|
304
|
+
<ITGrid item xs={12} md={6}>
|
|
305
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Product name</label>
|
|
306
|
+
<input type="text" defaultValue="MacBook Pro 16" 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" />
|
|
307
|
+
</ITGrid>
|
|
308
|
+
<ITGrid item xs={12} md={3}>
|
|
309
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Price</label>
|
|
310
|
+
<input type="text" defaultValue="$3,499" 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" />
|
|
311
|
+
</ITGrid>
|
|
312
|
+
<ITGrid item xs={12} md={3}>
|
|
313
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Stock</label>
|
|
314
|
+
<input type="text" defaultValue="24" 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" />
|
|
315
|
+
</ITGrid>
|
|
316
|
+
</ITGrid>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
|
|
320
|
+
{/* 3. Dashboard header — icon + title + desc + date range + refresh */}
|
|
321
|
+
<div>
|
|
322
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Dashboard</h4>
|
|
323
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
324
|
+
<div className="p-5">
|
|
325
|
+
<ITPageHeader
|
|
326
|
+
title="Dashboard"
|
|
327
|
+
description="Real-time overview of your business metrics and activity."
|
|
328
|
+
icon={<FaChartLine size={20} />}
|
|
329
|
+
iconColor="#10b981"
|
|
330
|
+
actions={
|
|
331
|
+
<ITFlex gap={2} align="center">
|
|
332
|
+
<select className="px-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-700 dark:text-slate-200 outline-none focus:ring-2 focus:ring-primary-500">
|
|
333
|
+
<option>Last 7 days</option>
|
|
334
|
+
<option>Last 30 days</option>
|
|
335
|
+
<option>This quarter</option>
|
|
336
|
+
<option>Custom range</option>
|
|
337
|
+
</select>
|
|
338
|
+
<ITButton label="Refresh" variant="outlined" color="gray" size="small" />
|
|
339
|
+
</ITFlex>
|
|
340
|
+
}
|
|
341
|
+
/>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
|
|
346
|
+
{/* 4. Settings header — no icon, no breadcrumbs, just title + desc + save */}
|
|
347
|
+
<div>
|
|
348
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Settings / Preferences</h4>
|
|
349
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
350
|
+
<div className="p-5">
|
|
351
|
+
<ITPageHeader
|
|
352
|
+
title="General settings"
|
|
353
|
+
description="Configure your workspace preferences, notifications and security options."
|
|
354
|
+
actions={
|
|
355
|
+
<ITFlex gap={2}>
|
|
356
|
+
<ITButton label="Reset" variant="outlined" color="gray" size="small" />
|
|
357
|
+
<ITButton label="Save" variant="filled" color="primary" size="small" />
|
|
358
|
+
</ITFlex>
|
|
359
|
+
}
|
|
360
|
+
/>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
</div>
|
|
364
|
+
|
|
365
|
+
{/* 5. Users list — icon + breadcrumbs + search in actions + add button */}
|
|
366
|
+
<div>
|
|
367
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Users list</h4>
|
|
368
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
369
|
+
<div className="p-5">
|
|
370
|
+
<ITPageHeader
|
|
371
|
+
title="Users"
|
|
372
|
+
description="1,245 registered users · 38 active right now"
|
|
373
|
+
icon={<FaUsers size={20} />}
|
|
374
|
+
iconColor="#8b5cf6"
|
|
375
|
+
backAction={() => {}}
|
|
376
|
+
breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Users" }]}
|
|
377
|
+
actions={
|
|
378
|
+
<ITFlex gap={2}>
|
|
379
|
+
<div className="relative">
|
|
380
|
+
<FaSearch size={11} className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
|
|
381
|
+
<input type="text" placeholder="Search..." className="w-[180px] pl-9 pr-3 py-2 text-xs border border-slate-200 dark:border-slate-700 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" />
|
|
382
|
+
</div>
|
|
383
|
+
<ITButton label="Invite" variant="filled" color="primary" size="small" />
|
|
384
|
+
</ITFlex>
|
|
385
|
+
}
|
|
386
|
+
/>
|
|
387
|
+
</div>
|
|
388
|
+
</div>
|
|
112
389
|
</div>
|
|
113
390
|
</ITStack>
|
|
114
391
|
}
|
|
@@ -116,91 +393,531 @@ export const PageHeaderShowcase = () => {
|
|
|
116
393
|
);
|
|
117
394
|
};
|
|
118
395
|
|
|
396
|
+
const USERS: Record<string, unknown>[] = [
|
|
397
|
+
{ name: "Sofía Castillo", email: "sofia@axzy.dev", role: "Admin", active: true, lastLogin: "2026-07-18T09:30:00" },
|
|
398
|
+
{ name: "Daniela Klein", email: "daniela@axzy.dev", role: "Editor", active: true, lastLogin: "2026-07-17T14:22:00" },
|
|
399
|
+
{ name: "Mariana Reyes", email: "mariana@axzy.dev", role: "Viewer", active: false, lastLogin: "2026-07-10T11:00:00" },
|
|
400
|
+
{ name: "Camila Torres", email: "camila@axzy.dev", role: "Admin", active: true, lastLogin: "2026-07-18T08:15:00" },
|
|
401
|
+
{ name: "Valentina Méndez", email: "valentina@axzy.dev", role: "Editor", active: true, lastLogin: "2026-07-16T19:45:00" },
|
|
402
|
+
{ name: "Luciana Rivas", email: "luciana@axzy.dev", role: "Viewer", active: false, lastLogin: "2026-06-28T16:30:00" },
|
|
403
|
+
{ name: "Isabella Cruz", email: "isabella@axzy.dev", role: "Editor", active: true, lastLogin: "2026-07-18T10:05:00" },
|
|
404
|
+
{ name: "Gabriela Vargas", email: "gabriela@axzy.dev", role: "Admin", active: true, lastLogin: "2026-07-15T22:10:00" },
|
|
405
|
+
];
|
|
406
|
+
|
|
119
407
|
export const PageShowcase = () => {
|
|
120
408
|
const [state, setState] = useState<"normal" | "loading" | "error" | "empty">("normal");
|
|
409
|
+
const [screen, setScreen] = useState<"list" | "detail">("list");
|
|
410
|
+
const [selectedUser, setSelectedUser] = useState<Record<string, unknown> | null>(null);
|
|
411
|
+
const [showIcon, setShowIcon] = useState(true);
|
|
412
|
+
|
|
413
|
+
const isNormal = state === "normal";
|
|
414
|
+
const isDetail = screen === "detail";
|
|
121
415
|
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
416
|
+
const handleViewUser = (row: Record<string, unknown>) => {
|
|
417
|
+
setSelectedUser(row);
|
|
418
|
+
setScreen("detail");
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const handleBackToList = () => {
|
|
422
|
+
setScreen("list");
|
|
423
|
+
setSelectedUser(null);
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
const user = selectedUser;
|
|
427
|
+
const initials = user
|
|
428
|
+
? (user.name as string).split(" ").map((w: string) => w[0]).join("")
|
|
429
|
+
: "";
|
|
430
|
+
const userInitial = initials.charAt(0).toUpperCase();
|
|
431
|
+
const roleColor =
|
|
432
|
+
user?.role === "Admin"
|
|
433
|
+
? "bg-primary-100 text-primary-700 dark:bg-primary-950/40 dark:text-primary-300"
|
|
434
|
+
: user?.role === "Editor"
|
|
435
|
+
? "bg-blue-100 text-blue-700 dark:bg-blue-950/40 dark:text-blue-300"
|
|
436
|
+
: "bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-400";
|
|
437
|
+
|
|
438
|
+
const buildCode = () => {
|
|
439
|
+
if (isDetail && user) {
|
|
440
|
+
return `<ITPage
|
|
441
|
+
title="${user.name as string}"
|
|
442
|
+
description="Member · ${user.role as string}"
|
|
443
|
+
icon={<FaUsers size={20} />}
|
|
444
|
+
iconColor="#6366f1"
|
|
445
|
+
breadcrumbs={[{ label: "Team", href: "#" }, { label: user.name as string }]}
|
|
446
|
+
backAction={() => history.back()}
|
|
447
|
+
>
|
|
448
|
+
{/* User detail card */}
|
|
449
|
+
</ITPage>`;
|
|
450
|
+
}
|
|
451
|
+
return `<ITPage
|
|
452
|
+
title="Team members"
|
|
453
|
+
description="Manage your organization workspace"
|
|
454
|
+
icon={<FaUsers size={20} />}
|
|
455
|
+
iconColor="#6366f1"
|
|
456
|
+
breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Team" }]}
|
|
126
457
|
loading={isLoading}
|
|
127
458
|
error={error}
|
|
459
|
+
empty={isEmpty}
|
|
128
460
|
onRetry={refetch}
|
|
461
|
+
actions={<ITButton label="Invite" size="small" />}
|
|
129
462
|
>
|
|
130
|
-
<
|
|
131
|
-
<ITGrid item xs={12} sm={6} lg={3}>
|
|
132
|
-
<ITStatCard label="Usuarios" value="1,245" />
|
|
133
|
-
</ITGrid>
|
|
134
|
-
</ITGrid>
|
|
463
|
+
<ITTable columns={[...]} data={users} />
|
|
135
464
|
</ITPage>`;
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const columns: Column[] = [
|
|
468
|
+
{
|
|
469
|
+
key: "name",
|
|
470
|
+
label: "Name",
|
|
471
|
+
type: "string",
|
|
472
|
+
sortable: true,
|
|
473
|
+
filter: true,
|
|
474
|
+
render: (row: Record<string, unknown>) => (
|
|
475
|
+
<ITFlex gap={2.5} align="center">
|
|
476
|
+
<ITAvatar initials={(row.name as string).split(" ").map(w => w[0]).join("")} size="sm" />
|
|
477
|
+
<span className="font-semibold text-slate-800 dark:text-white">{row.name as string}</span>
|
|
478
|
+
</ITFlex>
|
|
479
|
+
),
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
key: "email",
|
|
483
|
+
label: "Email",
|
|
484
|
+
type: "string",
|
|
485
|
+
sortable: true,
|
|
486
|
+
filter: true,
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
key: "role",
|
|
490
|
+
label: "Role",
|
|
491
|
+
type: "string",
|
|
492
|
+
sortable: true,
|
|
493
|
+
filter: true,
|
|
494
|
+
render: (row: Record<string, unknown>) => (
|
|
495
|
+
<span className={`px-2 py-0.5 text-[11px] font-bold uppercase tracking-wider rounded-md ${
|
|
496
|
+
row.role === "Admin"
|
|
497
|
+
? "bg-primary-100 text-primary-700 dark:bg-primary-950/40 dark:text-primary-300"
|
|
498
|
+
: row.role === "Editor"
|
|
499
|
+
? "bg-blue-100 text-blue-700 dark:bg-blue-950/40 dark:text-blue-300"
|
|
500
|
+
: "bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-400"
|
|
501
|
+
}`}>
|
|
502
|
+
{row.role as string}
|
|
503
|
+
</span>
|
|
504
|
+
),
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
key: "active",
|
|
508
|
+
label: "Active",
|
|
509
|
+
type: "boolean",
|
|
510
|
+
filter: true,
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
key: "lastLogin",
|
|
514
|
+
label: "Last login",
|
|
515
|
+
type: "string",
|
|
516
|
+
sortable: true,
|
|
517
|
+
render: (row: Record<string, unknown>) => {
|
|
518
|
+
const date = new Date(row.lastLogin as string);
|
|
519
|
+
return (
|
|
520
|
+
<span className="text-slate-500 text-xs">
|
|
521
|
+
{date.toLocaleDateString("en-US", { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" })}
|
|
522
|
+
</span>
|
|
523
|
+
);
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
key: "actions",
|
|
528
|
+
label: "",
|
|
529
|
+
type: "actions",
|
|
530
|
+
actions: (row: Record<string, unknown>) => (
|
|
531
|
+
<ITFlex gap={1}>
|
|
532
|
+
<button
|
|
533
|
+
onClick={() => handleViewUser(row)}
|
|
534
|
+
className="p-1.5 rounded-md hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-500 hover:text-primary-600 transition-colors"
|
|
535
|
+
title="View detail"
|
|
536
|
+
>
|
|
537
|
+
<FaEye size={13} />
|
|
538
|
+
</button>
|
|
539
|
+
</ITFlex>
|
|
540
|
+
),
|
|
541
|
+
},
|
|
542
|
+
];
|
|
543
|
+
|
|
544
|
+
const shouldShowIcon = showIcon ? <FaUsers size={20} /> : undefined;
|
|
545
|
+
const shouldShowIconColor = showIcon ? "#6366f1" : undefined;
|
|
136
546
|
|
|
137
547
|
return (
|
|
138
548
|
<ShowcaseLayout
|
|
139
549
|
title="ITPage"
|
|
140
|
-
description="Template completo de página con estados
|
|
141
|
-
code={
|
|
550
|
+
description="Template completo de página con tabla, detalle y 4 estados (carga, error, vacío, normal)."
|
|
551
|
+
code={buildCode()}
|
|
142
552
|
demo={
|
|
143
|
-
<div className="w-full">
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
<ITCard title="Actividad Reciente">
|
|
173
|
-
<ITStack spacing={3}>
|
|
174
|
-
{[
|
|
175
|
-
{ user: "Ana López", action: "creó un reporte" },
|
|
176
|
-
{ user: "Carlos Ruiz", action: "aprobó orden #1234" },
|
|
177
|
-
{ user: "María García", action: "actualizó perfil" },
|
|
178
|
-
].map((item, i) => (
|
|
179
|
-
<ITFlex key={i} gap={3} align="center">
|
|
180
|
-
<ITAvatar initials={item.user.split(" ").map(w => w[0]).join("")} size="sm" color="bg-primary-500" />
|
|
181
|
-
<div className="flex-1 min-w-0">
|
|
182
|
-
<p className="text-xs font-semibold text-slate-700 dark:text-slate-200">{item.user}</p>
|
|
183
|
-
<p className="text-[10px] text-slate-400">{item.action}</p>
|
|
553
|
+
<div className="w-full border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
554
|
+
{isDetail && user ? (
|
|
555
|
+
<ITPage
|
|
556
|
+
title={user.name as string}
|
|
557
|
+
description={`Member · ${user.role as string} · ${(user.active as boolean) ? "Active" : "Inactive"}`}
|
|
558
|
+
icon={shouldShowIcon}
|
|
559
|
+
iconColor={shouldShowIconColor}
|
|
560
|
+
breadcrumbs={[{ label: "Team", href: "#" }, { label: user.name as string }]}
|
|
561
|
+
backAction={handleBackToList}
|
|
562
|
+
loading={state === "loading"}
|
|
563
|
+
error={state === "error" ? "Could not load user details. Please try again." : null}
|
|
564
|
+
errorTitle="Details error"
|
|
565
|
+
onRetry={() => setState("normal")}
|
|
566
|
+
empty={state === "empty"}
|
|
567
|
+
emptyTitle="No user data"
|
|
568
|
+
emptyDescription="No information available for this user."
|
|
569
|
+
>
|
|
570
|
+
<ITGrid container spacing={4}>
|
|
571
|
+
<ITGrid item xs={12} md={4}>
|
|
572
|
+
<ITCard>
|
|
573
|
+
<div className="flex flex-col items-center gap-4 py-4">
|
|
574
|
+
<ITAvatar initials={userInitial} size="xl" />
|
|
575
|
+
<div className="text-center">
|
|
576
|
+
<ITText as="p" className="text-lg font-bold text-slate-800 dark:text-white">{user.name as string}</ITText>
|
|
577
|
+
<ITText as="p" className="text-sm text-slate-500">{user.email as string}</ITText>
|
|
578
|
+
</div>
|
|
579
|
+
<span className={roleColor + " px-3 py-1 text-xs font-bold uppercase tracking-wider rounded-md"}>
|
|
580
|
+
{user.role as string}
|
|
581
|
+
</span>
|
|
184
582
|
</div>
|
|
185
|
-
</
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
583
|
+
</ITCard>
|
|
584
|
+
</ITGrid>
|
|
585
|
+
<ITGrid item xs={12} md={8}>
|
|
586
|
+
<ITCard title="Account details">
|
|
587
|
+
<ITStack spacing={4}>
|
|
588
|
+
{[
|
|
589
|
+
{ label: "Full name", value: user.name as string },
|
|
590
|
+
{ label: "Email address", value: user.email as string },
|
|
591
|
+
{ label: "Role", value: user.role as string },
|
|
592
|
+
{ label: "Status", value: (user.active as boolean) ? "Active" : "Inactive" },
|
|
593
|
+
{ label: "Last login", value: new Date(user.lastLogin as string).toLocaleString("en-US") },
|
|
594
|
+
].map((f) => (
|
|
595
|
+
<div key={f.label}>
|
|
596
|
+
<p className="text-[11px] font-bold uppercase tracking-wider text-slate-400 mb-0.5">{f.label}</p>
|
|
597
|
+
<p className="text-sm font-semibold text-slate-800 dark:text-white">{f.value}</p>
|
|
598
|
+
</div>
|
|
599
|
+
))}
|
|
600
|
+
</ITStack>
|
|
601
|
+
</ITCard>
|
|
602
|
+
</ITGrid>
|
|
603
|
+
</ITGrid>
|
|
604
|
+
</ITPage>
|
|
605
|
+
) : (
|
|
606
|
+
<ITPage
|
|
607
|
+
title="Team members"
|
|
608
|
+
description="Manage invitations, roles and permissions for your organization workspace."
|
|
609
|
+
icon={shouldShowIcon}
|
|
610
|
+
iconColor={shouldShowIconColor}
|
|
611
|
+
breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Team" }]}
|
|
612
|
+
loading={state === "loading"}
|
|
613
|
+
error={state === "error" ? "Could not load team members. Check your connection and try again." : null}
|
|
614
|
+
errorTitle="Connection error"
|
|
615
|
+
onRetry={() => setState("normal")}
|
|
616
|
+
empty={state === "empty"}
|
|
617
|
+
emptyTitle="No team members yet"
|
|
618
|
+
emptyDescription="Invite your first team member to get started."
|
|
619
|
+
emptyAction={<ITButton label="Invite members" size="small" icon={<FaPlus />} />}
|
|
620
|
+
actions={<ITButton label="Invite" size="small" icon={<FaPlus />} />}
|
|
621
|
+
>
|
|
622
|
+
<ITTable
|
|
623
|
+
columns={columns}
|
|
624
|
+
data={USERS}
|
|
625
|
+
size="sm"
|
|
626
|
+
defaultItemsPerPage={5}
|
|
627
|
+
title="All members"
|
|
628
|
+
/>
|
|
629
|
+
</ITPage>
|
|
630
|
+
)}
|
|
190
631
|
</div>
|
|
191
632
|
}
|
|
192
633
|
controls={
|
|
193
|
-
<
|
|
194
|
-
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
634
|
+
<ITStack spacing={4}>
|
|
635
|
+
<div>
|
|
636
|
+
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">Page state</p>
|
|
637
|
+
<ITFlex gap={2} wrap="wrap">
|
|
638
|
+
{(["normal", "loading", "error", "empty"] as const).map((s) => (
|
|
639
|
+
<ITButton
|
|
640
|
+
key={s}
|
|
641
|
+
label={s.charAt(0).toUpperCase() + s.slice(1)}
|
|
642
|
+
variant={state === s ? "filled" : "outlined"}
|
|
643
|
+
size="small"
|
|
644
|
+
onClick={() => setState(s)}
|
|
645
|
+
/>
|
|
646
|
+
))}
|
|
647
|
+
</ITFlex>
|
|
648
|
+
</div>
|
|
649
|
+
|
|
650
|
+
<ITFlex justify="between" align="center">
|
|
651
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Icon in header</span>
|
|
652
|
+
<ITSlideToggle isOn={showIcon} onToggle={setShowIcon} size="sm" />
|
|
653
|
+
</ITFlex>
|
|
654
|
+
|
|
655
|
+
{isNormal && (
|
|
656
|
+
<div>
|
|
657
|
+
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">Screen</p>
|
|
658
|
+
<ITFlex gap={2} wrap="wrap">
|
|
659
|
+
<ITButton
|
|
660
|
+
label="List"
|
|
661
|
+
variant={screen === "list" ? "filled" : "outlined"}
|
|
662
|
+
size="small"
|
|
663
|
+
onClick={() => handleBackToList()}
|
|
664
|
+
/>
|
|
665
|
+
<ITButton
|
|
666
|
+
label="Detail (last viewed)"
|
|
667
|
+
variant={screen === "detail" ? "filled" : "outlined"}
|
|
668
|
+
size="small"
|
|
669
|
+
disabled={!selectedUser}
|
|
670
|
+
onClick={() => screen === "list" && selectedUser ? setScreen("detail") : handleBackToList()}
|
|
671
|
+
/>
|
|
672
|
+
</ITFlex>
|
|
673
|
+
{selectedUser && (
|
|
674
|
+
<p className="text-xs text-slate-500 mt-2">
|
|
675
|
+
Selected: <span className="font-semibold text-slate-700 dark:text-slate-200">{selectedUser.name as string}</span>
|
|
676
|
+
</p>
|
|
677
|
+
)}
|
|
678
|
+
</div>
|
|
679
|
+
)}
|
|
680
|
+
</ITStack>
|
|
681
|
+
}
|
|
682
|
+
gallery={
|
|
683
|
+
<ITStack spacing={6}>
|
|
684
|
+
{/* 1. Users list with ITTable */}
|
|
685
|
+
<div>
|
|
686
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Users — table with actions</h4>
|
|
687
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
688
|
+
<ITPage
|
|
689
|
+
title="Users"
|
|
690
|
+
description="1,245 registered · 38 active now"
|
|
691
|
+
icon={<FaUsers size={20} />}
|
|
692
|
+
iconColor="#6366f1"
|
|
693
|
+
breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Users" }]}
|
|
694
|
+
actions={
|
|
695
|
+
<ITFlex gap={2}>
|
|
696
|
+
<ITButton label="Export" variant="outlined" size="small" icon={<FaDownload />} />
|
|
697
|
+
<ITButton label="Add user" size="small" icon={<FaPlus />} />
|
|
698
|
+
</ITFlex>
|
|
699
|
+
}
|
|
700
|
+
>
|
|
701
|
+
<ITTable
|
|
702
|
+
columns={columns}
|
|
703
|
+
data={USERS}
|
|
704
|
+
size="sm"
|
|
705
|
+
defaultItemsPerPage={5}
|
|
706
|
+
/>
|
|
707
|
+
</ITPage>
|
|
708
|
+
</div>
|
|
709
|
+
</div>
|
|
710
|
+
|
|
711
|
+
{/* 2. Product detail */}
|
|
712
|
+
<div>
|
|
713
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Product detail</h4>
|
|
714
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
715
|
+
<ITPage
|
|
716
|
+
title="MacBook Pro 16'' M3 Max"
|
|
717
|
+
description="SKU: MBP-16-M3MAX-2024 · Stock: 24"
|
|
718
|
+
icon={<FaBoxOpen size={20} />}
|
|
719
|
+
iconColor="#ec4899"
|
|
720
|
+
breadcrumbs={[{ label: "Products", href: "#" }, { label: "MacBook Pro 16" }]}
|
|
721
|
+
backAction={() => {}}
|
|
722
|
+
actions={
|
|
723
|
+
<ITFlex gap={2}>
|
|
724
|
+
<ITButton label="Delete" variant="outlined" color="gray" size="small" icon={<FaTrash />} />
|
|
725
|
+
<ITButton label="Edit" size="small" icon={<FaEdit />} />
|
|
726
|
+
</ITFlex>
|
|
727
|
+
}
|
|
728
|
+
>
|
|
729
|
+
<ITGrid container spacing={3}>
|
|
730
|
+
<ITGrid item xs={12} md={5}>
|
|
731
|
+
<ITCard>
|
|
732
|
+
<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">
|
|
733
|
+
<FaBoxOpen className="text-6xl text-slate-400" />
|
|
734
|
+
</div>
|
|
735
|
+
</ITCard>
|
|
736
|
+
</ITGrid>
|
|
737
|
+
<ITGrid item xs={12} md={7}>
|
|
738
|
+
<ITStack spacing={3}>
|
|
739
|
+
<ITCard title="Pricing">
|
|
740
|
+
<ITFlex align="baseline" gap={2}>
|
|
741
|
+
<span className="text-3xl font-extrabold text-slate-800 dark:text-white">$3,499</span>
|
|
742
|
+
<span className="text-sm text-slate-400 line-through">$3,799</span>
|
|
743
|
+
<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>
|
|
744
|
+
</ITFlex>
|
|
745
|
+
</ITCard>
|
|
746
|
+
<ITCard title="Description">
|
|
747
|
+
<ITText className="text-sm text-slate-600 dark:text-slate-300">
|
|
748
|
+
Extreme performance for professionals. M3 Max chip with 16-core CPU, 40-core GPU, and 64GB unified memory.
|
|
749
|
+
</ITText>
|
|
750
|
+
</ITCard>
|
|
751
|
+
</ITStack>
|
|
752
|
+
</ITGrid>
|
|
753
|
+
</ITGrid>
|
|
754
|
+
</ITPage>
|
|
755
|
+
</div>
|
|
756
|
+
</div>
|
|
757
|
+
|
|
758
|
+
{/* 3. Edit profile form */}
|
|
759
|
+
<div>
|
|
760
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Edit profile</h4>
|
|
761
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
762
|
+
<ITPage
|
|
763
|
+
title="Edit profile"
|
|
764
|
+
description="Update your personal information and contact details"
|
|
765
|
+
icon={<FaEdit size={20} />}
|
|
766
|
+
iconColor="#10b981"
|
|
767
|
+
breadcrumbs={[{ label: "Account", href: "#" }, { label: "Edit profile" }]}
|
|
768
|
+
backAction={() => {}}
|
|
769
|
+
actions={
|
|
770
|
+
<ITFlex gap={2}>
|
|
771
|
+
<ITButton label="Cancel" variant="outlined" color="gray" size="small" />
|
|
772
|
+
<ITButton label="Save changes" size="small" icon={<FaSave />} />
|
|
773
|
+
</ITFlex>
|
|
774
|
+
}
|
|
775
|
+
>
|
|
776
|
+
<ITGrid container spacing={3}>
|
|
777
|
+
<ITGrid item xs={12} md={4}>
|
|
778
|
+
<ITCard title="Profile photo">
|
|
779
|
+
<div className="flex flex-col items-center gap-4">
|
|
780
|
+
<ITAvatar initials="AL" size="xl" />
|
|
781
|
+
<ITButton label="Upload image" variant="outlined" size="small" />
|
|
782
|
+
</div>
|
|
783
|
+
</ITCard>
|
|
784
|
+
</ITGrid>
|
|
785
|
+
<ITGrid item xs={12} md={8}>
|
|
786
|
+
<ITCard title="Personal information">
|
|
787
|
+
<ITGrid container spacing={3}>
|
|
788
|
+
<ITGrid item xs={12} sm={6}>
|
|
789
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">First name</label>
|
|
790
|
+
<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" />
|
|
791
|
+
</ITGrid>
|
|
792
|
+
<ITGrid item xs={12} sm={6}>
|
|
793
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Last name</label>
|
|
794
|
+
<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" />
|
|
795
|
+
</ITGrid>
|
|
796
|
+
<ITGrid item xs={12}>
|
|
797
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Email</label>
|
|
798
|
+
<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" />
|
|
799
|
+
</ITGrid>
|
|
800
|
+
</ITGrid>
|
|
801
|
+
</ITCard>
|
|
802
|
+
</ITGrid>
|
|
803
|
+
</ITGrid>
|
|
804
|
+
</ITPage>
|
|
805
|
+
</div>
|
|
806
|
+
</div>
|
|
807
|
+
|
|
808
|
+
{/* 4. Orders with table */}
|
|
809
|
+
<div>
|
|
810
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Orders — status table</h4>
|
|
811
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
812
|
+
<ITPage
|
|
813
|
+
title="Orders"
|
|
814
|
+
description="89 pending · 1,247 completed this month"
|
|
815
|
+
icon={<FaShoppingCart size={20} />}
|
|
816
|
+
iconColor="#f59e0b"
|
|
817
|
+
breadcrumbs={[{ label: "Dashboard", href: "#" }, { label: "Orders" }]}
|
|
818
|
+
actions={
|
|
819
|
+
<ITFlex gap={2}>
|
|
820
|
+
<ITButton label="Export" variant="outlined" color="gray" size="small" icon={<FaDownload />} />
|
|
821
|
+
<ITButton label="New order" size="small" icon={<FaPlus />} />
|
|
822
|
+
</ITFlex>
|
|
823
|
+
}
|
|
824
|
+
>
|
|
825
|
+
<ITTable
|
|
826
|
+
columns={[
|
|
827
|
+
{ key: "order", label: "Order", type: "string", sortable: true, render: (r: Record<string, unknown>) => <span className="font-mono font-semibold text-primary-600">#{r.order as string}</span> },
|
|
828
|
+
{ key: "customer", label: "Customer", type: "string", sortable: true, filter: true },
|
|
829
|
+
{ key: "status", label: "Status", type: "string", render: (r: Record<string, unknown>) => {
|
|
830
|
+
const s = r.status as string;
|
|
831
|
+
const c = s === "Completed" ? "bg-emerald-100 text-emerald-700 dark:bg-emerald-950/30 dark:text-emerald-300" :
|
|
832
|
+
s === "Pending" ? "bg-amber-100 text-amber-700 dark:bg-amber-950/30 dark:text-amber-300" :
|
|
833
|
+
"bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-400";
|
|
834
|
+
return <span className={`px-2 py-0.5 text-[11px] font-bold uppercase tracking-wider rounded-md ${c}`}>{s}</span>;
|
|
835
|
+
}},
|
|
836
|
+
{ key: "total", label: "Total", type: "number", sortable: true, currencyMX: true },
|
|
837
|
+
{ key: "actions", label: "", type: "actions", actions: () => (
|
|
838
|
+
<ITFlex gap={1}>
|
|
839
|
+
<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={13} /></button>
|
|
840
|
+
</ITFlex>
|
|
841
|
+
)},
|
|
842
|
+
]}
|
|
843
|
+
data={[
|
|
844
|
+
{ order: "ORD-1042", customer: "Sofía Castillo", status: "Completed", total: 3499 },
|
|
845
|
+
{ order: "ORD-1043", customer: "Daniela Klein", status: "Pending", total: 1299 },
|
|
846
|
+
{ order: "ORD-1044", customer: "Mariana Reyes", status: "Completed", total: 549 },
|
|
847
|
+
{ order: "ORD-1045", customer: "Camila Torres", status: "Pending", total: 2199 },
|
|
848
|
+
{ order: "ORD-1046", customer: "Valentina Méndez", status: "Cancelled", total: 799 },
|
|
849
|
+
{ order: "ORD-1047", customer: "Luciana Rivas", status: "Completed", total: 4999 },
|
|
850
|
+
{ order: "ORD-1048", customer: "Isabella Cruz", status: "Pending", total: 1599 },
|
|
851
|
+
{ order: "ORD-1049", customer: "Gabriela Vargas", status: "Completed", total: 899 },
|
|
852
|
+
] as Record<string, unknown>[]}
|
|
853
|
+
size="sm"
|
|
854
|
+
defaultItemsPerPage={5}
|
|
855
|
+
/>
|
|
856
|
+
</ITPage>
|
|
857
|
+
</div>
|
|
858
|
+
</div>
|
|
859
|
+
|
|
860
|
+
{/* 5. Settings with tabs */}
|
|
861
|
+
<div>
|
|
862
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Settings</h4>
|
|
863
|
+
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
864
|
+
<ITPage
|
|
865
|
+
title="Settings"
|
|
866
|
+
description="Manage your account and workspace preferences"
|
|
867
|
+
icon={<FaCog size={20} />}
|
|
868
|
+
iconColor="#10b981"
|
|
869
|
+
breadcrumbs={[{ label: "Account", href: "#" }, { label: "Settings" }]}
|
|
870
|
+
>
|
|
871
|
+
<ITGrid container spacing={3}>
|
|
872
|
+
<ITGrid item xs={12} md={4}>
|
|
873
|
+
<ITCard>
|
|
874
|
+
<ITStack spacing={1}>
|
|
875
|
+
{[
|
|
876
|
+
{ id: "general", label: "General", icon: <FaCog />, active: true },
|
|
877
|
+
{ id: "notif", label: "Notifications", icon: <FaBell /> },
|
|
878
|
+
{ id: "sec", label: "Security", icon: <FaShieldAlt /> },
|
|
879
|
+
{ id: "apariencia", label: "Appearance", icon: <FaPalette /> },
|
|
880
|
+
{ id: "billing", label: "Billing", icon: <FaDollarSign /> },
|
|
881
|
+
].map(item => (
|
|
882
|
+
<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"}`}>
|
|
883
|
+
<span className="text-base">{item.icon}</span>
|
|
884
|
+
{item.label}
|
|
885
|
+
</button>
|
|
886
|
+
))}
|
|
887
|
+
</ITStack>
|
|
888
|
+
</ITCard>
|
|
889
|
+
</ITGrid>
|
|
890
|
+
<ITGrid item xs={12} md={8}>
|
|
891
|
+
<ITCard title="General preferences">
|
|
892
|
+
<ITStack spacing={4}>
|
|
893
|
+
<div>
|
|
894
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Workspace name</label>
|
|
895
|
+
<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" />
|
|
896
|
+
</div>
|
|
897
|
+
<ITStack spacing={3} className="pt-2 border-t border-slate-100 dark:border-slate-800">
|
|
898
|
+
<ITFlex justify="between" align="center">
|
|
899
|
+
<div>
|
|
900
|
+
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">Dark mode</p>
|
|
901
|
+
<p className="text-xs text-slate-500">Follow system appearance</p>
|
|
902
|
+
</div>
|
|
903
|
+
<ITSlideToggle isOn={true} onToggle={() => {}} size="sm" />
|
|
904
|
+
</ITFlex>
|
|
905
|
+
<ITFlex justify="between" align="center">
|
|
906
|
+
<div>
|
|
907
|
+
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">Email notifications</p>
|
|
908
|
+
<p className="text-xs text-slate-500">Receive activity alerts</p>
|
|
909
|
+
</div>
|
|
910
|
+
<ITSlideToggle isOn={false} onToggle={() => {}} size="sm" />
|
|
911
|
+
</ITFlex>
|
|
912
|
+
</ITStack>
|
|
913
|
+
</ITStack>
|
|
914
|
+
</ITCard>
|
|
915
|
+
</ITGrid>
|
|
916
|
+
</ITGrid>
|
|
917
|
+
</ITPage>
|
|
918
|
+
</div>
|
|
919
|
+
</div>
|
|
920
|
+
</ITStack>
|
|
204
921
|
}
|
|
205
922
|
/>
|
|
206
923
|
);
|