style: reskin NovaSpark en las 7 apps
Del look editorial (verde #1B4332, esquinas a 0, botones en mayusculas) al sistema NovaSpark: primario azul #2563EB, detalle naranja #F97316, fondo #F8FAFC con tarjetas blancas rounded-xl + shadow-sm, chips rounded-full semanticos, focus ring azul, transiciones 100-200ms. Incluye headers de tabla en los PDFs (cotizador y estado de cuenta).
This commit is contained in:
@@ -5,9 +5,11 @@ import { ConfiguracionCuenta } from './components/ConfiguracionCuenta'
|
||||
export default function App() {
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<header className="px-6 pt-20 pb-16 sm:px-12 lg:px-24">
|
||||
<p className="text-xs font-bold tracking-widest text-accent uppercase">FRASA Desarrollos</p>
|
||||
<h1 className="mt-4 text-4xl font-light text-neutral-900 sm:text-5xl">
|
||||
<header className="border-b border-[#E5E7EB] bg-white px-6 pt-20 pb-16 sm:px-12 lg:px-24">
|
||||
<p className="text-xs font-semibold tracking-wider text-accent uppercase">
|
||||
FRASA Desarrollos <span aria-hidden="true" className="text-[#F97316]">●</span>
|
||||
</p>
|
||||
<h1 className="mt-4 text-4xl font-light text-[#111827] sm:text-5xl">
|
||||
Ecosistema comercial
|
||||
</h1>
|
||||
</header>
|
||||
@@ -25,7 +27,7 @@ export default function App() {
|
||||
</main>
|
||||
|
||||
<footer className="px-6 pt-24 pb-10 sm:px-12 lg:px-24">
|
||||
<p className="text-xs text-neutral-400">Consult (AS) Technology</p>
|
||||
<p className="text-xs text-[#64748B]">Consult (AS) Technology</p>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,9 +2,9 @@ import { useEffect, useState, type FormEvent } from 'react'
|
||||
import { ErrorLogin, getSesion, login, logout, type UsuarioSesion } from '../services/auth'
|
||||
import { getMe, getUsuariosMonday, guardarVinculoMonday, type UsuarioMonday } from '../services/api'
|
||||
|
||||
const labelEstilo = 'block text-xs font-bold tracking-widest text-neutral-500 uppercase'
|
||||
const labelEstilo = 'block text-xs font-medium text-[#4B5563]'
|
||||
const inputEstilo =
|
||||
'mt-2 w-full border border-neutral-200 bg-white px-3 py-2 text-sm text-neutral-900 focus:border-neutral-900'
|
||||
'mt-2 w-full rounded-lg border border-[#D1D5DB] bg-white px-3 py-2.5 text-sm text-[#111827] transition-colors focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/20'
|
||||
|
||||
/**
|
||||
* Sección "Configuración de cuenta": login inline y, con sesión, el vínculo
|
||||
@@ -95,14 +95,17 @@ export function ConfiguracionCuenta() {
|
||||
perfil?.mondayUserId != null ? (usuarios?.find((u) => u.id === perfil.mondayUserId) ?? null) : null
|
||||
|
||||
return (
|
||||
<section aria-labelledby="titulo-cuenta" className="mt-24 border-t border-neutral-200 pt-16">
|
||||
<h2 id="titulo-cuenta" className="text-xs font-bold tracking-widest text-accent uppercase">
|
||||
<section aria-labelledby="titulo-cuenta" className="mt-24 border-t border-[#E5E7EB] pt-16">
|
||||
<h2 id="titulo-cuenta" className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">
|
||||
Configuración de cuenta
|
||||
</h2>
|
||||
|
||||
{!conSesion ? (
|
||||
<form onSubmit={(e) => void entrar(e)} className="mt-8 max-w-sm">
|
||||
<p className="text-sm leading-relaxed text-neutral-500">
|
||||
<form
|
||||
onSubmit={(e) => void entrar(e)}
|
||||
className="mt-8 max-w-sm rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-sm"
|
||||
>
|
||||
<p className="text-sm leading-relaxed text-[#64748B]">
|
||||
Inicia sesión para vincular tu usuario de Monday.
|
||||
</p>
|
||||
<div className="mt-6">
|
||||
@@ -134,55 +137,55 @@ export function ConfiguracionCuenta() {
|
||||
/>
|
||||
</div>
|
||||
{errorLogin && (
|
||||
<p role="alert" className="mt-4 text-xs text-red-700">
|
||||
<p role="alert" className="mt-4 text-sm text-red-600">
|
||||
{errorLogin}
|
||||
</p>
|
||||
)}
|
||||
<button
|
||||
type="submit"
|
||||
disabled={entrando}
|
||||
className="mt-6 bg-accent px-5 py-2.5 text-xs font-bold tracking-widest text-white uppercase transition-colors duration-150 hover:bg-neutral-900 disabled:opacity-50"
|
||||
className="mt-6 rounded-lg bg-accent px-5 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-100 ease-out hover:bg-accent-hover disabled:opacity-50"
|
||||
>
|
||||
{entrando ? 'Entrando…' : 'Entrar'}
|
||||
</button>
|
||||
</form>
|
||||
) : (
|
||||
<div className="mt-8 max-w-md">
|
||||
{cargandoPerfil && <p className="text-sm text-neutral-500">Cargando tu perfil…</p>}
|
||||
<div className="mt-8 max-w-md rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-sm">
|
||||
{cargandoPerfil && <p className="text-sm text-[#64748B]">Cargando tu perfil…</p>}
|
||||
|
||||
{perfil && (
|
||||
<>
|
||||
<p className="text-sm text-neutral-900">
|
||||
<p className="text-sm text-[#111827]">
|
||||
Sesión: <span className="font-medium">{perfil.nombre}</span>
|
||||
</p>
|
||||
<p className="mt-2 text-sm text-neutral-500">
|
||||
<p className="mt-2 text-sm text-[#64748B]">
|
||||
Vínculo Monday actual:{' '}
|
||||
{perfil.mondayUserId === null ? (
|
||||
<span className="text-neutral-400">sin vincular</span>
|
||||
<span className="text-[#94A3B8]">sin vincular</span>
|
||||
) : vinculado ? (
|
||||
<span className="text-neutral-900">
|
||||
<span className="text-[#111827]">
|
||||
{vinculado.nombre} ({vinculado.email})
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-neutral-900">ID {perfil.mondayUserId}</span>
|
||||
<span className="text-[#111827]">ID {perfil.mondayUserId}</span>
|
||||
)}
|
||||
</p>
|
||||
|
||||
{errorUsuarios ? (
|
||||
<div className="mt-6">
|
||||
<p role="alert" className="text-xs text-red-700">
|
||||
<p role="alert" className="text-sm text-red-600">
|
||||
{errorUsuarios}
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={cargarUsuarios}
|
||||
className="mt-3 border border-neutral-900 bg-transparent px-4 py-2 text-xs font-bold tracking-widest text-neutral-900 uppercase transition-colors duration-150 hover:bg-neutral-900 hover:text-white"
|
||||
className="mt-3 rounded-lg border border-[#D1D5DB] bg-white px-4 py-2.5 text-sm font-medium text-[#374151] shadow-sm transition-all duration-100 ease-out hover:bg-[#F9FAFB]"
|
||||
>
|
||||
Reintentar
|
||||
</button>
|
||||
</div>
|
||||
) : usuarios === null ? (
|
||||
<p className="mt-6 text-sm text-neutral-500">Cargando usuarios de Monday…</p>
|
||||
<p className="mt-6 text-sm text-[#64748B]">Cargando usuarios de Monday…</p>
|
||||
) : (
|
||||
<div className="mt-6">
|
||||
<label htmlFor="cuenta-monday" className={labelEstilo}>
|
||||
@@ -206,7 +209,7 @@ export function ConfiguracionCuenta() {
|
||||
type="button"
|
||||
disabled={guardando}
|
||||
onClick={() => void guardar(seleccion === '' ? null : Number(seleccion))}
|
||||
className="bg-accent px-5 py-2.5 text-xs font-bold tracking-widest text-white uppercase transition-colors duration-150 hover:bg-neutral-900 disabled:opacity-50"
|
||||
className="rounded-lg bg-accent px-5 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-100 ease-out hover:bg-accent-hover disabled:opacity-50"
|
||||
>
|
||||
{guardando ? 'Guardando…' : 'Guardar'}
|
||||
</button>
|
||||
@@ -215,7 +218,7 @@ export function ConfiguracionCuenta() {
|
||||
type="button"
|
||||
disabled={guardando}
|
||||
onClick={() => void guardar(null)}
|
||||
className="border border-red-300 bg-white px-5 py-2.5 text-xs font-bold tracking-widest text-red-700 uppercase transition-colors duration-150 hover:bg-red-50 disabled:opacity-50"
|
||||
className="rounded-lg border border-red-300 bg-white px-5 py-2.5 text-sm font-medium text-red-600 transition-all duration-100 ease-out hover:bg-red-50 disabled:opacity-50"
|
||||
>
|
||||
Desvincular
|
||||
</button>
|
||||
@@ -225,12 +228,12 @@ export function ConfiguracionCuenta() {
|
||||
)}
|
||||
|
||||
{aviso && (
|
||||
<p role="status" className="mt-4 text-xs font-bold tracking-widest text-accent uppercase">
|
||||
<p role="status" className="mt-4 text-sm font-medium text-green-600">
|
||||
{aviso}
|
||||
</p>
|
||||
)}
|
||||
{errorGuardar && (
|
||||
<p role="alert" className="mt-4 text-xs text-red-700">
|
||||
<p role="alert" className="mt-4 text-sm text-red-600">
|
||||
{errorGuardar}
|
||||
</p>
|
||||
)}
|
||||
@@ -240,7 +243,7 @@ export function ConfiguracionCuenta() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={cerrarSesion}
|
||||
className="mt-8 border border-neutral-900 bg-transparent px-4 py-2 text-xs font-bold tracking-widest text-neutral-900 uppercase transition-colors duration-150 hover:bg-neutral-900 hover:text-white"
|
||||
className="mt-8 rounded-lg border border-[#D1D5DB] bg-white px-4 py-2.5 text-sm font-medium text-[#374151] shadow-sm transition-all duration-100 ease-out hover:bg-[#F9FAFB]"
|
||||
>
|
||||
Cerrar sesión
|
||||
</button>
|
||||
|
||||
@@ -10,11 +10,11 @@ export function TarjetaModulo({ modulo }: Props) {
|
||||
<li>
|
||||
<a
|
||||
href={modulo.url}
|
||||
className="group flex h-full flex-col border border-neutral-200 bg-white p-8 transition-colors duration-150 hover:border-neutral-900"
|
||||
className="group flex h-full flex-col rounded-xl border border-[#E5E7EB] bg-white p-8 shadow-sm transition-all duration-200 ease-in-out hover:shadow-md"
|
||||
>
|
||||
<h2 className="text-2xl font-light text-neutral-900">{modulo.nombre}</h2>
|
||||
<p className="mt-3 text-sm leading-relaxed text-neutral-500">{modulo.descripcion}</p>
|
||||
<span className="mt-auto pt-8 text-xs font-bold tracking-widest text-accent uppercase">
|
||||
<h2 className="text-2xl font-light text-[#111827]">{modulo.nombre}</h2>
|
||||
<p className="mt-3 text-sm leading-relaxed text-[#64748B]">{modulo.descripcion}</p>
|
||||
<span className="mt-auto pt-8 text-sm font-medium text-accent transition-colors duration-100 ease-out group-hover:text-accent-hover">
|
||||
Entrar <span aria-hidden="true">→</span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
@@ -2,26 +2,18 @@
|
||||
|
||||
@theme {
|
||||
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||
--color-accent: #1B4332;
|
||||
--color-accent-hover: #132f23;
|
||||
--radius-xs: 0;
|
||||
--radius-sm: 0;
|
||||
--radius-md: 0;
|
||||
--radius-lg: 0;
|
||||
--radius-xl: 0;
|
||||
--radius-2xl: 0;
|
||||
--radius-3xl: 0;
|
||||
--radius-4xl: 0;
|
||||
--color-accent: #2563EB;
|
||||
--color-accent-hover: #1D4ED8;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply bg-white text-neutral-900 antialiased;
|
||||
@apply bg-[#F8FAFC] text-[#111827] antialiased;
|
||||
}
|
||||
|
||||
/* Foco visible accesible: outline en color de acento */
|
||||
/* Foco visible accesible: anillo azul en elementos interactivos */
|
||||
:focus-visible {
|
||||
outline: 2px solid #1B4332;
|
||||
outline-offset: 2px;
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user