Skip to content
View LuisJimenez19's full-sized avatar
💭
c:
💭
c:

Block or report LuisJimenez19

Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
LuisJimenez19/README.md

👋 Hola, soy Luis

Soy un desarrollador web apasionado por construir sitios web con un diseño atractivo y una buena experiencia de usuario. Entre las herramientas con las que más disfruto trabajar estan tecnologías como ReactJS, Tailwind CSS + ViteJS y el stack MERN (MySQL, Express, React, Node.js). También he trabajado con Laravel e InertiaJS. Me emociona ver cómo la tendencia actual de unificar el desarrollo backend y frontend resalta la importancia de cada área.

luisjimenez19
luisjimenez19
luisjimenez19

Puedes encontrarme en internet🌐

Te comparto;

¡Gracias por revisar mi perfil! Si tienes alguna pregunta o deseas colaborar en proyectos interesantes, no dudes en contactarme.

tour starter

import { setSteps, setIsOpen } from "@reactour/tour";
import { usersSteps } from "./users.tour";
import { groupsSteps } from "./groups.tour";
import { rolesSteps } from "./roles.tour";
import { clientsSteps } from "./clients.tour";
import { clientScopesSteps } from "./clientScopes.tour";
import { mappersSteps } from "./mappers.tour";

export const tourStarters = {
  users: () => {
    setSteps(usersSteps);
    setIsOpen(true);
  },
  groups: () => {
    setSteps(groupsSteps);
    setIsOpen(true);
  },
  roles: () => {
    setSteps(rolesSteps);
    setIsOpen(true);
  },
  clients: () => {
    setSteps(clientsSteps);
    setIsOpen(true);
  },
  clientScopes: () => {
    setSteps(clientScopesSteps);
    setIsOpen(true);
  },
  mappers: () => {
    setSteps(mappersSteps);
    setIsOpen(true);
  },
};

welcome tour

import { Button } from "@/components/ui/button";
import { tourStarters } from "./tourStarters";
import { useNavigate } from "react-router-dom";
import React from "react";

export const getDashboardTour = (navigate: ReturnType<typeof useNavigate>) => [
  {
    selector: "body",
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">
          👋 Bienvenido/a a la Consola Administrativa
        </h2>
        <p className="text-sm text-muted-foreground leading-relaxed">
          Esta aplicación te permite gestionar usuarios, grupos, permisos y
          clientes de manera simple, rápida y organizada.
          <br />
          <br />
          Empecemos con una vista general de lo que puedes hacer.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.cards"]',
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">📌 ¿Qué puedes hacer aquí?</h2>
        <p className="text-sm text-muted-foreground leading-relaxed">
          Desde esta consola puedes crear cuentas, organizar usuarios, gestionar
          permisos y administrar aplicaciones vinculadas a la plataforma.
          <br />
          Todo está organizado por secciones para que encuentres fácilmente lo
          que necesitas.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.users"]',
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">👤 Usuarios</h2>
        <p className="text-sm text-muted-foreground">
          Permite crear, editar y administrar cuentas de usuario.  
          También puedes asignar permisos, roles y grupos.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.groups"]',
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">🧩 Grupos</h2>
        <p className="text-sm text-muted-foreground">
          Los grupos sirven para organizar usuarios y asignar permisos
          colectivos.  
          Facilita gestionar conjuntos grandes de usuarios.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.roles"]',
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">🛡️ Roles</h2>
        <p className="text-sm text-muted-foreground">
          Los roles representan permisos específicos dentro del sistema.  
          Puedes asignarlos a usuarios o grupos según sus responsabilidades.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.clients"]',
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">💼 Clientes</h2>
        <p className="text-sm text-muted-foreground">
          Un cliente representa una aplicación que utiliza esta plataforma para
          autenticar usuarios y aplicar permisos.  
          Desde aquí puedes ver sus configuraciones y roles asociados.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.clientScopes"]',
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">🔧 Client Scopes</h2>
        <p className="text-sm text-muted-foreground">
          Un client scope es un conjunto de configuraciones reutilizables que se
          pueden asociar a múltiples clientes.  
          Controla qué información se envía al iniciar sesión o autorizar.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.mappers"]',
    content: () => (
      <div>
        <h2 className="text-lg font-semibold mb-2">🧱 Mappers</h2>
        <p className="text-sm text-muted-foreground">
          Los mappers definen qué datos se incluyen en los tokens y respuestas
          de autorización.  
          Pueden tomar valores del usuario o valores fijos según tu necesidad.
        </p>
      </div>
    ),
  },

  {
    selector: '[data-tour="dashboard.footer"]',
    content: () => (
      <div className="space-y-4">
        <h2 className="text-lg font-semibold mb-1">
          🎉 ¡Tour inicial completado!
        </h2>
        <p className="text-sm text-muted-foreground leading-relaxed">
          Ya conoces la estructura general de la consola.  
          Si deseas explorar más en detalle cada módulo, elige uno para
          continuar:
        </p>

        <div className="grid grid-cols-1 gap-2 mt-4">
          <Button
            variant="outline"
            onClick={() => {
              navigate("/users");
              tourStarters.users();
            }}
          >
            👤 Tour de Usuarios
          </Button>

          <Button
            variant="outline"
            onClick={() => {
              navigate("/groups");
              tourStarters.groups();
            }}
          >
            🧩 Tour de Grupos
          </Button>

          <Button
            variant="outline"
            onClick={() => {
              navigate("/roles");
              tourStarters.roles();
            }}
          >
            🛡️ Tour de Roles
          </Button>

          <Button
            variant="outline"
            onClick={() => {
              navigate("/clients");
              tourStarters.clients();
            }}
          >
            💼 Tour de Clientes
          </Button>

          <Button
            variant="outline"
            onClick={() => {
              navigate("/client-scopes");
              tourStarters.clientScopes();
            }}
          >
            🔧 Tour de Client Scopes
          </Button>

          <Button
            variant="outline"
            onClick={() => {
              navigate("/mappers");
              tourStarters.mappers();
            }}
          >
            🧱 Tour de Mappers
          </Button>
        </div>
      </div>
    ),
  },
];

