Compare commits

..

No commits in common. "617c0e82e102a181a8e6fea5593c38dfa18b3025" and "a42e769c3e12bfb3e0dbd50253b82d4b54b4f8e6" have entirely different histories.

15 changed files with 669 additions and 373 deletions

View file

@ -1,10 +0,0 @@
[
{
"adapter": "JavaScript",
"type": "chrome",
"request": "attach",
"port": 9222,
"label": "Conectar a navegador",
"webRoot": "${GRAM_WORKTREE_ROOT}/src",
},
]

View file

@ -1,3 +0,0 @@
{
"language_servers": ["...", "!biome"],
}

View file

@ -1,4 +0,0 @@
[global]
flavor = "gfm"
[MD013]
reflow = true

View file

@ -1,12 +0,0 @@
POST http://localhost:5000/api/auth/login
{
"email": "test@test.com",
"password": "123123"
}
HTTP 200
[Captures]
token: jsonpath "$.token"
GET http://localhost:5000/api/auth/me
Authorization: Bearer {{token}}
HTTP 200

View file

@ -1,98 +1,94 @@
# Simple API JWT # Simple API JWT
API para consumir un servicio de Auth con JWT. API para consumir un servicio de Auth con JWT.
## Instalación ## Instalación
```sh ```sh
npm install npm install
``` ```
## Uso ## Uso
```sh ```sh
npm run dev npm run dev
``` ```
## Endpoints ## Endpoints
### Pizzas ### Pizzas
```sh ```sh
GET /api/pizzas GET /api/pizzas
``` ```
### Pizza (única) ### Pizza (única)
```sh ```sh
GET /api/pizzas/:id GET /api/pizzas/:id
``` ```
### Auth ### Auth
```sh ```sh
POST /api/auth/login POST /api/auth/login
POST /api/auth/register POST /api/auth/register
``` ```
body: body:
```json ```json
{ {
"email": "test@example.com", "email": "test@example.com",
"password": "123123" "password": "123123"
} }
``` ```
### Checkout & Profile ### Checkout & Profile
Esta ruta requiere un token JWT en el header, el token se obtiene en el endpoint Esta ruta requiere un token JWT en el header, el token se obtiene en el endpoint de Auth explicado en el item siguiente (JWT).
de Auth explicado en el item siguiente (JWT).
Además puedes enviar un carrito con los productos a comprar, esto es solo una simulación, no se guarda en la base de datos.
Además puedes enviar un carrito con los productos a comprar, esto es solo una
simulación, no se guarda en la base de datos. ```sh
POST /api/checkouts
```sh ```
POST /api/checkouts
``` body:
body: ```json
{
```json "cart": [...]
{ }
"cart": [...] ```
}
``` Endpoint para obtener el perfil del usuario autenticado. Necesitas enviar el token JWT en el header.
Endpoint para obtener el perfil del usuario autenticado. Necesitas enviar el ```sh
token JWT en el header. GET /api/auth/me
```
```sh
GET /api/auth/me ## JWT
```
Para obtener el token JWT, se debe hacer una petición a `/api/auth/login` o a `/api/auth/register` con el body correspondiente.
## JWT
El token JWT se debe enviar en el header `Authorization` de la siguiente manera:
Para obtener el token JWT, se debe hacer una petición a `/api/auth/login` o a
`/api/auth/register` con el body correspondiente. ```sh
Authorization Bearer token_jwt
El token JWT se debe enviar en el header `Authorization` de la siguiente manera: ```
```sh Ejemplo con fetch:
Authorization Bearer token_jwt
``` ```js
await fetch("http://localhost:5000/api/checkout", {
Ejemplo con fetch: method: "POST",
headers: {
```js "Content-Type": "application/json",
await fetch("http://localhost:5000/api/checkout", { Authorization: `Bearer token_jwt`,
method: "POST", },
headers: { body: JSON.stringify({
"Content-Type": "application/json", cart: carrito,
Authorization: `Bearer token_jwt`, }),
}, });
body: JSON.stringify({ ```
cart: carrito,
}),
});
```

231
biome.json Normal file
View file

@ -0,0 +1,231 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.8/schema.json",
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": { "ignoreUnknown": false },
"formatter": { "enabled": true, "indentStyle": "tab" },
"linter": {
"enabled": true,
"rules": { "recommended": false },
"includes": ["**", "!dist"]
},
"javascript": { "formatter": { "quoteStyle": "double" } },
"overrides": [
{
"includes": ["**/*.{js,jsx}"],
"linter": {
"rules": {
"complexity": {
"noAdjacentSpacesInRegex": "error",
"noExtraBooleanCast": "error",
"noUselessCatch": "error",
"noUselessEscapeInRegex": "error"
},
"correctness": {
"noConstAssign": "error",
"noConstantCondition": "error",
"noEmptyCharacterClassInRegex": "error",
"noEmptyPattern": "error",
"noGlobalObjectCalls": "error",
"noInvalidBuiltinInstantiation": "error",
"noInvalidConstructorSuper": "error",
"noNonoctalDecimalEscape": "error",
"noPrecisionLoss": "error",
"noSelfAssign": "error",
"noSetterReturn": "error",
"noSwitchDeclarations": "error",
"noUndeclaredVariables": "error",
"noUnreachable": "error",
"noUnreachableSuper": "error",
"noUnsafeFinally": "error",
"noUnsafeOptionalChaining": "error",
"noUnusedLabels": "error",
"noUnusedPrivateClassMembers": "error",
"noUnusedVariables": "error",
"useIsNan": "error",
"useValidForDirection": "error",
"useValidTypeof": "error",
"useYield": "error"
},
"suspicious": {
"noAsyncPromiseExecutor": "error",
"noCatchAssign": "error",
"noClassAssign": "error",
"noCompareNegZero": "error",
"noConstantBinaryExpressions": "error",
"noControlCharactersInRegex": "error",
"noDebugger": "error",
"noDuplicateCase": "error",
"noDuplicateClassMembers": "error",
"noDuplicateElseIf": "error",
"noDuplicateObjectKeys": "error",
"noDuplicateParameters": "error",
"noEmptyBlockStatements": "error",
"noFallthroughSwitchClause": "error",
"noFunctionAssign": "error",
"noGlobalAssign": "error",
"noImportAssign": "error",
"noIrregularWhitespace": "error",
"noMisleadingCharacterClass": "error",
"noPrototypeBuiltins": "error",
"noRedeclare": "error",
"noShadowRestrictedNames": "error",
"noSparseArray": "error",
"noUnsafeNegation": "error",
"noUselessRegexBackrefs": "error",
"noWith": "error",
"useGetterReturn": "error"
}
}
}
},
{
"includes": ["**/*.{js,jsx}"],
"linter": {
"rules": {
"correctness": {
"useExhaustiveDependencies": "warn",
"useHookAtTopLevel": "error"
}
}
}
},
{ "includes": ["**/*.{js,jsx}"], "linter": { "rules": {} } },
{
"includes": ["**/*.{js,jsx}"],
"javascript": {
"globals": [
"onanimationend",
"ongamepadconnected",
"onlostpointercapture",
"onanimationiteration",
"onkeyup",
"onmousedown",
"onanimationstart",
"onslotchange",
"onprogress",
"ontransitionstart",
"onpause",
"onended",
"onpointerover",
"onscrollend",
"onformdata",
"ontransitionrun",
"onanimationcancel",
"ondrag",
"onchange",
"onbeforeinstallprompt",
"onbeforexrselect",
"onmessage",
"ontransitioncancel",
"onpointerdown",
"onabort",
"onpointerout",
"oncuechange",
"ongotpointercapture",
"onscrollsnapchanging",
"onsearch",
"onsubmit",
"onstalled",
"onsuspend",
"onreset",
"onerror",
"onmouseenter",
"ongamepaddisconnected",
"onresize",
"ondragover",
"onbeforetoggle",
"onmouseover",
"onpagehide",
"onmousemove",
"onratechange",
"oncommand",
"onmessageerror",
"onwheel",
"ondevicemotion",
"onauxclick",
"ontransitionend",
"onpaste",
"onpageswap",
"ononline",
"ondeviceorientationabsolute",
"onkeydown",
"onclose",
"onselect",
"onpageshow",
"onpointercancel",
"onbeforematch",
"onpointerrawupdate",
"ondragleave",
"onscrollsnapchange",
"onseeked",
"onwaiting",
"onbeforeunload",
"onplaying",
"onvolumechange",
"ondragend",
"onstorage",
"onloadeddata",
"onfocus",
"onoffline",
"onplay",
"onafterprint",
"onclick",
"oncut",
"onmouseout",
"ondblclick",
"oncanplay",
"onloadstart",
"onappinstalled",
"onpointermove",
"ontoggle",
"oncontextmenu",
"onblur",
"oncancel",
"onbeforeprint",
"oncontextrestored",
"onloadedmetadata",
"onpointerup",
"onlanguagechange",
"oncopy",
"onselectstart",
"onscroll",
"onload",
"ondragstart",
"onbeforeinput",
"oncanplaythrough",
"oninput",
"oninvalid",
"ontimeupdate",
"ondurationchange",
"onselectionchange",
"onmouseup",
"location",
"onkeypress",
"onpointerleave",
"oncontextlost",
"ondrop",
"onsecuritypolicyviolation",
"oncontentvisibilityautostatechange",
"ondeviceorientation",
"onseeking",
"onrejectionhandled",
"onunload",
"onmouseleave",
"onhashchange",
"onpointerenter",
"onmousewheel",
"onunhandledrejection",
"ondragenter",
"onpopstate",
"onpagereveal",
"onemptied"
]
},
"linter": { "rules": { "correctness": { "noUnusedVariables": "error" } } }
}
],
"assist": {
"enabled": true,
"actions": { "source": { "organizeImports": "on" } }
}
}

View file

@ -1,15 +1,12 @@
mise-task task: mise-task task:
mise r {{ task }} mise r {{task}}
setup: setup:
mise x -- aube i mise x -- aube i
cd backend && npm i cd backend && npm i
start-backend: start-backend:
cd backend && npm start cd backend && npm start
start-frontend: start-frontend:
mise r dev mise r dev
start:
@mprocs

View file

@ -2,10 +2,10 @@
aube = "latest" aube = "latest"
mprocs = "latest" mprocs = "latest"
oxlint = "latest" oxlint = "latest"
pitchfork = "latest"
pnpm = "latest" pnpm = "latest"
prek = "latest" prek = "latest"
oxfmt = "latest" oxfmt = "latest"
node = "24"
[tasks.dev] [tasks.dev]
description = "Arranca el servidor dev" description = "Arranca el servidor dev"

View file

@ -1,35 +1,33 @@
{ {
"name": "desafio", "name": "desafio",
"version": "0.0.0", "private": true,
"private": true, "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"lint": "biome check", "lint": "biome check",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@tanstack/react-form": "^1.32.0", "radashi": "^12.7.2",
"radashi": "^12.7.2", "react": "^19.2.4",
"react": "^19.2.4", "react-dom": "^19.2.4",
"react-dom": "^19.2.4", "react-router-dom": "^7.14.2"
"react-router-dom": "^7.14.2", },
"zod": "^4.4.3" "devDependencies": {
}, "@commitlint/cli": "^20.5.0",
"devDependencies": { "@commitlint/config-conventional": "^20.5.0",
"@commitlint/cli": "^20.5.0", "@eslint/js": "^9.39.4",
"@commitlint/config-conventional": "^20.5.0", "@types/react": "^19.2.14",
"@eslint/js": "^9.39.4", "@types/react-dom": "^19.2.3",
"@types/react": "^19.2.14", "@unocss/reset": "^66.6.7",
"@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.1",
"@unocss/reset": "^66.6.7", "eslint": "^9.39.4",
"@vitejs/plugin-react": "^6.0.1", "eslint-plugin-react-hooks": "^7.0.1",
"eslint": "^9.39.4", "eslint-plugin-react-refresh": "^0.5.2",
"eslint-plugin-react-hooks": "^7.0.1", "globals": "^17.4.0",
"eslint-plugin-react-refresh": "^0.5.2", "unocss": "^66.6.7",
"globals": "^17.4.0", "vite": "^8.0.1"
"unocss": "^66.6.7", }
"vite": "^8.0.1"
}
} }

