0% found this document useful (0 votes)
16 views8 pages

Guia React Parcial

ew
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views8 pages

Guia React Parcial

ew
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

https://tailblocks.

cc/

https://mambaui.com/components

https://tailwindui.com/components

https://daisyui.com/components

https://www.hyperui.dev/components

árbol de directorios

dentro de la carpeta raiz creamos una cliente

en consola dentro de cliente por consola npm create vite@latest

√ Project name: ... frontend


? Select a framework: » - Use arrow-keys. Return to submit.

> Vanilla

Vue

√ Select a framework: » React

√ Select a variant: » TypeScript + SWC

Done. Now run:

cd frontend

npm install

demas dependencias a instalar en el frontend

npm i axios valibot react-router-dom

npm install -D tailwindcss postcss autoprefixer

npx tailwindcss init -p

Luego debemos configurar el archivo tailwind.config.js para que se apliquen los estilos a las
extensiones de archivos que deseemos.

/** @type {import('tailwindcss').Config} */


export default {
content: [ "./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
}

eliminar carpeta Public

eliminar carpeta assets

eliminamos app.css y app.tsx


vaciamos el archivo index.css y colocamos este código adentro

@tailwind base;
@tailwind components;
@tailwind utilities;

creamos carpetas dentro de /src

se crean las carpetas

 components
 layouts
 services
 types
 views

mkdir components layouts services types views

En postcss.config.js

export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

Archivo /types/index.tsx

import { object, string, number, InferOutput, array, boolean } from


"valibot";

export const UserObject = object({


userId: number(),
id: number(),
title: string(),
completed: boolean()
})

export const UserArray = array(UserObject)


export type UserType = InferOutput<typeof UserObject>

Archivo userService.ts
import { safeParse } from 'valibot'
import axios from 'axios'
import { UserObject, UserArray, UserType } from '../types/index'

const URL = 'https://jsonplaceholder.typicode.com/todos/'

export async function getUsers() {


try {

const { data } = await axios.get(URL)


const result = safeParse(UserArray, data )

if (result.success) {
return result.output
} else {
throw new Error('Error al obtener los usuarios.')
}
} catch (error) {
console.log(error)
}
}

export async function getUserID(id: UserType['id']) {


try {
const url = `${URL}${id}`
const { data } = await axios.get(url)

const result = safeParse(UserObject, data)

if (result.success) {
return result.output
} else {
throw new Error('Error al obtener el usuario.')
}
} catch (error) {
console.log(error)
}
}

El codigo de layout.tsx

import { Outlet } from 'react-router-dom';


import Banner from '../components/Banner';
const Layout = () => {
return (
<div className='flex flex-col min-h-screen'>
<Banner />
<main className='flex-grow mt-10'>
<Outlet />
</main>
</div>
);
};

export default Layout;

El codigo de view.tsx para un usuario (id)

import { Link, LoaderFunctionArgs, redirect, useLoaderData } from "react-router-dom";


import { getUserID } from "../services/userService";
import { UserType } from "../types/index";

export async function loader({ params }: LoaderFunctionArgs) {


if (params.id !== undefined) {
const user = await getUserID(+params.id);
if (!user) {
return redirect("/");
}
return user;
}
}

const User = () => {


const user = useLoaderData() as UserType;

return (
<>
<section className="flex items-center justify-center mt-10">
<div className="rounded-3xl shadow-2xl p-8 text-center sm:p-12">
<p className="text-3xl font-semibold uppercase tracking-widest text-pink-500">
INFORMACIÓN DEL USUARIO N° {user.id}
</p>
<h4 className="mt-6 text-2xl font-bold">Full ID: {user.userId}</h4>
<h2 className="mt-6 text-3xl font-bold">ID: {user.id}</h2>
<p className="mt-6 text-lg text-gray-600">Título: {user.title}</p>
<p className="mt-6 text-md text-gray-600">
Estado: {user.completed ? "Completo" : "Incompleto"}
</p>
<td className="whitespace-nowrap px-4 py-2">
<Link
to={"/"}
className="inline-block rounded bg-indigo-600 px-4 py-2 text-xs font-medium
text-white hover:bg-indigo-700"
>
Atrás
</Link>
</td>
</div>
</section>
</>
);
};

export default User;

Viwes.tsx para traer todos los usuarios

import { useLoaderData, Link } from "react-router-dom";

import { getUsers } from "../services/userService";

import { UserType } from "../types";

export async function loader() {

const users = await getUsers();

return users || [];

const Users = () => {

const users = useLoaderData() as UserType[];

return (

<>

<div className="overflow-x-auto text-center">

<table className="min-w-full divide-y-2 divide-gray-200 bg-white text-sm">

<thead className="ltr:text-left rtl:text-right">

<tr>

<th className="whitespace-nowrap px-4 py-2 font-medium text-gray-900">

UserID

</th>

<th className="whitespace-nowrap px-4 py-2 font-medium text-gray-900">

ID

</th>

<th className="whitespace-nowrap px-4 py-2 font-medium text-gray-900">


Title

</th>

<th className="whitespace-nowrap px-4 py-2 font-medium text-gray-900">

Completed

</th>

<th className="px-4 py-2"></th>

</tr>

</thead>

<tbody className="divide-y divide-gray-200">

{users.map((user) => (

<>

<tr key={user?.id}>

<td className="whitespace-nowrap px-4 py-2 font-medium text-gray-900">

{user.userId}

</td>

<td className="whitespace-nowrap px-4 py-2 text-gray-700">

{user.id}

</td>

<td className="whitespace-nowrap px-4 py-2 text-gray-700">

{user.title}

</td>

<td className="whitespace-nowrap px-4 py-2 text-gray-700">

{user.completed ? 'Si' : 'No'}

</td>

<td className="whitespace-nowrap px-4 py-2">

<Link

to={`/user/${user.id}`}

className="inline-block rounded bg-indigo-600 px-4 py-2 text-xs font-medium

text-white hover:bg-indigo-700"

>

Ver

</Link>

</td>

</tr>

</>

))}

</tbody>

</table>

</div>

</>

);

};

export default Users;


Crear dentro de /src el archivo router.tsx

import { createBrowserRouter } from 'react-router-dom';


import Layout from './Layout/Layout';
import Users, { loader as loaderUsers } from './views/Users';
import User, { loader as loaderUser } from './views/User';

export const router = createBrowserRouter([


{
path: '/',
element: <Layout />,
children: [
//todos
{
index: true,
element: <Users />,
loader: loaderUsers
},
//solito
{
path: 'user/:id',
element: <User />,
loader: loaderUser
}
]
}
])

dentro de main.tsx dejamos esto

import { StrictMode } from 'react'


import { createRoot } from 'react-dom/client'
import { RouterProvider } from 'react-router-dom'
import { router } from './router'
import './index.css'

createRoot(document.getElementById('root')!).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>,
)

You might also like