selectores

<div data-tour="dashboard.cards">...</div>

<Link to="/users" data-tour="dashboard.users">...</Link>

<Link to="/groups" data-tour="dashboard.groups">...</Link>

<Link to="/roles" data-tour="dashboard.roles">...</Link>

<Link to="/clients" data-tour="dashboard.clients">...</Link>

<Link to="/client-scopes" data-tour="dashboard.clientScopes">...</Link>

<Link to="/mappers" data-tour="dashboard.mappers">...</Link>

<footer data-tour="dashboard.footer">...</footer>

users tour

import { StepType } from "@reactour/tour";
import { Title } from "@/components/tour/Title";
import { Paragraph } from "@/components/tour/Paragraph";
import { Footer } from "@/components/tour/Footer";
import { Button } from "@/components/ui/button";
import { EMOJIS } from "@/constants/emojis";

export const usersSteps: StepType[] = [
  {
    selector: "body",
    content: () => (
      <div>
        <Title text={`${EMOJIS.users} Gestión de Usuarios`} />
        <Paragraph text="En esta sección puedes administrar todas las cuentas del sistema: crear usuarios, editar información, modificar permisos y organizarlos en grupos." />
        <Footer text="Veamos cada parte de esta pantalla." />
      </div>
    ),
  },

  {
    selector: '[data-tour="users.title"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Título de la sección" />
        <Paragraph text="Aquí siempre podrás ver en qué módulo te encuentras. En este caso, estás administrando usuarios." />
      </div>
    ),
  },

  {
    selector: '[data-tour="users.table.filters"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Filtros y herramientas" />
        <Paragraph text="Puedes buscar usuarios por nombre de usuario y ajustar cuántos resultados se muestran por página." />
        <Footer text="Ideal para trabajar con listas largas." />
      </div>
    ),
  },

  {
    selector: '[data-tour="users.create"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Crear un nuevo usuario" />
        <Paragraph text="Aquí puedes añadir una nueva cuenta completando un formulario con información básica como nombre, apellido y correo electrónico." />
        <Footer text="La creación rápida te permite mantener el control del sistema." />
      </div>
    ),
  },

  {
    selector: '[data-tour="users.addToGroup"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Agregar usuarios a un grupo" />
        <Paragraph text="Selecciona varios usuarios y asígnalos a un grupo. Es útil cuando administras grandes equipos o áreas." />
      </div>
    ),
  },

  {
    selector: '[data-tour="users.table"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Lista de usuarios" />
        <Paragraph text="Aquí ves todos los usuarios registrados, junto con su información principal: email, nombres, estado y roles asignados." />
        <Footer text="Cada fila representa una cuenta del sistema." />
      </div>
    ),
  },

  {
    selector: '[data-tour="users.table.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones disponibles" />
        <Paragraph text="Desde aquí puedes editar datos del usuario, asignar roles, añadirlo a grupos, gestionar sus atributos e incluso cambiar su contraseña." />
        <Footer text="Todo al alcance de un clic." />
      </div>
    ),
  },

  {
    selector: '[data-tour="users.table.pagination"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Paginación" />
        <Paragraph text="Navega entre las páginas de resultados. Esto es especialmente útil cuando administras cientos o miles de usuarios." />
        <Footer text="Y listo. Con esto ya conoces la gestión de usuarios." />
      </div>
    ),
  },
];




