CursosEmpresasBlogLiveConfPrecios

Validaciones

Clase 26 de 29 • Curso de React Router 5 y Redux

Clase anteriorSiguiente clase

Contenido del curso

Bienvenida al curso

  • 1
    Todo lo que aprenderás sobre React Router y Redux

    Todo lo que aprenderás sobre React Router y Redux

    01:30 min

¿Qué es React Router? y Aplicarlo en tus proyectos

  • 2
    ¿Qué es React Router y cómo instalarlo?

    ¿Qué es React Router y cómo instalarlo?

    02:54 min
  • 3
    Crear nuestro archivo de Rutas

    Crear nuestro archivo de Rutas

    07:33 min
  • 4
    Container: Login

    Container: Login

    10:29 min
  • 5
    Container: Register

    Container: Register

    06:28 min
  • 6
    Container: 404 Not Found

    Container: 404 Not Found

    06:43 min
  • 7
    Componente: Layout

    Componente: Layout

    05:10 min
  • 8
    Manejando enlaces y configuraciones

    Manejando enlaces y configuraciones

    06:33 min

¿Qué es Redux?

  • 9
    Qué es Redux

    Qué es Redux

    02:17 min
  • 10

    ¿Qué es Redux? Profundizando en la herramienta

    01:32 min
  • 11
    Instalación de Redux

    Instalación de Redux

    04:40 min
  • 12
    Creando el Store de Redux

    Creando el Store de Redux

    12:53 min

Aplicando Redux a nuestra aplicación

  • 13
    Creando los reducers

    Creando los reducers

    10:40 min
  • 14
    Finalizando reducers y eliminar favoritos

    Finalizando reducers y eliminar favoritos

    08:26 min
  • 15
    Debuggeando nuestro proyecto (agregando validaciones a nuestro componente card)

    Debuggeando nuestro proyecto (agregando validaciones a nuestro componente card)

    04:19 min
  • 16
    Crear Formulario de Login

    Crear Formulario de Login

    10:08 min
  • 17
    Formulario de Login con Redux

    Formulario de Login con Redux

    06:28 min
  • 18
    Creando un Servicio para Gravatar

    Creando un Servicio para Gravatar

    05:28 min
  • 19
    Uso de gravatar en nuestro proyecto

    Uso de gravatar en nuestro proyecto

    07:16 min
  • 20
    Validación para LogIn LogOut

    Validación para LogIn LogOut

    09:15 min
  • 21
    Register

    Register

    07:00 min
  • 22
    Register con Redux

    Register con Redux

    04:17 min
  • 23
    Vista general del player

    Vista general del player

    05:26 min
  • 24
    Arreglando la funcionalidad del player

    Arreglando la funcionalidad del player

    06:55 min
  • 25
    Terminando de detallar nuestro player

    Terminando de detallar nuestro player

    13:50 min
  • 26
    Validaciones

    Validaciones

    Viendo ahora
  • 27
    Validaciones de UI

    Validaciones de UI

    07:04 min
  • 28
    Debug con Redux Devtools

    Debug con Redux Devtools

    05:57 min