View file

@ -5,23 +5,12 @@ settings:
excludeLinksFromLockfile: false excludeLinksFromLockfile: false
time: time:
'@tanstack/devtools-event-client@0.4.3': 2026-03-11T13:42:37.747Z
'@tanstack/form-core@1.32.0': 2026-05-10T22:35:01.878Z
'@tanstack/pacer-lite@0.1.1': 2025-12-06T05:29:43.362Z
'@tanstack/react-form@1.32.0': 2026-05-10T22:35:03.027Z
'@tanstack/react-store@0.9.3': 2026-03-25T17:43:08.336Z
'@tanstack/store@0.9.3': 2026-03-25T17:43:08.346Z
radashi@12.7.2: 2026-02-24T20:32:30.146Z radashi@12.7.2: 2026-02-24T20:32:30.146Z
use-sync-external-store@1.6.0: 2025-10-01T21:39:12.499Z
zod@4.4.3: 2026-05-04T07:06:40.819Z
importers: importers:
.: .:
dependencies: dependencies:
'@tanstack/react-form':
specifier: ^1.32.0
version: 1.32.0(react@19.2.4)
'@types/node': '@types/node':
specifier: ^20.19.0 || >=22.12.0 specifier: ^20.19.0 || >=22.12.0
version: 25.6.0 version: 25.6.0
@ -40,9 +29,6 @@ importers:
react-router-dom: react-router-dom:
specifier: ^7.14.2 specifier: ^7.14.2
version: 7.14.2(react@19.2.4)(react-dom@19.2.4(react@19.2.4)) version: 7.14.2(react@19.2.4)(react-dom@19.2.4(react@19.2.4))
zod:
specifier: ^4.4.3
version: 4.4.3
devDependencies: devDependencies:
'@commitlint/cli': '@commitlint/cli':
specifier: ^20.5.0 specifier: ^20.5.0
@ -313,6 +299,34 @@ packages:
'@jridgewell/trace-mapping@0.3.31': '@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@oxc-parser/binding-darwin-arm64@0.115.0':
resolution: {integrity: sha512-ii/oOZjfGY1aszXTy29Z5DRyCEnBOrAXDVCvfdfXFQsOZlbbOa7NMHD7D+06YFe5qdxfmbWAYv4yn6QJi/0d2g==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- darwin
cpu:
- arm64
'@oxc-parser/binding-linux-arm64-gnu@0.115.0':
resolution: {integrity: sha512-1ej/MjuTY9tJEunU/hUPIFmgH5PqgMQoRjNOvOkibtJ3Zqlw/+Lc+HGHDNET8sjbgIkWzdhX+p4J96A5CPdbag==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- linux
cpu:
- arm64
libc:
- glibc
'@oxc-parser/binding-linux-arm64-musl@0.115.0':
resolution: {integrity: sha512-HjsZbJPH9mMd4swJRywVMsDZsJX0hyKb1iNHo5ijRl5yhtbO3lj7ImSrrL1oZ1VEg0te4iKmDGGz/6YPLd1G8w==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- linux
cpu:
- arm64
libc:
- musl
'@oxc-parser/binding-linux-x64-gnu@0.115.0': '@oxc-parser/binding-linux-x64-gnu@0.115.0':
resolution: {integrity: sha512-9iVX789DoC3SaOOG+X6NcF/tVChgLp2vcHffzOC2/Z1JTPlz6bMG2ogvcW6/9s0BG2qvhNQImd+gbWYeQbOwVw==} resolution: {integrity: sha512-9iVX789DoC3SaOOG+X6NcF/tVChgLp2vcHffzOC2/Z1JTPlz6bMG2ogvcW6/9s0BG2qvhNQImd+gbWYeQbOwVw==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
@ -323,6 +337,32 @@ packages:
libc: libc:
- glibc - glibc
'@oxc-parser/binding-linux-x64-musl@0.115.0':
resolution: {integrity: sha512-RmQmk+mjCB0nMNfEYhaCxwofLo1Z95ebHw1AGvRiWGCd4zhCNOyskgCbMogIcQzSB3SuEKWgkssyaiQYVAA4hQ==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- linux
cpu:
- x64
libc:
- musl
'@oxc-parser/binding-win32-arm64-msvc@0.115.0':
resolution: {integrity: sha512-/ym+Absk/TLFvbhh3se9XYuI1D7BrUVHw4RaG/2dmWKgBenrZHaJsgnRb7NJtaOyjEOLIPtULx1wDdVL0SX2eg==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- win32
cpu:
- arm64
'@oxc-parser/binding-win32-x64-msvc@0.115.0':
resolution: {integrity: sha512-oxUl82N+fIO9jIaXPph8SPPHQXrA08BHokBBJW8ct9F/x6o6bZE6eUAhUtWajbtvFhL8UYcCWRMba+kww6MBlA==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- win32
cpu:
- x64
'@oxc-project/types@0.115.0': '@oxc-project/types@0.115.0':
resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==}
@ -335,6 +375,34 @@ packages:
'@quansync/fs@1.0.0': '@quansync/fs@1.0.0':
resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==}
'@rolldown/binding-darwin-arm64@1.0.0-rc.11':
resolution: {integrity: sha512-7WQgR8SfOPwmDZGFkThUvsmd/nwAWv91oCO4I5LS7RKrssPZmOt7jONN0cW17ydGC1n/+puol1IpoieKqQidmg==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- darwin
cpu:
- arm64
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.11':
resolution: {integrity: sha512-WMW1yE6IOnehTcFE9eipFkm3XN63zypWlrJQ2iF7NrQ9b2LDRjumFoOGJE8RJJTJCTBAdmLMnJ8uVitACUUo1Q==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- linux
cpu:
- arm64
libc:
- glibc
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.11':
resolution: {integrity: sha512-jfndI9tsfm4APzjNt6QdBkYwre5lRPUgHeDHoI7ydKUuJvz3lZeCfMsI56BZj+7BYqiKsJm7cfd/6KYV7ubrBg==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- linux
cpu:
- arm64
libc:
- musl
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.11': '@rolldown/binding-linux-x64-gnu@1.0.0-rc.11':
resolution: {integrity: sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==} resolution: {integrity: sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
@ -345,6 +413,32 @@ packages:
libc: libc:
- glibc - glibc
'@rolldown/binding-linux-x64-musl@1.0.0-rc.11':
resolution: {integrity: sha512-/tpFfoSTzUkH9LPY+cYbqZBDyyX62w5fICq9qzsHLL8uTI6BHip3Q9Uzft0wylk/i8OOwKik8OxW+QAhDmzwmg==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- linux
cpu:
- x64
libc:
- musl
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.11':
resolution: {integrity: sha512-dDwf5otnx0XgRY1yqxOC4ITizcdzS/8cQ3goOWv3jFAo4F+xQYni+hnMuO6+LssHHdJW7+OCVL3CoU4ycnh35Q==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- win32
cpu:
- arm64
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.11':
resolution: {integrity: sha512-LN4/skhSggybX71ews7dAj6r2geaMJfm3kMbK2KhFMg9B10AZXnKoLCVVgzhMHL0S+aKtr4p8QbAW8k+w95bAA==}
engines: {node: ^20.19.0 || >=22.12.0}
os:
- win32
cpu:
- x64
'@rolldown/pluginutils@1.0.0-rc.11': '@rolldown/pluginutils@1.0.0-rc.11':
resolution: {integrity: sha512-xQO9vbwBecJRv9EUcQ/y0dzSTJgA7Q6UVN7xp6B81+tBGSLVAK03yJ9NkJaUA7JFD91kbjxRSC/mDnmvXzbHoQ==} resolution: {integrity: sha512-xQO9vbwBecJRv9EUcQ/y0dzSTJgA7Q6UVN7xp6B81+tBGSLVAK03yJ9NkJaUA7JFD91kbjxRSC/mDnmvXzbHoQ==}
@ -359,35 +453,6 @@ packages:
resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@tanstack/devtools-event-client@0.4.3':
resolution: {integrity: sha512-OZI6QyULw0FI0wjgmeYzCIfbgPsOEzwJtCpa69XrfLMtNXLGnz3d/dIabk7frg0TmHo+Ah49w5I4KC7Tufwsvw==}
engines: {node: '>=18'}
hasBin: true
'@tanstack/form-core@1.32.0':
resolution: {integrity: sha512-Tn5VRDSjyqjmaet2tJMuEWDRFyrCaon03vxXPlSSaiSs6C/N7lCIwGCXJbZXEUq1kTj8jYN9qyXHbsz4LQHcow==}
'@tanstack/pacer-lite@0.1.1':
resolution: {integrity: sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w==}
engines: {node: '>=18'}
'@tanstack/react-form@1.32.0':
resolution: {integrity: sha512-6WP5SQTA6/H9crCpvpq3ZppYWqtrdE5NjOy6ebABi6uAQPqhfTzrdjS9t40mCZCFtGI5585OhJV6zBP/KN2zcw==}
peerDependencies:
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@tanstack/react-start':
optional: true
'@tanstack/react-store@0.9.3':
resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
'@tanstack/store@0.9.3':
resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==}
'@types/estree@1.0.8': '@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
@ -772,6 +837,12 @@ packages:
flatted@3.4.2: flatted@3.4.2:
resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os:
- darwin
gensync@1.0.0-beta.2: gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -903,6 +974,34 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
lightningcss-darwin-arm64@1.32.0:
resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
engines: {node: '>= 12.0.0'}
os:
- darwin
cpu:
- arm64
lightningcss-linux-arm64-gnu@1.32.0:
resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
engines: {node: '>= 12.0.0'}
os:
- linux
cpu:
- arm64
libc:
- glibc
lightningcss-linux-arm64-musl@1.32.0:
resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
engines: {node: '>= 12.0.0'}
os:
- linux
cpu:
- arm64
libc:
- musl
lightningcss-linux-x64-gnu@1.32.0: lightningcss-linux-x64-gnu@1.32.0:
resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
@ -913,6 +1012,32 @@ packages:
libc: libc:
- glibc - glibc
lightningcss-linux-x64-musl@1.32.0:
resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
engines: {node: '>= 12.0.0'}
os:
- linux
cpu:
- x64
libc:
- musl
lightningcss-win32-arm64-msvc@1.32.0:
resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
engines: {node: '>= 12.0.0'}
os:
- win32
cpu:
- arm64
lightningcss-win32-x64-msvc@1.32.0:
resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
engines: {node: '>= 12.0.0'}
os:
- win32
cpu:
- x64
lightningcss@1.32.0: lightningcss@1.32.0:
resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
@ -1239,11 +1364,6 @@ packages:
uri-js@4.4.1: uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
use-sync-external-store@1.6.0:
resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
vite@8.0.2: vite@8.0.2:
resolution: {integrity: sha512-1gFhNi+bHhRE/qKZOJXACm6tX4bA3Isy9KuKF15AgSRuRazNBOJfdDemPBU16/mpMxApDPrWvZ08DcLPEoRnuA==} resolution: {integrity: sha512-1gFhNi+bHhRE/qKZOJXACm6tX4bA3Isy9KuKF15AgSRuRazNBOJfdDemPBU16/mpMxApDPrWvZ08DcLPEoRnuA==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
@ -1331,9 +1451,6 @@ packages:
zod@4.3.6: zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
zod@4.4.3:
resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
snapshots: snapshots:
'@antfu/install-pkg@1.1.0': '@antfu/install-pkg@1.1.0':
@ -1647,9 +1764,27 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2 '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/sourcemap-codec': 1.5.5
'@oxc-parser/binding-darwin-arm64@0.115.0':
optional: true
'@oxc-parser/binding-linux-arm64-gnu@0.115.0':
optional: true
'@oxc-parser/binding-linux-arm64-musl@0.115.0':
optional: true
'@oxc-parser/binding-linux-x64-gnu@0.115.0': '@oxc-parser/binding-linux-x64-gnu@0.115.0':
optional: true optional: true
'@oxc-parser/binding-linux-x64-musl@0.115.0':
optional: true
'@oxc-parser/binding-win32-arm64-msvc@0.115.0':
optional: true
'@oxc-parser/binding-win32-x64-msvc@0.115.0':
optional: true
'@oxc-project/types@0.115.0': {} '@oxc-project/types@0.115.0': {}
'@oxc-project/types@0.122.0': {} '@oxc-project/types@0.122.0': {}
@ -1660,9 +1795,27 @@ snapshots:
dependencies: dependencies:
quansync: 1.0.0 quansync: 1.0.0
'@rolldown/binding-darwin-arm64@1.0.0-rc.11':
optional: true
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.11':
optional: true
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.11':
optional: true
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.11': '@rolldown/binding-linux-x64-gnu@1.0.0-rc.11':
optional: true optional: true
'@rolldown/binding-linux-x64-musl@1.0.0-rc.11':
optional: true
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.11':
optional: true
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.11':
optional: true
'@rolldown/pluginutils@1.0.0-rc.11': {} '@rolldown/pluginutils@1.0.0-rc.11': {}
'@rolldown/pluginutils@1.0.0-rc.7': {} '@rolldown/pluginutils@1.0.0-rc.7': {}
@ -1673,31 +1826,6 @@ snapshots:
'@simple-libs/stream-utils@1.2.0': {} '@simple-libs/stream-utils@1.2.0': {}
'@tanstack/devtools-event-client@0.4.3': {}
'@tanstack/form-core@1.32.0':
dependencies:
'@tanstack/devtools-event-client': 0.4.3
'@tanstack/pacer-lite': 0.1.1
'@tanstack/store': 0.9.3
'@tanstack/pacer-lite@0.1.1': {}
'@tanstack/react-form@1.32.0(react@19.2.4)':
dependencies:
'@tanstack/form-core': 1.32.0
'@tanstack/react-store': 0.9.3(react@19.2.4)(react-dom@19.2.4(react@19.2.4))
react: 19.2.4
'@tanstack/react-store@0.9.3(react@19.2.4)(react-dom@19.2.4(react@19.2.4))':
dependencies:
'@tanstack/store': 0.9.3
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
use-sync-external-store: 1.6.0(react@19.2.4)
'@tanstack/store@0.9.3': {}
'@types/estree@1.0.8': {} '@types/estree@1.0.8': {}
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
@ -2131,6 +2259,9 @@ snapshots:
flatted@3.4.2: {} flatted@3.4.2: {}
fsevents@2.3.3:
optional: true
gensync@1.0.0-beta.2: {} gensync@1.0.0-beta.2: {}
get-caller-file@2.0.5: {} get-caller-file@2.0.5: {}
@ -2227,14 +2358,38 @@ snapshots:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
type-check: 0.4.0 type-check: 0.4.0
lightningcss-darwin-arm64@1.32.0:
optional: true
lightningcss-linux-arm64-gnu@1.32.0:
optional: true
lightningcss-linux-arm64-musl@1.32.0:
optional: true
lightningcss-linux-x64-gnu@1.32.0: lightningcss-linux-x64-gnu@1.32.0:
optional: true optional: true
lightningcss-linux-x64-musl@1.32.0:
optional: true
lightningcss-win32-arm64-msvc@1.32.0:
optional: true
lightningcss-win32-x64-msvc@1.32.0:
optional: true
lightningcss@1.32.0: lightningcss@1.32.0:
dependencies: dependencies:
detect-libc: 2.1.2 detect-libc: 2.1.2
optionalDependencies: optionalDependencies:
lightningcss-darwin-arm64: 1.32.0
lightningcss-linux-arm64-gnu: 1.32.0
lightningcss-linux-arm64-musl: 1.32.0
lightningcss-linux-x64-gnu: 1.32.0 lightningcss-linux-x64-gnu: 1.32.0
lightningcss-linux-x64-musl: 1.32.0
lightningcss-win32-arm64-msvc: 1.32.0
lightningcss-win32-x64-msvc: 1.32.0
lines-and-columns@1.2.4: {} lines-and-columns@1.2.4: {}
@ -2322,7 +2477,13 @@ snapshots:
dependencies: dependencies:
'@oxc-project/types': 0.115.0 '@oxc-project/types': 0.115.0
optionalDependencies: optionalDependencies:
'@oxc-parser/binding-darwin-arm64': 0.115.0
'@oxc-parser/binding-linux-arm64-gnu': 0.115.0
'@oxc-parser/binding-linux-arm64-musl': 0.115.0
'@oxc-parser/binding-linux-x64-gnu': 0.115.0 '@oxc-parser/binding-linux-x64-gnu': 0.115.0
'@oxc-parser/binding-linux-x64-musl': 0.115.0
'@oxc-parser/binding-win32-arm64-msvc': 0.115.0
'@oxc-parser/binding-win32-x64-msvc': 0.115.0
oxc-walker@0.7.0(oxc-parser@0.115.0): oxc-walker@0.7.0(oxc-parser@0.115.0):
dependencies: dependencies:
@ -2420,7 +2581,13 @@ snapshots:
'@oxc-project/types': 0.122.0 '@oxc-project/types': 0.122.0
'@rolldown/pluginutils': 1.0.0-rc.11 '@rolldown/pluginutils': 1.0.0-rc.11
optionalDependencies: optionalDependencies:
'@rolldown/binding-darwin-arm64': 1.0.0-rc.11
'@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.11
'@rolldown/binding-linux-arm64-musl': 1.0.0-rc.11
'@rolldown/binding-linux-x64-gnu': 1.0.0-rc.11 '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.11
'@rolldown/binding-linux-x64-musl': 1.0.0-rc.11
'@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.11
'@rolldown/binding-win32-x64-msvc': 1.0.0-rc.11
scheduler@0.27.0: {} scheduler@0.27.0: {}
@ -2538,10 +2705,6 @@ snapshots:
dependencies: dependencies:
punycode: 2.3.1 punycode: 2.3.1
use-sync-external-store@1.6.0(react@19.2.4):
dependencies:
react: 19.2.4
vite@8.0.2(@types/node@25.6.0)(jiti@2.6.1): vite@8.0.2(@types/node@25.6.0)(jiti@2.6.1):
dependencies: dependencies:
lightningcss: 1.32.0 lightningcss: 1.32.0
@ -2551,6 +2714,7 @@ snapshots:
tinyglobby: 0.2.15 tinyglobby: 0.2.15
optionalDependencies: optionalDependencies:
'@types/node': 25.6.0 '@types/node': 25.6.0
fsevents: 2.3.3
jiti: 2.6.1 jiti: 2.6.1
webpack-virtual-modules@0.6.2: {} webpack-virtual-modules@0.6.2: {}
@ -2590,5 +2754,3 @@ snapshots:
zod: 4.3.6 zod: 4.3.6
zod@4.3.6: {} zod@4.3.6: {}
zod@4.4.3: {}

View file

@ -1,7 +1,7 @@
[[repos]] [[repos]]
hooks = [ hooks = [
{ id = "commitlint", name = "commitlint", language = "system", entry = "mise x -- aubx commitlint -e", stages = [ { id = "commitlint", name = "commitlint", language = "system", entry = "mise x -- aubx commitlint -e", stages = [
"commit-msg", "commit-msg",
] }, ] },
] ]
repo = "local" repo = "local"

View file

@ -9,7 +9,7 @@ const UserProvider = ({ children }) => {
const storeData = (email, token) => { const storeData = (email, token) => {
setEmail(email); setEmail(email);
setToken(token); setToken(token);
localStorage.setItem("loginToken", token); localStorage.setItem("loginToken", data.token);
}; };
const login = async (user, password) => { const login = async (user, password) => {
const res = await fetch("http://localhost:5000/api/auth/login", { const res = await fetch("http://localhost:5000/api/auth/login", {
@ -40,29 +40,8 @@ const UserProvider = ({ children }) => {
setToken(null); setToken(null);
setEmail(null); setEmail(null);
}; };
const getProfile = async () => {
const res = await fetch("http://localhost:5000/api/auth/me", {
headers: { Authorization: `Bearer ${token}` },
});
if (!res.ok) {
throw new Error("Error al obtener perfil", res.status);
}
const data = await res.json();
return data;
};
return ( return (
<UserContext.Provider <UserContext.Provider value={{ token, setToken, email, setEmail, login, register, logout }}>
value={{
token,
setToken,
email,
setEmail,
login,
register,
getProfile,
logout,
}}
>
{children} {children}
</UserContext.Provider> </UserContext.Provider>
); );

View file

@ -1,89 +1,65 @@
import { useContext, useState } from "react"; import { useContext, useState } from "react";
import { CartContext } from "../context/CartContext"; import { CartContext } from "../context/CartContext";
import { pizzaCart } from "../pizzas";
import { UserContext } from "../context/UserContext"; import { UserContext } from "../context/UserContext";
const Cart = () => { const Cart = () => {
const { token } = useContext(UserContext); const { token } = useContext(UserContext);
const { cart, setCart, getTotal } = useContext(CartContext); const { cart, setCart } = useContext(CartContext);
const [success, setSuccess] = useState(false);
return ( return (
<> <>
<h1 className="text-4xl font-bold">Carrito</h1> <h1 className="text-4xl font-bold">Carrito</h1>
{!success ? ( <div id="cartContainer" className="flex gap-4 flex-col">
<> {cart.map((pizza) => (
<div id="cartContainer" className="flex gap-4 flex-col"> <div
{cart.map((pizza) => ( className="border-3 border-lime-300 rounded-md flex gap-4 overflow-hidden"
<div key={pizza.id}
className="border-3 border-lime-300 rounded-md flex gap-4 overflow-hidden"
key={pizza.id}
>
<img src={pizza.img} className="w-32 rounded-r-sm" />
<div>
<h2>Pizza {pizza.name}</h2>
<div className="flex gap-4">
<button
onClick={() => {
setCart((cart) =>
cart.map((p) =>
p.id === pizza.id
? { ...p, count: p.count + 1 }
: p,
),
);
}}
className="bg-blue-500 px-4 text-white rounded-md"
>
+
</button>
<p className="text-grey-500">{pizza.count}</p>
<button
onClick={() => {
setCart((cart) =>
cart
.map((p) =>
p.id === pizza.id
? { ...p, count: p.count - 1 }
: p,
)
.filter((p) => p.count > 0),
);
}}
className="bg-red-500 px-4 text-white rounded-md"
>
-
</button>
</div>
</div>
</div>
))}
<p className="text-3xl">
Total:
<strong>{` $${getTotal().toLocaleString("es-CL")}`}</strong>
</p>
</div>
<button
type="button"
disabled={!token}
className="bg-black text-white rounded-md p-2 text-lg hover:bg-gray-500 disabled:bg-gray-200"
onClick={async () => {
const res = await fetch("http://localhost:5000/api/checkouts", {
method: "POST",
headers: { Authorization: `Bearer ${token}` },
body: JSON.stringify({ cart }),
});
if (!res.ok) {
console.error(res);
return;
}
setSuccess(true);
}}
> >
Pagar <img src={pizza.img} className="w-32 rounded-r-sm" />
</button> <div>
</> <h2>Pizza {pizza.name}</h2>
) : ( <div className="flex gap-4">
<p class="text-4xl text-teal-500">¡Compra hecha con éxito!</p> <button
)} onClick={() => {
setCart((cart) =>
cart.map((p) => (p.id === pizza.id ? { ...p, count: p.count + 1 } : p)),
);
}}
className="bg-blue-500 px-4 text-white rounded-md"
>
+
</button>
<p className="text-grey-500">{pizza.count}</p>
<button
onClick={() => {
setCart((cart) =>
cart
.map((p) => (p.id === pizza.id ? { ...p, count: p.count - 1 } : p))
.filter((p) => p.count > 0),
);
}}
className="bg-red-500 px-4 text-white rounded-md"
>
-
</button>
</div>
</div>
</div>
))}
<p className="text-3xl">
Total:
<strong>
{` $${cart.reduce((acc, it) => acc + it.price * it.count, 0).toLocaleString("es-CL")}`}
</strong>
</p>
</div>
<button
type="submit"
disabled={!token}
className="bg-black text-white rounded-md p-2 text-lg hover:bg-gray-500 disabled:bg-gray-200"
>
Pagar
</button>
</> </>
); );
}; };

View file

@ -4,15 +4,12 @@ import { useContext } from "react";
// Librería recomendada en tutoría // Librería recomendada en tutoría
import { z } from "zod"; import { z } from "zod";
import { UserContext } from "../context/UserContext"; import { UserContext } from "../context/UserContext";
import { useNavigate } from "react-router-dom";
// Esquema de validación de login // Esquema de validación de login
const loginSchema = z.object({ const loginSchema = z.object({
user: z user: z.email({ error: "Email inválido" }).nonempty({ error: "Se requiere un email" }),
.email({ error: "Email inválido" }) password: z.string().min(6, { error: "La contraseña debe tener al menos 6 caracteres" }),
.nonempty({ error: "Se requiere un email" }),
password: z
.string()
.min(6, { error: "La contraseña debe tener al menos 6 caracteres" }),
}); });
const Login = () => { const Login = () => {
@ -24,7 +21,6 @@ const Login = () => {
try { try {
await login(user, password); await login(user, password);
} catch (error) { } catch (error) {
console.error(error);
alert("Error de login"); alert("Error de login");
} }
}, },

View file

@ -1,19 +1,9 @@
import { useContext, useState } from "react"; import { useContext } from "react";
import { UserContext } from "../context/UserContext"; import { UserContext } from "../context/UserContext";
import { useEffect } from "react";
const Profile = () => { const Profile = () => {
const [email, setEmail] = useState(""); const email = "test@example.com";
const { getProfile, logout } = useContext(UserContext); const { logout } = useContext(UserContext);
useEffect(() => {
getProfile()
.then((data) => {
setEmail(data.email);
})
.catch((error) => {
console.error(error);
});
});
return ( return (
<div> <div>
<p> <p>