<h1 data-tour="users.title">Usuarios</h1>

<div data-tour="users.table.filters">...</div>

<button data-tour="users.create">Crear nuevo usuario</button>

<button data-tour="users.addToGroup">Agregar a grupo</button>

<table data-tour="users.table">...</table>

<div data-tour="users.table.actions">...</div>

<div data-tour="users.table.pagination">...</div>



{
  selector: "body",
  content: () => (
    <div>
      <Title text="¿Quieres seguir explorando?" />
      <Paragraph text="Puedes continuar con otras secciones del sistema para conocer todas las funcionalidades disponibles." />
      <div className="flex flex-col mt-3 gap-2">
        <Button onClick={() => tourStarters.groups()}>Tour de Grupos</Button>
        <Button onClick={() => tourStarters.roles()}>Tour de Roles</Button>
        <Button onClick={() => tourStarters.clients()}>Tour de Clientes</Button>
      </div>
    </div>
  ),
}

###Grupos


<h1 data-tour="groups.title">Grupos</h1>

<div data-tour="groups.filters">...</div>

<button data-tour="groups.create">Crear nuevo grupo</button>

<table data-tour="groups.table">...</table>

<div data-tour="groups.table.actions">...</div>

<div data-tour="groups.table.pagination">...</div>






import { StepType } from "@reactour/tour";
import { Title } from "@/components/tour/Title";
import { Paragraph } from "@/components/tour/Paragraph";
import { Footer } from "@/components/tour/Footer";
import { EMOJIS } from "@/constants/emojis";

export const groupsSteps: StepType[] = [
  {
    selector: "body",
    content: () => (
      <div>
        <Title text={`${EMOJIS.groups} Gestión de Grupos`} />
        <Paragraph text="Aquí puedes crear y organizar grupos para estructurar usuarios según equipos, áreas o necesidades específicas." />
        <Footer text="Vamos a recorrer cada parte de la pantalla." />
      </div>
    ),
  },

  {
    selector: '[data-tour="groups.title"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Título de la sección" />
        <Paragraph text="Esta es la vista principal para administrar los grupos existentes dentro de la plataforma." />
      </div>
    ),
  },

  {
    selector: '[data-tour="groups.filters"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Filtros disponibles" />
        <Paragraph text="Puedes buscar grupos por nombre y ajustar cuántos resultados ver por página. Perfecto para entornos con muchos equipos." />
      </div>
    ),
  },

  {
    selector: '[data-tour="groups.create"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Crear nuevo grupo" />
        <Paragraph text="Desde aquí puedes añadir un grupo completamente nuevo. Solo necesitas asignarle un nombre." />
        <Footer text="Una forma rápida de estructurar mejor tus usuarios." />
      </div>
    ),
  },

  {
    selector: '[data-tour="groups.table"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Listado de grupos" />
        <Paragraph text="Aquí verás todos los grupos creados, junto con accesos directos para administrarlos: editar información, gestionar roles y explorar diagramas." />
      </div>
    ),
  },

  {
    selector: '[data-tour="groups.table.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones disponibles" />
        <Paragraph text="Cada grupo tiene accesos rápidos para editarlo, asignar roles globales, asignar roles de cliente, visualizar el diagrama y eliminar el grupo." />
        <Footer text="Todas las herramientas de administración organizadas en un solo lugar." />
      </div>
    ),
  },

  {
    selector: '[data-tour="groups.table.pagination"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Paginación" />
        <Paragraph text="Controla la navegación entre páginas cuando tienes muchos grupos creados." />
        <Footer text="Y listo, ya conoces la gestión de grupos." />
      </div>
    ),
  },
];