Cierre del curso

  • 29
    Cierre del Proyecto

    Cierre del Proyecto

    00:39 min
  • Tomar el examen del curso
    • Victor Baruch Pazaran Jaimes

      Victor Baruch Pazaran Jaimes

      student•
      hace 5 años

      Logre hacer esta validacion sin necesidad de agregar un paquete extra, para ello utilice el hook useLocation desde react router dom, les comparto mi codigo

      import React from 'react'; import { Link, useLocation } from 'react-router-dom'; import { connect } from 'react-redux'; import { logoutRequest } from '../actions/' import gravatar from '../utils/gravatar'; import '../assets/styles/components/Header.scss'; import logo from '../assets/images/logo-platzi.png'; import userIcon from '../assets/images/profile-user.svg'; const Header = (props) => { const { user } = props const userLogedIn = () => user.email !== undefined; /* Verificamos si nuestro usuario ya tiene un email registrado en su sesion */ const handleLogout = () => { props.logoutRequest({}) /* Le pasamos un objeto vacio como payload que sera lo que se establezca en el reducer */ } const headerClass = (useLocation().pathname === '/register' || useLocation().pathname === '/login') ? 'greenHeader' : ''; return( <header className={`header ${headerClass}`}> {console.log(headerClass)} <Link to="/"> <img className="header__img" src={ logo } alt="" /> </Link> {/* Usamos el elemento link de react router dom, ya que nos permite poder desplazarnos por nuestra aplicacion sin necesidad de hacer un refresh a la pagina completa */} <div className="header__menu"> <div className="header__menu--profile"> {userLogedIn() ? <img src={ gravatar(user.email) } alt="user icon" /> : <img src={ userIcon } alt="user icon" /> } <p>Perfil</p> </div> {userLogedIn() ? <ul> <li><p>Bienvenido <b>{user.name}</b></p></li> <li><p>Mi perfil</p></li> <li><a onClick={handleLogout}>Cerrar sesion</a></li> </ul> : <ul> <li><Link to="/login">Iniciar sesion</Link></li> <li><Link to="/register">Registrate</Link></li> </ul> } </div> </header> )}; const mapStateToProps = state => { return { user: state.user, } } const mapDispatchToProps = { logoutRequest } export default connect(mapStateToProps,mapDispatchToProps)(Header);

      Con esto agrego una clase mas al header para así poder cambiarle simplemente el color con una propiedad css solo agregando y quitando la clase

      ahora en mi css solo tuve que agregar esta clase

      .greenHeader { background-color: #21C08B; }```
        Tatiana Karina Valencia Hernández

        Tatiana Karina Valencia Hernández

        student•
        hace 5 años

        Gracias

        Yeison Montoya

        Yeison Montoya

        student•
        hace 5 años

        Eso mismo estaba penmsado yo, no se necesita esta validación con un paquete extra, gracias por tu comentario.

      Juan Manuel Pedraza

      Juan Manuel Pedraza

      student•
      hace 5 años

      Luego de ver la clase, quede triste, ya que me gustaba la ideal del Layout y la forma tan simple de ahorrar muchas repeticiones de llamadas a componentes y en general de código.

      Pero al mismo tiempo pienso que debe haber una forma dinámica de establecer este tipo de cambios, sin tener que llamar el componentes desde cada container y componente que lo requiere.

      Por esto se me ocurrió que podía establecer una propiedad en el state que almacena las clases de Header y crear un action que actualizara las clases dependiendo del container que se cargaba.

      En ese caso cada container llama el action que actualiza la propiedad del state que almacena las clases del header.

      y el header consulta esta propiedad y establece las clases del header.

      pero este me generaba un Warning, finalmente lo solucione con un effect, que ejecuta el cambio de clase cuando ya todo se ha renderizado, y funciona.

      Si alguien también lo esta intentando, o sabe como lograrlo de una forma mucho mejor me encantaría aprender.

      propiedad nueva en el state:

      const initialState = { "user":{}, "playing": {}, "headerClass": ['header'], ... lo demas.. }

      Luego en el index.js de actions, se genera una nueva action para actualizar esta propiedad

      export const changeClassHeader = payload => ({ type: actions.changeClassHeader, payload, })

      En el el index.js de los reduces, se crea un nuevo case, que reciba y realice la actualziación del state, con el cambio en la propiedad del state que almacena las clases.

      case actions.changeClassHeader: state.headerClass = action.payload console.log(state) return { ...state }

      Por último en cada container, se añade el action y se ejecuta el un useEffect para que no genere errores la aplicación y se renderice el cambio de forma correcta luego de haber renderizado el container inicial.

      Ejemplo del código en el container Login

      useEffect(() => { props.changeClassHeader(['isLogin']); })

      Muchas gracias a todos por sus aportes en otras clases, eso me ha ayudado mucho, quedo atento a sus provechos comentarios para seguir aprendiendo.

      Cristhian Daza

      Cristhian Daza

      student•
      hace 5 años

      Bueno yo si desde un principio le puse un color oscuro al fondo entonces no tuve que hacer esto

      PlatziVideo.png
      Laura Camila Pregonero

      Laura Camila Pregonero

      student•
      hace 5 años

      Login

      ........ Registro

      ............. Maquetacion
      ................... Parte del Video
      ......... :)

      Manuel Entrena Jimenez

      Manuel Entrena Jimenez

      student•
      hace 5 años

      Yo simplemente modifique los estilos de los componentes con un gradiente de 3 colores y me parecia un resultado mejor para poder mantener el header en el layot.

      background-image: linear-gradient(#8f57fd, #21c08b, #8f57fd);
      2021-01-28_16h07_20.png
        Carlos Alfonso Garcia Rivera

        Carlos Alfonso Garcia Rivera

        student•
        hace 5 años

        eso mismo hice yo ✌

      Xavi Isach Alemany

      Xavi Isach Alemany

      student•
      hace 5 años

      En esta clase vemos como generar clases dinámicas con la dependencia ++classname++.

      # npm npm install classnames # Bower bower install classnames # Yarn yarn add classnames

      Esta utilidad nos permite añadir clases según se cumplan x condiciones. Ejemplos:

      import classNames from 'classnames'; classNames('foo', 'bar'); // => 'foo bar' classNames('foo', { bar: true }); // => 'foo bar' classNames({ 'foo-bar': true }); // => 'foo-bar' classNames({ 'foo-bar': false }); // => '' classNames({ foo: true }, { bar: true }); // => 'foo bar' classNames({ foo: true, bar: true }); // => 'foo bar'
        Diego Fernando Rojas Quintero

        Diego Fernando Rojas Quintero

        student•
        hace 5 años

        Que significa ++'foo'++ y ++'bar'++

        Freddy Camilo Orozco Romero

        Freddy Camilo Orozco Romero

        student•
        hace 5 años

        ¡Hola Diego! 'foo' y 'bar' son ejemplos (en este caso de clases) usados mucho para fake data en programación. Es como una manera 'default' de llamar a algo.

      Jorge Alberto Rodriguez Flores

      Jorge Alberto Rodriguez Flores

      student•
      hace 5 años

      Aqui les dejo la documentacion del paquete classnames para que le echen un ojo... o dos si quieren 👀 -> (https://www.npmjs.com/package/classnames)

      Cristian Felipe Patiño Cáceres

      Cristian Felipe Patiño Cáceres

      student•
      hace 5 años

      En mi caso preferí usar un action/reducer para realizar este cambio :)

      Actions:

      export const setHeader = (payLoad) => ({ type: actions.setHeader, payLoad, });

      reducers:

      case actions.setHeader: return { ...state, isForm: action.payLoad, };

      Login

      useLayoutEffect(() => { props.setHeader(true); }, []);
      DAMIÁN NICOLAS PINEDO

      DAMIÁN NICOLAS PINEDO

      student•
      hace 5 años

      hice exactamente lo mismo q el profe pero a mi no me sale el cambio, me fije en el inspector de elementos y parece que si pasa la variable pero no la registra alguien tiene alguna idea?

      headerredux.PNG

        Edilberto Vazquez Luna

        Edilberto Vazquez Luna

        student•
        hace 5 años

        puedes mostrar tu archivo de estilos del header?, talvez estas sobrescribiendo tu estilo del background-color, por eso te lo marca como subrayado, acuérdate que CSS tomo como prioridad al ultimo estilo aplicado, también checa que no tengas otra etiqueta header en tus demás archivos de estilos, talvez eso pueda generar un conflicto

        DAMIÁN NICOLAS PINEDO

        DAMIÁN NICOLAS PINEDO

        student•
        hace 5 años

        este es mi codigo de header.scss

        .header { align-items: center; background: #8f57fd; color: white; display: flex; height: 100px; justify-content: space-between; top: 0px; width: 100%; } .isLogin, .isRegister { background-color: #21c08b; } .header__img { margin-left: 30px; width: 200px; } .header__menu { margin-right: 30px; } .header__menu ul { display: none; list-style: none; margin: 0px 0px 0px -14px; padding: 0px; position: absolute; width: 100px; text-align: right; } .header__menu:hover ul, ul:hover { display: block; } .header__menu li { margin: 10px 0px; } .header__menu li a { color: white; text-decoration: none; } .header__menu li a:hover { text-decoration: underline; } .header__menu--profile { align-items: center; display: flex; cursor: pointer; } .header__menu--profile img { margin-right: 8px; width: 40px; }```
      DAMIÁN NICOLAS PINEDO

      DAMIÁN NICOLAS PINEDO

      student•
      hace 5 años

      no entiendo el caso de fragment, que es lo que hace en si ? ayuda a poder encapsular todo o como es?

        Pablo Nicolás Alonso

        Pablo Nicolás Alonso

        student•
        hace 5 años

        Ayuda a que no de error si tienes 2 etiquetas sueltas (es decir que no esten contenidas dentro de un padre.

        ... return ( <div> ... // otros elementos </div> <div> ... //otros elementos </div> )

        En el caso anterior daría error y para eso esta react.fragment:

        ... return ( <> <div> ... // otros elementos </div> <div> ... //otros elementos </div> </> )
      Sebastián Buitrago

      Sebastián Buitrago

      student•
      hace 5 años

      Como se pueden separar lo esilos de un componente para que no hagan conflicto con los demas estilos?

        Mario Eduardo Contreras Serrano

        Mario Eduardo Contreras Serrano

        student•
        hace 5 años

        Yo utilizo Styled Components, hasta ahora me ha funcionado bastante bien!

      Cristian Florez

      Cristian Florez

      student•
      hace 5 años

      Que tan buena idea es hacer esto en el router/app.js ??

      if (!token) { return ( <BrowserRouter> <Login exact path="/" />; </BrowserRouter> ); } else { return ( <BrowserRouter> <Header /> <Switch> <Route path="/" component={Home} /> </Switch> <Footer/> </BrowserRouter> ); }
        Nilson Diaz

        Nilson Diaz

        student•
        hace 5 años

        Hey ! , En realidad para hacer esto podrias generar un componente layout de esta forma

        const Layout = (props) => { return ( <Header /> {props.children} <Footer /> ) }

        Y luego envuelves el resto de aplicacion en este

        return ( <BrowserRouter> <Layout /> <Switch> <Routepath="/"component={Home} /> </Switch> <Layout/> </BrowserRouter> );

        Y Daria el mismo resultado pero ya teniendo un componente general que sirva de layout y no poniendolos direactamente en nuestra app, Puedes ver mas en Esta Clase Del curso de React.js

      Sebastian Vizcarra

      Sebastian Vizcarra

      student•
      hace 5 años

      Por si quieren saber más sobre el className aquí está este link

      Jair Neri

      Jair Neri

      student•
      hace 4 años

      Esto se pudo resolver facilmente con operador || y template strings, en vez de usar una dependencia extra

      Karen Paola Diaz Duarte

      Karen Paola Diaz Duarte

      student•
      hace 5 años

      Prácticas:

      31.PNG
      Platzi Team

      Platzi Team

      student•
      hace 5 años

      🤯🤯🤯 Genial !!

      Daniel Ruiz

      Daniel Ruiz

      student•
      hace 5 años

      En que casos reales han usado la dependencia classnames? porque claramente para efectos practicos del curso es sobreingenieria, pero algo me dice que puede ser muy util en la vida real.

        Cristian Florez

        Cristian Florez

        student•
        hace 5 años

        En mi experiencia nuna lo he usado, pero no descarto la posibilidad de utilizarlo en algun momento

      Carlos Eduardo Santaella Guevara

      Carlos Eduardo Santaella Guevara

      student•
      hace 5 años

      una pregunta, eso no es lo mismo que poner css aparte en cada componente que requiera un Header? creo que lo de classnames esta demas y hace mas engorroso el trabajo en react

        Sneyder Barreto

        Sneyder Barreto

        student•
        hace 5 años

        ¡Hola! Recuerda que existen varias maneras de lograr el mismo resultado. En esta ocasión Oscar nos muestra una herramientra para validar y trabajar el color de header. Siempre es bueno conocer este tipo de herramientas que a lo mejor las vemos más últiles en algún otro momento. Un saludo.

      Renato Renzo Luna Herrera

      Renato Renzo Luna Herrera

      student•
      hace 4 años

      Yo lo hice de esta forma, sin instalar classnames, espero les sirva

      const headerClass = () => { if (isLogin) return 'isLogin' if (isRegister) return 'isRegister' } return ( <header className={`header ${headerClass()}`}> // ...
      Christian Humberto

      Christian Humberto

      student•
      hace 4 años

      de hecho lo hice desde un inicio

      envio el distintivo como props

      header1.png

      lo recivo y lo concateno en el className

      header2.png

      esta es el archivo del estilo donde esta declarada la clase

      header3.png

    Escuelas

    • Desarrollo Web
      • Fundamentos del Desarrollo Web Profesional
      • Diseño y Desarrollo Frontend
      • Desarrollo Frontend con JavaScript
      • Desarrollo Frontend con Vue.js
      • Desarrollo Frontend con Angular
      • Desarrollo Frontend con React.js
      • Desarrollo Backend con Node.js
      • Desarrollo Backend con Python
      • Desarrollo Backend con Java
      • Desarrollo Backend con PHP
      • Desarrollo Backend con Ruby
      • Bases de Datos para Web
      • Seguridad Web & API
      • Testing Automatizado y QA para Web
      • Arquitecturas Web Modernas y Escalabilidad
      • DevOps y Cloud para Desarrolladores Web
    • English Academy
      • Inglés Básico A1
      • Inglés Básico A2
      • Inglés Intermedio B1
      • Inglés Intermedio Alto B2
      • Inglés Avanzado C1
      • Inglés para Propósitos Específicos
      • Inglés de Negocios
    • Marketing Digital
      • Fundamentos de Marketing Digital
      • Marketing de Contenidos y Redacción Persuasiva
      • SEO y Posicionamiento Web
      • Social Media Marketing y Community Management
      • Publicidad Digital y Paid Media
      • Analítica Digital y Optimización (CRO)
      • Estrategia de Marketing y Growth
      • Marketing de Marca y Comunicación Estratégica
      • Marketing para E-commerce
      • Marketing B2B
      • Inteligencia Artificial Aplicada al Marketing
      • Automatización del Marketing
      • Marca Personal y Marketing Freelance
      • Ventas y Experiencia del Cliente
      • Creación de Contenido para Redes Sociales
    • Inteligencia Artificial y Data Science
      • Fundamentos de Data Science y AI
      • Análisis y Visualización de Datos
      • Machine Learning y Deep Learning
      • Data Engineer
      • Inteligencia Artificial para la Productividad
      • Desarrollo de Aplicaciones con IA
      • AI Software Engineer
    • Ciberseguridad
      • Fundamentos de Ciberseguridad
      • Hacking Ético y Pentesting (Red Team)
      • Análisis de Malware e Ingeniería Forense
      • Seguridad Defensiva y Cumplimiento (Blue Team)
      • Ciberseguridad Estratégica
    • Liderazgo y Habilidades Blandas
      • Fundamentos de Habilidades Profesionales
      • Liderazgo y Gestión de Equipos
      • Comunicación Avanzada y Oratoria
      • Negociación y Resolución de Conflictos
      • Inteligencia Emocional y Autogestión
      • Productividad y Herramientas Digitales
      • Gestión de Proyectos y Metodologías Ágiles
      • Desarrollo de Carrera y Marca Personal
      • Diversidad, Inclusión y Entorno Laboral Saludable
      • Filosofía y Estrategia para Líderes
    • Diseño de Producto y UX
      • Fundamentos de Diseño UX/UI
      • Investigación de Usuarios (UX Research)
      • Arquitectura de Información y Usabilidad
      • Diseño de Interfaces y Prototipado (UI Design)
      • Sistemas de Diseño y DesignOps
      • Redacción UX (UX Writing)
      • Creatividad e Innovación en Diseño
      • Diseño Accesible e Inclusivo
      • Diseño Asistido por Inteligencia Artificial
      • Gestión de Producto y Liderazgo en Diseño
      • Diseño de Interacciones Emergentes (VUI/VR)
      • Desarrollo Web para Diseñadores
      • Diseño y Prototipado No-Code
    • Contenido Audiovisual
      • Fundamentos de Producción Audiovisual
      • Producción de Video para Plataformas Digitales
      • Producción de Audio y Podcast
      • Fotografía y Diseño Gráfico para Contenido Digital
      • Motion Graphics y Animación
      • Contenido Interactivo y Realidad Aumentada
      • Estrategia, Marketing y Monetización de Contenidos
    • Desarrollo Móvil
      • Fundamentos de Desarrollo Móvil
      • Desarrollo Nativo Android con Kotlin
      • Desarrollo Nativo iOS con Swift
      • Desarrollo Multiplataforma con React Native
      • Desarrollo Multiplataforma con Flutter
      • Arquitectura y Patrones de Diseño Móvil
      • Integración de APIs y Persistencia Móvil
      • Testing y Despliegue en Móvil
      • Diseño UX/UI para Móviles
    • Diseño Gráfico y Arte Digital
      • Fundamentos del Diseño Gráfico y Digital
      • Diseño de Identidad Visual y Branding
      • Ilustración Digital y Arte Conceptual
      • Diseño Editorial y de Empaques
      • Motion Graphics y Animación 3D
      • Diseño Gráfico Asistido por Inteligencia Artificial
      • Creatividad e Innovación en Diseño
    • Programación
      • Fundamentos de Programación e Ingeniería de Software
      • Herramientas de IA para el trabajo
      • Matemáticas para Programación
      • Programación con Python
      • Programación con JavaScript
      • Programación con TypeScript
      • Programación Orientada a Objetos con Java
      • Desarrollo con C# y .NET
      • Programación con PHP
      • Programación con Go y Rust
      • Programación Móvil con Swift y Kotlin
      • Programación con C y C++
      • Administración Básica de Servidores Linux
    • Negocios
      • Fundamentos de Negocios y Emprendimiento
      • Estrategia y Crecimiento Empresarial
      • Finanzas Personales y Corporativas
      • Inversión en Mercados Financieros
      • Ventas, CRM y Experiencia del Cliente
      • Operaciones, Logística y E-commerce
      • Gestión de Proyectos y Metodologías Ágiles
      • Aspectos Legales y Cumplimiento
      • Habilidades Directivas y Crecimiento Profesional
      • Diversidad e Inclusión en el Entorno Laboral
      • Herramientas Digitales y Automatización para Negocios
    • Blockchain y Web3
      • Fundamentos de Blockchain y Web3
      • Desarrollo de Smart Contracts y dApps
      • Finanzas Descentralizadas (DeFi)
      • NFTs y Economía de Creadores
      • Seguridad Blockchain
      • Ecosistemas Blockchain Alternativos (No-EVM)
      • Producto, Marketing y Legal en Web3
    • Recursos Humanos
      • Fundamentos y Cultura Organizacional en RRHH
      • Atracción y Selección de Talento
      • Cultura y Employee Experience
      • Gestión y Desarrollo de Talento
      • Desarrollo y Evaluación de Liderazgo
      • Diversidad, Equidad e Inclusión
      • AI y Automatización en Recursos Humanos
      • Tecnología y Automatización en RRHH
    • Finanzas e Inversiones
      • Fundamentos de Finanzas Personales y Corporativas
      • Análisis y Valoración Financiera
      • Inversión y Mercados de Capitales
      • Finanzas Descentralizadas (DeFi) y Criptoactivos
      • Finanzas y Estrategia para Startups
      • Inteligencia Artificial Aplicada a Finanzas
      • Domina Excel
      • Financial Analyst
      • Conseguir trabajo en Finanzas e Inversiones
    • Startups
      • Fundamentos y Validación de Ideas
      • Estrategia de Negocio y Product-Market Fit
      • Desarrollo de Producto y Operaciones Lean
      • Finanzas, Legal y Fundraising
      • Marketing, Ventas y Growth para Startups
      • Cultura, Talento y Liderazgo
      • Finanzas y Operaciones en Ecommerce
      • Startups Web3 y Blockchain
      • Startups con Impacto Social
      • Expansión y Ecosistema Startup
    • Cloud Computing y DevOps
      • Fundamentos de Cloud y DevOps
      • Administración de Servidores Linux
      • Contenerización y Orquestación
      • Infraestructura como Código (IaC) y CI/CD
      • Amazon Web Services
      • Microsoft Azure
      • Serverless y Observabilidad
      • Certificaciones Cloud (Preparación)
      • Plataforma Cloud GCP

    Platzi y comunidad

    • Platzi Business
    • Live Classes
    • Lanzamientos
    • Executive Program
    • Trabaja con nosotros
    • Podcast

    Recursos

    • Manual de Marca

    Soporte

    • Preguntas Frecuentes
    • Contáctanos

    Legal

    • Términos y Condiciones
    • Privacidad
    • Tyc promociones
    Reconocimientos
    Reconocimientos
    Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
    Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
    Logo reconocimientoPrimera Startup EdTech · 2018
    Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
    Logo reconocimientoCEO Mejor Emprendedor del año · 2024
    De LATAM conpara el mundo
    YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads