From a042662e1b87b74b2027d9fc6760522dac122060 Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Fri, 6 Jun 2025 21:45:25 -0400 Subject: [PATCH 1/3] Fixing routes and details for preview apk --- app.json | 6 +- declarations.d.ts | 9 + package-lock.json | 440 +++++++++++++++++++- package.json | 1 + src/assets/images/Pharmatech_icon_1024.png | Bin 0 -> 70397 bytes src/components/DeliveryMap.tsx | 48 +-- src/components/HistoryMap.tsx | 49 +-- src/config.ts | 1 + src/screens/CartListScreen.tsx | 4 - src/screens/DirectionScreen.tsx | 2 +- src/screens/MenuScreen.tsx | 4 - src/screens/OrdersScreen.tsx | 4 - src/screens/delivery/DeliveryHomeScreen.tsx | 39 +- 13 files changed, 496 insertions(+), 111 deletions(-) create mode 100644 src/assets/images/Pharmatech_icon_1024.png diff --git a/app.json b/app.json index 44e6854..a479d0f 100644 --- a/app.json +++ b/app.json @@ -1,11 +1,11 @@ { "expo": { - "name": "app", + "name": "PharmaTech", "slug": "pharmatech", "scheme": "pharmatech", "version": "0.2.0", "orientation": "portrait", - "icon": "./src/assets/images/PharmaTech-icon.png", + "icon": "./src/assets/images/Pharmatech_icon_1024.png", "userInterfaceStyle": "light", "newArchEnabled": true, "splash": { @@ -22,7 +22,7 @@ "android": { "permissions": ["ACCESS_FINE_LOCATION", "ACCESS_COARSE_LOCATION"], "adaptiveIcon": { - "foregroundImage": "./src/assets/images/PharmaTech-icon.png", + "foregroundImage": "./src/assets/images/Pharmatech_icon_1024.png", "backgroundColor": "#1C2143" }, "package": "com.pharmatech.pharmatech", diff --git a/declarations.d.ts b/declarations.d.ts index 933d520..805b73c 100644 --- a/declarations.d.ts +++ b/declarations.d.ts @@ -7,3 +7,12 @@ declare module '*.jpg' { const value: string; export default value; } + +declare module '@mapbox/polyline' { + interface Polyline { + decode(encoded: string, precision?: number): [number, number][]; + encode(coordinates: [number, number][], precision?: number): string; + } + const polyline: Polyline; + export = polyline; +} diff --git a/package-lock.json b/package-lock.json index 64e45d6..66f7062 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.2.0", "dependencies": { "@expo-google-fonts/poppins": "^0.2.3", + "@mapbox/polyline": "^1.2.1", "@pharmatech/sdk": "^0.4.21", "@ptomasroos/react-native-multi-slider": "^2.2.2", "@react-native-community/slider": "^4.5.6", @@ -3529,6 +3530,17 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mapbox/polyline": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@mapbox/polyline/-/polyline-1.2.1.tgz", + "integrity": "sha512-sn0V18O3OzW4RCcPoUIVDWvEGQaBNH9a0y5lgqrf5hUycyw1CzrhEoxV5irzrMNXKCkw1xRsZXcaVbsVZggHXA==", + "dependencies": { + "meow": "^9.0.0" + }, + "bin": { + "polyline": "bin/polyline.bin.js" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4787,6 +4799,12 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.13.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", @@ -4803,6 +4821,12 @@ "@types/node": "*" } }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "license": "MIT" + }, "node_modules/@types/prop-types": { "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", @@ -5623,6 +5647,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -6328,6 +6361,23 @@ "node": ">= 6" } }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001700", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", @@ -7097,6 +7147,40 @@ } } }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decimal.js": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", @@ -9340,6 +9424,15 @@ "node": ">= 10.x" } }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -10127,6 +10220,15 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -12067,6 +12169,18 @@ "tmpl": "1.0.5" } }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/marky": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", @@ -12114,6 +12228,53 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -12554,6 +12715,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -12810,6 +12985,63 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -13970,6 +14202,15 @@ } ] }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -14775,6 +15016,153 @@ "node": ">=0.10.0" } }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -14843,7 +15231,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" @@ -15870,6 +16257,38 @@ "node": ">=0.10.0" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "license": "CC0-1.0" + }, "node_modules/split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", @@ -16857,6 +17276,15 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ts-api-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", @@ -17264,6 +17692,16 @@ "node": ">=10.12.0" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/validate-npm-package-name": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", diff --git a/package.json b/package.json index e85ed37..c520393 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "@expo-google-fonts/poppins": "^0.2.3", + "@mapbox/polyline": "^1.2.1", "@pharmatech/sdk": "^0.4.21", "@ptomasroos/react-native-multi-slider": "^2.2.2", "@react-native-community/slider": "^4.5.6", diff --git a/src/assets/images/Pharmatech_icon_1024.png b/src/assets/images/Pharmatech_icon_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..a91ee618229af27d4d15b5bd11956b11d73713e0 GIT binary patch literal 70397 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 z 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 = ({ const data = await response.json(); if (data.routes && data.routes.length > 0) { - const points = decodePolyline(data.routes[0].overview_polyline.points); + const decoded = polyline.decode( + data.routes[0].overview_polyline.points, + ); + const points = decoded.map(([latitude, longitude]) => ({ + latitude, + longitude, + })); setRoute(points); } else { console.error('No se pudo obtener la ruta.'); @@ -108,45 +115,6 @@ const DeliveryMap: React.FC = ({ } }, [deliveryLocation, branchLocation, customerLocation]); - // Decodificar la polyline de Google Maps - const decodePolyline = (encoded: string) => { - const points: { latitude: number; longitude: number }[] = []; - let index = 0; - const len = encoded.length; - let lat = 0, - lng = 0; - - while (index < len) { - let b, - shift = 0, - result = 0; - do { - b = encoded.charCodeAt(index++) - 63; - result |= (b & 0x1f) << shift; - shift += 5; - } while (b >= 0x20); - const dlat = result & 1 ? ~(result >> 1) : result >> 1; - lat += dlat; - - shift = 0; - result = 0; - do { - b = encoded.charCodeAt(index++) - 63; - result |= (b & 0x1f) << shift; - shift += 5; - } while (b >= 0x20); - const dlng = result & 1 ? ~(result >> 1) : result >> 1; - lng += dlng; - - points.push({ - latitude: lat / 1e5, - longitude: lng / 1e5, - }); - } - - return points; - }; - if ( // Solo espera si faltan datos críticos branchLocation.latitude === 0 || diff --git a/src/components/HistoryMap.tsx b/src/components/HistoryMap.tsx index 0f0d229..6fc25d9 100644 --- a/src/components/HistoryMap.tsx +++ b/src/components/HistoryMap.tsx @@ -3,7 +3,7 @@ import MapView, { Marker, Polyline } from 'react-native-maps'; import { StyleSheet, View, Alert, ViewStyle } from 'react-native'; import { Config } from '../config'; import { Colors } from '../styles/theme'; - +import polyline from '@mapbox/polyline'; import { MapPinIcon, UserIcon } from 'react-native-heroicons/solid'; import { FontAwesome5 } from '@expo/vector-icons'; @@ -74,7 +74,13 @@ const HistoryMap: React.FC = ({ const data = await response.json(); if (data.routes && data.routes.length > 0) { - const points = decodePolyline(data.routes[0].overview_polyline.points); + const decoded = polyline.decode( + data.routes[0].overview_polyline.points, + ); + const points = decoded.map(([latitude, longitude]) => ({ + latitude, + longitude, + })); setRoute(points); } else { console.error('No se pudo obtener la ruta.'); @@ -84,45 +90,6 @@ const HistoryMap: React.FC = ({ } }; - // Decodificar la polyline de Google Maps - const decodePolyline = (encoded: string) => { - const points: { latitude: number; longitude: number }[] = []; - let index = 0; - const len = encoded.length; - let lat = 0, - lng = 0; - - while (index < len) { - let b, - shift = 0, - result = 0; - do { - b = encoded.charCodeAt(index++) - 63; - result |= (b & 0x1f) << shift; - shift += 5; - } while (b >= 0x20); - const dlat = result & 1 ? ~(result >> 1) : result >> 1; - lat += dlat; - - shift = 0; - result = 0; - do { - b = encoded.charCodeAt(index++) - 63; - result |= (b & 0x1f) << shift; - shift += 5; - } while (b >= 0x20); - const dlng = result & 1 ? ~(result >> 1) : result >> 1; - lng += dlng; - - points.push({ - latitude: lat / 1e5, - longitude: lng / 1e5, - }); - } - - return points; - }; - return ( { )} - ); }; @@ -282,9 +281,6 @@ const styles = StyleSheet.create({ color: Colors.textMain, marginBottom: 20, }, - height: { - height: 64, - }, row: { flexDirection: 'row', justifyContent: 'space-between', diff --git a/src/screens/DirectionScreen.tsx b/src/screens/DirectionScreen.tsx index 0a0f58a..12f4871 100644 --- a/src/screens/DirectionScreen.tsx +++ b/src/screens/DirectionScreen.tsx @@ -202,7 +202,7 @@ const styles = StyleSheet.create({ paddingTop: -20, }, height: { - height: 64, + height: 32, }, alertContainer: { position: 'absolute', diff --git a/src/screens/MenuScreen.tsx b/src/screens/MenuScreen.tsx index 47df5a4..78ba921 100644 --- a/src/screens/MenuScreen.tsx +++ b/src/screens/MenuScreen.tsx @@ -179,7 +179,6 @@ export default function MenuScreen() { - @@ -210,9 +209,6 @@ const styles = StyleSheet.create({ zIndex: 100, elevation: 10, }, - height: { - height: 64, - }, safeArea: { flex: 1, }, diff --git a/src/screens/OrdersScreen.tsx b/src/screens/OrdersScreen.tsx index d2865b8..5433cbf 100644 --- a/src/screens/OrdersScreen.tsx +++ b/src/screens/OrdersScreen.tsx @@ -188,7 +188,6 @@ const OrdersScreen = () => { ))} - ); @@ -201,9 +200,6 @@ const styles = StyleSheet.create({ padding: 20, paddingTop: -20, }, - height: { - height: 64, - }, alertContainer: { position: 'absolute', width: 326, diff --git a/src/screens/delivery/DeliveryHomeScreen.tsx b/src/screens/delivery/DeliveryHomeScreen.tsx index 3485722..502fd41 100644 --- a/src/screens/delivery/DeliveryHomeScreen.tsx +++ b/src/screens/delivery/DeliveryHomeScreen.tsx @@ -28,13 +28,6 @@ import { } from '../../lib/deliverySocket/deliverySocket'; // Importar funciones de socket import { Socket } from 'socket.io-client'; // Importar el tipo Socket -// Definir el tipo para un leg de la API de Google Maps Directions -interface GoogleMapsLeg { - duration: { - value: number; // Duración en segundos - }; -} - const calculateTravelTime = async ( origin: { latitude: number; longitude: number }, destination: { latitude: number; longitude: number }, @@ -45,17 +38,20 @@ const calculateTravelTime = async ( ); const data = await response.json(); - if (data.routes && data.routes.length > 0) { - // Extraer el tiempo estimado en segundos + if ( + data.routes && + data.routes.length > 0 && + data.routes[0].legs && + data.routes[0].legs.length > 0 + ) { const durationInSeconds = data.routes[0].legs.reduce( - (total: number, leg: GoogleMapsLeg) => total + leg.duration.value, + (total: number, leg: { duration: { value: number } }) => + total + (leg.duration?.value || 0), 0, ); - - // Convertir a minutos return Math.ceil(durationInSeconds / 60); } else { - console.error('No se pudo calcular el tiempo estimado.'); + console.error('No se pudo calcular el tiempo estimado.', data); return 0; } } catch (error) { @@ -87,6 +83,23 @@ export default function DeliveryHomeScreen() { const fetchAssignedOrders = async () => { try { + // Solicitar permisos de ubicación antes de obtener la posición + const { status } = await Location.getForegroundPermissionsAsync(); + if (status !== 'granted') { + const { status: newStatus } = + await Location.requestForegroundPermissionsAsync(); + if (newStatus !== 'granted') { + showAlert( + 'error', + 'Permiso denegado', + 'No se pudo obtener la ubicación. No se pueden calcular los tiempos estimados.', + ); + setLoading(false); + setRefreshing(false); + return; + } + } + const jwt = await SecureStore.getItemAsync('auth_token'); if (!jwt) { throw new Error('Token de autenticación no encontrado'); From b96abc08091b7ed5c3773b60952203cf08a0276c Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Fri, 6 Jun 2025 23:58:48 -0400 Subject: [PATCH 2/3] Fixing promos in cards, product details and cartlist --- src/components/Card.tsx | 2 + src/redux/slices/cartSlice.ts | 10 ++- src/screens/CartListScreen.tsx | 17 ++-- src/screens/ProductDetailScreen.tsx | 23 ++++-- src/screens/tab/HomeScreen.tsx | 15 ++-- src/screens/tab/OffersScreen.tsx | 118 +++++++++++++++++++--------- src/types/Product.ts | 3 + src/utils/promoUtils.ts | 10 +++ 8 files changed, 142 insertions(+), 56 deletions(-) create mode 100644 src/utils/promoUtils.ts diff --git a/src/components/Card.tsx b/src/components/Card.tsx index 8e492cb..546b92e 100644 --- a/src/components/Card.tsx +++ b/src/components/Card.tsx @@ -18,6 +18,7 @@ const ProductCard: React.FC = ({ category, originalPrice, discount, + promo, finalPrice, getQuantity, }) => { @@ -70,6 +71,7 @@ const ProductCard: React.FC = ({ quantity, image: imageUrl, discount: discount ?? 0, + promo, }); }} initialValue={getItemQuantity(id)} diff --git a/src/redux/slices/cartSlice.ts b/src/redux/slices/cartSlice.ts index 017b1d9..20c4c2e 100644 --- a/src/redux/slices/cartSlice.ts +++ b/src/redux/slices/cartSlice.ts @@ -1,4 +1,5 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import type { Promo } from '@pharmatech/sdk'; export type CartItem = { id: string; @@ -7,6 +8,7 @@ export type CartItem = { quantity: number; image: string; discount?: number; + promo?: Promo; }; type CartState = { @@ -40,10 +42,10 @@ const cartSlice = createSlice({ (item) => item.id === action.payload.id, ); if (existing) { - // Si ya existe, actualiza cantidad y descuento correctamente existing.quantity = action.payload.quantity; existing.price = action.payload.price; - existing.discount = action.payload.discount; // <-- ¡Asegúrate de actualizar el descuento! + existing.discount = action.payload.discount; + existing.promo = action.payload.promo; } else { state.items.push({ ...action.payload }); } @@ -60,6 +62,7 @@ const cartSlice = createSlice({ quantity: number; discount?: number; price?: number; + promo?: Promo; }>, ) => { const item = state.items.find((item) => item.id === action.payload.id); @@ -71,6 +74,9 @@ const cartSlice = createSlice({ if (typeof action.payload.price === 'number') { item.price = action.payload.price; } + if (action.payload.promo) { + item.promo = action.payload.promo; + } } state.total = calculateTotal(state.items); }, diff --git a/src/screens/CartListScreen.tsx b/src/screens/CartListScreen.tsx index 80b47a6..541bd22 100644 --- a/src/screens/CartListScreen.tsx +++ b/src/screens/CartListScreen.tsx @@ -15,6 +15,7 @@ import Button from '../components/Button'; import { TrashIcon } from 'react-native-heroicons/outline'; import { useRouter } from 'expo-router'; import { formatPrice } from '../utils/formatPrice'; +import { isPromoActive } from '../utils/promoUtils'; const CartListScreen = () => { const router = useRouter(); @@ -24,18 +25,24 @@ const CartListScreen = () => { (sum, item) => sum + item.price * item.quantity, 0, ); - // Total price sum + const totalDiscount = cartItems.reduce( (sum, item) => - sum + item.price * item.quantity * ((item.discount ?? 0) / 100), + sum + + item.price * + item.quantity * + ((item.promo && isPromoActive(item.promo) ? item.promo.discount : 0) / + 100), 0, - ); // Discount sum - const total = subtotal - totalDiscount; // Subtotal with discount + ); + + const total = subtotal - totalDiscount; const renderItem = ({ item }: { item: CartItem }) => { console.log('[CartListScreen] Renderizando item:', item); // <-- LOG // Usar el descuento del item, si existe, si no 0 - const discount = item.discount ?? 0; + const discount = + item.promo && isPromoActive(item.promo) ? item.promo.discount : 0; const discountedPrice = item.price * (1 - discount / 100); const totalDiscountedPrice = discountedPrice * item.quantity; const totalOriginalPrice = item.price * item.quantity; diff --git a/src/screens/ProductDetailScreen.tsx b/src/screens/ProductDetailScreen.tsx index 80c2f73..e08c84e 100644 --- a/src/screens/ProductDetailScreen.tsx +++ b/src/screens/ProductDetailScreen.tsx @@ -38,6 +38,7 @@ import Button from '../components/Button'; import { BranchService } from '../services/branches'; import { formatPrice } from '../utils/formatPrice'; import Alert from '../components/Alerts'; +import { isPromoActive } from '../utils/promoUtils'; const ProductDetailScreen: React.FC = () => { const { id, productId } = useLocalSearchParams<{ @@ -290,7 +291,11 @@ const ProductDetailScreen: React.FC = () => { const getProductDiscount = () => { // Busca promo en product.promo - if (product?.promo && typeof product.promo.discount === 'number') { + if ( + product?.promo && + typeof product.promo.discount === 'number' && + isPromoActive(product.promo) + ) { return product.promo.discount; } return 0; @@ -638,10 +643,17 @@ const ProductDetailScreen: React.FC = () => { } // Si hay stock y cantidad válida, agrega o actualiza en el carrito if (product?.id && quantity > 0) { - const promo = product.promo; - const discount = - typeof promo?.discount === 'number' ? promo.discount : 0; - updateCartQuantity(product.id, quantity); + const promo = + product.promo && isPromoActive(product.promo) + ? product.promo + : undefined; + const discount = promo ? promo.discount : 0; + updateCartQuantity( + product.id, + quantity, + discount, + product.price, + ); addToCart({ id: product.id, name: @@ -656,6 +668,7 @@ const ProductDetailScreen: React.FC = () => { quantity, image: images?.[0]?.url || 'https://via.placeholder.com/150', discount, + promo, }); } }} diff --git a/src/screens/tab/HomeScreen.tsx b/src/screens/tab/HomeScreen.tsx index af1aa33..ad9942c 100644 --- a/src/screens/tab/HomeScreen.tsx +++ b/src/screens/tab/HomeScreen.tsx @@ -18,6 +18,7 @@ import type { Promo } from '@pharmatech/sdk'; import EmailVerificationModal from './EmailVerificationModal'; import { decodeJWT } from '../../helper/jwtHelper'; import { useNotifications } from '../../hooks/useNotifications'; +import { isPromoActive } from '../../utils/promoUtils'; export default function HomeScreen() { const [products, setProducts] = useState([]); @@ -73,15 +74,10 @@ export default function HomeScreen() { const productsData = await ProductService.getProducts(1, 20); if (productsData.success) { const pd = productsData.data.results; - // Filtra solo los que tengan stock > 0 const availableProducts = pd.filter((p) => p.stock > 0); const carouselProducts = availableProducts.map((p) => { - // Usa el descuento real si hay promo, si no, no lo agregues // @ts-expect-error: promo puede estar en p o en p.presentation const promo: Promo | undefined = p.promo ?? p.presentation.promo; - const discount: Promo['discount'] | undefined = promo?.discount - ? Math.round(promo.discount * 100) / 100 - : undefined; return { id: p.id, presentationId: p.presentation.id, @@ -97,7 +93,9 @@ export default function HomeScreen() { p.presentation.measurementUnit, category: p.product.categories[0].name, originalPrice: p.price, - ...(discount !== undefined ? { discount } : {}), + discount: + promo && isPromoActive(promo) ? promo.discount : undefined, + promo: promo && isPromoActive(promo) ? promo : undefined, finalPrice: p.price, quantity: getItemQuantity(p.id), getQuantity: (quantity: number) => { @@ -125,9 +123,8 @@ export default function HomeScreen() { // Usa el descuento real si hay promo, si no, no lo agregues // @ts-expect-error: promo puede estar en p o en p.presentation const promo: Promo | undefined = p.promo ?? p.presentation.promo; - const discount: Promo['discount'] | undefined = promo?.discount - ? Math.round(promo.discount * 100) / 100 - : undefined; + const discount: Promo['discount'] | undefined = + promo && isPromoActive(promo) ? promo.discount : undefined; return { id: p.id, presentationId: p.presentation.id, diff --git a/src/screens/tab/OffersScreen.tsx b/src/screens/tab/OffersScreen.tsx index adf3708..52c9117 100644 --- a/src/screens/tab/OffersScreen.tsx +++ b/src/screens/tab/OffersScreen.tsx @@ -11,8 +11,11 @@ import { Colors, FontSizes } from '../../styles/theme'; import Card from '../../components/Card'; import { ProductService } from '../../services/products'; import type { Promo } from '@pharmatech/sdk'; +import { isPromoActive } from '../../utils/promoUtils'; +import { useCart } from '../../hooks/useCart'; export default function OffersScreen() { + const { addToCart, updateCartQuantity, getItemQuantity } = useCart(); const [offers, setOffers] = useState< Array<{ id: string; @@ -23,6 +26,7 @@ export default function OffersScreen() { category: string; originalPrice: number; discount: number; + promo?: Promo; finalPrice: number; quantity: number; getQuantity: (quantity: number) => void; @@ -44,32 +48,55 @@ export default function OffersScreen() { (item) => hasPromo(item) && Boolean(item.promo?.discount), ); - const mappedPromoItems = promoItems.map((p) => { - const promo: Promo | undefined = hasPromo(p) ? p.promo : undefined; - const discount: Promo['discount'] = promo?.discount ?? 0; + const mappedPromoItems = promoItems + .filter((p) => hasPromo(p) && isPromoActive(p.promo)) + .map((p) => { + const promo: Promo | undefined = hasPromo(p) ? p.promo : undefined; + const discount: Promo['discount'] = promo?.discount ?? 0; - return { - id: p.id, - presentationId: p.presentation.id, - productId: p.product.id, - imageUrl: - p.product.images?.[0]?.url || 'https://via.placeholder.com/150', - name: - p.product.name + - ' ' + - p.presentation.name + - ' ' + - p.presentation.quantity + - ' ' + - p.presentation.measurementUnit, - category: p.product.categories?.[0]?.name || 'Sin categoría', - originalPrice: p.price, - discount, - finalPrice: p.price, - quantity: 0, - getQuantity: () => 0, - }; - }); + return { + id: p.id, + presentationId: p.presentation.id, + productId: p.product.id, + imageUrl: + p.product.images?.[0]?.url || 'https://via.placeholder.com/150', + name: + p.product.name + + ' ' + + p.presentation.name + + ' ' + + p.presentation.quantity + + ' ' + + p.presentation.measurementUnit, + category: p.product.categories?.[0]?.name || 'Sin categoría', + originalPrice: p.price, + discount, + promo, + finalPrice: p.price, + quantity: getItemQuantity(p.id), + getQuantity: (quantity: number) => { + addToCart({ + id: p.id, + name: + p.product.name + + ' ' + + p.presentation.name + + ' ' + + p.presentation.quantity + + ' ' + + p.presentation.measurementUnit, + price: p.price, + quantity, + image: + p.product.images?.[0]?.url || + 'https://via.placeholder.com/150', + discount, + promo, + }); + updateCartQuantity(p.id, quantity, discount, p.price); + }, + }; + }); setOffers(mappedPromoItems); } else { console.error('Error al cargar productos:', res.error); @@ -100,6 +127,7 @@ export default function OffersScreen() { category: string; originalPrice: number; discount: number; + promo?: Promo; finalPrice: number; quantity: number; getQuantity: (quantity: number) => void; @@ -114,6 +142,7 @@ export default function OffersScreen() { category={item.category} originalPrice={item.originalPrice} discount={item.discount} + promo={item.promo} finalPrice={item.finalPrice} quantity={item.quantity} getQuantity={item.getQuantity} @@ -126,16 +155,24 @@ export default function OffersScreen() { Ofertas especiales - item.id} - numColumns={2} - contentContainerStyle={styles.list} - renderItem={renderOffer} - columnWrapperStyle={styles.columnWrapper} - onRefresh={loadOffers} - refreshing={loading} - /> + {offers.length === 0 ? ( + + + No hay ofertas disponibles en este momento. + + + ) : ( + item.id} + numColumns={2} + contentContainerStyle={styles.list} + renderItem={renderOffer} + columnWrapperStyle={styles.columnWrapper} + onRefresh={loadOffers} + refreshing={loading} + /> + )} ); @@ -169,4 +206,15 @@ const styles = StyleSheet.create({ height: { height: 64, }, + emptyContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + paddingVertical: 40, + }, + emptyText: { + fontSize: FontSizes.s1.size, + color: Colors.textLowContrast, + textAlign: 'center', + }, }); diff --git a/src/types/Product.ts b/src/types/Product.ts index a759249..20c884d 100644 --- a/src/types/Product.ts +++ b/src/types/Product.ts @@ -1,3 +1,5 @@ +import type { Promo } from '@pharmatech/sdk'; + export type Product = { id: string; presentationId: string; @@ -7,6 +9,7 @@ export type Product = { category: string; originalPrice?: number; discount?: number; + promo?: Promo; finalPrice: number; quantity: number; getQuantity: (quantity: number) => void; diff --git a/src/utils/promoUtils.ts b/src/utils/promoUtils.ts new file mode 100644 index 0000000..36c50e4 --- /dev/null +++ b/src/utils/promoUtils.ts @@ -0,0 +1,10 @@ +export function isPromoActive(promo?: { + startAt?: Date | string; + expiredAt?: Date | string; +}) { + if (!promo?.startAt || !promo?.expiredAt) return false; + const now = new Date(); + const start = new Date(promo.startAt); + const end = new Date(promo.expiredAt); + return now >= start && now <= end; +} From 608f581d9a19dbcaf58985b52375e818189aa297 Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Sat, 7 Jun 2025 18:50:14 -0400 Subject: [PATCH 3/3] Various fixes --- src/components/OrderSummary.tsx | 27 +++++++++++++++++++++++++-- src/hooks/useDollarPrice.ts | 14 ++++++++++++++ src/screens/CartListScreen.tsx | 23 +++++++++++++++++++++++ src/screens/InProgressOrderScreen.tsx | 5 +++-- src/screens/LoginScreen.tsx | 23 ++++++++++++----------- 5 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 src/hooks/useDollarPrice.ts diff --git a/src/components/OrderSummary.tsx b/src/components/OrderSummary.tsx index 5b441a0..3000668 100644 --- a/src/components/OrderSummary.tsx +++ b/src/components/OrderSummary.tsx @@ -6,10 +6,12 @@ import { Colors, FontSizes } from '../styles/theme'; import type { CartItem } from '../redux/slices/cartSlice'; import { ChevronDownIcon, ChevronUpIcon } from 'react-native-heroicons/outline'; import { formatPrice } from '../utils/formatPrice'; +import { useDollarPrice } from '../hooks/useDollarPrice'; const OrderSummary = () => { const { cartItems } = useCart(); const [isOpen, setIsOpen] = useState(false); + const dollarPrice = useDollarPrice(); const subtotal = cartItems.reduce( (sum, item) => sum + item.price * item.quantity, @@ -114,12 +116,27 @@ const OrderSummary = () => { -${formatPrice(totalDiscount)} - + {/* Mostrar total en bolívares */} + {dollarPrice && ( + + + Total en Bs + + + Bs{' '} + {((total / 100) * dollarPrice).toLocaleString('es-VE', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + + + )} + {/* Total ${formatPrice(total)} - + */} )} @@ -249,6 +266,12 @@ const styles = StyleSheet.create({ color: Colors.textMain, marginTop: 4, }, + bolivarText: { + fontSize: FontSizes.b1.size, + lineHeight: FontSizes.b1.lineHeight, + color: Colors.primary, + marginBottom: 8, + }, }); export default OrderSummary; diff --git a/src/hooks/useDollarPrice.ts b/src/hooks/useDollarPrice.ts new file mode 100644 index 0000000..7afcdd2 --- /dev/null +++ b/src/hooks/useDollarPrice.ts @@ -0,0 +1,14 @@ +import { useEffect, useState } from 'react'; + +export function useDollarPrice() { + const [dollarPrice, setDollarPrice] = useState(null); + + useEffect(() => { + fetch('https://pydolarve.org/api/v1/dollar?page=bcv&monitor=usd') + .then((res) => res.json()) + .then((data) => setDollarPrice(data.price)) + .catch(() => setDollarPrice(null)); + }, []); + + return dollarPrice; +} diff --git a/src/screens/CartListScreen.tsx b/src/screens/CartListScreen.tsx index 541bd22..da499f3 100644 --- a/src/screens/CartListScreen.tsx +++ b/src/screens/CartListScreen.tsx @@ -16,10 +16,12 @@ import { TrashIcon } from 'react-native-heroicons/outline'; import { useRouter } from 'expo-router'; import { formatPrice } from '../utils/formatPrice'; import { isPromoActive } from '../utils/promoUtils'; +import { useDollarPrice } from '../hooks/useDollarPrice'; const CartListScreen = () => { const router = useRouter(); const { cartItems, removeFromCart, updateCartQuantity } = useCart(); + const dollarPrice = useDollarPrice(); const subtotal = cartItems.reduce( (sum, item) => sum + item.price * item.quantity, @@ -151,6 +153,21 @@ const CartListScreen = () => { -${formatPrice(totalDiscount)} + {/* Mostrar total en bolívares */} + {dollarPrice && ( + + + Total en Bs + + + Bs{' '} + {((total / 100) * dollarPrice).toLocaleString('es-VE', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + + + )} Total @@ -339,6 +356,12 @@ const styles = StyleSheet.create({ emptyCartButton: { marginTop: 16, }, + bolivarText: { + fontSize: FontSizes.b1.size, + lineHeight: FontSizes.b1.lineHeight, + color: Colors.primary, + marginBottom: 8, + }, }); export default CartListScreen; diff --git a/src/screens/InProgressOrderScreen.tsx b/src/screens/InProgressOrderScreen.tsx index cebbf75..c625ba6 100644 --- a/src/screens/InProgressOrderScreen.tsx +++ b/src/screens/InProgressOrderScreen.tsx @@ -34,6 +34,7 @@ import { useRouter } from 'expo-router'; import { useDispatch } from 'react-redux'; import { clearCart } from '../redux/slices/cartSlice'; import { resetCheckout } from '../redux/slices/checkoutSlice'; +import { formatPrice } from '../utils/formatPrice'; const stepsLabels = [ 'Opciones de Compra', @@ -251,7 +252,7 @@ const InProgressOrderScreen = () => { Total: - ${order.totalPrice ? order.totalPrice : ''} + ${order.totalPrice ? formatPrice(order.totalPrice) : ''} @@ -349,7 +350,7 @@ const InProgressOrderScreen = () => { Total: - ${order.totalPrice ? order.totalPrice : ''} + ${order.totalPrice ? formatPrice(order.totalPrice) : ''} diff --git a/src/screens/LoginScreen.tsx b/src/screens/LoginScreen.tsx index 716c083..672bb40 100644 --- a/src/screens/LoginScreen.tsx +++ b/src/screens/LoginScreen.tsx @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import { View, - Image, TouchableOpacity, StyleSheet, KeyboardAvoidingView, @@ -15,7 +14,7 @@ import Input from '../components/Input'; import PoppinsText from '../components/PoppinsText'; import { Colors, FontSizes } from '../styles/theme'; import Logo from '../assets/images/logos/PharmaTech_Logo.svg'; -import GoogleLogo from '../assets/images/logos/Google_Logo.png'; +//import GoogleLogo from '../assets/images/logos/Google_Logo.png'; import { AuthService } from '../services/auth'; import { UserService } from '../services/user'; import Alert from '../components/Alerts'; @@ -86,10 +85,10 @@ export default function LoginScreen() { router.push('/passwordRecovery'); }; - const handleGoogleLogin = () => { - console.log('Iniciar sesión con Google'); - // Google login logic - }; + // const handleGoogleLogin = () => { + // console.log('Iniciar sesión con Google'); + // // Google login logic + // }; const handleRegister = () => { router.replace('/register'); @@ -173,7 +172,7 @@ export default function LoginScreen() { loading={loading} /> {/* Google button */} - @@ -185,7 +184,7 @@ export default function LoginScreen() { Iniciar sesión con Google - + */} {/* Register link */}