From 23521d5d3488d26013f96e266c3cc8e4c979e39a Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 22:31:37 +0000 Subject: [PATCH 01/11] =?UTF-8?q?renderizaci=C3=B3n=20inicial?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/.App.jsx.swp | Bin 0 -> 4096 bytes src/App.jsx | 34 ++++++++++------------------------ src/components/Datatable.jsx | 0 src/components/login.jsx | 7 +++++++ src/pages/Dashboard.jsx | 7 +++++++ 5 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 src/.App.jsx.swp create mode 100644 src/components/Datatable.jsx create mode 100644 src/components/login.jsx create mode 100644 src/pages/Dashboard.jsx diff --git a/src/.App.jsx.swp b/src/.App.jsx.swp new file mode 100644 index 0000000000000000000000000000000000000000..111f808504da23689b1bb0189b0746804d99645b GIT binary patch literal 4096 zcmYc?2=nw+u+TGP00IF921ngv>23^642&iW49WQ^sl^3}$*CYYJOHk)ST{M*#KJTU zhg$ve{Gx2IfyMerdWupLlS}lAi<0#n3kvkIiYstv9~B-Afzc44C -
- logo -

- GitHub Codespaces ♥️ React -

-

- Edit src/App.jsx and save to reload. -

-

- - Learn React - -

-
- + const [isAuthenticated, setIsAuthenticated] = useState(false); + + return isAuthenticated ? ( + + ) : ( + ); } -export default App; +export default App; \ No newline at end of file diff --git a/src/components/Datatable.jsx b/src/components/Datatable.jsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/login.jsx b/src/components/login.jsx new file mode 100644 index 000000000..14791f76e --- /dev/null +++ b/src/components/login.jsx @@ -0,0 +1,7 @@ +import React from "react"; + +const LoginForm = () => { + return

Holaee

; +}; + +export default LoginForm; \ No newline at end of file diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx new file mode 100644 index 000000000..d0c07a5a8 --- /dev/null +++ b/src/pages/Dashboard.jsx @@ -0,0 +1,7 @@ +import React from "react"; + +const Dashboard = () => { + return

Howwla

; +}; + +export default Dashboard; \ No newline at end of file From 37967a0ecc7d7e7fe50cb4ab150be4ddf86ba1d3 Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 22:33:01 +0000 Subject: [PATCH 02/11] Login inicial --- src/components/login.jsx | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/components/login.jsx b/src/components/login.jsx index 14791f76e..0ccd62f69 100644 --- a/src/components/login.jsx +++ b/src/components/login.jsx @@ -1,7 +1,34 @@ -import React from "react"; +import { useState } from "react"; -const LoginForm = () => { - return

Holaee

; -}; +function LoginForm({ setIsAuthenticated }) { + const [user, setUser] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(false); -export default LoginForm; \ No newline at end of file + const handleLogin = () => { + setLoading(true); + setTimeout(() => { + if (user === "admin" && password === "1234") { + setIsAuthenticated(true); + } else { + setError("Credenciales incorrectas"); + } + setLoading(false); + }, 1000); + }; + + return ( +
+

Iniciar Sesión

+ setUser(e.target.value)} /> + setPassword(e.target.value)} /> + {error &&

{error}

} + +
+ ); +} + +export default LoginForm; From 117e8a3fb841bd33146c41e2990da2352503b022 Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 22:35:37 +0000 Subject: [PATCH 03/11] =?UTF-8?q?instalaci=C3=B3n=20sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 557 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + src/.App.jsx.swp | Bin 4096 -> 12288 bytes 3 files changed, 555 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b1713e2d4..4ad0ac7fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@testing-library/user-event": "^14.4.3", "react": "^18.2.0", "react-dom": "^18.2.0", + "sass": "^1.85.1", "web-vitals": "^3.1.0" }, "devDependencies": { @@ -1011,6 +1012,302 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@testing-library/dom": { "version": "8.19.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.1.tgz", @@ -1707,6 +2004,21 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/ci-info": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", @@ -1871,6 +2183,19 @@ "node": ">=0.4.0" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -2211,6 +2536,12 @@ "node": ">=0.10.0" } }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "license": "MIT" + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -2298,6 +2629,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -2805,6 +3159,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -3033,6 +3394,19 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -3100,6 +3474,26 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/sass": { + "version": "1.85.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.85.1.tgz", + "integrity": "sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -3151,7 +3545,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4414,6 +4807,109 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "optional": true, + "requires": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1", + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + } + }, + "@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "optional": true + }, + "@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "optional": true + }, + "@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "optional": true + }, + "@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "optional": true + }, + "@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "optional": true + }, + "@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "optional": true + }, + "@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "optional": true + }, + "@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "optional": true + }, + "@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "optional": true + }, + "@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "optional": true + }, + "@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "optional": true + }, + "@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "optional": true + }, + "@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "optional": true + }, "@testing-library/dom": { "version": "8.19.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.1.tgz", @@ -4947,6 +5443,14 @@ "get-func-name": "^2.0.2" } }, + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "requires": { + "readdirp": "^4.0.1" + } + }, "ci-info": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", @@ -5067,6 +5571,12 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "optional": true + }, "diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -5318,6 +5828,11 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==" + }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -5372,6 +5887,21 @@ "has-tostringtag": "^1.0.0" } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "optional": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "optional": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -5736,6 +6266,12 @@ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true }, + "node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "optional": true + }, "node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -5897,6 +6433,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==" + }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -5948,6 +6489,17 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sass": { + "version": "1.85.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.85.1.tgz", + "integrity": "sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag==", + "requires": { + "@parcel/watcher": "^2.4.1", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, "saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -5989,8 +6541,7 @@ "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" }, "source-map-support": { "version": "0.5.21", diff --git a/package.json b/package.json index c47e82140..24531ed50 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@testing-library/user-event": "^14.4.3", "react": "^18.2.0", "react-dom": "^18.2.0", + "sass": "^1.85.1", "web-vitals": "^3.1.0" }, "overrides": { diff --git a/src/.App.jsx.swp b/src/.App.jsx.swp index 111f808504da23689b1bb0189b0746804d99645b..e4ed2fbb96938d0f7f439cfc32e501588fd48ac1 100644 GIT binary patch literal 12288 zcmeI&&rcIU6bJBE?x2Bx;8`yvv7MrjG*&cC3<-&z2wsebVRp7G(w%i?HlR&oqIZoK z{|x>N&Kx=MxA?ZdPy`dXk$fllcH5mdZ)ZQZO?R*TX8SdFT5BZZK2fiE+TWrDs;v_l zm)KBfW2?D;jCoyX8ol1xNN=cBN6x<=Hw@~xHQs6yRq#gjilTK8j&E3w(-45bZ3W7h zHam;EPadzes}>LI4|rvH_qN@z4gwH>00bZa0SG_<0uZ=^00S6nmL$8ecHjkOn(I%V2zt4?WJ+GGYQ*KN;ywqWT&uO3h zUk7hv>2uEhyd=Mnw$j(QJVbtbW%kiEmw3mUTn4)nWyg(F9|kM8mX^7RnaisiZmjZ< zC>x9+E;pNcH{g0p6}oSOnxC(CXQh`ivr^-vNiIA=%_pV4KWROjZ-YlXSu%d Date: Mon, 3 Mar 2025 22:38:24 +0000 Subject: [PATCH 04/11] Estilos agregados --- src/index.css | 13 -------- src/index.jsx | 2 +- src/index.scss | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 14 deletions(-) delete mode 100644 src/index.css create mode 100644 src/index.scss diff --git a/src/index.css b/src/index.css deleted file mode 100644 index ec2585e8c..000000000 --- a/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/src/index.jsx b/src/index.jsx index d563c0fb1..206e279d1 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,6 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import './index.css'; +import './index.scss'; import App from './App'; import reportWebVitals from './reportWebVitals'; diff --git a/src/index.scss b/src/index.scss new file mode 100644 index 000000000..b76dfa05a --- /dev/null +++ b/src/index.scss @@ -0,0 +1,86 @@ +$primary-color: purple; +$secondary-color: black; +$button-radius: 5px; + +body { + font-family: Arial, sans-serif; + margin: 0; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; + background: linear-gradient(135deg, $secondary-color, purple, gray); +} + +.login-wrapper { + width: 70%; + /* max-width: 700px; */ + display: flex; + flex-direction: row; /* Cambiado de columna a fila */ + background: white; + border-radius: 12px; + box-shadow: 4px 4px 15px rgba(0, 0, 0, 0.3); + overflow: hidden; + margin: auto; +} + +.login-image { + width: 50%; + display: flex; + justify-content: center; + align-items: center; + background: rgba(0, 0, 0, 0.1); +} + +.login-image img { + max-width: 100%; + height: auto; +} + +.login-form { + width: 50%; + padding: 30px; + text-align: center; + display: flex; + flex-direction: column; + justify-content: center; +} + +h2 { + margin-bottom: 20px; +} + +input { + width: 100%; + padding: 10px; + margin: 10px 0; + border: 1px solid #ccc; + border-radius: 5px; +} + +button { + width: 100%; + padding: 10px; + background: $primary-color; + color: white; + border: none; + border-radius: $button-radius; + cursor: pointer; + transition: background 0.3s; + + &:hover { + background: lighten($primary-color, 20%); + } +} + +.error { + color: red; + font-size: 14px; +} + +.dashboard-container{ + max-height: 100vh; /* Corrección: vh en lugar de hv */ + overflow-y: auto; /* Agrega scroll solo si es necesario */ + padding: 20px; /* Evita que el contenido se pegue a los bordes */ + box-sizing: border-box; /* Asegura que padding no afecte el tamaño total */ +} \ No newline at end of file From a89e717b84ee14bed34afc4767b82a67bb0469d2 Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 22:41:01 +0000 Subject: [PATCH 05/11] =?UTF-8?q?instalaci=C3=B3n=20axios=20y=20creaci?= =?UTF-8?q?=C3=B3n=20de=20datatable=20y=20Dashboard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 78 ++++++++++++++++++++++++++++-------- package.json | 1 + src/components/Datatable.jsx | 23 +++++++++++ src/pages/Dashboard.jsx | 44 +++++++++++++++++--- 4 files changed, 125 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ad0ac7fe..b028898d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", + "axios": "^1.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.85.1", @@ -1853,8 +1854,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -1867,6 +1867,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz", + "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -2053,7 +2064,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2178,7 +2188,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -2317,6 +2326,26 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -2329,7 +2358,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3098,7 +3126,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -3107,7 +3134,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -3345,6 +3371,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -5353,14 +5385,23 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, + "axios": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz", + "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -5473,7 +5514,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -5568,8 +5608,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "detect-libc": { "version": "1.0.3", @@ -5673,6 +5712,11 @@ "to-regex-range": "^5.0.1" } }, + "follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" + }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -5685,7 +5729,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -6225,14 +6268,12 @@ "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "requires": { "mime-db": "1.52.0" } @@ -6393,6 +6434,11 @@ } } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", diff --git a/package.json b/package.json index 24531ed50..09938d648 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", + "axios": "^1.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.85.1", diff --git a/src/components/Datatable.jsx b/src/components/Datatable.jsx index e69de29bb..2bafa976e 100644 --- a/src/components/Datatable.jsx +++ b/src/components/Datatable.jsx @@ -0,0 +1,23 @@ +function DataTable({ data }) { + return ( + + + + + + + + + {data.map((album) => ( + + + + + ))} + +
IDTítulo
{album.id}{album.title}
+ ); + } + + export default DataTable; + \ No newline at end of file diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index d0c07a5a8..b2c5e579a 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -1,7 +1,41 @@ -import React from "react"; +import { useState, useEffect } from "react"; +import axios from "axios"; +import DataTable from "../components/Datatable"; -const Dashboard = () => { - return

Howwla

; -}; +function Dashboard({ setIsAuthenticated }) { + const [albums, setAlbums] = useState([]); + const [page, setPage] = useState(1); + const [loading, setLoading] = useState(false); -export default Dashboard; \ No newline at end of file + useEffect(() => { + fetchData(); + }, []); + + const fetchData = async () => { + setLoading(true); + try { + const response = await axios.get( + `https://jsonplaceholder.typicode.com/albums?_limit=10&_page=${page}` + ); + setAlbums((prev) => [...prev, ...response.data]); + setPage(page + 1); + } catch (error) { + console.error("Error al obtener los datos", error); + } finally { + setLoading(false); + } + }; + + return ( +
+

Dashboard

+ + + +
+ ); +} + +export default Dashboard; From f47ef721bf9feb8cb6468b3b2483fada87078169 Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 22:52:44 +0000 Subject: [PATCH 06/11] =?UTF-8?q?instalaci=C3=B3n=20sweatalert2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 16 ++++++++++++++++ package.json | 1 + src/App.jsx | 18 ++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b028898d0..92e5b04a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.85.1", + "sweetalert2": "^11.17.2", "web-vitals": "^3.1.0" }, "devDependencies": { @@ -3669,6 +3670,16 @@ "node": ">=8" } }, + "node_modules/sweetalert2": { + "version": "11.17.2", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.17.2.tgz", + "integrity": "sha512-HKxDr1IyV3Lxr3W6sb61qm/p2epFIEdr5EKwteRFHnIg6f8nHFl2kX++DBVz16Mac+fFiU3hMpjq1L6yE2Ge5w==", + "license": "MIT", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -6663,6 +6674,11 @@ "has-flag": "^4.0.0" } }, + "sweetalert2": { + "version": "11.17.2", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.17.2.tgz", + "integrity": "sha512-HKxDr1IyV3Lxr3W6sb61qm/p2epFIEdr5EKwteRFHnIg6f8nHFl2kX++DBVz16Mac+fFiU3hMpjq1L6yE2Ge5w==" + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 09938d648..db3350a4a 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.85.1", + "sweetalert2": "^11.17.2", "web-vitals": "^3.1.0" }, "overrides": { diff --git a/src/App.jsx b/src/App.jsx index 58b4754c0..27be736b4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,9 +1,23 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import LoginForm from "./components/login"; import Dashboard from "./pages/Dashboard"; function App() { - const [isAuthenticated, setIsAuthenticated] = useState(false); + const [isAuthenticated, setIsAuthenticated] = useState( + () => JSON.parse(localStorage.getItem("isAuthenticated")) || false + ); + + document.body.style.background = isAuthenticated + ? "linear-gradient(135deg, rgb(124, 208, 238), rgb(5, 105, 196))" + : "linear-gradient(135deg, black, purple, gray)"; + + useEffect(() => { + if(isAuthenticated){ + console.log("Autenticado"); + }else{ + console.log("No autenticado"); + } + },[isAuthenticated]); return isAuthenticated ? ( From 8ab7eb4086c896488e821b7e8ed4026b830cc132 Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 23:01:48 +0000 Subject: [PATCH 07/11] =?UTF-8?q?Modificaci=C3=B3n=20de=20Login=20con=20Sw?= =?UTF-8?q?al=20y=20nuevos=20estilos.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 23 +++++++++++------ src/components/login.jsx | 53 ++++++++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 27be736b4..5b30baa8d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,23 +1,30 @@ import { useState, useEffect } from "react"; import LoginForm from "./components/login"; import Dashboard from "./pages/Dashboard"; +import Swal from "sweetalert2"; function App() { const [isAuthenticated, setIsAuthenticated] = useState( () => JSON.parse(localStorage.getItem("isAuthenticated")) || false ); - document.body.style.background = isAuthenticated + useEffect(() => { + localStorage.setItem("isAuthenticated", JSON.stringify(isAuthenticated)); + + document.body.style.background = isAuthenticated ? "linear-gradient(135deg, rgb(124, 208, 238), rgb(5, 105, 196))" : "linear-gradient(135deg, black, purple, gray)"; - useEffect(() => { - if(isAuthenticated){ - console.log("Autenticado"); - }else{ - console.log("No autenticado"); + // Mostrar alerta al iniciar/cerrar sesión + if (isAuthenticated ) { + Swal.fire({ + title: "Bienvenido", + text: "Has iniciado sesión correctamente.", + icon: "success", + confirmButtonColor: "#3085d6", + }); } - },[isAuthenticated]); + }, [isAuthenticated]); return isAuthenticated ? ( @@ -26,4 +33,4 @@ function App() { ); } -export default App; \ No newline at end of file +export default App; diff --git a/src/components/login.jsx b/src/components/login.jsx index 0ccd62f69..024cf16af 100644 --- a/src/components/login.jsx +++ b/src/components/login.jsx @@ -1,4 +1,5 @@ import { useState } from "react"; +import Swal from 'sweetalert2'; function LoginForm({ setIsAuthenticated }) { const [user, setUser] = useState(""); @@ -9,24 +10,50 @@ function LoginForm({ setIsAuthenticated }) { const handleLogin = () => { setLoading(true); setTimeout(() => { - if (user === "admin" && password === "1234") { - setIsAuthenticated(true); - } else { - setError("Credenciales incorrectas"); - } + if (user === "admin" && password === "1234") { + setIsAuthenticated(true); + Swal.fire({ + title: "Bienvenido", + text: "Has iniciado sesión correctamente.", + icon: "success", + confirmButtonColor: "#3085d6", + }); + } else { + Swal.fire({ + title: "Credenciales incorrectas", + icon: "error", + confirmButtonColor: "#d33", + }); + setError("Credenciales incorrectas."); + } setLoading(false); }, 1000); }; return ( -
-

Iniciar Sesión

- setUser(e.target.value)} /> - setPassword(e.target.value)} /> - {error &&

{error}

} - +
+
+ Infinito +
+
+

Iniciar Sesión

+ setUser(e.target.value)} + /> + setPassword(e.target.value)} + /> + {error &&

{error}

} + +
); } From a38012d40fe92fb1b4235c28fa9cc2aefe62df80 Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 23:08:09 +0000 Subject: [PATCH 08/11] =?UTF-8?q?Modificaci=C3=B3n=20estilos=20Dashboard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Datatable.jsx | 40 +++++++++++++++++++++--------------- src/pages/Dashboard.jsx | 36 +++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/components/Datatable.jsx b/src/components/Datatable.jsx index 2bafa976e..1e173d22d 100644 --- a/src/components/Datatable.jsx +++ b/src/components/Datatable.jsx @@ -1,21 +1,29 @@ -function DataTable({ data }) { +function DataTable({ data = [] }) { // Asegura que data sea un array por defecto return ( - - - - - - - - - {data.map((album) => ( - - - +
+
IDTítulo
{album.id}{album.title}
+ + + + - ))} - -
IDTítulo
+ + + {data.length > 0 ? ( + data.map((album) => ( + + {album.id} + {album.title} + + )) + ) : ( + + No hay datos disponibles + + )} + + +
); } diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index b2c5e579a..fd52edde3 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useCallback } from "react"; import axios from "axios"; import DataTable from "../components/Datatable"; @@ -7,33 +7,45 @@ function Dashboard({ setIsAuthenticated }) { const [page, setPage] = useState(1); const [loading, setLoading] = useState(false); - useEffect(() => { - fetchData(); - }, []); - - const fetchData = async () => { + const fetchData = useCallback(async () => { + let pageMod = 0; + if (loading) return; // Evita llamadas duplicadas setLoading(true); try { const response = await axios.get( `https://jsonplaceholder.typicode.com/albums?_limit=10&_page=${page}` ); - setAlbums((prev) => [...prev, ...response.data]); - setPage(page + 1); + pageMod = page+1; + setAlbums((prev) => { + const existingIds = new Set(prev.map((album) => album.id)); + const newData = response.data.filter((album) => !existingIds.has(album.id)); + + return [...prev, ...newData]; // Ordenar por ID + }); + + setPage(pageMod); } catch (error) { console.error("Error al obtener los datos", error); } finally { setLoading(false); } - }; + }, [loading]); + + useEffect(() => { + fetchData(); + }, []); // ✅ Solo se ejecuta una vez al montar el componente return ( -
+

Dashboard

- + - + {loading &&

Cargando datos...

}
); } From 06a58f99d31f1fa1599daf511df9a3c05677fc7d Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 23:11:19 +0000 Subject: [PATCH 09/11] Se me olvidava uso de CallBack para evitar que llame dos veces fetchdata --- src/pages/Dashboard.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index fd52edde3..8d1cbe2f8 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -31,6 +31,8 @@ function Dashboard({ setIsAuthenticated }) { } }, [loading]); + + useEffect(() => { fetchData(); }, []); // ✅ Solo se ejecuta una vez al montar el componente From 68bc9e42351efad2dda968a539a2299a8fc7d0ef Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 23:21:55 +0000 Subject: [PATCH 10/11] Pending changes exported from your codespace --- src/pages/Dashboard.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index 8d1cbe2f8..cfd2078e9 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -1,6 +1,7 @@ import { useState, useEffect, useCallback } from "react"; import axios from "axios"; import DataTable from "../components/Datatable"; +import Swal from "sweetalert2"; function Dashboard({ setIsAuthenticated }) { const [albums, setAlbums] = useState([]); @@ -31,7 +32,15 @@ function Dashboard({ setIsAuthenticated }) { } }, [loading]); - + const isAuth = () => { + setIsAuthenticated(false); + Swal.fire({ + title: "Sesión cerrada", + text: "Has cerrado sesión.", + icon: "info", + confirmButtonColor: "#d33", + }); + } useEffect(() => { fetchData(); @@ -40,7 +49,7 @@ function Dashboard({ setIsAuthenticated }) { return (

