@axzydev/axzy_ui_system 1.2.7 → 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 +576 -398
- 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 +1463 -86
- package/dist/index.d.ts +1463 -86
- package/dist/index.js +597 -417
- 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 +19 -0
- 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 +29 -2
- 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 +27 -0
- package/src/components/page/page.doc.mdx +80 -0
- package/src/components/page/page.props.ts +21 -0
- package/src/components/page/page.tsx +18 -0
- package/src/components/page-header/page-header.doc.mdx +54 -0
- package/src/components/page-header/page-header.props.ts +9 -0
- package/src/components/page-header/page-header.tsx +15 -0
- 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 +2 -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 +688 -391
- package/src/showcases/ShowcaseLayout.tsx +237 -73
- package/src/showcases/StructureShowcases.tsx +846 -73
- package/src/types/table.types.ts +1 -1
- package/src/utils/styles.ts +2 -1
|
@@ -39,158 +39,353 @@ import ITFlex from "../components/flex/flex";
|
|
|
39
39
|
import ITAvatar from "../components/avatar/avatar";
|
|
40
40
|
import ITSlideToggle from "../components/slide/slide";
|
|
41
41
|
import ITText from "@/components/text/text";
|
|
42
|
+
import ITTable from "@/components/table/table";
|
|
43
|
+
import type { Column } from "@/components/table/table.props";
|
|
42
44
|
import { ShowcaseLayout } from "./ShowcaseLayout";
|
|
43
45
|
|
|
44
46
|
export const PageHeaderShowcase = () => {
|
|
45
47
|
const [showBack, setShowBack] = useState(true);
|
|
46
48
|
const [showBreadcrumbs, setShowBreadcrumbs] = useState(true);
|
|
47
|
-
const [showDescription, setShowDescription] = useState(true);
|
|
48
|
-
const [showActions, setShowActions] = useState(true);
|
|
49
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);
|
|
50
54
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
breadcrumbs={[
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
+
);
|
|
62
81
|
|
|
63
82
|
return (
|
|
64
83
|
<ShowcaseLayout
|
|
65
84
|
title="ITPageHeader"
|
|
66
85
|
description="Encabezado estandarizado para pantallas. Incluye título, descripción, icono, breadcrumbs, botón de volver y área de acciones."
|
|
67
|
-
code={
|
|
86
|
+
code={buildCode()}
|
|
68
87
|
demo={
|
|
69
|
-
<div className="w-full
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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>
|
|
82
153
|
</div>
|
|
83
154
|
}
|
|
84
155
|
controls={
|
|
85
156
|
<ITStack spacing={4}>
|
|
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
|
-
|
|
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>
|
|
112
191
|
</div>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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>
|
|
118
207
|
</div>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
]}
|
|
127
|
-
actions={
|
|
128
|
-
<>
|
|
129
|
-
<ITButton label="Exportar" variant="outlined" size="small" />
|
|
130
|
-
<ITButton label="Nueva" size="small" />
|
|
131
|
-
</>
|
|
132
|
-
}
|
|
133
|
-
/>
|
|
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>
|
|
134
215
|
</div>
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
216
|
+
</ITStack>
|
|
217
|
+
}
|
|
218
|
+
gallery={
|
|
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>
|
|
151
281
|
</div>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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>
|
|
159
318
|
</div>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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>
|
|
172
344
|
</div>
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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>
|
|
180
363
|
</div>
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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>
|
|
194
389
|
</div>
|
|
195
390
|
</ITStack>
|
|
196
391
|
}
|
|
@@ -198,119 +393,247 @@ export const PageHeaderShowcase = () => {
|
|
|
198
393
|
);
|
|
199
394
|
};
|
|
200
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
|
+
|
|
201
407
|
export const PageShowcase = () => {
|
|
202
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);
|
|
203
411
|
const [showIcon, setShowIcon] = useState(true);
|
|
204
412
|
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
413
|
+
const isNormal = state === "normal";
|
|
414
|
+
const isDetail = screen === "detail";
|
|
415
|
+
|
|
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} />}
|
|
209
444
|
iconColor="#6366f1"
|
|
210
|
-
breadcrumbs={[{ label: "
|
|
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" }]}
|
|
211
457
|
loading={isLoading}
|
|
212
458
|
error={error}
|
|
213
459
|
empty={isEmpty}
|
|
214
460
|
onRetry={refetch}
|
|
461
|
+
actions={<ITButton label="Invite" size="small" />}
|
|
215
462
|
>
|
|
216
|
-
{
|
|
463
|
+
<ITTable columns={[...]} data={users} />
|
|
217
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;
|
|
218
546
|
|
|
219
547
|
return (
|
|
220
548
|
<ShowcaseLayout
|
|
221
549
|
title="ITPage"
|
|
222
|
-
description="Template completo de página con estados
|
|
223
|
-
code={
|
|
550
|
+
description="Template completo de página con tabla, detalle y 4 estados (carga, error, vacío, normal)."
|
|
551
|
+
code={buildCode()}
|
|
224
552
|
demo={
|
|
225
553
|
<div className="w-full border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden bg-white dark:bg-slate-900/50">
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
{ label: "
|
|
233
|
-
{
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
key={
|
|
268
|
-
|
|
269
|
-
|
|
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>
|
|
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>
|
|
582
|
+
</div>
|
|
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>
|
|
299
598
|
</div>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
</ITCard>
|
|
599
|
+
))}
|
|
600
|
+
</ITStack>
|
|
601
|
+
</ITCard>
|
|
602
|
+
</ITGrid>
|
|
305
603
|
</ITGrid>
|
|
306
|
-
</
|
|
307
|
-
|
|
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
|
+
)}
|
|
308
631
|
</div>
|
|
309
632
|
}
|
|
310
633
|
controls={
|
|
311
634
|
<ITStack spacing={4}>
|
|
312
635
|
<div>
|
|
313
|
-
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">
|
|
636
|
+
<p className="text-xs font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2">Page state</p>
|
|
314
637
|
<ITFlex gap={2} wrap="wrap">
|
|
315
638
|
{(["normal", "loading", "error", "empty"] as const).map((s) => (
|
|
316
639
|
<ITButton
|
|
@@ -323,93 +646,84 @@ export const PageShowcase = () => {
|
|
|
323
646
|
))}
|
|
324
647
|
</ITFlex>
|
|
325
648
|
</div>
|
|
649
|
+
|
|
326
650
|
<ITFlex justify="between" align="center">
|
|
327
|
-
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">
|
|
651
|
+
<span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Icon in header</span>
|
|
328
652
|
<ITSlideToggle isOn={showIcon} onToggle={setShowIcon} size="sm" />
|
|
329
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
|
+
)}
|
|
330
680
|
</ITStack>
|
|
331
681
|
}
|
|
332
682
|
gallery={
|
|
333
683
|
<ITStack spacing={6}>
|
|
684
|
+
{/* 1. Users list with ITTable */}
|
|
334
685
|
<div>
|
|
335
|
-
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">
|
|
686
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Users — table with actions</h4>
|
|
336
687
|
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
337
688
|
<ITPage
|
|
338
|
-
title="
|
|
339
|
-
description="1,245
|
|
689
|
+
title="Users"
|
|
690
|
+
description="1,245 registered · 38 active now"
|
|
340
691
|
icon={<FaUsers size={20} />}
|
|
341
692
|
iconColor="#6366f1"
|
|
342
|
-
breadcrumbs={[{ label: "
|
|
693
|
+
breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Users" }]}
|
|
343
694
|
actions={
|
|
344
|
-
|
|
345
|
-
<ITButton label="
|
|
346
|
-
<ITButton label="
|
|
347
|
-
|
|
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>
|
|
348
699
|
}
|
|
349
700
|
>
|
|
350
|
-
<
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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>
|
|
701
|
+
<ITTable
|
|
702
|
+
columns={columns}
|
|
703
|
+
data={USERS}
|
|
704
|
+
size="sm"
|
|
705
|
+
defaultItemsPerPage={5}
|
|
706
|
+
/>
|
|
390
707
|
</ITPage>
|
|
391
708
|
</div>
|
|
392
709
|
</div>
|
|
393
710
|
|
|
711
|
+
{/* 2. Product detail */}
|
|
394
712
|
<div>
|
|
395
|
-
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">
|
|
713
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Product detail</h4>
|
|
396
714
|
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
397
715
|
<ITPage
|
|
398
716
|
title="MacBook Pro 16'' M3 Max"
|
|
399
|
-
description="SKU: MBP-16-M3MAX-2024 · Stock: 24
|
|
717
|
+
description="SKU: MBP-16-M3MAX-2024 · Stock: 24"
|
|
400
718
|
icon={<FaBoxOpen size={20} />}
|
|
401
719
|
iconColor="#ec4899"
|
|
402
|
-
breadcrumbs={[
|
|
403
|
-
{ label: "Inicio", href: "#" },
|
|
404
|
-
{ label: "Productos", href: "#" },
|
|
405
|
-
{ label: "MacBook Pro 16" },
|
|
406
|
-
]}
|
|
720
|
+
breadcrumbs={[{ label: "Products", href: "#" }, { label: "MacBook Pro 16" }]}
|
|
407
721
|
backAction={() => {}}
|
|
408
722
|
actions={
|
|
409
|
-
|
|
410
|
-
<ITButton label="
|
|
411
|
-
<ITButton label="
|
|
412
|
-
|
|
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>
|
|
413
727
|
}
|
|
414
728
|
>
|
|
415
729
|
<ITGrid container spacing={3}>
|
|
@@ -418,124 +732,71 @@ export const PageShowcase = () => {
|
|
|
418
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">
|
|
419
733
|
<FaBoxOpen className="text-6xl text-slate-400" />
|
|
420
734
|
</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
735
|
</ITCard>
|
|
427
736
|
</ITGrid>
|
|
428
737
|
<ITGrid item xs={12} md={7}>
|
|
429
|
-
<
|
|
430
|
-
<
|
|
431
|
-
<
|
|
432
|
-
<
|
|
433
|
-
<
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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>
|
|
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>
|
|
468
752
|
</ITGrid>
|
|
469
753
|
</ITGrid>
|
|
470
754
|
</ITPage>
|
|
471
755
|
</div>
|
|
472
756
|
</div>
|
|
473
757
|
|
|
758
|
+
{/* 3. Edit profile form */}
|
|
474
759
|
<div>
|
|
475
|
-
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">
|
|
760
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Edit profile</h4>
|
|
476
761
|
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
477
762
|
<ITPage
|
|
478
|
-
title="
|
|
479
|
-
description="
|
|
763
|
+
title="Edit profile"
|
|
764
|
+
description="Update your personal information and contact details"
|
|
480
765
|
icon={<FaEdit size={20} />}
|
|
481
766
|
iconColor="#10b981"
|
|
482
|
-
breadcrumbs={[
|
|
483
|
-
{ label: "Inicio", href: "#" },
|
|
484
|
-
{ label: "Mi cuenta", href: "#" },
|
|
485
|
-
{ label: "Editar perfil" },
|
|
486
|
-
]}
|
|
767
|
+
breadcrumbs={[{ label: "Account", href: "#" }, { label: "Edit profile" }]}
|
|
487
768
|
backAction={() => {}}
|
|
488
769
|
actions={
|
|
489
|
-
|
|
490
|
-
<ITButton label="
|
|
491
|
-
<ITButton label="
|
|
492
|
-
|
|
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>
|
|
493
774
|
}
|
|
494
775
|
>
|
|
495
776
|
<ITGrid container spacing={3}>
|
|
496
777
|
<ITGrid item xs={12} md={4}>
|
|
497
|
-
<ITCard title="
|
|
778
|
+
<ITCard title="Profile photo">
|
|
498
779
|
<div className="flex flex-col items-center gap-4">
|
|
499
|
-
<ITAvatar initials="AL" size="xl"
|
|
500
|
-
<
|
|
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" />
|
|
780
|
+
<ITAvatar initials="AL" size="xl" />
|
|
781
|
+
<ITButton label="Upload image" variant="outlined" size="small" />
|
|
505
782
|
</div>
|
|
506
783
|
</ITCard>
|
|
507
784
|
</ITGrid>
|
|
508
785
|
<ITGrid item xs={12} md={8}>
|
|
509
|
-
<ITCard title="
|
|
786
|
+
<ITCard title="Personal information">
|
|
510
787
|
<ITGrid container spacing={3}>
|
|
511
788
|
<ITGrid item xs={12} sm={6}>
|
|
512
|
-
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">
|
|
789
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">First name</label>
|
|
513
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" />
|
|
514
791
|
</ITGrid>
|
|
515
792
|
<ITGrid item xs={12} sm={6}>
|
|
516
|
-
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">
|
|
793
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Last name</label>
|
|
517
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" />
|
|
518
795
|
</ITGrid>
|
|
519
796
|
<ITGrid item xs={12}>
|
|
520
797
|
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Email</label>
|
|
521
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" />
|
|
522
799
|
</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
800
|
</ITGrid>
|
|
540
801
|
</ITCard>
|
|
541
802
|
</ITGrid>
|
|
@@ -544,15 +805,68 @@ export const PageShowcase = () => {
|
|
|
544
805
|
</div>
|
|
545
806
|
</div>
|
|
546
807
|
|
|
808
|
+
{/* 4. Orders with table */}
|
|
547
809
|
<div>
|
|
548
|
-
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">
|
|
810
|
+
<h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">Orders — status table</h4>
|
|
549
811
|
<div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden">
|
|
550
812
|
<ITPage
|
|
551
|
-
title="
|
|
552
|
-
description="
|
|
553
|
-
icon={<
|
|
813
|
+
title="Orders"
|
|
814
|
+
description="89 pending · 1,247 completed this month"
|
|
815
|
+
icon={<FaShoppingCart size={20} />}
|
|
554
816
|
iconColor="#f59e0b"
|
|
555
|
-
breadcrumbs={[{ label: "
|
|
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" }]}
|
|
556
870
|
>
|
|
557
871
|
<ITGrid container spacing={3}>
|
|
558
872
|
<ITGrid item xs={12} md={4}>
|
|
@@ -560,11 +874,10 @@ export const PageShowcase = () => {
|
|
|
560
874
|
<ITStack spacing={1}>
|
|
561
875
|
{[
|
|
562
876
|
{ id: "general", label: "General", icon: <FaCog />, active: true },
|
|
563
|
-
{ id: "notif", label: "
|
|
564
|
-
{ id: "sec", label: "
|
|
565
|
-
{ id: "apariencia", label: "
|
|
566
|
-
{ id: "
|
|
567
|
-
{ id: "billing", label: "Facturación", icon: <FaDollarSign /> },
|
|
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 /> },
|
|
568
881
|
].map(item => (
|
|
569
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"}`}>
|
|
570
883
|
<span className="text-base">{item.icon}</span>
|
|
@@ -575,40 +888,24 @@ export const PageShowcase = () => {
|
|
|
575
888
|
</ITCard>
|
|
576
889
|
</ITGrid>
|
|
577
890
|
<ITGrid item xs={12} md={8}>
|
|
578
|
-
<ITCard title="
|
|
891
|
+
<ITCard title="General preferences">
|
|
579
892
|
<ITStack spacing={4}>
|
|
580
893
|
<div>
|
|
581
|
-
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">
|
|
894
|
+
<label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Workspace name</label>
|
|
582
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" />
|
|
583
896
|
</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
897
|
<ITStack spacing={3} className="pt-2 border-t border-slate-100 dark:border-slate-800">
|
|
601
898
|
<ITFlex justify="between" align="center">
|
|
602
899
|
<div>
|
|
603
|
-
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">
|
|
604
|
-
<p className="text-xs text-slate-500">
|
|
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>
|
|
605
902
|
</div>
|
|
606
903
|
<ITSlideToggle isOn={true} onToggle={() => {}} size="sm" />
|
|
607
904
|
</ITFlex>
|
|
608
905
|
<ITFlex justify="between" align="center">
|
|
609
906
|
<div>
|
|
610
|
-
<p className="text-sm font-semibold text-slate-700 dark:text-slate-200">
|
|
611
|
-
<p className="text-xs text-slate-500">
|
|
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>
|
|
612
909
|
</div>
|
|
613
910
|
<ITSlideToggle isOn={false} onToggle={() => {}} size="sm" />
|
|
614
911
|
</ITFlex>
|