From 9b85436196d71ca061b944e9b4ee836361432cba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?=
Date: Wed, 3 Jul 2024 18:36:54 -0300
Subject: [PATCH 01/23] perf: change all components to use `memo` and avoid
unnecessary renderings
---
.eslintrc.json | 13 +--
CHANGELOG.md | 121 ++++++++++++------------
package-lock.json | 12 +--
package.json | 1 -
src/components/Carousel/index.tsx | 22 ++++-
src/components/CarouselButton/index.tsx | 8 +-
src/components/CarouselEvent/index.tsx | 7 +-
src/components/CarouselImage/index.tsx | 6 +-
src/components/Footer/index.tsx | 5 +-
src/components/GenericButton/index.tsx | 9 +-
src/components/Header/index.tsx | 7 +-
src/components/Icon/index.tsx | 7 +-
src/components/Metric/index.tsx | 8 +-
src/components/Modal/index.tsx | 5 +-
src/components/ProductCard/index.tsx | 8 +-
src/components/SearchInput/index.tsx | 6 +-
src/components/Spinner/index.tsx | 5 +-
src/components/Text/index.tsx | 6 +-
src/components/WhatsAppButton/index.tsx | 6 +-
src/components/index.ts | 48 +++++++---
20 files changed, 182 insertions(+), 128 deletions(-)
diff --git a/.eslintrc.json b/.eslintrc.json
index a4d86d3..8d82eb5 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -16,19 +16,10 @@
},
"ecmaVersion": "latest"
},
- "plugins": [
- "react-refresh",
- "@typescript-eslint",
- "simple-import-sort",
- "prettier"
- ],
+ "plugins": ["@typescript-eslint", "simple-import-sort", "prettier"],
"rules": {
"prettier/prettier": "error",
"simple-import-sort/imports": "error",
- "simple-import-sort/exports": "error",
- "react-refresh/only-export-components": [
- "warn",
- { "allowConstantExport": true }
- ]
+ "simple-import-sort/exports": "error"
}
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fd9d55..24b6e32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,72 +1,69 @@
# 1.0.0 (2024-07-03)
-
### Bug Fixes
-* add `textColors` constant to manager colors of `Text` component ([1ce1641](https://github.com/ArtelierMaisa/artelier-maisa/commit/1ce16411952e34ecd34e2d23ce343609c5db115c))
-* add correct `favicon` image ([978ded8](https://github.com/ArtelierMaisa/artelier-maisa/commit/978ded8fec4a8277567ad52178de524c1cff9ac9))
-* add cover to profile image ([54ec48e](https://github.com/ArtelierMaisa/artelier-maisa/commit/54ec48e7aa1c13f6f4f86e059824b199f69f5165))
-* add highlight to tab products when user open platform directly in the `Product` page ([5ae34ab](https://github.com/ArtelierMaisa/artelier-maisa/commit/5ae34ab8ceed56646f410df78ec89718a281b206))
-* add safe `z-index` to overlay in `Modal` component ([903f119](https://github.com/ArtelierMaisa/artelier-maisa/commit/903f1196df4e0f94397a7043ed9178178f2769f3))
-* add scroll Y auto to `Modal` component and custom style ([29587f8](https://github.com/ArtelierMaisa/artelier-maisa/commit/29587f829131444bdd45eeeef4cdcd603ad7280c))
-* adjust in `SendMessageProps` interface when its used by `WhatsAppButton` and `Footer` ([5403d73](https://github.com/ArtelierMaisa/artelier-maisa/commit/5403d73a8dce639620668f57cf7fc3c94a304c4e))
-* bigger adjusts in colors and sizes of `Icon` types component, and size of `Text` component ([9402a49](https://github.com/ArtelierMaisa/artelier-maisa/commit/9402a49b647f8b2154591690b35e0036cfb842a6))
-* improve `Text` component and add responsiveness to `Footer` component ([c0218bc](https://github.com/ArtelierMaisa/artelier-maisa/commit/c0218bc18f87166fe96363692602443925a03787))
-* release 1.0.3 ([48dd83d](https://github.com/ArtelierMaisa/artelier-maisa/commit/48dd83d9ca8f5bee52cb61293c34a8362b8f6233))
-* remove Uri import ([4d933b6](https://github.com/ArtelierMaisa/artelier-maisa/commit/4d933b6917b545125a347be074f63d58c722d39b))
-* resolve problem when products doesn't exists in category ([d2d625e](https://github.com/ArtelierMaisa/artelier-maisa/commit/d2d625e25fc61b01e427c4432cd790e14786f8ca))
-* small adjust in favicon path image ([9da52a1](https://github.com/ArtelierMaisa/artelier-maisa/commit/9da52a185b75191f635188e411842056fd675a4d))
-
+- add `textColors` constant to manager colors of `Text` component ([1ce1641](https://github.com/ArtelierMaisa/artelier-maisa/commit/1ce16411952e34ecd34e2d23ce343609c5db115c))
+- add correct `favicon` image ([978ded8](https://github.com/ArtelierMaisa/artelier-maisa/commit/978ded8fec4a8277567ad52178de524c1cff9ac9))
+- add cover to profile image ([54ec48e](https://github.com/ArtelierMaisa/artelier-maisa/commit/54ec48e7aa1c13f6f4f86e059824b199f69f5165))
+- add highlight to tab products when user open platform directly in the `Product` page ([5ae34ab](https://github.com/ArtelierMaisa/artelier-maisa/commit/5ae34ab8ceed56646f410df78ec89718a281b206))
+- add safe `z-index` to overlay in `Modal` component ([903f119](https://github.com/ArtelierMaisa/artelier-maisa/commit/903f1196df4e0f94397a7043ed9178178f2769f3))
+- add scroll Y auto to `Modal` component and custom style ([29587f8](https://github.com/ArtelierMaisa/artelier-maisa/commit/29587f829131444bdd45eeeef4cdcd603ad7280c))
+- adjust in `SendMessageProps` interface when its used by `WhatsAppButton` and `Footer` ([5403d73](https://github.com/ArtelierMaisa/artelier-maisa/commit/5403d73a8dce639620668f57cf7fc3c94a304c4e))
+- bigger adjusts in colors and sizes of `Icon` types component, and size of `Text` component ([9402a49](https://github.com/ArtelierMaisa/artelier-maisa/commit/9402a49b647f8b2154591690b35e0036cfb842a6))
+- improve `Text` component and add responsiveness to `Footer` component ([c0218bc](https://github.com/ArtelierMaisa/artelier-maisa/commit/c0218bc18f87166fe96363692602443925a03787))
+- release 1.0.3 ([48dd83d](https://github.com/ArtelierMaisa/artelier-maisa/commit/48dd83d9ca8f5bee52cb61293c34a8362b8f6233))
+- remove Uri import ([4d933b6](https://github.com/ArtelierMaisa/artelier-maisa/commit/4d933b6917b545125a347be074f63d58c722d39b))
+- resolve problem when products doesn't exists in category ([d2d625e](https://github.com/ArtelierMaisa/artelier-maisa/commit/d2d625e25fc61b01e427c4432cd790e14786f8ca))
+- small adjust in favicon path image ([9da52a1](https://github.com/ArtelierMaisa/artelier-maisa/commit/9da52a185b75191f635188e411842056fd675a4d))
### Features
-* add `.env.example` ([84922f8](https://github.com/ArtelierMaisa/artelier-maisa/commit/84922f84ed80baf438637f4ee5749a906972d32b))
-* add `CarouselButton` and `Carousel` components ([8e2e052](https://github.com/ArtelierMaisa/artelier-maisa/commit/8e2e05253e7e518186454ea823cf749fa1800e33))
-* add `CarouselEvent` component and small style adjust in `ProductCard` component ([c2580c7](https://github.com/ArtelierMaisa/artelier-maisa/commit/c2580c7bdb5aab85d92f2bf74638a11884f86409))
-* add `CarouselImage` component ([fa1a946](https://github.com/ArtelierMaisa/artelier-maisa/commit/fa1a946cb4931745261625b4fd7e6d9fa31c68e1))
-* add `firabase` config ([c6458ea](https://github.com/ArtelierMaisa/artelier-maisa/commit/c6458eac190a47f54abcd09075d93195030815d4))
-* add `flowbite` and `flowbite-react` config ([2eb6203](https://github.com/ArtelierMaisa/artelier-maisa/commit/2eb6203d62d9b850e10abda07b7a73eebba35245))
-* add `Footer` component ([ac105b9](https://github.com/ArtelierMaisa/artelier-maisa/commit/ac105b986893761ace626b363779d35b41a112dc))
-* add `GenericButton` component ([a86f529](https://github.com/ArtelierMaisa/artelier-maisa/commit/a86f5298e2c6653fea84a1db4219f2ca8c8d5b25))
-* add `Header` component ([dd0d4b9](https://github.com/ArtelierMaisa/artelier-maisa/commit/dd0d4b925f78cb447087b372b5a4849fd299e31f))
-* add `inter` font to tailwind ([125f10c](https://github.com/ArtelierMaisa/artelier-maisa/commit/125f10c0f17a90aafa1b323bef74b78146c7a9a4))
-* add `isLoading` property to `GenericButton` component ([a38c559](https://github.com/ArtelierMaisa/artelier-maisa/commit/a38c55945eff5f65b5cb055046a4f3965a39b25b))
-* add `Metric` component and custom `box-shadow` in `tailwindcss` ([f1646e5](https://github.com/ArtelierMaisa/artelier-maisa/commit/f1646e5e1a95b0bee13776a0d49f6898b9b67997))
-* add `Modal` component ([2458bea](https://github.com/ArtelierMaisa/artelier-maisa/commit/2458bea6e85aa731268f1cf6373a98350404ef6e))
-* add `Modal` component and `tailwind-scrollbar` plugin ([5e535b5](https://github.com/ArtelierMaisa/artelier-maisa/commit/5e535b5d07f0b8e90e4070bff2777e7c229ea196))
-* add `NotFound` page ([63523b7](https://github.com/ArtelierMaisa/artelier-maisa/commit/63523b7efc9a155c1315381b1b6d3729e6cb01ef))
-* add `ProductCard` component ([af05290](https://github.com/ArtelierMaisa/artelier-maisa/commit/af05290efabdb78f37506f9212f1bba736d163b2))
-* add `react-scroll` for scroll to correctly section in structure of landing page ([2e4ee45](https://github.com/ArtelierMaisa/artelier-maisa/commit/2e4ee45b20114788f2cb6ddf34fd625ec0d17cde))
-* add `ScrollTopContext` and `useScrollTop` to when we go back from `Products` page ([a14ef70](https://github.com/ArtelierMaisa/artelier-maisa/commit/a14ef700a6ce3f8aafd7b4d62e1a15e7ec62491c))
-* add `SearchInput` component ([a6abe6e](https://github.com/ArtelierMaisa/artelier-maisa/commit/a6abe6ecbc211a0c28a96f26a78076f39c8a6280))
-* add `Spinner` component ([cd57837](https://github.com/ArtelierMaisa/artelier-maisa/commit/cd578373a63b0e71ee9e9e236a782eb3e21e6983))
-* add `tailwindcss ` and setup colors ([afd6e85](https://github.com/ArtelierMaisa/artelier-maisa/commit/afd6e85942776176400409243bee14305eb04a33))
-* add `useUser` hook to handle with user requests ([08c29c9](https://github.com/ArtelierMaisa/artelier-maisa/commit/08c29c9ef3e2fd69f7f2422e33fa6c51c18598fa))
-* add `weights` and `sizes` of `Text` component in `constants` folder ([f83e82c](https://github.com/ArtelierMaisa/artelier-maisa/commit/f83e82cdf2b9ad33bf96c903bf82e3813d88753f))
-* add `WhatsAppButton` component ([c03307a](https://github.com/ArtelierMaisa/artelier-maisa/commit/c03307a46ffeab70b60627d7730f6ad3734ae366))
-* add conditional to show `additional` of the about in `LandingPage` ([309c8e9](https://github.com/ArtelierMaisa/artelier-maisa/commit/309c8e99266014b3f19593d74cfbe7dbcd2b5663))
-* add default phone and email ([e955c99](https://github.com/ArtelierMaisa/artelier-maisa/commit/e955c99fd30b8d6b1189a39882147b359cfd3677))
-* add integration in the `Products` page ([728339e](https://github.com/ArtelierMaisa/artelier-maisa/commit/728339ee590d17c6708887164bf981fea6da0c09))
-* add integration with banners ([2ad30de](https://github.com/ArtelierMaisa/artelier-maisa/commit/2ad30ded2d1d4aae0507673891d5fd3d9dc9ee51))
-* add integration with highlight data ([0e5086f](https://github.com/ArtelierMaisa/artelier-maisa/commit/0e5086f39ef838f6ba820ce01ee092123a5db085))
-* add integration with WhatsApp API ([18303e5](https://github.com/ArtelierMaisa/artelier-maisa/commit/18303e56414cc868d2fa527a11e3fad818a6fc3b))
-* add mail to in envelope icon in the `Footer` component ([99d3e86](https://github.com/ArtelierMaisa/artelier-maisa/commit/99d3e86d5ae4b6e4dc5f74c7e4752d362a2067c9))
-* add products to `LandingPage` ([997699e](https://github.com/ArtelierMaisa/artelier-maisa/commit/997699e59ea4c34f7f8b4ed86e044a1365a6f66a))
-* add project logo ([38fd301](https://github.com/ArtelierMaisa/artelier-maisa/commit/38fd301a299623c89b0ad55843bb2697da1d7895))
-* add routes in `App` ([f0886c0](https://github.com/ArtelierMaisa/artelier-maisa/commit/f0886c00398dd3c2bba1bf5f535be78c19e745ce))
-* add support ts to images ([c0dfd4e](https://github.com/ArtelierMaisa/artelier-maisa/commit/c0dfd4e391f7b39401e3d0420b27e0dee80e06f8))
-* create `envs` file to manager all environment variables ([8f58e8a](https://github.com/ArtelierMaisa/artelier-maisa/commit/8f58e8a82651678c003c49a96b80fd0c1f61f657))
-* create `react` project with `vite` ([597aab4](https://github.com/ArtelierMaisa/artelier-maisa/commit/597aab4465565f84ca35b9a753067d7e484dc515))
-* create `Text` component ([7d9551a](https://github.com/ArtelierMaisa/artelier-maisa/commit/7d9551a1a0f76cd951df7250b44ba3eed14ff2ae))
-* create Icon component ([01df400](https://github.com/ArtelierMaisa/artelier-maisa/commit/01df400fcbdafcf31423c7dc03848a41aae0ce7b))
-* finish `LandingPage` structure and style ([06a1697](https://github.com/ArtelierMaisa/artelier-maisa/commit/06a1697e2e3ed5afdd4398ea16add925d7f7d5a5))
-* finish structure and styles from Products page ([ebdeff4](https://github.com/ArtelierMaisa/artelier-maisa/commit/ebdeff4ae320a11ae5aaab56de030fdc666b2685))
-* integrate `Header` component with `react-router-dom` ([26891c9](https://github.com/ArtelierMaisa/artelier-maisa/commit/26891c911a541381c101332a75c8ed80b5144141))
-* release 1.0.0 ([152a936](https://github.com/ArtelierMaisa/artelier-maisa/commit/152a9361cedba93aac9d738918830cce424fa62e))
-* release 1.0.1 ([4a419f5](https://github.com/ArtelierMaisa/artelier-maisa/commit/4a419f5135d7875f19b7e1ef86a940d339252559))
-* release 1.0.2 ([6415cef](https://github.com/ArtelierMaisa/artelier-maisa/commit/6415cef7178b58e41592d2ac1dfbedbaba60ae01))
-
+- add `.env.example` ([84922f8](https://github.com/ArtelierMaisa/artelier-maisa/commit/84922f84ed80baf438637f4ee5749a906972d32b))
+- add `CarouselButton` and `Carousel` components ([8e2e052](https://github.com/ArtelierMaisa/artelier-maisa/commit/8e2e05253e7e518186454ea823cf749fa1800e33))
+- add `CarouselEvent` component and small style adjust in `ProductCard` component ([c2580c7](https://github.com/ArtelierMaisa/artelier-maisa/commit/c2580c7bdb5aab85d92f2bf74638a11884f86409))
+- add `CarouselImage` component ([fa1a946](https://github.com/ArtelierMaisa/artelier-maisa/commit/fa1a946cb4931745261625b4fd7e6d9fa31c68e1))
+- add `firabase` config ([c6458ea](https://github.com/ArtelierMaisa/artelier-maisa/commit/c6458eac190a47f54abcd09075d93195030815d4))
+- add `flowbite` and `flowbite-react` config ([2eb6203](https://github.com/ArtelierMaisa/artelier-maisa/commit/2eb6203d62d9b850e10abda07b7a73eebba35245))
+- add `Footer` component ([ac105b9](https://github.com/ArtelierMaisa/artelier-maisa/commit/ac105b986893761ace626b363779d35b41a112dc))
+- add `GenericButton` component ([a86f529](https://github.com/ArtelierMaisa/artelier-maisa/commit/a86f5298e2c6653fea84a1db4219f2ca8c8d5b25))
+- add `Header` component ([dd0d4b9](https://github.com/ArtelierMaisa/artelier-maisa/commit/dd0d4b925f78cb447087b372b5a4849fd299e31f))
+- add `inter` font to tailwind ([125f10c](https://github.com/ArtelierMaisa/artelier-maisa/commit/125f10c0f17a90aafa1b323bef74b78146c7a9a4))
+- add `isLoading` property to `GenericButton` component ([a38c559](https://github.com/ArtelierMaisa/artelier-maisa/commit/a38c55945eff5f65b5cb055046a4f3965a39b25b))
+- add `Metric` component and custom `box-shadow` in `tailwindcss` ([f1646e5](https://github.com/ArtelierMaisa/artelier-maisa/commit/f1646e5e1a95b0bee13776a0d49f6898b9b67997))
+- add `Modal` component ([2458bea](https://github.com/ArtelierMaisa/artelier-maisa/commit/2458bea6e85aa731268f1cf6373a98350404ef6e))
+- add `Modal` component and `tailwind-scrollbar` plugin ([5e535b5](https://github.com/ArtelierMaisa/artelier-maisa/commit/5e535b5d07f0b8e90e4070bff2777e7c229ea196))
+- add `NotFound` page ([63523b7](https://github.com/ArtelierMaisa/artelier-maisa/commit/63523b7efc9a155c1315381b1b6d3729e6cb01ef))
+- add `ProductCard` component ([af05290](https://github.com/ArtelierMaisa/artelier-maisa/commit/af05290efabdb78f37506f9212f1bba736d163b2))
+- add `react-scroll` for scroll to correctly section in structure of landing page ([2e4ee45](https://github.com/ArtelierMaisa/artelier-maisa/commit/2e4ee45b20114788f2cb6ddf34fd625ec0d17cde))
+- add `ScrollTopContext` and `useScrollTop` to when we go back from `Products` page ([a14ef70](https://github.com/ArtelierMaisa/artelier-maisa/commit/a14ef700a6ce3f8aafd7b4d62e1a15e7ec62491c))
+- add `SearchInput` component ([a6abe6e](https://github.com/ArtelierMaisa/artelier-maisa/commit/a6abe6ecbc211a0c28a96f26a78076f39c8a6280))
+- add `Spinner` component ([cd57837](https://github.com/ArtelierMaisa/artelier-maisa/commit/cd578373a63b0e71ee9e9e236a782eb3e21e6983))
+- add `tailwindcss ` and setup colors ([afd6e85](https://github.com/ArtelierMaisa/artelier-maisa/commit/afd6e85942776176400409243bee14305eb04a33))
+- add `useUser` hook to handle with user requests ([08c29c9](https://github.com/ArtelierMaisa/artelier-maisa/commit/08c29c9ef3e2fd69f7f2422e33fa6c51c18598fa))
+- add `weights` and `sizes` of `Text` component in `constants` folder ([f83e82c](https://github.com/ArtelierMaisa/artelier-maisa/commit/f83e82cdf2b9ad33bf96c903bf82e3813d88753f))
+- add `WhatsAppButton` component ([c03307a](https://github.com/ArtelierMaisa/artelier-maisa/commit/c03307a46ffeab70b60627d7730f6ad3734ae366))
+- add conditional to show `additional` of the about in `LandingPage` ([309c8e9](https://github.com/ArtelierMaisa/artelier-maisa/commit/309c8e99266014b3f19593d74cfbe7dbcd2b5663))
+- add default phone and email ([e955c99](https://github.com/ArtelierMaisa/artelier-maisa/commit/e955c99fd30b8d6b1189a39882147b359cfd3677))
+- add integration in the `Products` page ([728339e](https://github.com/ArtelierMaisa/artelier-maisa/commit/728339ee590d17c6708887164bf981fea6da0c09))
+- add integration with banners ([2ad30de](https://github.com/ArtelierMaisa/artelier-maisa/commit/2ad30ded2d1d4aae0507673891d5fd3d9dc9ee51))
+- add integration with highlight data ([0e5086f](https://github.com/ArtelierMaisa/artelier-maisa/commit/0e5086f39ef838f6ba820ce01ee092123a5db085))
+- add integration with WhatsApp API ([18303e5](https://github.com/ArtelierMaisa/artelier-maisa/commit/18303e56414cc868d2fa527a11e3fad818a6fc3b))
+- add mail to in envelope icon in the `Footer` component ([99d3e86](https://github.com/ArtelierMaisa/artelier-maisa/commit/99d3e86d5ae4b6e4dc5f74c7e4752d362a2067c9))
+- add products to `LandingPage` ([997699e](https://github.com/ArtelierMaisa/artelier-maisa/commit/997699e59ea4c34f7f8b4ed86e044a1365a6f66a))
+- add project logo ([38fd301](https://github.com/ArtelierMaisa/artelier-maisa/commit/38fd301a299623c89b0ad55843bb2697da1d7895))
+- add routes in `App` ([f0886c0](https://github.com/ArtelierMaisa/artelier-maisa/commit/f0886c00398dd3c2bba1bf5f535be78c19e745ce))
+- add support ts to images ([c0dfd4e](https://github.com/ArtelierMaisa/artelier-maisa/commit/c0dfd4e391f7b39401e3d0420b27e0dee80e06f8))
+- create `envs` file to manager all environment variables ([8f58e8a](https://github.com/ArtelierMaisa/artelier-maisa/commit/8f58e8a82651678c003c49a96b80fd0c1f61f657))
+- create `react` project with `vite` ([597aab4](https://github.com/ArtelierMaisa/artelier-maisa/commit/597aab4465565f84ca35b9a753067d7e484dc515))
+- create `Text` component ([7d9551a](https://github.com/ArtelierMaisa/artelier-maisa/commit/7d9551a1a0f76cd951df7250b44ba3eed14ff2ae))
+- create Icon component ([01df400](https://github.com/ArtelierMaisa/artelier-maisa/commit/01df400fcbdafcf31423c7dc03848a41aae0ce7b))
+- finish `LandingPage` structure and style ([06a1697](https://github.com/ArtelierMaisa/artelier-maisa/commit/06a1697e2e3ed5afdd4398ea16add925d7f7d5a5))
+- finish structure and styles from Products page ([ebdeff4](https://github.com/ArtelierMaisa/artelier-maisa/commit/ebdeff4ae320a11ae5aaab56de030fdc666b2685))
+- integrate `Header` component with `react-router-dom` ([26891c9](https://github.com/ArtelierMaisa/artelier-maisa/commit/26891c911a541381c101332a75c8ed80b5144141))
+- release 1.0.0 ([152a936](https://github.com/ArtelierMaisa/artelier-maisa/commit/152a9361cedba93aac9d738918830cce424fa62e))
+- release 1.0.1 ([4a419f5](https://github.com/ArtelierMaisa/artelier-maisa/commit/4a419f5135d7875f19b7e1ef86a940d339252559))
+- release 1.0.2 ([6415cef](https://github.com/ArtelierMaisa/artelier-maisa/commit/6415cef7178b58e41592d2ac1dfbedbaba60ae01))
### Performance Improvements
-* change `Text` to span when it's a text inside text ([10969e1](https://github.com/ArtelierMaisa/artelier-maisa/commit/10969e1681bbdd92e50eba35fc209420392fb58c))
+- change `Text` to span when it's a text inside text ([10969e1](https://github.com/ArtelierMaisa/artelier-maisa/commit/10969e1681bbdd92e50eba35fc209420392fb58c))
diff --git a/package-lock.json b/package-lock.json
index 41bea3d..5430933 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -38,7 +38,6 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-react-refresh": "^0.4.6",
"eslint-plugin-simple-import-sort": "^12.1.0",
"git-commit-msg-linter": "^5.0.7",
"husky": "^9.0.11",
@@ -53,7 +52,7 @@
"vite": "^5.2.0"
},
"engines": {
- "node": ">= 20.11.x"
+ "node": ">= 20.x"
}
},
"node_modules/@alloc/quick-lru": {
@@ -4777,15 +4776,6 @@
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
}
},
- "node_modules/eslint-plugin-react-refresh": {
- "version": "0.4.6",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.6.tgz",
- "integrity": "sha512-NjGXdm7zgcKRkKMua34qVO9doI7VOxZ6ancSvBELJSSoX97jyndXcSoa8XBh69JoB31dNz3EEzlMcizZl7LaMA==",
- "dev": true,
- "peerDependencies": {
- "eslint": ">=7"
- }
- },
"node_modules/eslint-plugin-react/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
diff --git a/package.json b/package.json
index beb520b..98c460f 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,6 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-react-refresh": "^0.4.6",
"eslint-plugin-simple-import-sort": "^12.1.0",
"git-commit-msg-linter": "^5.0.7",
"husky": "^9.0.11",
diff --git a/src/components/Carousel/index.tsx b/src/components/Carousel/index.tsx
index 63c1c19..160b062 100644
--- a/src/components/Carousel/index.tsx
+++ b/src/components/Carousel/index.tsx
@@ -1,10 +1,11 @@
import { Carousel as FlowbiteCarousel } from 'flowbite-react';
+import { memo } from 'react';
import { CarouselProps } from '../../@types';
import { carouselHeights } from '../../constants';
-import { CarouselButton } from '../CarouselButton';
+import { CarouselButton } from '../';
-export function Carousel(props: CarouselProps) {
+function Carousel(props: CarouselProps) {
const {
children,
type = 'banner',
@@ -18,17 +19,30 @@ export function Carousel(props: CarouselProps) {
const isBanner = type === 'banner';
const slideInterval = isBanner ? 3000 : 5000;
+ const rightControl: React.JSX.Element = !hasChildren ? (
+
+ ) : (
+
+ );
+ const leftControl: React.JSX.Element = !hasChildren ? (
+
+ ) : (
+
+ );
+
return (
}
- leftControl={}
+ rightControl={rightControl}
+ leftControl={leftControl}
>
{children}
);
}
+
+export default memo(Carousel);
diff --git a/src/components/CarouselButton/index.tsx b/src/components/CarouselButton/index.tsx
index 73f8f7d..bd6fc9c 100644
--- a/src/components/CarouselButton/index.tsx
+++ b/src/components/CarouselButton/index.tsx
@@ -1,11 +1,13 @@
+import { memo } from 'react';
+
import {
CarouselButtonProps,
CarouselButtonType,
IconProps,
} from '../../@types';
-import { Icon } from '../Icon';
+import { Icon } from '../';
-export function CarouselButton(props: CarouselButtonProps) {
+function CarouselButton(props: CarouselButtonProps) {
const { type } = props;
const isNext = type === 'next';
@@ -30,3 +32,5 @@ export function CarouselButton(props: CarouselButtonProps) {
>
);
}
+
+export default memo(CarouselButton);
diff --git a/src/components/CarouselEvent/index.tsx b/src/components/CarouselEvent/index.tsx
index ee9ef26..ed4e1f3 100644
--- a/src/components/CarouselEvent/index.tsx
+++ b/src/components/CarouselEvent/index.tsx
@@ -1,9 +1,10 @@
import { Card } from 'flowbite-react';
+import { memo } from 'react';
import { CarouselEventProps } from '../../@types';
-import { Text } from '../Text';
+import { Text } from '../';
-export function CarouselEvent(props: CarouselEventProps) {
+function CarouselEvent(props: CarouselEventProps) {
const { description, image, title } = props;
return (
@@ -36,3 +37,5 @@ export function CarouselEvent(props: CarouselEventProps) {
);
}
+
+export default memo(CarouselEvent);
diff --git a/src/components/CarouselImage/index.tsx b/src/components/CarouselImage/index.tsx
index 814f4ba..eb7754b 100644
--- a/src/components/CarouselImage/index.tsx
+++ b/src/components/CarouselImage/index.tsx
@@ -1,6 +1,8 @@
+import { memo } from 'react';
+
import { CarouselImageProps } from '../../@types';
-export function CarouselImage(props: CarouselImageProps) {
+function CarouselImage(props: CarouselImageProps) {
const { id, uri } = props;
return (
@@ -12,3 +14,5 @@ export function CarouselImage(props: CarouselImageProps) {
/>
);
}
+
+export default memo(CarouselImage);
diff --git a/src/components/Footer/index.tsx b/src/components/Footer/index.tsx
index dc8a47a..f3d4075 100644
--- a/src/components/Footer/index.tsx
+++ b/src/components/Footer/index.tsx
@@ -1,4 +1,5 @@
import { Footer as FlowbiteFooter } from 'flowbite-react';
+import { memo } from 'react';
import packageJson from '../../../package.json';
import { IconProps } from '../../@types';
@@ -6,7 +7,7 @@ import { DEFAULT_EMAIL } from '../../config';
import { sendMessage } from '../../utils';
import { Icon, Text } from '../';
-export function Footer() {
+function Footer() {
const version = packageJson.version;
const currentYear = new Date().getFullYear();
@@ -98,3 +99,5 @@ export function Footer() {
);
}
+
+export default memo(Footer);
diff --git a/src/components/GenericButton/index.tsx b/src/components/GenericButton/index.tsx
index 2badeeb..8375146 100644
--- a/src/components/GenericButton/index.tsx
+++ b/src/components/GenericButton/index.tsx
@@ -1,9 +1,10 @@
+import { memo } from 'react';
+
import { Colors, GenericButtonProps, SpinnerColor } from '../../@types';
import { genericButtonHeights } from '../../constants';
-import { Spinner } from '../Spinner';
-import { Text } from '../Text';
+import { Spinner, Text } from '../';
-export function GenericButton(props: GenericButtonProps) {
+function GenericButton(props: GenericButtonProps) {
const {
title,
variant = 'primary',
@@ -67,3 +68,5 @@ export function GenericButton(props: GenericButtonProps) {
);
}
+
+export default memo(GenericButton);
diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx
index d598223..621833b 100644
--- a/src/components/Header/index.tsx
+++ b/src/components/Header/index.tsx
@@ -1,12 +1,13 @@
import { Navbar } from 'flowbite-react';
+import { memo } from 'react';
import { Link } from 'react-scroll';
import { TextProps } from '../../@types';
import { PRIMARY_LOGO } from '../../config';
import { useScrollTop, useUser } from '../../hooks';
-import { Text } from '../Text';
+import { Text } from '../';
-export function Header() {
+function Header() {
const { highlights } = useUser();
const { handleTo, to } = useScrollTop();
@@ -87,3 +88,5 @@ export function Header() {
);
}
+
+export default memo(Header);
diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx
index e5c58ff..1802d96 100644
--- a/src/components/Icon/index.tsx
+++ b/src/components/Icon/index.tsx
@@ -12,11 +12,12 @@ import {
WhatsappLogo,
X,
} from '@phosphor-icons/react';
+import { memo } from 'react';
import { IconProps } from '../../@types';
-import { iconColors, iconSizes } from '../../constants/components';
+import { iconColors, iconSizes } from '../../constants';
-export function Icon(props: IconProps) {
+function Icon(props: IconProps) {
const {
variant,
color = 'background-color',
@@ -49,3 +50,5 @@ export function Icon(props: IconProps) {
return icons[variant];
}
+
+export default memo(Icon);
diff --git a/src/components/Metric/index.tsx b/src/components/Metric/index.tsx
index d6ab10f..7603312 100644
--- a/src/components/Metric/index.tsx
+++ b/src/components/Metric/index.tsx
@@ -1,8 +1,10 @@
+import { memo } from 'react';
+
import { MetricProps } from '../../@types';
import { metricsVariants } from '../../constants';
-import { Text } from '../Text';
+import { Text } from '../';
-export function Metric(props: MetricProps) {
+function Metric(props: MetricProps) {
const { value, variant = 'material' } = props;
return (
@@ -33,3 +35,5 @@ export function Metric(props: MetricProps) {
);
}
+
+export default memo(Metric);
diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx
index 8ae706a..8b1ccf3 100644
--- a/src/components/Modal/index.tsx
+++ b/src/components/Modal/index.tsx
@@ -1,3 +1,4 @@
+import { memo } from 'react';
import ReactModal from 'react-modal';
import { ModalProps } from '../../@types';
@@ -10,7 +11,7 @@ import {
WhatsAppButton,
} from '../';
-export function Modal(props: ModalProps) {
+function Modal(props: ModalProps) {
const { isOpen, product, onClose } = props;
const hasMetrics = !!product.size || !!product.weight || !!product.material;
@@ -70,3 +71,5 @@ export function Modal(props: ModalProps) {
);
}
+
+export default memo(Modal);
diff --git a/src/components/ProductCard/index.tsx b/src/components/ProductCard/index.tsx
index a593e08..6823788 100644
--- a/src/components/ProductCard/index.tsx
+++ b/src/components/ProductCard/index.tsx
@@ -1,10 +1,10 @@
import { Card } from 'flowbite-react';
+import { memo } from 'react';
import { ProductCardProps } from '../../@types';
-import { GenericButton } from '../GenericButton';
-import { Text } from '../Text';
+import { GenericButton, Text } from '../';
-export function ProductCard(props: ProductCardProps) {
+function ProductCard(props: ProductCardProps) {
const { id, name, description, price, image, onSeeMore } = props;
return (
@@ -40,3 +40,5 @@ export function ProductCard(props: ProductCardProps) {
);
}
+
+export default memo(ProductCard);
diff --git a/src/components/SearchInput/index.tsx b/src/components/SearchInput/index.tsx
index cad2317..47a6cc9 100644
--- a/src/components/SearchInput/index.tsx
+++ b/src/components/SearchInput/index.tsx
@@ -1,9 +1,9 @@
-import { useState } from 'react';
+import { memo, useState } from 'react';
import { SearchInputCategoryProps, SearchInputProps } from '../../@types';
import { GenericButton, Icon, Text } from '../';
-export function SearchInput(props: SearchInputProps) {
+function SearchInput(props: SearchInputProps) {
const { categories, searchValue, onChange, onSelect, onSearch } = props;
const [showDropdown, setShowDropdown] = useState(false);
@@ -101,3 +101,5 @@ export function SearchInput(props: SearchInputProps) {
);
}
+
+export default memo(SearchInput);
diff --git a/src/components/Spinner/index.tsx b/src/components/Spinner/index.tsx
index 0de81af..42f3b8f 100644
--- a/src/components/Spinner/index.tsx
+++ b/src/components/Spinner/index.tsx
@@ -1,9 +1,10 @@
import { Spinner as FlowbiteSpinner } from 'flowbite-react';
+import { memo } from 'react';
import { SpinnerProps } from '../../@types';
import { spinnerSizes } from '../../constants';
-export function Spinner(props: SpinnerProps) {
+function Spinner(props: SpinnerProps) {
const { size = 'medium', color = 'primary' } = props;
return (
@@ -14,3 +15,5 @@ export function Spinner(props: SpinnerProps) {
/>
);
}
+
+export default memo(Spinner);
diff --git a/src/components/Text/index.tsx b/src/components/Text/index.tsx
index 126f9d8..6e46e63 100644
--- a/src/components/Text/index.tsx
+++ b/src/components/Text/index.tsx
@@ -1,3 +1,5 @@
+import { memo } from 'react';
+
import { TextProps } from '../../@types';
import {
textColors,
@@ -7,7 +9,7 @@ import {
textWeights,
} from '../../constants';
-export function Text(props: TextProps) {
+function Text(props: TextProps) {
const {
children,
type = 'regular',
@@ -35,3 +37,5 @@ export function Text(props: TextProps) {
);
}
+
+export default memo(Text);
diff --git a/src/components/WhatsAppButton/index.tsx b/src/components/WhatsAppButton/index.tsx
index f48a0bc..3ad9653 100644
--- a/src/components/WhatsAppButton/index.tsx
+++ b/src/components/WhatsAppButton/index.tsx
@@ -1,9 +1,11 @@
+import { memo } from 'react';
+
import { WhatsAppButtonProps } from '../../@types';
import { DEFAULT_PHONE } from '../../config';
import { sendMessage } from '../../utils';
import { Icon, Text } from '../';
-export function WhatsAppButton(props: WhatsAppButtonProps) {
+function WhatsAppButton(props: WhatsAppButtonProps) {
const { product, phone = DEFAULT_PHONE } = props;
function onSendWhatsAppMessage(): void {
@@ -29,3 +31,5 @@ export function WhatsAppButton(props: WhatsAppButtonProps) {
);
}
+
+export default memo(WhatsAppButton);
diff --git a/src/components/index.ts b/src/components/index.ts
index 8be13f4..58a8b7a 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -1,15 +1,33 @@
-export * from './Carousel';
-export * from './CarouselButton';
-export * from './CarouselEvent';
-export * from './CarouselImage';
-export * from './Footer';
-export * from './GenericButton';
-export * from './Header';
-export * from './Icon';
-export * from './Metric';
-export * from './Modal';
-export * from './ProductCard';
-export * from './SearchInput';
-export * from './Spinner';
-export * from './Text';
-export * from './WhatsAppButton';
+import Carousel from './Carousel';
+import CarouselButton from './CarouselButton';
+import CarouselEvent from './CarouselEvent';
+import CarouselImage from './CarouselImage';
+import Footer from './Footer';
+import GenericButton from './GenericButton';
+import Header from './Header';
+import Icon from './Icon';
+import Metric from './Metric';
+import Modal from './Modal';
+import ProductCard from './ProductCard';
+import SearchInput from './SearchInput';
+import Spinner from './Spinner';
+import Text from './Text';
+import WhatsAppButton from './WhatsAppButton';
+
+export {
+ Carousel,
+ CarouselButton,
+ CarouselEvent,
+ CarouselImage,
+ Footer,
+ GenericButton,
+ Header,
+ Icon,
+ Metric,
+ Modal,
+ ProductCard,
+ SearchInput,
+ Spinner,
+ Text,
+ WhatsAppButton,
+};
From 58b13d6a0e94881c44eaae71d1da74696fe559c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?=
Date: Wed, 3 Jul 2024 18:57:37 -0300
Subject: [PATCH 02/23] perf: add change all `get` firebase function to
`onValue`
---
src/contexts/UserContext.tsx | 140 ++++++++++++++++-------------------
1 file changed, 63 insertions(+), 77 deletions(-)
diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx
index a421146..502138d 100644
--- a/src/contexts/UserContext.tsx
+++ b/src/contexts/UserContext.tsx
@@ -1,11 +1,5 @@
-import { get, onValue, ref, remove } from 'firebase/database';
-import {
- createContext,
- PropsWithChildren,
- useCallback,
- useEffect,
- useState,
-} from 'react';
+import { onValue, ref, remove } from 'firebase/database';
+import { createContext, PropsWithChildren, useEffect, useState } from 'react';
import { toast } from 'sonner';
import {
@@ -20,10 +14,8 @@ import { categoryMapper } from '../helpers';
import { database } from '../services';
import { mapper } from '../utils';
-// TODO: Create type to UserContext in @types/contexts.
export const UserContext = createContext({} as UserContextProps);
-// TODO: Create the data user logic. Add all requests and states this context.
export function UserProvider({ children }: Required) {
const [isLoaded, setIsLoaded] = useState(false);
const [highlights, setHighlights] = useState([]);
@@ -37,6 +29,10 @@ export function UserProvider({ children }: Required) {
return currentTime > highlight.removedAt;
}
+ function sortProducts(product: Product, productCompare: Product): number {
+ return productCompare.createdAt - product.createdAt;
+ }
+
function handleGenericErrorToast(): void {
toast.error(
'Falha ao buscar suas informações! Algo deu errado durante a busca de informações. Por favor, tente novamente. Se o problema persistir, entre em contato com o suporte técnico.',
@@ -44,78 +40,26 @@ export function UserProvider({ children }: Required) {
);
}
- const handleGetAbout = useCallback(async () => {
- const aboutRef = ref(database, 'about');
- const aboutSnapshot = await get(aboutRef);
-
- if (!aboutSnapshot.exists()) return handleGenericErrorToast();
-
- const aboutFirebase = mapper(aboutSnapshot)[0];
-
- if (!aboutFirebase) return handleGenericErrorToast();
-
- setAbout(aboutFirebase);
- }, []);
-
- const handleGetHighlights = useCallback(async () => {
+ useEffect(() => {
+ const bannersRef = ref(database, 'banners');
+ const categoriesRef = ref(database, 'categories');
const highlightsRef = ref(database, 'highlights');
- const highlightsSnapshot = await get(highlightsRef);
-
- if (!highlightsSnapshot.exists()) return setHighlights([]);
-
- const highlightsFirebase = mapper(highlightsSnapshot);
-
- if (!highlightsFirebase) return handleGenericErrorToast();
+ const aboutRef = ref(database, 'about');
- // TODO -> REMOVE HIGHLIGHTS IMAGES FROM FIREBASE STORAGE
- highlightsFirebase.forEach(async highlight => {
- if (isGreaterThanPeriodRemove(highlight)) {
- const highlightRef = ref(database, `highlights/${highlight.id}`);
- remove(highlightRef);
+ const unsubscribeBanners = onValue(bannersRef, bannersSnapshot => {
+ if (!bannersSnapshot.exists()) {
+ setBanners([]);
+ return handleGenericErrorToast();
}
- });
-
- const highlightsInPeriod = highlightsFirebase.filter(
- highlight => !isGreaterThanPeriodRemove(highlight),
- );
-
- setHighlights(highlightsInPeriod);
- }, []);
-
- const handleGetBanners = useCallback(async () => {
- const bannersRef = ref(database, 'banners');
- const bannersSnapshot = await get(bannersRef);
-
- if (!bannersSnapshot.exists()) return handleGenericErrorToast();
-
- const bannersFirebase = mapper(bannersSnapshot);
- if (!bannersFirebase) return handleGenericErrorToast();
+ const bannersFirebase = mapper(bannersSnapshot);
+ if (!bannersFirebase) return handleGenericErrorToast();
- setBanners(bannersFirebase);
- }, []);
-
- function sortProducts(product: Product, productCompare: Product): number {
- return productCompare.createdAt - product.createdAt;
- }
-
- const fetchFirebase = useCallback(async () => {
- await handleGetBanners();
- await handleGetHighlights();
- await handleGetAbout();
-
- setIsLoaded(true);
- }, [handleGetAbout, handleGetHighlights, handleGetBanners]);
-
- useEffect(() => {
- fetchFirebase();
- }, [fetchFirebase]);
-
- useEffect(() => {
- const categoriesRef = ref(database, 'categories');
+ setBanners(bannersFirebase);
+ });
- const unsubscribe = onValue(categoriesRef, categoriesSnapshot => {
- if (!categoriesSnapshot.val()) {
+ const unsubscribeCategories = onValue(categoriesRef, categoriesSnapshot => {
+ if (!categoriesSnapshot.exists()) {
setProducts([]);
setCategories([]);
return;
@@ -134,11 +78,53 @@ export function UserProvider({ children }: Required) {
setCategories(categoriesMapped);
});
+ const unsubscribeHighlights = onValue(highlightsRef, highlightsSnapshot => {
+ if (!highlightsSnapshot.exists()) {
+ setHighlights([]);
+ return handleGenericErrorToast();
+ }
+
+ const highlightsFirebase = mapper(highlightsSnapshot);
+ if (!highlightsFirebase) return handleGenericErrorToast();
+
+ highlightsFirebase.forEach(async highlight => {
+ if (isGreaterThanPeriodRemove(highlight)) {
+ const highlightRef = ref(database, `highlights/${highlight.id}`);
+ remove(highlightRef);
+ }
+ });
+
+ const highlightsInPeriod = highlightsFirebase.filter(
+ highlight => !isGreaterThanPeriodRemove(highlight),
+ );
+
+ setHighlights(highlightsInPeriod);
+ });
+
+ const unsubscribeAbout = onValue(aboutRef, aboutSnapshot => {
+ if (!aboutSnapshot.exists()) return handleGenericErrorToast();
+
+ const aboutFirebase = mapper(aboutSnapshot)[0];
+ if (!aboutFirebase) {
+ setAbout({} as About);
+ return handleGenericErrorToast();
+ }
+
+ setAbout(aboutFirebase);
+ });
+
() => {
- unsubscribe();
+ unsubscribeBanners();
+ unsubscribeCategories();
+ unsubscribeHighlights();
+ unsubscribeAbout();
};
}, []);
+ useEffect(() => {
+ if (banners.length > 0 && about?.id) setIsLoaded(true);
+ }, [banners, about]);
+
return (
Date: Wed, 3 Jul 2024 19:08:24 -0300
Subject: [PATCH 03/23] perf: improve search product by name in
`handleSearchProducts`
---
src/pages/Products/index.tsx | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/src/pages/Products/index.tsx b/src/pages/Products/index.tsx
index 938213d..f77ecda 100644
--- a/src/pages/Products/index.tsx
+++ b/src/pages/Products/index.tsx
@@ -34,10 +34,10 @@ export function Products() {
const productsSelected = searchValue.trim()
? allProductsOfTheCategory.filter(product =>
- searchValue
+ product.name
.trim()
.toLowerCase()
- .includes(product.name.trim().toLowerCase()),
+ .includes(searchValue.trim().toLowerCase()),
)
: allProductsOfTheCategory;
@@ -51,11 +51,6 @@ export function Products() {
setCategorySelected(categories.find(({ id }) => id === category.id)!);
}
- useEffect(() => {
- if (productsFirebase.length) setProducts(productsFirebase);
- else setProducts([]);
- }, [productsFirebase]);
-
useEffect(() => {
if (!searchValue) handleSearchProducts();
}, [searchValue, productsFirebase, handleSearchProducts]);
From 44d2084ae44fcef1542780893e53ff27ee682ad2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?=
Date: Wed, 3 Jul 2024 20:25:27 -0300
Subject: [PATCH 04/23] feat: add `meta` tags to show platform preview
---
index.html | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/index.html b/index.html
index b6c1b0b..4001b85 100644
--- a/index.html
+++ b/index.html
@@ -5,6 +5,7 @@
+
@@ -13,6 +14,45 @@
rel="stylesheet"
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Artelier Maisa
From 5ecc7cfde03a9ac3b78ca2c41bded166d9238664 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?=
Date: Fri, 5 Jul 2024 20:05:02 -0300
Subject: [PATCH 05/23] feat: add internationalization libraries and
implementation
---
package-lock.json | 70 ++++++++++++++++++++++++++++
package.json | 3 ++
src/@types/components/Translator.ts | 3 ++
src/@types/components/index.ts | 1 +
src/components/SearchInput/index.tsx | 14 ++++--
src/components/Translator/index.tsx | 14 ++++++
src/components/index.ts | 2 +
src/i18n/index.ts | 15 ++++++
src/i18n/locales/en-us.ts | 7 +++
src/i18n/locales/index.ts | 2 +
src/i18n/locales/pt-br.ts | 7 +++
src/main.tsx | 1 +
src/pages/LandingPage/index.tsx | 19 ++++----
src/pages/NotFound/index.tsx | 7 ++-
src/pages/Products/index.tsx | 26 +++++++----
15 files changed, 169 insertions(+), 22 deletions(-)
create mode 100644 src/@types/components/Translator.ts
create mode 100644 src/components/Translator/index.tsx
create mode 100644 src/i18n/index.ts
create mode 100644 src/i18n/locales/en-us.ts
create mode 100644 src/i18n/locales/index.ts
create mode 100644 src/i18n/locales/pt-br.ts
diff --git a/package-lock.json b/package-lock.json
index 5430933..1afb084 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,8 +12,11 @@
"firebase": "^10.11.1",
"flowbite": "^2.3.0",
"flowbite-react": "^0.9.0",
+ "i18next": "^23.11.5",
+ "i18next-browser-languagedetector": "^8.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-i18next": "^14.1.2",
"react-modal": "^3.16.1",
"react-router-dom": "^6.23.1",
"react-scroll": "^1.9.0",
@@ -5868,6 +5871,14 @@
"node": "14 || >=16.14"
}
},
+ "node_modules/html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "dependencies": {
+ "void-elements": "3.1.0"
+ }
+ },
"node_modules/http-parser-js": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
@@ -5923,6 +5934,36 @@
"url": "https://github.com/sponsors/typicode"
}
},
+ "node_modules/i18next": {
+ "version": "23.11.5",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz",
+ "integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "dependencies": {
+ "@babel/runtime": "^7.23.2"
+ }
+ },
+ "node_modules/i18next-browser-languagedetector": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.0.tgz",
+ "integrity": "sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.2"
+ }
+ },
"node_modules/idb": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
@@ -10949,6 +10990,27 @@
"react": "^18.3.1"
}
},
+ "node_modules/react-i18next": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz",
+ "integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.9",
+ "html-parse-stringify": "^3.0.1"
+ },
+ "peerDependencies": {
+ "i18next": ">= 23.2.3",
+ "react": ">= 16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-icons": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
@@ -12810,6 +12872,14 @@
}
}
},
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
diff --git a/package.json b/package.json
index 98c460f..b6a98c3 100644
--- a/package.json
+++ b/package.json
@@ -16,8 +16,11 @@
"firebase": "^10.11.1",
"flowbite": "^2.3.0",
"flowbite-react": "^0.9.0",
+ "i18next": "^23.11.5",
+ "i18next-browser-languagedetector": "^8.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-i18next": "^14.1.2",
"react-modal": "^3.16.1",
"react-router-dom": "^6.23.1",
"react-scroll": "^1.9.0",
diff --git a/src/@types/components/Translator.ts b/src/@types/components/Translator.ts
new file mode 100644
index 0000000..aa2600b
--- /dev/null
+++ b/src/@types/components/Translator.ts
@@ -0,0 +1,3 @@
+export interface TranslatorProps {
+ path: string;
+}
diff --git a/src/@types/components/index.ts b/src/@types/components/index.ts
index 9322e74..cde66ce 100644
--- a/src/@types/components/index.ts
+++ b/src/@types/components/index.ts
@@ -10,4 +10,5 @@ export * from './ProductCard';
export * from './SearchInput';
export * from './Spinner';
export * from './Text';
+export * from './Translator';
export * from './WhatsAppButton';
diff --git a/src/components/SearchInput/index.tsx b/src/components/SearchInput/index.tsx
index 47a6cc9..91fdf86 100644
--- a/src/components/SearchInput/index.tsx
+++ b/src/components/SearchInput/index.tsx
@@ -1,4 +1,4 @@
-import { memo, useState } from 'react';
+import { FormEvent, memo, useState } from 'react';
import { SearchInputCategoryProps, SearchInputProps } from '../../@types';
import { GenericButton, Icon, Text } from '../';
@@ -16,6 +16,12 @@ function SearchInput(props: SearchInputProps) {
setShowDropdown(false);
}
+ function onSubmit(event: FormEvent): void {
+ event.preventDefault();
+
+ if (onSearch) onSearch();
+ }
+
const renderCategoryDropdown: React.JSX.Element = (
@@ -46,7 +52,10 @@ function SearchInput(props: SearchInputProps) {
return (