diff --git a/.gram/debug.jsonc b/.gram/debug.jsonc new file mode 100644 index 0000000..d6f2bd2 --- /dev/null +++ b/.gram/debug.jsonc @@ -0,0 +1,10 @@ +[ + { + "adapter": "JavaScript", + "type": "chrome", + "request": "attach", + "port": 9222, + "label": "Conectar a navegador", + "webRoot": "${GRAM_WORKTREE_ROOT}/src", + }, +] diff --git a/.gram/settings.jsonc b/.gram/settings.jsonc new file mode 100644 index 0000000..54c5941 --- /dev/null +++ b/.gram/settings.jsonc @@ -0,0 +1,3 @@ +{ + "language_servers": ["...", "!biome"], +} diff --git a/.rumdl.toml b/.rumdl.toml new file mode 100644 index 0000000..a096bfa --- /dev/null +++ b/.rumdl.toml @@ -0,0 +1,4 @@ +[global] +flavor = "gfm" +[MD013] +reflow = true diff --git a/api-tests/profile.hurl b/api-tests/profile.hurl new file mode 100644 index 0000000..877986c --- /dev/null +++ b/api-tests/profile.hurl @@ -0,0 +1,12 @@ +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 diff --git a/backend/README.md b/backend/README.md index 6546d6b..2d51495 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,94 +1,98 @@ -# Simple API JWT - -API para consumir un servicio de Auth con JWT. - -## Instalación - -```sh -npm install -``` - -## Uso - -```sh -npm run dev -``` - -## Endpoints - -### Pizzas - -```sh -GET /api/pizzas -``` - -### Pizza (única) - -```sh -GET /api/pizzas/:id -``` - -### Auth - -```sh -POST /api/auth/login -POST /api/auth/register -``` - -body: - -```json -{ - "email": "test@example.com", - "password": "123123" -} -``` - -### Checkout & Profile - -Esta ruta requiere un token JWT en el header, el token se obtiene en el endpoint 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. - -```sh -POST /api/checkouts -``` - -body: - -```json -{ - "cart": [...] -} -``` - -Endpoint para obtener el perfil del usuario autenticado. Necesitas enviar el token JWT en el header. - -```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. - -El token JWT se debe enviar en el header `Authorization` de la siguiente manera: - -```sh -Authorization Bearer token_jwt -``` - -Ejemplo con fetch: - -```js -await fetch("http://localhost:5000/api/checkout", { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer token_jwt`, - }, - body: JSON.stringify({ - cart: carrito, - }), -}); -``` +# Simple API JWT + +API para consumir un servicio de Auth con JWT. + +## Instalación + +```sh +npm install +``` + +## Uso + +```sh +npm run dev +``` + +## Endpoints + +### Pizzas + +```sh +GET /api/pizzas +``` + +### Pizza (única) + +```sh +GET /api/pizzas/:id +``` + +### Auth + +```sh +POST /api/auth/login +POST /api/auth/register +``` + +body: + +```json +{ + "email": "test@example.com", + "password": "123123" +} +``` + +### Checkout & Profile + +Esta ruta requiere un token JWT en el header, el token se obtiene en el endpoint +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. + +```sh +POST /api/checkouts +``` + +body: + +```json +{ + "cart": [...] +} +``` + +Endpoint para obtener el perfil del usuario autenticado. Necesitas enviar el +token JWT en el header. + +```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. + +El token JWT se debe enviar en el header `Authorization` de la siguiente manera: + +```sh +Authorization Bearer token_jwt +``` + +Ejemplo con fetch: + +```js +await fetch("http://localhost:5000/api/checkout", { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer token_jwt`, + }, + body: JSON.stringify({ + cart: carrito, + }), +}); +``` diff --git a/biome.json b/biome.json deleted file mode 100644 index 5498814..0000000 --- a/biome.json +++ /dev/null @@ -1,231 +0,0 @@ -{ - "$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" } } - } -} diff --git a/justfile b/justfile index 2c2b420..9a2a472 100644 --- a/justfile +++ b/justfile @@ -1,12 +1,15 @@ mise-task task: - mise r {{task}} + mise r {{ task }} setup: - mise x -- aube i - cd backend && npm i + mise x -- aube i + cd backend && npm i start-backend: - cd backend && npm start + cd backend && npm start start-frontend: - mise r dev + mise r dev + +start: + @mprocs diff --git a/mise.toml b/mise.toml index 16563cf..d35fff7 100644 --- a/mise.toml +++ b/mise.toml @@ -2,10 +2,10 @@ aube = "latest" mprocs = "latest" oxlint = "latest" -pitchfork = "latest" pnpm = "latest" prek = "latest" oxfmt = "latest" +node = "24" [tasks.dev] description = "Arranca el servidor dev" diff --git a/package.json b/package.json index ae3056b..e455a23 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,35 @@ { - "name": "desafio", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "lint": "biome check", - "preview": "vite preview" - }, - "dependencies": { - "radashi": "^12.7.2", - "react": "^19.2.4", - "react-dom": "^19.2.4", - "react-router-dom": "^7.14.2" - }, - "devDependencies": { - "@commitlint/cli": "^20.5.0", - "@commitlint/config-conventional": "^20.5.0", - "@eslint/js": "^9.39.4", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@unocss/reset": "^66.6.7", - "@vitejs/plugin-react": "^6.0.1", - "eslint": "^9.39.4", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.5.2", - "globals": "^17.4.0", - "unocss": "^66.6.7", - "vite": "^8.0.1" - } + "name": "desafio", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "biome check", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/react-form": "^1.32.0", + "radashi": "^12.7.2", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-router-dom": "^7.14.2", + "zod": "^4.4.3" + }, + "devDependencies": { + "@commitlint/cli": "^20.5.0", + "@commitlint/config-conventional": "^20.5.0", + "@eslint/js": "^9.39.4", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@unocss/reset": "^66.6.7", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.4.0", + "unocss": "^66.6.7", + "vite": "^8.0.1" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 790bd40..3880af8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,12 +5,23 @@ settings: excludeLinksFromLockfile: false 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 + use-sync-external-store@1.6.0: 2025-10-01T21:39:12.499Z + zod@4.4.3: 2026-05-04T07:06:40.819Z importers: .: dependencies: + '@tanstack/react-form': + specifier: ^1.32.0 + version: 1.32.0(react@19.2.4) '@types/node': specifier: ^20.19.0 || >=22.12.0 version: 25.6.0 @@ -29,6 +40,9 @@ importers: react-router-dom: specifier: ^7.14.2 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: '@commitlint/cli': specifier: ^20.5.0 @@ -299,34 +313,6 @@ packages: '@jridgewell/trace-mapping@0.3.31': 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': resolution: {integrity: sha512-9iVX789DoC3SaOOG+X6NcF/tVChgLp2vcHffzOC2/Z1JTPlz6bMG2ogvcW6/9s0BG2qvhNQImd+gbWYeQbOwVw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -337,32 +323,6 @@ packages: libc: - 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': resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} @@ -375,34 +335,6 @@ packages: '@quansync/fs@1.0.0': 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': resolution: {integrity: sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -413,32 +345,6 @@ packages: libc: - 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': resolution: {integrity: sha512-xQO9vbwBecJRv9EUcQ/y0dzSTJgA7Q6UVN7xp6B81+tBGSLVAK03yJ9NkJaUA7JFD91kbjxRSC/mDnmvXzbHoQ==} @@ -453,6 +359,35 @@ packages: resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} 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': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -837,12 +772,6 @@ packages: flatted@3.4.2: 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: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -974,34 +903,6 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 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: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} @@ -1012,32 +913,6 @@ packages: libc: - 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: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} @@ -1364,6 +1239,11 @@ packages: uri-js@4.4.1: 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: resolution: {integrity: sha512-1gFhNi+bHhRE/qKZOJXACm6tX4bA3Isy9KuKF15AgSRuRazNBOJfdDemPBU16/mpMxApDPrWvZ08DcLPEoRnuA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1451,6 +1331,9 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + snapshots: '@antfu/install-pkg@1.1.0': @@ -1764,27 +1647,9 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@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': 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.122.0': {} @@ -1795,27 +1660,9 @@ snapshots: dependencies: 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': 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.7': {} @@ -1826,6 +1673,31 @@ snapshots: '@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/json-schema@7.0.15': {} @@ -2259,9 +2131,6 @@ snapshots: flatted@3.4.2: {} - fsevents@2.3.3: - optional: true - gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -2358,38 +2227,14 @@ snapshots: prelude-ls: 1.2.1 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: 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: dependencies: detect-libc: 2.1.2 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-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 lines-and-columns@1.2.4: {} @@ -2477,13 +2322,7 @@ snapshots: dependencies: '@oxc-project/types': 0.115.0 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-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): dependencies: @@ -2581,13 +2420,7 @@ snapshots: '@oxc-project/types': 0.122.0 '@rolldown/pluginutils': 1.0.0-rc.11 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-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: {} @@ -2705,6 +2538,10 @@ snapshots: dependencies: 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): dependencies: lightningcss: 1.32.0 @@ -2714,7 +2551,6 @@ snapshots: tinyglobby: 0.2.15 optionalDependencies: '@types/node': 25.6.0 - fsevents: 2.3.3 jiti: 2.6.1 webpack-virtual-modules@0.6.2: {} @@ -2754,3 +2590,5 @@ snapshots: zod: 4.3.6 zod@4.3.6: {} + + zod@4.4.3: {} diff --git a/prek.toml b/prek.toml index 6a64ab0..2706b2c 100644 --- a/prek.toml +++ b/prek.toml @@ -1,7 +1,7 @@ [[repos]] hooks = [ - { id = "commitlint", name = "commitlint", language = "system", entry = "mise x -- aubx commitlint -e", stages = [ - "commit-msg", - ] }, + { id = "commitlint", name = "commitlint", language = "system", entry = "mise x -- aubx commitlint -e", stages = [ + "commit-msg", + ] }, ] repo = "local" diff --git a/src/pages/Cart.jsx b/src/pages/Cart.jsx index 35e0a7d..07a59b5 100644 --- a/src/pages/Cart.jsx +++ b/src/pages/Cart.jsx @@ -1,65 +1,89 @@ import { useContext, useState } from "react"; import { CartContext } from "../context/CartContext"; -import { pizzaCart } from "../pizzas"; import { UserContext } from "../context/UserContext"; const Cart = () => { const { token } = useContext(UserContext); - const { cart, setCart } = useContext(CartContext); + const { cart, setCart, getTotal } = useContext(CartContext); + const [success, setSuccess] = useState(false); return ( <>

Carrito

-
- {cart.map((pizza) => ( -
- -
-

Pizza {pizza.name}

-
- -

{pizza.count}

- + {!success ? ( + <> +
+ {cart.map((pizza) => ( +
+ +
+

Pizza {pizza.name}

+
+ +

{pizza.count}

+ +
+
-
+ ))} +

+ Total: + {` $${getTotal().toLocaleString("es-CL")}`} +

- ))} -

- Total: - - {` $${cart.reduce((acc, it) => acc + it.price * it.count, 0).toLocaleString("es-CL")}`} - -

-
- + + + ) : ( +

¡Compra hecha con éxito!

+ )} ); };