{
  selector: "body",
  content: () => (
    <div>
      <Title text="¿Quieres continuar?" />
      <Paragraph text="Puedes explorar los tours de otras secciones para entender el sistema por completo." />
      <div className="flex flex-col mt-3 gap-2">
        <Button onClick={() => tourStarters.users()}>Tour de Usuarios</Button>
        <Button onClick={() => tourStarters.roles()}>Tour de Roles</Button>
        <Button onClick={() => tourStarters.clients()}>Tour de Clientes</Button>
      </div>
    </div>
  ),
}


Clientes


<h1 data-tour="clients.title">Clientes</h1>

<div data-tour="clients.filters">...</div>

<div className="flex items-center gap-2" data-tour="clients.actions">
  <button>Crear nuevo cliente</button>
  <button>Client scopes</button> {/* o un link */}
</div>

<table data-tour="clients.table">...</table>

<div data-tour="clients.table.actions">...</div>

<div data-tour="clients.table.pagination">...</div>




import { StepType } from "@reactour/tour";
import { Title } from "@/components/tour/Title";
import { Paragraph } from "@/components/tour/Paragraph";
import { Footer } from "@/components/tour/Footer";
import { EMOJIS } from "@/constants/emojis";

export const clientsSteps: StepType[] = [
  {
    selector: "body",
    content: () => (
      <div>
        <Title text={`${EMOJIS.clients} Gestión de Clientes`} />
        <Paragraph text="Los clientes representan aplicaciones o servicios que se conectan a la plataforma y necesitan autenticación, permisos y reglas personalizadas." />
        <Footer text="Veamos cómo administrar los clientes disponibles." />
      </div>
    ),
  },

  {
    selector: '[data-tour="clients.title"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Página de Clientes" />
        <Paragraph text="Aquí encontrarás todas las aplicaciones registradas dentro de la plataforma, junto con sus configuraciones más importantes." />
      </div>
    ),
  },

  {
    selector: '[data-tour="clients.filters"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Filtros" />
        <Paragraph text="Puedes buscar clientes por ID y ajustar el número de resultados para encontrar más rápido la aplicación que necesitas." />
      </div>
    ),
  },

  {
    selector: '[data-tour="clients.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones principales" />
        <Paragraph text="Desde aquí puedes crear un nuevo cliente o acceder al catálogo de Client Scopes disponibles en la plataforma." />
        <Footer text="Ideal para administrar aplicaciones y sus permisos asociados." />
      </div>
    ),
  },

  {
    selector: '[data-tour="clients.table"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Listado de Clientes" />
        <Paragraph text="Cada fila representa una aplicación configurada. Puedes ver su estado, editarla y administrar roles, scopes, mappers y credenciales." />
      </div>
    ),
  },

  {
    selector: '[data-tour="clients.table.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones por cliente" />

        <Paragraph text="Cada cliente tiene acciones específicas:" />

        <Paragraph
          text={`
• Editar: cambiar nombre, protocolo o configuraciones básicas.  
• Roles: administrar los roles que la aplicación puede asignar.  
• Scopes: definir qué información es accesible desde la app.  
• Mappers: personalizar qué atributos se exponen al autenticarse.  
• Diagramas: visualizar la estructura y conexiones del cliente.  
• Credenciales: gestionar secretos y configuraciones de acceso.  
• Eliminar: borrar el cliente de la plataforma.
          `}
        />

        <Footer text="Todo lo necesario para administrar aplicaciones de forma segura y ordenada." />
      </div>
    ),
  },

  {
    selector: '[data-tour="clients.table.pagination"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Paginación" />
        <Paragraph text="Navega entre las páginas para ver todos los clientes configurados." />
        <Footer text="¡Listo! Ya conoces la sección de Clientes." />
      </div>
    ),
  },
];



{
  selector: "body",
  content: () => (
    <div>
      <Title text="¿Quieres continuar con otro tour?" />
      <Paragraph text="Puedes explorar otras secciones para conocer más sobre la plataforma." />
      <div className="flex flex-col gap-2 mt-3">
        <Button onClick={() => goToTour("users")}>Usuarios</Button>
        <Button onClick={() => goToTour("groups")}>Grupos</Button>
        <Button onClick={() => goToTour("roles")}>Roles</Button>
        <Button onClick={() => goToTour("client-scopes")}>Client Scopes</Button>
      </div>
    </div>
  ),
}

roles

<h1 data-tour="roles.title">Roles</h1>

<div data-tour="roles.roleTypeSelector">...</div>

<div data-tour="roles.filters">...</div>

<div data-tour="roles.actions">...</div>

<table data-tour="roles.table">...</table>

<div data-tour="roles.table.actions">...</div>

<div data-tour="roles.table.pagination">...</div>





import { StepType } from "@reactour/tour";
import { Title } from "@/components/tour/Title";
import { Paragraph } from "@/components/tour/Paragraph";
import { Footer } from "@/components/tour/Footer";
import { EMOJIS } from "@/constants/emojis";

export const rolesSteps: StepType[] = [
  {
    selector: "body",
    content: () => (
      <div>
        <Title text={`${EMOJIS.roles} Roles`} />
        <Paragraph text="En esta sección puedes administrar los permisos disponibles dentro de la plataforma, tanto roles globales como roles asociados a clientes específicos." />
        <Footer text="Primero veamos cómo está organizada la pantalla." />
      </div>
    ),
  },

  {
    selector: '[data-tour="roles.title"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Administración de Roles" />
        <Paragraph text="Aquí puedes gestionar los roles disponibles, organizarlos, editarlos y asignarlos a usuarios o grupos." />
      </div>
    ),
  },

  // SELECTOR GLOBAL / CLIENT
  {
    selector: '[data-tour="roles.roleTypeSelector"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Tipos de Roles" />

        <Paragraph
          text={`
Esta plataforma maneja dos tipos de roles:

• **Roles Globales**: afectan a toda la plataforma.  
• **Client Roles**: roles pertenecientes a una aplicación específica.

Puedes alternar entre ellos usando este selector.
        `}
        />

        <Footer text="Cambia entre vistas según lo que necesites administrar." />
      </div>
    ),
  },

  // FILTERS
  {
    selector: '[data-tour="roles.filters"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Filtros" />
        <Paragraph text="Filtra roles por nombre y ajusta la cantidad de filas a mostrar por página." />
      </div>
    ),
  },

  // ACTIONS
  {
    selector: '[data-tour="roles.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones principales" />
        <Paragraph text="Puedes crear nuevos roles globales, o asignar roles (globales o de cliente) a usuarios y grupos." />
        <Footer text="Es una forma rápida de administrar permisos a gran escala." />
      </div>
    ),
  },

  // TABLE GENERAL
  {
    selector: '[data-tour="roles.table"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Listado de Roles" />
        <Paragraph text="Aquí verás todos los roles disponibles según la vista seleccionada (global o de cliente)." />
      </div>
    ),
  },

  // TABLE ACTIONS
  {
    selector: '[data-tour="roles.table.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones por Rol" />

        <Paragraph
          text={`
Cada rol tiene acciones específicas según su tipo:

• **Editar**: cambia nombre o información del rol.  
• **Usuarios**: asigna o quita este rol a usuarios.  
• **Grupos**: asigna o quita este rol a grupos.  
• **Eliminar**: solo para roles globales o roles de cliente creados por el usuario.
          `}
        />

        <Footer text="Permite administrar permisos de manera detallada." />
      </div>
    ),
  },

  // PAGINATION
  {
    selector: '[data-tour="roles.table.pagination"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Paginación" />
        <Paragraph text="Navega entre páginas para ver todos los roles disponibles." />
        <Footer text="Listo. Ya conoces la sección de Roles." />
      </div>
    ),
  },
];

client scopes

<h1 data-tour="client-scopes.title">Client Scopes</h1>

<div data-tour="client-scopes.filters">...</div>

<div data-tour="client-scopes.actions">...</div>

<table data-tour="client-scopes.table">...</table>

<div data-tour="client-scopes.table.actions">...</div>

<div data-tour="client-scopes.table.pagination">...</div>





import { StepType } from "@reactour/tour";
import { Title } from "@/components/tour/Title";
import { Paragraph } from "@/components/tour/Paragraph";
import { Footer } from "@/components/tour/Footer";
import { EMOJIS } from "@/constants/emojis";

export const clientScopesSteps: StepType[] = [
  // INTRO
  {
    selector: "body",
    content: () => (
      <div>
        <Title text={`${EMOJIS.scopes} Client Scopes`} />
        <Paragraph
          text={`
Los Client Scopes son conjuntos de atributos y configuraciones que
pueden añadirse a uno o varios clientes para ampliar la información
que reciben durante la autenticación.
          `}
        />
        <Footer text="Veamos cómo funciona esta sección." />
      </div>
    ),
  },

  // TITLE
  {
    selector: '[data-tour="client-scopes.title"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Administración de Client Scopes" />
        <Paragraph text="Aquí puedes ver, crear, editar y gestionar scopes utilizados por los clientes de la plataforma." />
      </div>
    ),
  },

  // FILTERS
  {
    selector: '[data-tour="client-scopes.filters"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Filtros" />
        <Paragraph text="Filtra los scopes por nombre y ajusta cuántos elementos ver por página." />
      </div>
    ),
  },

  // ACTIONS
  {
    selector: '[data-tour="client-scopes.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Crear nuevo Scope" />
        <Paragraph
          text={`
Puedes crear un nuevo Client Scope.  
Durante la creación deberás definir su nombre, descripción y protocolo.
          `}
        />
        <Footer text="Algunos scopes pueden estar limitados por el protocolo." />
      </div>
    ),
  },

  // TABLE
  {
    selector: '[data-tour="client-scopes.table"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Listado de Scopes" />
        <Paragraph
          text={`
Cada fila representa un Client Scope disponible en la plataforma.
Estos scopes pueden ser reutilizados por múltiples clientes.
          `}
        />
      </div>
    ),
  },

  // TABLE ACTIONS
  {
    selector: '[data-tour="client-scopes.table.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones por Scope" />

        <Paragraph
          text={`
• **Editar**: modifica nombre, descripción y configuración básica.  
• **Mappers**: administra qué atributos o datos se incluyen dentro del scope.  
• **Eliminar**: disponible solo para scopes creados por el usuario.
          `}
        />

        <Footer text="Los mappers son claves para definir qué información viaja en el token." />
      </div>
    ),
  },

  // PAGINATION
  {
    selector: '[data-tour="client-scopes.table.pagination"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Paginación" />
        <Paragraph text="Usa los controles para navegar entre los scopes disponibles." />
        <Footer text="Listo. Ya conoces la sección de Client Scopes." />
      </div>
    ),
  },
];

Mappers

<h1 data-tour="mappers.title">Mappers</h1>

<div data-tour="mappers.description"></div>

<div data-tour="mappers.actions"></div>

<table data-tour="mappers.table"></table>

<div data-tour="mappers.table.actions"></div>

<div data-tour="mappers.table.pagination"></div>






import { StepType } from "@reactour/tour";
import { Title } from "@/components/tour/Title";
import { Paragraph } from "@/components/tour/Paragraph";
import { Footer } from "@/components/tour/Footer";
import { EMOJIS } from "@/constants/emojis";

