Skip to content

Commit 38912a3

Browse files
committed
feat(ajustes): zona admin tipo AdminBar, precios en una fila, conexión bajo apariencia
1 parent acd2c18 commit 38912a3

1 file changed

Lines changed: 56 additions & 33 deletions

File tree

‎app/src/pages/Ajustes.tsx‎

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
BatteryCharging,
77
Bell,
88
Check,
9+
ChevronDown,
910
FileText,
1011
Github,
1112
Heart,
@@ -97,13 +98,47 @@ function Section({
9798
);
9899
}
99100

100-
/** Cabecera de zona (no es tarjeta): delimita el territorio de administración. */
101-
function ZoneHeader({ title }: { title: string }) {
101+
/** Zona de administración (patrón AdminBar del skill): tarjeta horizontal con
102+
* borde de acento, título "Administración" y secciones desplegables a la derecha. */
103+
function AdminZone() {
104+
const { t } = useTranslation();
105+
const [open, setOpen] = useState(false);
102106
return (
103-
<div className="flex items-center gap-2 px-1 pt-1">
104-
<ShieldCheck size={15} strokeWidth={1.75} className="text-faint" />
105-
<h2 className="text-[13px] font-semibold uppercase tracking-[0.08em] text-faint">{title}</h2>
106-
</div>
107+
<motion.section
108+
initial={{ opacity: 0, y: 24 }}
109+
whileInView={{ opacity: 1, y: 0 }}
110+
viewport={{ once: true, amount: 0.15 }}
111+
transition={{ duration: 0.5, ease: easeOutQuart }}
112+
className="helios-card scroll-mt-20 rounded-l-lg border-l-4 border-l-amber-500 bg-amber-500/[0.03] p-5 shadow-card dark:shadow-card-dark"
113+
>
114+
<div className="flex flex-wrap items-center gap-3">
115+
<div className="flex h-9 items-center gap-2">
116+
<ShieldCheck size={18} strokeWidth={1.75} className="text-amber-500" />
117+
<h2 className="font-display text-[15px] font-semibold text-app">{t('ajustes.sections.administracion')}</h2>
118+
</div>
119+
<div className="hidden h-6 w-px bg-app sm:block" />
120+
<button
121+
type="button"
122+
aria-expanded={open}
123+
onClick={() => setOpen((v) => !v)}
124+
className={cn(
125+
'ml-auto inline-flex h-9 items-center gap-2 rounded-lg border px-3 text-[13px] font-medium transition-colors',
126+
open
127+
? 'border-amber-500 bg-amber-500/10 text-amber-500'
128+
: 'border-app bg-surface text-muted hover:bg-surface-2 hover:text-app',
129+
)}
130+
>
131+
<UserPlus size={16} strokeWidth={1.75} />
132+
<span className="hidden sm:inline">{t('ajustes.sections.usuarios')}</span>
133+
<ChevronDown size={14} className={cn('transition-transform', open && 'rotate-180')} />
134+
</button>
135+
</div>
136+
{open && (
137+
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="mt-4 border-t border-app pt-4">
138+
<UsersSection />
139+
</motion.div>
140+
)}
141+
</motion.section>
107142
);
108143
}
109144

@@ -623,7 +658,7 @@ function PricesSection() {
623658

624659
return (
625660
<div className="flex flex-col gap-4">
626-
<div className="grid max-w-md gap-4">
661+
<div className="grid gap-4 sm:grid-cols-3">
627662
{fields.map((f, i) => (
628663
<motion.div
629664
key={f.id}
@@ -1543,49 +1578,37 @@ export default function Ajustes() {
15431578

15441579
<div className="mx-auto flex w-full max-w-[1100px] flex-col gap-5">
15451580

1546-
{/* 1. Tu instalación (span-7) + Apariencia (span-5) en horizontal */}
1581+
{/* 1. Tu instalación (izquierda) + columna derecha: Apariencia y debajo Conexión
1582+
(aprovecha la diferencia de altura entre instalación y apariencia) */}
15471583
<div className="grid items-start gap-5 lg:grid-cols-12">
15481584
<div className="lg:col-span-7">
15491585
<Section id="instalacion" title={t('ajustes.sections.instalacion')}>
15501586
<InstallationSection />
15511587
</Section>
15521588
</div>
1553-
<div className="lg:col-span-5">
1589+
<div className="flex flex-col gap-5 lg:col-span-5">
15541590
<Section id="apariencia" title={t('ajustes.sections.apariencia')}>
15551591
<ThemeSection />
15561592
</Section>
1593+
<Section
1594+
id="conexion"
1595+
title={t('ajustes.sections.conexionDatos')}
1596+
badge={<HealthBadge ok={connectionStatus === 'connected' && dataOk} />}
1597+
>
1598+
<ConnectionSection />
1599+
</Section>
15571600
</div>
15581601
</div>
15591602

1560-
{/* 2. Conexión y datos (span-12, horizontal) */}
1561-
<Section
1562-
id="conexion"
1563-
title={t('ajustes.sections.conexionDatos')}
1564-
badge={<HealthBadge ok={connectionStatus === 'connected' && dataOk} />}
1565-
>
1566-
<ConnectionSection />
1567-
</Section>
1568-
1569-
{/* 3. Mi perfil (span-12) */}
1603+
{/* 2. Mi perfil (span-12) */}
15701604
<Section id="perfil" title={t('ajustes.sections.perfil')}>
15711605
<ProfileSection />
15721606
</Section>
15731607

1574-
{/* 4. Zona administración: Usuarios (admin, span-12) */}
1575-
{userRole === 'admin' && (
1576-
<>
1577-
<ZoneHeader title={t('ajustes.sections.administracion')} />
1578-
<Section
1579-
id="usuarios"
1580-
title={t('ajustes.sections.usuarios')}
1581-
className="border-amber-500/40 bg-amber-500/[0.03]"
1582-
>
1583-
<UsersSection />
1584-
</Section>
1585-
</>
1586-
)}
1608+
{/* 3. Zona administración (solo admin): barra AdminBar con Usuarios desplegable */}
1609+
{userRole === 'admin' && <AdminZone />}
15871610

1588-
{/* 5. Precios (span-12, abajo, fila vertical) */}
1611+
{/* 4. Precios (abajo, en una única fila) */}
15891612
<Section id="precios" title={t('ajustes.sections.precios')}>
15901613
<PricesSection />
15911614
</Section>

0 commit comments

Comments
 (0)