diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/weatherApp/README.md b/weatherApp/README.md
index f768e33..119d95a 100644
--- a/weatherApp/README.md
+++ b/weatherApp/README.md
@@ -1,8 +1,48 @@
-# React + Vite
+# PR: Implementación de React Router y Mejoras en la UI para Weather App
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+## Descripción
+Este PR introduce la implementación de React Router para navegación multi-página, la creación de nuevas páginas (Home, Weather, Map y About), la funcionalidad para guardar ciudades favoritas y mejoras en la UI utilizando Shadcn/ui. Además, se ha agregado una funcionalidad de mapa para visualizar datos meteorológicos y se han implementado mejoras avanzadas como modo oscuro, historial climático y comparación de clima.
-Currently, two official plugins are available:
+## Cambios Principales
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+### 1. Implementación de React Router
+- Instalado **react-router-dom** con `npm install react-router-dom`
+- Configuradas rutas para:
+ - `/` → Home
+ - `/weather` → Weather
+ - `/map` → Map
+ - `/about` → About
+- Creado un componente de navegación para cambiar entre las páginas.
+
+### 2. Creación de Nuevas Páginas
+- **Home**: Mensaje de bienvenida y enlaces rápidos.
+- **Weather**: Mantiene la funcionalidad de búsqueda y visualización de clima.
+- **Map**: Vista de mapa para datos meteorológicos utilizando **react-leaflet**.
+- **About**: Información sobre la aplicación y sus características.
+
+### 3. Funcionalidad para Guardar Ciudades Favoritas
+- Implementado almacenamiento de ciudades favoritas en **localStorage**.
+- Creado un listado de ciudades favoritas para acceso rápido.
+
+### 4. Mejora de UI con Shadcn/ui
+- Instalado **Shadcn/ui** con `pm install tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react`.
+- Sustituido CSS por componentes de Shadcn/ui.
+- Implementación de componentes con tailwind.
+
+### 5. Implementación de Funcionalidad de Mapa
+- Integrado **react-leaflet** para mostrar datos meteorológicos geográficamente.
+- Mostrados íconos del clima en el mapa para ciudades buscadas o favoritas.
+- Agregada funcionalidad de clic en el mapa para obtener clima en ubicaciones seleccionadas.
+
+### 6. Mejoras Avanzadas Implementadas
+- **Modo Oscuro**: Implementado un switch para cambiar entre modos claro y oscuro utilizando el sistema de temas de Shadcn/ui.
+- **Historial Climático**: Agregado un selector de fecha para consultar datos históricos de clima de una ciudad.
+- **Comparación de Clima**: Implementada funcionalidad para comparar el clima de múltiples ciudades en un gráfico interactivo usando **recharts**.
+
+## Pruebas Realizadas
+- [x] Navegación fluida entre páginas.
+- [x] Almacenamiento y recuperación de ciudades favoritas desde localStorage.
+- [x] Integración correcta de mapa y visualización de datos meteorológicos.
+- [x] Funcionalidad de modo oscuro operativa.
+- [x] Histórico de búsquedas.
+- [x] Comparación de clima entre dos ciudades.
\ No newline at end of file
diff --git a/weatherApp/components.json b/weatherApp/components.json
new file mode 100644
index 0000000..500e6bc
--- /dev/null
+++ b/weatherApp/components.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": false,
+ "tsx": false,
+ "tailwind": {
+ "config": "",
+ "css": "src/index.css",
+ "baseColor": "slate",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils",
+ "ui": "@/components/ui",
+ "lib": "@/lib",
+ "hooks": "@/hooks"
+ },
+ "iconLibrary": "lucide"
+}
\ No newline at end of file
diff --git a/weatherApp/components/mode-toggle.jsx b/weatherApp/components/mode-toggle.jsx
new file mode 100644
index 0000000..d70a48c
--- /dev/null
+++ b/weatherApp/components/mode-toggle.jsx
@@ -0,0 +1,37 @@
+import { Moon, Sun } from "lucide-react"
+
+import { Button } from "@/components/ui/button"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { useTheme } from "@/components/theme-provider"
+
+export function ModeToggle() {
+ const { setTheme } = useTheme()
+
+ return (
+
+
+
+
+
+ setTheme("light")}>
+ Light
+
+ setTheme("dark")}>
+ Dark
+
+ setTheme("system")}>
+ System
+
+
+
+ )
+}
diff --git a/weatherApp/components/theme-provider.jsx b/weatherApp/components/theme-provider.jsx
new file mode 100644
index 0000000..5686ea3
--- /dev/null
+++ b/weatherApp/components/theme-provider.jsx
@@ -0,0 +1,62 @@
+/* eslint-disable react/prop-types */
+import { createContext, useState, useEffect, useContext } from "react"
+
+const initialState = {
+ theme: "system",
+ setTheme: () => null
+}
+
+const ThemeProviderContext = createContext(initialState)
+
+export function ThemeProvider({
+ children,
+ defaultTheme = "system",
+ storageKey ="vite-ui-theme",
+ ...props
+}) {
+ const [theme, setTheme] = useState(
+ () => (localStorage.getItem(storageKey)) || defaultTheme
+ )
+
+ useEffect(() => {
+ const root = window.document.documentElement
+
+ root.classList.remove("light", "dark")
+
+ if (theme === "system") {
+ const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
+ .matches
+ ? "dark"
+ : "light"
+
+ root.classList.add(systemTheme)
+ return
+ }
+
+ root.classList.add(theme)
+ }, [theme])
+
+ const value = {
+ theme,
+ setTheme: (theme) => {
+ localStorage.setItem(storageKey, theme)
+ setTheme(theme)
+ },
+ }
+
+ return (
+
+ {children}
+
+ )
+ }
+
+
+ export const useTheme = () => {
+ const context = useContext(ThemeProviderContext)
+
+ if (context === undefined)
+ throw new Error("useTheme must be used within a ThemeProvider")
+
+ return context
+ }
\ No newline at end of file
diff --git a/weatherApp/components/ui/button.jsx b/weatherApp/components/ui/button.jsx
new file mode 100644
index 0000000..eb534c9
--- /dev/null
+++ b/weatherApp/components/ui/button.jsx
@@ -0,0 +1,54 @@
+
+import { Slot } from "@radix-ui/react-slot"
+import { cva } from "class-variance-authority";
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ {
+ variants: {
+ variant: {
+ default:
+ "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
+ outline:
+ "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
+ secondary:
+ "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
+ icon: "size-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function Button({
+ className,
+ variant,
+ size,
+ asChild = false,
+ ...props
+}) {
+ const Comp = asChild ? Slot : "button"
+
+ return (
+
+ );
+}
+
+export { Button, buttonVariants }
diff --git a/weatherApp/components/ui/card.jsx b/weatherApp/components/ui/card.jsx
new file mode 100644
index 0000000..3f99be9
--- /dev/null
+++ b/weatherApp/components/ui/card.jsx
@@ -0,0 +1,75 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Card({
+ className,
+ ...props
+}) {
+ return (
+
+ );
+}
+
+function CardHeader({
+ className,
+ ...props
+}) {
+ return (
+
+ );
+}
+
+function CardTitle({
+ className,
+ ...props
+}) {
+ return (
+
+ );
+}
+
+function CardDescription({
+ className,
+ ...props
+}) {
+ return (
+
+ );
+}
+
+function CardContent({
+ className,
+ ...props
+}) {
+ return ();
+}
+
+function CardFooter({
+ className,
+ ...props
+}) {
+ return (
+
+ );
+}
+
+export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
diff --git a/weatherApp/components/ui/chart.jsx b/weatherApp/components/ui/chart.jsx
new file mode 100644
index 0000000..0b9519f
--- /dev/null
+++ b/weatherApp/components/ui/chart.jsx
@@ -0,0 +1,309 @@
+import * as React from "react"
+import * as RechartsPrimitive from "recharts"
+
+import { cn } from "@/lib/utils"
+
+// Format: { THEME_NAME: CSS_SELECTOR }
+const THEMES = {
+ light: "",
+ dark: ".dark"
+}
+
+const ChartContext = React.createContext(null)
+
+function useChart() {
+ const context = React.useContext(ChartContext)
+
+ if (!context) {
+ throw new Error("useChart must be used within a ")
+ }
+
+ return context
+}
+
+function ChartContainer({
+ id,
+ className,
+ children,
+ config,
+ ...props
+}) {
+ const uniqueId = React.useId()
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
+
+ return (
+
+
+
+
+ {children}
+
+
+
+ );
+}
+
+const ChartStyle = ({
+ id,
+ config
+}) => {
+ const colorConfig = Object.entries(config).filter(([, config]) => config.theme || config.color)
+
+ if (!colorConfig.length) {
+ return null
+ }
+
+ return (
+