export const mappersSteps: StepType[] = [
  // INTRO
  {
    selector: "body",
    content: () => (
      <div>
        <Title text={`${EMOJIS.mappers} Mappers`} />
        <Paragraph
          text={`
Los Mappers definen qué información del usuario o del sistema
se incluye dentro del token generado durante la autenticación.
          `}
        />
        <Footer text="Veamos cómo funciona esta sección." />
      </div>
    ),
  },

  // TITLE
  {
    selector: '[data-tour="mappers.title"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Administración de Mappers" />
        <Paragraph
          text={`
Aquí puedes crear, editar y eliminar mappers.  
Cada mapper representa una regla que indica qué dato debe agregarse
al token final.
          `}
        />
      </div>
    ),
  },

  // GENERAL DESCRIPTION (OPTIONAL)
  {
    selector: '[data-tour="mappers.description"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="¿Qué es un Mapper?" />

        <Paragraph
          text={`
Un mapper define cómo un atributo debe transformarse o enviarse dentro
de un token de autenticación.

Existen distintos tipos de mappers, por ejemplo:

• **Hardcoded**: agrega un valor fijo al token.  
• **Usermodel Attribute**: toma un atributo del usuario y lo incluye.  
• **Role List**: envía roles según configuración.  
• **Protocol-specific**: depende del protocolo (SAML o OpenID Connect).
          `}
        />

        <Footer text="El tipo de mapper influye en la configuración disponible." />
      </div>
    ),
  },

  // ACTIONS
  {
    selector: '[data-tour="mappers.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Crear nuevo Mapper" />
        <Paragraph
          text={`
Puedes crear un mapper seleccionando:

• Tipo de mapper  
• Claim name  
• Valor fijo o atributo del usuario  
• A qué tokens debe añadirse (Access, ID, UserInfo)

Ten presente que algunas opciones dependen del protocolo.
          `}
        />
        <Footer text="Elige bien el tipo de mapper según lo que desees transmitir." />
      </div>
    ),
  },

  // TABLE
  {
    selector: '[data-tour="mappers.table"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Listado de Mappers" />
        <Paragraph
          text={`
Aquí puedes ver todos los mappers existentes para este Client o Client Scope.
Cada fila muestra el nombre, la descripción y el tipo de mapper.
          `}
        />
      </div>
    ),
  },

  // TABLE ACTIONS
  {
    selector: '[data-tour="mappers.table.actions"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Acciones por Mapper" />

        <Paragraph
          text={`
• **Editar**: permite modificar el tipo, claim y configuración.  
• **Eliminar**: borra definitivamente el mapper.  
• **Ver configuración**: según tu interfaz, puede mostrar detalles adicionales.

Ten en cuenta que algunos mappers vienen preconfigurados por el sistema
y pueden tener restricciones.
          `}
        />

        <Footer text="Usa estas acciones para ajustar cómo se construyen los tokens." />
      </div>
    ),
  },

  // PAGINATION
  {
    selector: '[data-tour="mappers.table.pagination"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Paginación" />
        <Paragraph text="Navega entre páginas para revisar todos los mappers asociados." />
        <Footer text="Listo. Ya conoces la sección de Mappers." />
      </div>
    ),
  },
];

credenciales

<h1 data-tour="credentials.title"></h1>

<div data-tour="credentials.secret"></div>

<button data-tour="credentials.secret.regenerate"></button>

<div data-tour="credentials.flows"></div>

<button data-tour="credentials.update"></button>





import { StepType } from "@reactour/tour";
import { Title } from "@/components/tour/Title";
import { Paragraph } from "@/components/tour/Paragraph";
import { Footer } from "@/components/tour/Footer";
import { EMOJIS } from "@/constants/emojis";