Dashboard

- From 3d5a2ac63bfbd2ef750be5e9ba0167f5f05b7ef6 Mon Sep 17 00:00:00 2001 From: Julian David Ortega Solarte <95juliandos@gmail.com> Date: Mon, 3 Mar 2025 18:06:18 -0600 Subject: [PATCH 11/11] README.md --- README.md | 81 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index f360b3fb1..9780cb0bc 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,75 @@ -# GitHub Codespaces ♥️ React +Proyecto ReactJS con Autenticación y DataTable -Welcome to your shiny new Codespace running React! We've got everything fired up and running for you to explore React. +Este es un proyecto desarrollado en ReactJS que incluye un sistema de autenticación simple, consumo de API con paginación y una tabla de datos interactiva. -You've got a blank canvas to work on from a git perspective as well. There's a single initial commit with the what you're seeing right now - where you go from here is up to you! +📌 Características -Everything you do here is contained within this one codespace. There is no repository on GitHub yet. If and when you’re ready you can click "Publish Branch" and we’ll create your repository and push up your project. If you were just exploring then and have no further need for this code then you can simply delete your codespace and it's gone forever. +Inicio de sesión con validación y alertas visuales con SweetAlert2. -This project was bootstrapped for you with [Vite](https://vitejs.dev/). +Persistencia de sesión en localStorage. -## Available Scripts +Consumo de API con axios, manejando la paginación de datos. -In the project directory, you can run: +Tabla de datos con paginación y ordenamiento. -### `npm start` +Indicador de carga (spinner) para mejorar la experiencia de usuario. -We've already run this for you in the `Codespaces: server` terminal window below. If you need to stop the server for any reason you can just run `npm start` again to bring it back online. +Diseño responsivo con estilos mejorados. -Runs the app in the development mode.\ -Open [http://localhost:3000/](http://localhost:3000/) in the built-in Simple Browser (`Cmd/Ctrl + Shift + P > Simple Browser: Show`) to view your running application. +🚀 Instalación y Configuración -The page will reload automatically when you make changes.\ -You may also see any lint errors in the console. +Clona el repositorio: -### `npm test` +git clone https://github.com/tuusuario/react-dashboard.git +cd react-dashboard -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. +Instala las dependencias: -### `npm run build` +npm install -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. +Inicia el servidor de desarrollo: -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! +npm start -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. +🛠️ Tecnologías Utilizadas -## Learn More +ReactJS (useState, useEffect, useCallback) -You can learn more in the [Vite documentation](https://vitejs.dev/guide/). +Axios (Consumo de API) -To learn Vitest, a Vite-native testing framework, go to [Vitest documentation](https://vitest.dev/guide/) +SweetAlert2 (Alertas visuales) -To learn React, check out the [React documentation](https://reactjs.org/). +Bootstrap (Diseño y estilos) -### Code Splitting +📂 Estructura del Proyecto -This section has moved here: [https://sambitsahoo.com/blog/vite-code-splitting-that-works.html](https://sambitsahoo.com/blog/vite-code-splitting-that-works.html) +📁 src/ + ├── 📁 components/ + │ ├── LoginForm.jsx # Formulario de inicio de sesión + │ ├── DataTable.jsx # Tabla de datos con paginación + ├── 📁 pages/ + │ ├── Dashboard.jsx # Página principal tras el login + ├── App.js # Controla la autenticación y el layout + ├── index.js # Punto de entrada de la aplicación -### Analyzing the Bundle Size +🔑 Credenciales de Prueba -This section has moved here: [https://github.com/btd/rollup-plugin-visualizer#rollup-plugin-visualizer](https://github.com/btd/rollup-plugin-visualizer#rollup-plugin-visualizer) +Para iniciar sesión, usa: -### Making a Progressive Web App +Usuario: admin -This section has moved here: [https://dev.to/hamdankhan364/simplifying-progressive-web-app-pwa-development-with-vite-a-beginners-guide-38cf](https://dev.to/hamdankhan364/simplifying-progressive-web-app-pwa-development-with-vite-a-beginners-guide-38cf) +Contraseña: 1234 -### Advanced Configuration +📌 Mejoras Futuras -This section has moved here: [https://vitejs.dev/guide/build.html#advanced-base-options](https://vitejs.dev/guide/build.html#advanced-base-options) +Implementar autenticación con JWT. -### Deployment +Mejorar la interfaz con Material-UI o TailwindCSS. -This section has moved here: [https://vitejs.dev/guide/build.html](https://vitejs.dev/guide/build.html) +Añadir más funcionalidades al Dashboard. -### Troubleshooting +📄 Licencia -This section has moved here: [https://vitejs.dev/guide/troubleshooting.html](https://vitejs.dev/guide/troubleshooting.html) +Este proyecto está bajo la licencia MIT. ¡Siéntete libre de modificarlo y usarlo! 🚀 + +Julian Ortega.