export const credentialsSteps: StepType[] = [
  // INTRO
  {
    selector: "body",
    content: () => (
      <div>
        <Title text={`${EMOJIS.lock} Credenciales del Cliente`} />
        <Paragraph
          text={`
Aquí puedes administrar la información sensible relacionada a la autenticación
del cliente, como su Client Secret y los flujos de autenticación permitidos.
          `}
        />
        <Footer text="Vamos a ver cada parte en detalle." />
      </div>
    ),
  },

  // TITLE
  {
    selector: '[data-tour="credentials.title"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Sección de Credenciales" />
        <Paragraph
          text={`
Cada cliente tiene credenciales únicas que permiten validar su identidad
al interactuar con otros servicios. Aquí puedes consultarlas y administrarlas.
          `}
        />
      </div>
    ),
  },

  // CLIENT SECRET
  {
    selector: '[data-tour="credentials.secret"]',
    position: "right",
    content: () => (
      <div>
        <Title text="Client Secret" />
        <Paragraph
          text={`
El *Client Secret* es la clave privada que autentica al cliente
cuando se comunica mediante flujos confidenciales.
Tenla presente: es información sensible y debe mantenerse segura.
          `}
        />
        <Footer text="Puedes ocultarla o visualizarla según lo necesites." />
      </div>
    ),
  },

  // REGENERATE
  {
    selector: '[data-tour="credentials.secret.regenerate"]',
    position: "bottom",
    content: () => (
      <div>
        <Title text="Regenerar Secret" />
        <Paragraph
          text={`
Este botón genera un nuevo Client Secret.
Es útil si crees que la clave fue comprometida o necesitas rotarla por seguridad.

⚠ Recuerda: al regenerar, integraciones externas dejarán de funcionar
hasta actualizar la clave en sus configuraciones.
          `}
        />
        <Footer text="Úsalo solo cuando sea necesario." />
      </div>
    ),
  },

  // FLOWS
  {
    selector: '[data-tour="credentials.flows"]',
    position: "left",
    content: () => (
      <div>
        <Title text="Flujos de Autenticación" />
        <Paragraph
          text={`
Aquí puedes habilitar o deshabilitar los flujos permitidos para este cliente.

Cada flujo representa una forma distinta de cómo la aplicación puede obtener tokens:
          
• **Standard Flow** – Usado por aplicaciones web.  
• **Implicit Flow** – Para apps SPA (legacy).  
• **Direct Access Grants** – Permite que el usuario envíe credenciales directamente.  
• **Service Account** – Credenciales para integración servidor-servidor.  
• **Authorization Services** – Activa control de permisos avanzado.  
• **Public Client** – El cliente no tiene secret; útil para SPAs o apps móviles.

Dependiendo de la arquitectura, algunos flujos pueden no ser recomendados.
          `}
        />
        <Footer text="Activa solo los flujos que tu aplicación necesite." />
      </div>
    ),
  },

  // UPDATE BUTTON
  {
    selector: '[data-tour="credentials.update"]',
    position: "top",
    content: () => (
      <div>
        <Title text="Guardar Cambios" />
        <Paragraph
          text={`
Una vez configurados los flujos, debes aplicar los cambios desde este botón.
De lo contrario, las nuevas reglas no tendrán efecto.
          `}
        />
        <Footer text="¡Eso es todo! Ya conoces las credenciales de un cliente." />
      </div>
    ),
  },
];

versiones estables de radix primitive, para que no haya problemas con la anidación de componentes con overlay

npm install \
npm install \
@radix-ui/react-alert-dialog@latest \
@radix-ui/react-avatar@latest \
@radix-ui/react-checkbox@latest \
@radix-ui/react-collapsible@latest \
@radix-ui/react-dialog@latest \
@radix-ui/react-dropdown-menu@latest \
@radix-ui/react-hover-card@latest \
@radix-ui/react-label@latest \
@radix-ui/react-popover@latest \
@radix-ui/react-scroll-area@latest \
@radix-ui/react-select@latest \
@radix-ui/react-separator@latest \
@radix-ui/react-tabs@latest \
@radix-ui/react-toast@latest \
@radix-ui/react-tooltip@latest \
@radix-ui/react-slot@latest


⬆️La versión de arriba no sirve porque hay componente que no tienen versión 2 por lo tanto nunca van ha a ser compatibles. y hay componentes que no son compatibles con la version 19 de react, la solución, usar react 18 y los componentes en v1.

npm install react@18 react-dom@18
npm install \
@radix-ui/react-alert-dialog@^1 \
@radix-ui/react-avatar@^1 \
@radix-ui/react-checkbox@^1 \
@radix-ui/react-collapsible@^1 \
@radix-ui/react-dialog@^1 \
@radix-ui/react-dropdown-menu@^1 \
@radix-ui/react-hover-card@^1 \
@radix-ui/react-label@^1 \
@radix-ui/react-popover@^1 \
@radix-ui/react-scroll-area@^1 \
@radix-ui/react-select@^1 \
@radix-ui/react-separator@^1 \
@radix-ui/react-tabs@^1 \
@radix-ui/react-toast@^1 \
@radix-ui/react-tooltip@^1 \
@radix-ui/react-slot@^1

rm -rf node_modules package-lock.json
npm install
npm dedupe

Pinned Loading

  1. desafios-frontend-mentor desafios-frontend-mentor Public

    portafolio of solutions to frontend mentor challenges

    HTML 2

  2. english-notes english-notes Public

    Small application to review English phrases

    TypeScript 1

  3. app-fullstack app-fullstack Public

    First app fullstack with node, express and react

    JavaScript 3

  4. rompebezacas rompebezacas Public

    JavaScript 2

  5. web web Public

    Mi portafolio web

    JavaScript 6 2

  6. IncludeTeam1/recicanje IncludeTeam1/recicanje Public

    JavaScript 2