From 21e3f7c0902e98de7f80f9a7183d933a9e3c4b7a Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 17 Oct 2021 13:47:23 +0000
Subject: [PATCH 01/39] build(deps): bump ansi-regex from 5.0.0 to 5.0.1
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)
---
updated-dependencies:
- dependency-name: ansi-regex
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
---
yarn.lock | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/yarn.lock b/yarn.lock
index a8e80c1..bef5a16 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1590,9 +1590,9 @@ ansi-colors@^4.1.1:
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
ansi-regex@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
- integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^3.2.1:
version "3.2.1"
From 33cbeeea7ea3ad5b5be36a43b613d2ac977c1ad6 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 17 Oct 2021 13:47:30 +0000
Subject: [PATCH 02/39] build(deps): bump next from 11.0.1 to 11.1.1
Bumps [next](https://github.com/vercel/next.js) from 11.0.1 to 11.1.1.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v11.0.1...v11.1.1)
---
updated-dependencies:
- dependency-name: next
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
---
package.json | 2 +-
yarn.lock | 212 +++++++++++++++++++++++++--------------------------
2 files changed, 104 insertions(+), 110 deletions(-)
diff --git a/package.json b/package.json
index 02d3e62..e0ffaae 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"@emotion/styled": "^11",
"firebase": "^8.9.1",
"framer-motion": "^4",
- "next": "11.0.1",
+ "next": "11.1.1",
"react": "17.0.2",
"react-datepicker": "^4.2.1",
"react-dom": "17.0.2",
diff --git a/yarn.lock b/yarn.lock
index a8e80c1..f786ce8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -181,7 +181,7 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862"
integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==
-"@babel/plugin-syntax-jsx@^7.12.13":
+"@babel/plugin-syntax-jsx@7.14.5", "@babel/plugin-syntax-jsx@^7.12.13":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201"
integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==
@@ -196,17 +196,10 @@
core-js-pure "^3.16.0"
regenerator-runtime "^0.13.4"
-"@babel/runtime@7.12.5":
- version "7.12.5"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
- integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
- dependencies:
- regenerator-runtime "^0.13.4"
-
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.7.2":
- version "7.14.8"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.8.tgz#7119a56f421018852694290b9f9148097391b446"
- integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==
+"@babel/runtime@7.15.3", "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.7.2":
+ version "7.15.3"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b"
+ integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==
dependencies:
regenerator-runtime "^0.13.4"
@@ -234,16 +227,7 @@
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c"
- integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==
- dependencies:
- esutils "^2.0.2"
- lodash "^4.17.13"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.0":
+"@babel/types@7.15.0", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.0":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd"
integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==
@@ -1213,25 +1197,30 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==
-"@next/env@11.0.1":
- version "11.0.1"
- resolved "https://registry.yarnpkg.com/@next/env/-/env-11.0.1.tgz#6dc96ac76f1663ab747340e907e8933f190cc8fd"
- integrity sha512-yZfKh2U6R9tEYyNUrs2V3SBvCMufkJ07xMH5uWy8wqcl5gAXoEw6A/1LDqwX3j7pUutF9d1ZxpdGDA3Uag+aQQ==
+"@napi-rs/triples@^1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c"
+ integrity sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA==
+
+"@next/env@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.1.tgz#d403282accbe8795aa2341f0e02c2e8bfc92bfb0"
+ integrity sha512-UEAzlfKofotLmj9LIgNixAfXpRck9rt/1CU9Q4ZtNDueGBJQP3HUzPHlrLChltWY2TA5MOzDQGL82H0a3+i5Ag==
"@next/eslint-plugin-next@11.0.1":
version "11.0.1"
resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-11.0.1.tgz#5dd3264a40fadcf28eba00d914d69103422bb7e6"
integrity sha512-UzdX3y6XSrj9YuASUb/p4sRvfjP2klj2YgIOfMwrWoLTTPJQMh00hREB9Ftr7m7RIxjVSAaaLXIRLdxvq948GA==
-"@next/polyfill-module@11.0.1":
- version "11.0.1"
- resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.0.1.tgz#ca2a110c1c44672cbcff6c2b983f0c0549d87291"
- integrity sha512-Cjs7rrKCg4CF4Jhri8PCKlBXhszTfOQNl9AjzdNy4K5jXFyxyoSzuX2rK4IuoyE+yGp5A3XJCBEmOQ4xbUp9Mg==
+"@next/polyfill-module@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.1.tgz#89d5a70685a52a0fad79f05a1f97a6b15cc727aa"
+ integrity sha512-9FyVSnz00WGdlLsgc2w1xL1Lm/Q25y6FYIyA+1WlJvT6LA2lbR78GKiHgedzUvrAatVGAcg/Og+d0d7B4tsJOg==
-"@next/react-dev-overlay@11.0.1":
- version "11.0.1"
- resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.0.1.tgz#3c481e83347255abd466dcf7e59ac8a79a0d7fd6"
- integrity sha512-lvUjMVpLsgzADs9Q8wtC5LNqvfdN+M0BDMSrqr04EDWAyyX0vURHC9hkvLbyEYWyh+WW32pwjKBXdkMnJhoqMg==
+"@next/react-dev-overlay@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.1.tgz#3cd99202a85412bada8ba9c8e3f4cf7c19294b24"
+ integrity sha512-CXc/A0DbSk5VXYu4+zr0fHm52Zh/LhPlLyVPEctJOZL64ccxkls5xGoXvgolJCku9L0pLjJzvdfAmhNLOp5dyw==
dependencies:
"@babel/code-frame" "7.12.11"
anser "1.4.9"
@@ -1245,10 +1234,37 @@
stacktrace-parser "0.1.10"
strip-ansi "6.0.0"
-"@next/react-refresh-utils@11.0.1":
- version "11.0.1"
- resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.0.1.tgz#a7509f22b6f70c13101a26573afd295295f1c020"
- integrity sha512-K347DM6Z7gBSE+TfUaTTceWvbj0B6iNAsFZXbFZOlfg3uyz2sbKpzPYYFocCc27yjLaS8OfR8DEdS2mZXi8Saw==
+"@next/react-refresh-utils@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.1.tgz#8d1a5432a53c9f987503d5ab07d3241230afb33f"
+ integrity sha512-j186y+lWc8BHAuysAWvlOqO9Bp7E3BLK/d/Ju3W2sP5BCH5ZLyLG/p308zSy/O0MGTag0B038ZA1dCy/msouRQ==
+
+"@next/swc-darwin-arm64@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-11.1.1.tgz#ea9a76bcff00945df29a81bc43b3b22dd0a6cb53"
+ integrity sha512-KyB0aLpfQ+B2dsyGYpkM0ZwK3PV0t4C4b9yjgQc1VoTVnIjzXdDPnNOuVvmD849ZNOHfj3x8e2rlbxkj0lPm3A==
+
+"@next/swc-darwin-x64@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-11.1.1.tgz#95838e9116897ae734d02fdbbfa601b6f52adaf3"
+ integrity sha512-B3ZXgrGx0bQplbrk2oggPjKPPsmyg8Fl0PJLMTVQ+erQ8g1m5QzyS9P6tB3SiIZa180JgENuguTHlVK5qEj4UA==
+
+"@next/swc-linux-x64-gnu@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-11.1.1.tgz#42c4973213a880977ebdfad01474217d7d71e8c2"
+ integrity sha512-qvZL7gSKF+E+GZ3L1XiTnE3cOh9rk0wkqimT/q+wwcZA4E720Lu4lrT79I3HPuj6i/JPgGvmNskcnYrDeaoFaw==
+
+"@next/swc-win32-x64-msvc@11.1.1":
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-11.1.1.tgz#1ffcbd01a0155fa8558f7aefffea1066e9bebe74"
+ integrity sha512-jhnCiA1De1L+kA0gmHG1AJijHoxOcrETWziDWy8fcqSrM1NlC4aJ5Mnu6k0QMcM9MnmXTA4TQZOEv3kF7vhJUQ==
+
+"@node-rs/helper@1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@node-rs/helper/-/helper-1.2.1.tgz#e079b05f21ff4329d82c4e1f71c0290e4ecdc70c"
+ integrity sha512-R5wEmm8nbuQU0YGGmYVjEc0OHtYsuXdpRG+Ut/3wZ9XAvQWyThN08bTh2cBJgoZxHQUPtvRfeQuxcAgLuiBISg==
+ dependencies:
+ "@napi-rs/triples" "^1.0.3"
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
@@ -1751,11 +1767,6 @@ babel-plugin-module-resolver@^4.1.0:
reselect "^4.0.0"
resolve "^1.13.1"
-babel-plugin-syntax-jsx@6.18.0:
- version "6.18.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
- integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
-
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -1934,12 +1945,7 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228:
- version "1.0.30001249"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz#90a330057f8ff75bfe97a94d047d5e14fabb2ee8"
- integrity sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==
-
-caniuse-lite@^1.0.30001251:
+caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228, caniuse-lite@^1.0.30001251:
version "1.0.30001251"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz#6853a606ec50893115db660f82c094d18f096d85"
integrity sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==
@@ -2181,19 +2187,19 @@ css.escape@1.5.1:
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=
-cssnano-preset-simple@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-2.0.0.tgz#b55e72cb970713f425560a0e141b0335249e2f96"
- integrity sha512-HkufSLkaBJbKBFx/7aj5HmCK9Ni/JedRQm0mT2qBzMG/dEuJOLnMt2lK6K1rwOOyV4j9aSY+knbW9WoS7BYpzg==
+cssnano-preset-simple@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-3.0.0.tgz#e95d0012699ca2c741306e9a3b8eeb495a348dbe"
+ integrity sha512-vxQPeoMRqUT3c/9f0vWeVa2nKQIHFpogtoBvFdW4GQ3IvEJ6uauCP6p3Y5zQDLFcI7/+40FTgX12o7XUL0Ko+w==
dependencies:
caniuse-lite "^1.0.30001202"
-cssnano-simple@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-2.0.0.tgz#930d9dcd8ba105c5a62ce719cb00854da58b5c05"
- integrity sha512-0G3TXaFxlh/szPEG/o3VcmCwl0N3E60XNb9YZZijew5eIs6fLjJuOPxQd9yEBaX2p/YfJtt49i4vYi38iH6/6w==
+cssnano-simple@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-3.0.0.tgz#a4b8ccdef4c7084af97e19bc5b93b4ecf211e90f"
+ integrity sha512-oU3ueli5Dtwgh0DyeohcIEE00QVfbPR3HzyXdAl89SfnQG3y0/qcpfLVW+jPIh3/rgMZGwuW96rejZGaYE9eUg==
dependencies:
- cssnano-preset-simple "^2.0.0"
+ cssnano-preset-simple "^3.0.0"
csstype@^3.0.2, csstype@^3.0.6:
version "3.0.8"
@@ -3473,11 +3479,6 @@ lodash.truncate@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
-lodash@^4.17.13:
- version "4.17.21"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
long@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
@@ -3576,10 +3577,10 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-nanoid@^3.1.22:
- version "3.1.23"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
- integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
+nanoid@^3.1.23:
+ version "3.1.30"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
+ integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
native-url@0.3.4:
version "0.3.4"
@@ -3593,17 +3594,18 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-next@11.0.1:
- version "11.0.1"
- resolved "https://registry.yarnpkg.com/next/-/next-11.0.1.tgz#b8e3914d153aaf7143cb98c09bcd3c8230eeb17a"
- integrity sha512-yR7be7asNbvpVNpi6xxEg28wZ7Gqmj1nOt0sABH9qORmF3+pms2KZ7Cng33oK5nqPIzEEFJD0pp2PCe3/ueMIg==
+next@11.1.1:
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/next/-/next-11.1.1.tgz#ca15c6d6b4b4bf8c3e859f7fc4f9657ce59bcb63"
+ integrity sha512-vfLJDkwAHsZUho5R1K4w49nfYhftUMWNmeNSjCtulOvnRBuEFb7ROyRZOQk7f29rMz02eLQrPZ9yiAmPsexL2g==
dependencies:
- "@babel/runtime" "7.12.5"
+ "@babel/runtime" "7.15.3"
"@hapi/accept" "5.0.2"
- "@next/env" "11.0.1"
- "@next/polyfill-module" "11.0.1"
- "@next/react-dev-overlay" "11.0.1"
- "@next/react-refresh-utils" "11.0.1"
+ "@next/env" "11.1.1"
+ "@next/polyfill-module" "11.1.1"
+ "@next/react-dev-overlay" "11.1.1"
+ "@next/react-refresh-utils" "11.1.1"
+ "@node-rs/helper" "1.2.1"
assert "2.0.0"
ast-types "0.13.2"
browserify-zlib "0.2.0"
@@ -3614,7 +3616,7 @@ next@11.0.1:
chokidar "3.5.1"
constants-browserify "1.0.0"
crypto-browserify "3.12.0"
- cssnano-simple "2.0.0"
+ cssnano-simple "3.0.0"
domain-browser "4.19.0"
encoding "0.1.13"
etag "1.8.1"
@@ -3631,9 +3633,8 @@ next@11.0.1:
p-limit "3.1.0"
path-browserify "1.0.1"
pnp-webpack-plugin "1.6.4"
- postcss "8.2.13"
+ postcss "8.2.15"
process "0.11.10"
- prop-types "15.7.2"
querystring-es3 "0.2.1"
raw-body "2.4.1"
react-is "17.0.2"
@@ -3641,13 +3642,18 @@ next@11.0.1:
stream-browserify "3.0.0"
stream-http "3.1.1"
string_decoder "1.3.0"
- styled-jsx "3.3.2"
+ styled-jsx "4.0.0"
timers-browserify "2.0.12"
tty-browserify "0.0.1"
use-subscription "1.5.1"
- util "0.12.3"
+ util "0.12.4"
vm-browserify "1.1.2"
watchpack "2.1.1"
+ optionalDependencies:
+ "@next/swc-darwin-arm64" "11.1.1"
+ "@next/swc-darwin-x64" "11.1.1"
+ "@next/swc-linux-x64-gnu" "11.1.1"
+ "@next/swc-win32-x64-msvc" "11.1.1"
node-fetch@2.6.1:
version "2.6.1"
@@ -4011,13 +4017,13 @@ popmotion@9.3.6:
style-value-types "4.1.4"
tslib "^2.1.0"
-postcss@8.2.13:
- version "8.2.13"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.13.tgz#dbe043e26e3c068e45113b1ed6375d2d37e2129f"
- integrity sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ==
+postcss@8.2.15:
+ version "8.2.15"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65"
+ integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q==
dependencies:
colorette "^1.2.2"
- nanoid "^3.1.22"
+ nanoid "^3.1.23"
source-map "^0.6.1"
prelude-ls@^1.2.1:
@@ -4057,7 +4063,7 @@ promise-polyfill@8.1.3:
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116"
integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==
-prop-types@15.7.2, prop-types@^15.6.2, prop-types@^15.7.2:
+prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -4695,13 +4701,13 @@ style-value-types@4.1.4:
hey-listen "^1.0.8"
tslib "^2.1.0"
-styled-jsx@3.3.2:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.3.2.tgz#2474601a26670a6049fb4d3f94bd91695b3ce018"
- integrity sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g==
+styled-jsx@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.0.tgz#f7b90e7889d0a4f4635f8d1ae9ac32f3acaedc57"
+ integrity sha512-2USeoWMoJ/Lx5s2y1PxuvLy/cz2Yrr8cTySV3ILHU1Vmaw1bnV7suKdblLPjnyhMD+qzN7B1SWyh4UZTARn/WA==
dependencies:
- "@babel/types" "7.8.3"
- babel-plugin-syntax-jsx "6.18.0"
+ "@babel/plugin-syntax-jsx" "7.14.5"
+ "@babel/types" "7.15.0"
convert-source-map "1.7.0"
loader-utils "1.2.3"
source-map "0.7.3"
@@ -4938,10 +4944,10 @@ util@0.10.3:
dependencies:
inherits "2.0.1"
-util@0.12.3:
- version "0.12.3"
- resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888"
- integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==
+util@0.12.4, util@^0.12.0:
+ version "0.12.4"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
+ integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==
dependencies:
inherits "^2.0.3"
is-arguments "^1.0.4"
@@ -4957,18 +4963,6 @@ util@^0.11.0:
dependencies:
inherits "2.0.3"
-util@^0.12.0:
- version "0.12.4"
- resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
- integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==
- dependencies:
- inherits "^2.0.3"
- is-arguments "^1.0.4"
- is-generator-function "^1.0.7"
- is-typed-array "^1.1.3"
- safe-buffer "^5.1.2"
- which-typed-array "^1.1.2"
-
v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
From 56531e2e92c17a0bb168a0f891ac7d829076f190 Mon Sep 17 00:00:00 2001
From: Victor Lucas <11355873+victorlucss@users.noreply.github.com>
Date: Tue, 26 Oct 2021 19:41:36 -0300
Subject: [PATCH 03/39] feat: Migrating to Next 12 (#8)
---
modules/Category/.gitkeep | 0
next-env.d.ts | 3 +
package.json | 4 +-
yarn.lock | 418 +++++++++++++-------------------------
4 files changed, 149 insertions(+), 276 deletions(-)
delete mode 100644 modules/Category/.gitkeep
diff --git a/modules/Category/.gitkeep b/modules/Category/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/next-env.d.ts b/next-env.d.ts
index c6643fd..9bc3dd4 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,3 +1,6 @@
///
///
///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/package.json b/package.json
index e0ffaae..085d1c4 100644
--- a/package.json
+++ b/package.json
@@ -16,8 +16,8 @@
"@emotion/styled": "^11",
"firebase": "^8.9.1",
"framer-motion": "^4",
- "next": "11.1.1",
- "react": "17.0.2",
+ "next": "^12.0.0",
+ "react": "^17.0.2",
"react-datepicker": "^4.2.1",
"react-dom": "17.0.2",
"react-hook-form": "^7.12.2"
diff --git a/yarn.lock b/yarn.lock
index 4821bfc..88d68b1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -195,11 +195,17 @@
dependencies:
core-js-pure "^3.16.0"
regenerator-runtime "^0.13.4"
+"@babel/runtime@7.15.4", "@babel/runtime@^7.15.4":
+ version "7.15.4"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
+ integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
+ dependencies:
+ regenerator-runtime "^0.13.4"
-"@babel/runtime@7.15.3", "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.7.2":
- version "7.15.3"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b"
- integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.7.2":
+ version "7.14.8"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.8.tgz#7119a56f421018852694290b9f9148097391b446"
+ integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==
dependencies:
regenerator-runtime "^0.13.4"
@@ -1202,25 +1208,26 @@
resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c"
integrity sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA==
-"@next/env@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.1.tgz#d403282accbe8795aa2341f0e02c2e8bfc92bfb0"
- integrity sha512-UEAzlfKofotLmj9LIgNixAfXpRck9rt/1CU9Q4ZtNDueGBJQP3HUzPHlrLChltWY2TA5MOzDQGL82H0a3+i5Ag==
+"@next/env@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-12.0.0.tgz#1ce019c9e470d7ad05cf0523ee9f606a2e460b65"
+ integrity sha512-ztXvXG0dEHbWsOZZ2x443fVJK2QtVOhCU6QfmeJjnbmeYhiHhJ4sWOF2QFt0EgNTcyt6prLBVUFGQheW6Jc6lA==
"@next/eslint-plugin-next@11.0.1":
version "11.0.1"
resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-11.0.1.tgz#5dd3264a40fadcf28eba00d914d69103422bb7e6"
integrity sha512-UzdX3y6XSrj9YuASUb/p4sRvfjP2klj2YgIOfMwrWoLTTPJQMh00hREB9Ftr7m7RIxjVSAaaLXIRLdxvq948GA==
-"@next/polyfill-module@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.1.tgz#89d5a70685a52a0fad79f05a1f97a6b15cc727aa"
- integrity sha512-9FyVSnz00WGdlLsgc2w1xL1Lm/Q25y6FYIyA+1WlJvT6LA2lbR78GKiHgedzUvrAatVGAcg/Og+d0d7B4tsJOg==
+"@next/polyfill-module@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-12.0.0.tgz#9516a57b72150bb250f76b8f94667dadf2973988"
+ integrity sha512-eajaHprq5AaCdhWLlLW53mJWykWSgThAJ2IBUvm2Jx13ruole3t6rMOVPR2MvTacaq8ayj3zRtLM5j9j4Ejqyw==
+
+"@next/react-dev-overlay@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-12.0.0.tgz#ddad018afa1ebc9fa79d3a3ef09103e1901a0983"
+ integrity sha512-sGDNFQFV6H+KAi6yQRIv4LtZ8Mg8zu1CwyVimwgYboai4eVIOg4rigZADV2xp4YEtwkgvQEijDh6J7rLCKPDXA==
-"@next/react-dev-overlay@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.1.tgz#3cd99202a85412bada8ba9c8e3f4cf7c19294b24"
- integrity sha512-CXc/A0DbSk5VXYu4+zr0fHm52Zh/LhPlLyVPEctJOZL64ccxkls5xGoXvgolJCku9L0pLjJzvdfAmhNLOp5dyw==
dependencies:
"@babel/code-frame" "7.12.11"
anser "1.4.9"
@@ -1232,32 +1239,67 @@
shell-quote "1.7.2"
source-map "0.8.0-beta.0"
stacktrace-parser "0.1.10"
- strip-ansi "6.0.0"
-
-"@next/react-refresh-utils@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.1.tgz#8d1a5432a53c9f987503d5ab07d3241230afb33f"
- integrity sha512-j186y+lWc8BHAuysAWvlOqO9Bp7E3BLK/d/Ju3W2sP5BCH5ZLyLG/p308zSy/O0MGTag0B038ZA1dCy/msouRQ==
-
-"@next/swc-darwin-arm64@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-11.1.1.tgz#ea9a76bcff00945df29a81bc43b3b22dd0a6cb53"
- integrity sha512-KyB0aLpfQ+B2dsyGYpkM0ZwK3PV0t4C4b9yjgQc1VoTVnIjzXdDPnNOuVvmD849ZNOHfj3x8e2rlbxkj0lPm3A==
-
-"@next/swc-darwin-x64@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-11.1.1.tgz#95838e9116897ae734d02fdbbfa601b6f52adaf3"
- integrity sha512-B3ZXgrGx0bQplbrk2oggPjKPPsmyg8Fl0PJLMTVQ+erQ8g1m5QzyS9P6tB3SiIZa180JgENuguTHlVK5qEj4UA==
-
-"@next/swc-linux-x64-gnu@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-11.1.1.tgz#42c4973213a880977ebdfad01474217d7d71e8c2"
- integrity sha512-qvZL7gSKF+E+GZ3L1XiTnE3cOh9rk0wkqimT/q+wwcZA4E720Lu4lrT79I3HPuj6i/JPgGvmNskcnYrDeaoFaw==
-
-"@next/swc-win32-x64-msvc@11.1.1":
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-11.1.1.tgz#1ffcbd01a0155fa8558f7aefffea1066e9bebe74"
- integrity sha512-jhnCiA1De1L+kA0gmHG1AJijHoxOcrETWziDWy8fcqSrM1NlC4aJ5Mnu6k0QMcM9MnmXTA4TQZOEv3kF7vhJUQ==
+ strip-ansi "6.0.1"
+
+"@next/react-refresh-utils@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-12.0.0.tgz#515826c7c0ca01fc39ef7e7f6f8990c4ff388494"
+ integrity sha512-S5EjnsNus4vX4hU0Ky/NIGXAWO2aPxS78ZQO2qK4yvEpNJ554B/xDoErb6D1HSpMiwBxSXE36FLsjvaxMvUs3g==
+
+"@next/swc-android-arm64@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.0.0.tgz#4ccb356f70cabc6399e215c9bb9129835ae0b408"
+ integrity sha512-m0CSgD+aUZ49fctjJ7IRbkPtEYkFk+AtpJ73sfjbxzOXwAEfB2LM33rIQNp/G7D1WLqWITF00keNaeGAADD0aw==
+
+"@next/swc-darwin-arm64@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.0.0.tgz#770abf91bc4e201d096e9283af2795ee7c027bc5"
+ integrity sha512-y+p+rTVx1sfQqBURZkheVTyz7ugkIMcFxQkd+yNU4IMCT6nOH9SdL1jr+E+neqY1D1vvsOj/UwkPxyOHH2p8Lw==
+
+"@next/swc-darwin-x64@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.0.0.tgz#ebe5878c5b568ae0a4f4adac7ce937d380f332e9"
+ integrity sha512-A4gsNmMg+TN89djBJMKbYlKIWrTwKw+dvyvaE8rx+CDUzh4hdro3mhqWtaNTqCWhE28WnoGhXLdANeDWsoXg1Q==
+
+"@next/swc-linux-arm-gnueabihf@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.0.0.tgz#18b82c7e64f37803f5104544840ab3ee89af1ade"
+ integrity sha512-DntdAybXbEOzP7wiv/Ppa9BTaGkb/Fp3SVxrZv694OjtGbmY0Q8+YGsShh0FQmhMKBwcJ0GMLI+anmsWj9ZUcA==
+
+"@next/swc-linux-arm64-gnu@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.0.0.tgz#8fd3db89d206be3f9a66ca004a159998a2eeb1a4"
+ integrity sha512-3D18X1dpziBnk9UEg7b/hIyQA6Qt18UDKY3dmKqKcGcFMwtMqBsunVLDoNmB5SHVDVBGvA4zOtq28Xovb/3MOA==
+
+"@next/swc-linux-arm64-musl@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.0.0.tgz#0b895996ea87a9cd18de836a78f824c66b598301"
+ integrity sha512-el+Xin2vl2JnWw809Eg+otWxvIcw+waBuOj4B36+d8yircexhNvSDjAnZkhXCWA6I05IANUx83Q0Up/NrnZ5yQ==
+
+"@next/swc-linux-x64-gnu@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.0.0.tgz#13bb694f1dabd25ca6722a2a574039c50c0589f0"
+ integrity sha512-jMOBEc7wbsJfq6UZinrEFky3kK4LCjFPL2caHqfXpodTv/oVA/DMkiXhpYRkdfLc9vNZbw/a4Ut7gQjgYPVPtg==
+
+"@next/swc-linux-x64-musl@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.0.0.tgz#f6718cecd37bd6e77b7edf19fbfb0f27a1d17411"
+ integrity sha512-0pizk3CZasxbaSyn7FzXb9cfrgIjmyq0dA3+MqvFZJNTLjDw8/yk0w3HdAOPFor3Tgoqhu5nsX/X5mnE6tObng==
+
+"@next/swc-win32-arm64-msvc@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.0.0.tgz#456d357cab970d7fa1b6d4ca6dee323e8f4b3883"
+ integrity sha512-0+NT/FY2qfwgScqRhNabV6vVCfx+4PmRS4675/iMKdGLdGzat69FGjUqxW6rPS+bJGc8qvpa6oztsvsVODJHSQ==
+
+"@next/swc-win32-ia32-msvc@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.0.0.tgz#8a82da7f95c6c45f1487e991ab8af8bd45b75c84"
+ integrity sha512-sbjvdZGKiSJQrOSJRooEPIWwSfyatBiuRC7Q6R2jiR2KW1jg98nbnXRwiI8tj7OSl28h0yswmtGFjz5t5O1EbQ==
+
+"@next/swc-win32-x64-msvc@12.0.0":
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.0.0.tgz#c19e6cfdb1cebe088ea663d6405a6ed76fc4e79d"
+ integrity sha512-NMZRwS59X4+yQT53jROZMcboiPVd6zCGlEN3kuPewelTDVwKAXxzhpLuxCO46e0ssol8UZiOTdgB4NPVbsLK2A==
"@node-rs/helper@1.2.1":
version "1.2.1"
@@ -1610,6 +1652,11 @@ ansi-regex@^5.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -1709,24 +1756,11 @@ assert@2.0.0:
object-is "^1.0.1"
util "^0.12.0"
-assert@^1.1.1:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
- integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
- dependencies:
- object-assign "^4.1.1"
- util "0.10.3"
-
ast-types-flow@^0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
-ast-types@0.13.2:
- version "0.13.2"
- resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48"
- integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==
-
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
@@ -1871,7 +1905,7 @@ browserify-sign@^4.0.0:
readable-stream "^3.6.0"
safe-buffer "^5.2.0"
-browserify-zlib@0.2.0, browserify-zlib@^0.2.0:
+browserify-zlib@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
@@ -1913,15 +1947,6 @@ buffer@5.6.0:
base64-js "^1.0.2"
ieee754 "^1.1.4"
-buffer@^4.3.0:
- version "4.9.2"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
- integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
- dependencies:
- base64-js "^1.0.2"
- ieee754 "^1.1.4"
- isarray "^1.0.0"
-
builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
@@ -2061,12 +2086,7 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-console-browserify@^1.1.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
- integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
-
-constants-browserify@1.0.0, constants-browserify@^1.0.0:
+constants-browserify@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
@@ -2102,11 +2122,6 @@ core-js@3.6.5:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a"
integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==
-core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
cosmiconfig@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
@@ -2158,7 +2173,7 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
-crypto-browserify@3.12.0, crypto-browserify@^3.11.0:
+crypto-browserify@3.12.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
@@ -2312,11 +2327,6 @@ domain-browser@4.19.0:
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1"
integrity sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ==
-domain-browser@^1.1.1:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
- integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
-
electron-to-chromium@^1.3.723:
version "1.3.801"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.801.tgz#f41c588e408ad1a4f794f91f38aa94a89c492f51"
@@ -2677,7 +2687,7 @@ etag@1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
-events@^3.0.0:
+events@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@@ -3061,7 +3071,7 @@ http-parser-js@>=0.5.1:
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9"
integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==
-https-browserify@1.0.0, https-browserify@^1.0.0:
+https-browserify@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
@@ -3128,21 +3138,11 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-inherits@2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
- integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
-
-inherits@2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
- integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
internal-slot@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
@@ -3293,11 +3293,6 @@ is-typed-array@^1.1.3, is-typed-array@^1.1.6:
foreach "^2.0.5"
has-tostringtag "^1.0.0"
-isarray@^1.0.0, isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
- integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -3594,20 +3589,19 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-next@11.1.1:
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/next/-/next-11.1.1.tgz#ca15c6d6b4b4bf8c3e859f7fc4f9657ce59bcb63"
- integrity sha512-vfLJDkwAHsZUho5R1K4w49nfYhftUMWNmeNSjCtulOvnRBuEFb7ROyRZOQk7f29rMz02eLQrPZ9yiAmPsexL2g==
+next@^12.0.0:
+ version "12.0.0"
+ resolved "https://registry.yarnpkg.com/next/-/next-12.0.0.tgz#f9df3f1788c7e0526c2cde861dbb391b499af758"
+ integrity sha512-FCV4ODfm+7g8TWi9FjwjH+z5Rt1UHIVnFFO7GfCg+LLYC2LF89gCjjXEIeK8loaiDEkxafPqjyCWWfUU7xJ8DA==
dependencies:
- "@babel/runtime" "7.15.3"
+ "@babel/runtime" "7.15.4"
"@hapi/accept" "5.0.2"
- "@next/env" "11.1.1"
- "@next/polyfill-module" "11.1.1"
- "@next/react-dev-overlay" "11.1.1"
- "@next/react-refresh-utils" "11.1.1"
+ "@next/env" "12.0.0"
+ "@next/polyfill-module" "12.0.0"
+ "@next/react-dev-overlay" "12.0.0"
+ "@next/react-refresh-utils" "12.0.0"
"@node-rs/helper" "1.2.1"
assert "2.0.0"
- ast-types "0.13.2"
browserify-zlib "0.2.0"
browserslist "4.16.6"
buffer "5.6.0"
@@ -3620,29 +3614,28 @@ next@11.1.1:
domain-browser "4.19.0"
encoding "0.1.13"
etag "1.8.1"
+ events "3.3.0"
find-cache-dir "3.3.1"
get-orientation "1.1.2"
https-browserify "1.0.0"
image-size "1.0.0"
jest-worker "27.0.0-next.5"
- native-url "0.3.4"
node-fetch "2.6.1"
node-html-parser "1.4.9"
- node-libs-browser "^2.2.1"
os-browserify "0.3.0"
p-limit "3.1.0"
path-browserify "1.0.1"
- pnp-webpack-plugin "1.6.4"
postcss "8.2.15"
process "0.11.10"
querystring-es3 "0.2.1"
raw-body "2.4.1"
react-is "17.0.2"
react-refresh "0.8.3"
+ regenerator-runtime "0.13.4"
stream-browserify "3.0.0"
stream-http "3.1.1"
string_decoder "1.3.0"
- styled-jsx "4.0.0"
+ styled-jsx "5.0.0-beta.3"
timers-browserify "2.0.12"
tty-browserify "0.0.1"
use-subscription "1.5.1"
@@ -3650,10 +3643,17 @@ next@11.1.1:
vm-browserify "1.1.2"
watchpack "2.1.1"
optionalDependencies:
- "@next/swc-darwin-arm64" "11.1.1"
- "@next/swc-darwin-x64" "11.1.1"
- "@next/swc-linux-x64-gnu" "11.1.1"
- "@next/swc-win32-x64-msvc" "11.1.1"
+ "@next/swc-android-arm64" "12.0.0"
+ "@next/swc-darwin-arm64" "12.0.0"
+ "@next/swc-darwin-x64" "12.0.0"
+ "@next/swc-linux-arm-gnueabihf" "12.0.0"
+ "@next/swc-linux-arm64-gnu" "12.0.0"
+ "@next/swc-linux-arm64-musl" "12.0.0"
+ "@next/swc-linux-x64-gnu" "12.0.0"
+ "@next/swc-linux-x64-musl" "12.0.0"
+ "@next/swc-win32-arm64-msvc" "12.0.0"
+ "@next/swc-win32-ia32-msvc" "12.0.0"
+ "@next/swc-win32-x64-msvc" "12.0.0"
node-fetch@2.6.1:
version "2.6.1"
@@ -3667,35 +3667,6 @@ node-html-parser@1.4.9:
dependencies:
he "1.2.0"
-node-libs-browser@^2.2.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
- integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
- dependencies:
- assert "^1.1.1"
- browserify-zlib "^0.2.0"
- buffer "^4.3.0"
- console-browserify "^1.1.0"
- constants-browserify "^1.0.0"
- crypto-browserify "^3.11.0"
- domain-browser "^1.1.1"
- events "^3.0.0"
- https-browserify "^1.0.0"
- os-browserify "^0.3.0"
- path-browserify "0.0.1"
- process "^0.11.10"
- punycode "^1.2.4"
- querystring-es3 "^0.2.0"
- readable-stream "^2.3.3"
- stream-browserify "^2.0.1"
- stream-http "^2.7.2"
- string_decoder "^1.0.0"
- timers-browserify "^2.0.4"
- tty-browserify "0.0.0"
- url "^0.11.0"
- util "^0.11.0"
- vm-browserify "^1.0.1"
-
node-releases@^1.1.71:
version "1.1.74"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.74.tgz#e5866488080ebaa70a93b91144ccde06f3c3463e"
@@ -3801,7 +3772,7 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
-os-browserify@0.3.0, os-browserify@^0.3.0:
+os-browserify@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
@@ -3899,11 +3870,6 @@ parse-json@^5.0.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
-path-browserify@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
- integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
-
path-browserify@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
@@ -4000,13 +3966,6 @@ platform@1.3.6:
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7"
integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==
-pnp-webpack-plugin@1.6.4:
- version "1.6.4"
- resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149"
- integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==
- dependencies:
- ts-pnp "^1.1.6"
-
popmotion@9.3.6:
version "9.3.6"
resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-9.3.6.tgz#b5236fa28f242aff3871b9e23721f093133248d1"
@@ -4043,12 +4002,7 @@ prettier@^2.3.2:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
-process-nextick-args@~2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
- integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-process@0.11.10, process@^0.11.10:
+process@0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
@@ -4103,36 +4057,16 @@ public-encrypt@^4.0.0:
randombytes "^2.0.1"
safe-buffer "^5.1.2"
-punycode@1.3.2:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
- integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-
-punycode@^1.2.4:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
- integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-
punycode@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
-querystring-es3@0.2.1, querystring-es3@^0.2.0:
+querystring-es3@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
-querystring@0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
- integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
-
-querystring@^0.2.0:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd"
- integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==
-
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -4189,7 +4123,7 @@ react-datepicker@^4.2.1:
react-onclickoutside "^6.10.0"
react-popper "^2.2.5"
-react-dom@17.0.2:
+react-dom@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
@@ -4276,7 +4210,7 @@ react-style-singleton@^2.1.0:
invariant "^2.2.4"
tslib "^1.0.0"
-react@17.0.2:
+react@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
@@ -4301,19 +4235,6 @@ read-pkg@^3.0.0:
normalize-package-data "^2.3.2"
path-type "^3.0.0"
-readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6:
- version "2.3.7"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
- integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
readable-stream@^3.5.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
@@ -4330,6 +4251,11 @@ readdirp@~3.5.0:
dependencies:
picomatch "^2.2.1"
+regenerator-runtime@0.13.4:
+ version "0.13.4"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz#e96bf612a3362d12bb69f7e8f74ffeab25c7ac91"
+ integrity sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==
+
regenerator-runtime@^0.13.4:
version "0.13.9"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
@@ -4416,7 +4342,7 @@ safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1,
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
@@ -4582,14 +4508,6 @@ stream-browserify@3.0.0:
inherits "~2.0.4"
readable-stream "^3.5.0"
-stream-browserify@^2.0.1:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
- integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==
- dependencies:
- inherits "~2.0.1"
- readable-stream "^2.0.2"
-
stream-http@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564"
@@ -4600,17 +4518,6 @@ stream-http@3.1.1:
readable-stream "^3.6.0"
xtend "^4.0.2"
-stream-http@^2.7.2:
- version "2.8.3"
- resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc"
- integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==
- dependencies:
- builtin-status-codes "^3.0.0"
- inherits "^2.0.1"
- readable-stream "^2.3.6"
- to-arraybuffer "^1.0.0"
- xtend "^4.0.0"
-
stream-parser@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773"
@@ -4662,21 +4569,21 @@ string.prototype.trimstart@^1.0.4:
call-bind "^1.0.2"
define-properties "^1.1.3"
-string_decoder@1.3.0, string_decoder@^1.0.0, string_decoder@^1.1.1:
+string_decoder@1.3.0, string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+strip-ansi@6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
- safe-buffer "~5.1.0"
+ ansi-regex "^5.0.1"
-strip-ansi@6.0.0, strip-ansi@^6.0.0:
+strip-ansi@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
@@ -4701,10 +4608,10 @@ style-value-types@4.1.4:
hey-listen "^1.0.8"
tslib "^2.1.0"
-styled-jsx@4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.0.tgz#f7b90e7889d0a4f4635f8d1ae9ac32f3acaedc57"
- integrity sha512-2USeoWMoJ/Lx5s2y1PxuvLy/cz2Yrr8cTySV3ILHU1Vmaw1bnV7suKdblLPjnyhMD+qzN7B1SWyh4UZTARn/WA==
+styled-jsx@5.0.0-beta.3:
+ version "5.0.0-beta.3"
+ resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0-beta.3.tgz#400d16179b5dff10d5954ab8be27a9a1b7780dd2"
+ integrity sha512-HtDDGSFPvmjHIqWf9n8Oo54tAoY/DTplvlyOH2+YOtD80Sp31Ap8ffSmxhgk5EkUoJ7xepdXMGT650mSffWuRA==
dependencies:
"@babel/plugin-syntax-jsx" "7.14.5"
"@babel/types" "7.15.0"
@@ -4768,7 +4675,7 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
-timers-browserify@2.0.12, timers-browserify@^2.0.4:
+timers-browserify@2.0.12:
version "2.0.12"
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee"
integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==
@@ -4785,11 +4692,6 @@ tinycolor2@1.4.2:
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
-to-arraybuffer@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
- integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
-
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -4819,11 +4721,6 @@ tr46@^1.0.1:
dependencies:
punycode "^2.1.0"
-ts-pnp@^1.1.6:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
- integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==
-
tsconfig-paths@^3.9.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz#79ae67a68c15289fdf5c51cb74f397522d795ed7"
@@ -4850,11 +4747,6 @@ tsutils@^3.21.0:
dependencies:
tslib "^1.8.1"
-tty-browserify@0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
- integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
-
tty-browserify@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"
@@ -4904,14 +4796,6 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
-url@^0.11.0:
- version "0.11.0"
- resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
- integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
- dependencies:
- punycode "1.3.2"
- querystring "0.2.0"
-
use-callback-ref@^1.2.1, use-callback-ref@^1.2.3:
version "1.2.5"
resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.5.tgz#6115ed242cfbaed5915499c0a9842ca2912f38a5"
@@ -4932,18 +4816,11 @@ use-subscription@1.5.1:
dependencies:
object-assign "^4.1.1"
-util-deprecate@^1.0.1, util-deprecate@~1.0.1:
+util-deprecate@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-util@0.10.3:
- version "0.10.3"
- resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
- integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
- dependencies:
- inherits "2.0.1"
-
util@0.12.4, util@^0.12.0:
version "0.12.4"
resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
@@ -4956,13 +4833,6 @@ util@0.12.4, util@^0.12.0:
safe-buffer "^5.1.2"
which-typed-array "^1.1.2"
-util@^0.11.0:
- version "0.11.1"
- resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61"
- integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==
- dependencies:
- inherits "2.0.3"
-
v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
@@ -4976,7 +4846,7 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
-vm-browserify@1.1.2, vm-browserify@^1.0.1:
+vm-browserify@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
@@ -5083,7 +4953,7 @@ xmlhttprequest@1.8.0:
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=
-xtend@^4.0.0, xtend@^4.0.2:
+xtend@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
From 1ba2ab884f5338c433d5a73526a071d3c80ddee0 Mon Sep 17 00:00:00 2001
From: Victor Lucas <11355873+victorlucss@users.noreply.github.com>
Date: Tue, 26 Oct 2021 19:41:54 -0300
Subject: [PATCH 04/39] Feature/BaseModule (#7)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: Modal component
* feat: Bubble types
* feat: added yup
* feat: Bubble component to render fields
* feat: 🤘🏽 BaseForm component
* feat: 🤘🏽 BaseList component
* feat: BaseField and SelectOption types
* feat: 🤘🏽 renderFields method
---
components/Modal/index.tsx | 18 +++
components/index.ts | 1 +
.../BaseModule/components/Bubble/index.tsx | 62 ++++++++++
modules/BaseModule/constants/Bubble.ts | 6 +
.../BaseModule/container/BaseForm/index.tsx | 82 +++++++++++++
.../BaseModule/container/BaseList/index.tsx | 115 ++++++++++++++++++
modules/BaseModule/interfaces/BaseField.ts | 11 ++
modules/BaseModule/interfaces/SelectOption.ts | 4 +
modules/BaseModule/shared/renderFields.tsx | 20 +++
package.json | 4 +-
yarn.lock | 63 +++++++++-
11 files changed, 380 insertions(+), 6 deletions(-)
create mode 100644 components/Modal/index.tsx
create mode 100644 modules/BaseModule/components/Bubble/index.tsx
create mode 100644 modules/BaseModule/constants/Bubble.ts
create mode 100644 modules/BaseModule/container/BaseForm/index.tsx
create mode 100644 modules/BaseModule/container/BaseList/index.tsx
create mode 100644 modules/BaseModule/interfaces/BaseField.ts
create mode 100644 modules/BaseModule/interfaces/SelectOption.ts
create mode 100644 modules/BaseModule/shared/renderFields.tsx
diff --git a/components/Modal/index.tsx b/components/Modal/index.tsx
new file mode 100644
index 0000000..36ee630
--- /dev/null
+++ b/components/Modal/index.tsx
@@ -0,0 +1,18 @@
+import { Modal as ModalChakra, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
+
+interface ModalInterface {
+ onClose: () => void;
+ isOpen: boolean;
+ children: React.ReactElement;
+}
+
+export const Modal = ({ onClose, isOpen, children }: ModalInterface) => {
+ return (
+
+
+
+ {children}
+
+
+ );
+};
diff --git a/components/index.ts b/components/index.ts
index 0653a6d..9a1f7f4 100644
--- a/components/index.ts
+++ b/components/index.ts
@@ -2,3 +2,4 @@ export * from './MoneyInput';
export * from './Input';
export * from './Select';
export * from './DatePicker';
+export * from './Modal';
diff --git a/modules/BaseModule/components/Bubble/index.tsx b/modules/BaseModule/components/Bubble/index.tsx
new file mode 100644
index 0000000..14968c2
--- /dev/null
+++ b/modules/BaseModule/components/Bubble/index.tsx
@@ -0,0 +1,62 @@
+import React from 'react';
+import { FieldErrors, FieldValues, UseFormRegister } from 'react-hook-form';
+
+import { Input, Select } from '@Components';
+import SelectOption from '@Modules/BaseModule/interfaces/SelectOption';
+
+import { BubbleEnum, BUBBLE_TYPES } from '../../constants/Bubble';
+
+interface BubbleInterface {
+ type: BubbleEnum;
+ name: string;
+ label: string;
+ register: UseFormRegister;
+ errors: FieldErrors;
+ required?: boolean;
+ props?: object;
+ options?: SelectOption[];
+ value?: (string | number | readonly string[]) & string;
+}
+
+const Bubble = ({
+ type,
+ name,
+ label,
+ register,
+ errors,
+ required = false,
+ options = [],
+ value,
+ props = {},
+}: BubbleInterface) => {
+ switch (type) {
+ case BUBBLE_TYPES.INPUT:
+ return (
+
+ );
+
+ case BUBBLE_TYPES.SELECT:
+ return (
+
+ );
+
+ default:
+ return <>>;
+ }
+};
+
+export default Bubble;
diff --git a/modules/BaseModule/constants/Bubble.ts b/modules/BaseModule/constants/Bubble.ts
new file mode 100644
index 0000000..c547777
--- /dev/null
+++ b/modules/BaseModule/constants/Bubble.ts
@@ -0,0 +1,6 @@
+export const BUBBLE_TYPES = {
+ INPUT: 'INPUT',
+ SELECT: 'SELECT',
+};
+
+export type BubbleEnum = keyof typeof BUBBLE_TYPES;
diff --git a/modules/BaseModule/container/BaseForm/index.tsx b/modules/BaseModule/container/BaseForm/index.tsx
new file mode 100644
index 0000000..0bf8709
--- /dev/null
+++ b/modules/BaseModule/container/BaseForm/index.tsx
@@ -0,0 +1,82 @@
+import React, { useCallback, useEffect } from 'react';
+import { useForm } from 'react-hook-form';
+import { Button } from '@chakra-ui/button';
+import { Flex } from '@chakra-ui/react';
+import { yupResolver } from '@hookform/resolvers/yup';
+import * as Yup from 'yup';
+
+import BaseField from '@Modules/BaseModule/interfaces/BaseField';
+import renderFields from '@Modules/BaseModule/shared/renderFields';
+
+interface BaseFormInterface {
+ id?: string | number;
+ fetch?: (id: string | number) => Promise;
+ fields: BaseField[];
+ onSubmit: (element: T) => T | Promise | Promise;
+ submitLabel?: string;
+ schema: Yup.AnyObjectSchema;
+}
+
+const BaseForm = ({
+ id,
+ fetch,
+ onSubmit,
+ fields,
+ submitLabel = 'Submit',
+ schema,
+}: BaseFormInterface) => {
+ const {
+ handleSubmit,
+ register,
+ setValue,
+ formState: { errors, isSubmitting },
+ } = useForm({
+ resolver: yupResolver(schema),
+ });
+
+ const wrapperOnSubmit = values => {
+ const element = values as T;
+
+ onSubmit(element);
+ };
+
+ const fetchData = useCallback(
+ async (id): Promise => {
+ if (id && !!fetch) {
+ const model = await fetch(id);
+
+ if (model) {
+ fields.forEach(({ name }) => {
+ if (model[name]) {
+ setValue(name, model[name]);
+ }
+ });
+ }
+
+ return model;
+ }
+ },
+ [fetch, fields, setValue]
+ );
+
+ useEffect(() => {
+ if (id) {
+ fetchData(id);
+ }
+ }, [fetchData, id]);
+
+ return (
+
+ );
+};
+
+export { BaseForm };
+export default BaseForm;
diff --git a/modules/BaseModule/container/BaseList/index.tsx b/modules/BaseModule/container/BaseList/index.tsx
new file mode 100644
index 0000000..416013e
--- /dev/null
+++ b/modules/BaseModule/container/BaseList/index.tsx
@@ -0,0 +1,115 @@
+import React, { useEffect, useMemo, useState } from 'react';
+import { Box, Table, Thead, Tbody, Tr, Th, Td, Spinner, Button } from '@chakra-ui/react';
+
+import { Modal } from '@Components';
+
+const MODAL_TYPES = {
+ EDIT_MODAL: 'EDIT_MODAL',
+ DELETE_MODAL: 'DELETE_MODAL',
+};
+
+interface BaseHeader {
+ label: string;
+ field: string;
+}
+
+interface BaseListInterface {
+ headers: BaseHeader[];
+ items: T[];
+ isLoading: boolean;
+ optionsEnabled?: boolean;
+ onDeleteItem?: (id: string | number) => void;
+ onCloseOption?: () => void;
+ editComponent?: (id: string | number) => React.ReactElement;
+}
+
+const BaseList = ({
+ headers,
+ items,
+ isLoading,
+ optionsEnabled = false,
+ editComponent,
+ onCloseOption,
+ onDeleteItem,
+}: BaseListInterface) => {
+ const [modalType, setModalType] = useState(null);
+ const [id, setId] = useState();
+
+ useEffect(() => {
+ if (!modalType) {
+ onCloseOption();
+ }
+ }, [modalType]);
+
+ const handleOpenModalWithId = (id, type) => {
+ setId(id);
+ setModalType(type);
+ };
+
+ const tableItems = useMemo(() => {
+ const fields = headers.map(({ field }) => field);
+
+ return items.map((item: T, index) => (
+
+ {fields.map(field => {
+ if (!item[field]) return;
+ return | {item[field]} | ;
+ })}
+ {optionsEnabled && (
+
+
+
+ |
+ )}
+
+ ));
+ }, [headers, items, optionsEnabled]);
+
+ const modalContent = useMemo(() => {
+ switch (modalType) {
+ case MODAL_TYPES.DELETE_MODAL:
+ return (
+ <>
+ Are you sure about this action?
+
+
+ >
+ );
+
+ case MODAL_TYPES.EDIT_MODAL:
+ return <>{editComponent(id)}>;
+
+ default:
+ return <>>;
+ }
+ }, [editComponent, id, modalType]);
+
+ return (
+ <>
+ setModalType(null)}>
+ {modalContent}
+
+
+
+
+
+ {headers.map(({ label }) => (
+ | {label} |
+ ))}
+ {optionsEnabled && Options | }
+
+
+
+ <>
+ {isLoading && }
+ {!isLoading && tableItems}
+ >
+
+
+
+ >
+ );
+};
+
+export { BaseList };
+export default BaseList;
diff --git a/modules/BaseModule/interfaces/BaseField.ts b/modules/BaseModule/interfaces/BaseField.ts
new file mode 100644
index 0000000..a2cb787
--- /dev/null
+++ b/modules/BaseModule/interfaces/BaseField.ts
@@ -0,0 +1,11 @@
+import { BubbleEnum } from '@Modules/BaseModule/constants/Bubble';
+
+import SelectOption from './SelectOption';
+
+export default interface BaseField {
+ name: string;
+ type: BubbleEnum;
+ label: string;
+ options?: SelectOption[];
+ value?: (string | number | readonly string[]) & string;
+}
diff --git a/modules/BaseModule/interfaces/SelectOption.ts b/modules/BaseModule/interfaces/SelectOption.ts
new file mode 100644
index 0000000..3a585d5
--- /dev/null
+++ b/modules/BaseModule/interfaces/SelectOption.ts
@@ -0,0 +1,4 @@
+export default interface SelectOption {
+ label: string;
+ value: string | number;
+}
diff --git a/modules/BaseModule/shared/renderFields.tsx b/modules/BaseModule/shared/renderFields.tsx
new file mode 100644
index 0000000..88c29a2
--- /dev/null
+++ b/modules/BaseModule/shared/renderFields.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+
+import Bubble from '../components/Bubble';
+import BaseField from '../interfaces/BaseField';
+
+const renderFields = (fields: BaseField[], errors, register) =>
+ fields.map(({ name, type, label, options, value }) => (
+
+ ));
+
+export default renderFields;
diff --git a/package.json b/package.json
index 085d1c4..2769521 100644
--- a/package.json
+++ b/package.json
@@ -14,13 +14,15 @@
"@chakra-ui/react": "^1.6.6",
"@emotion/react": "^11",
"@emotion/styled": "^11",
+ "@hookform/resolvers": "^2.8.2",
"firebase": "^8.9.1",
"framer-motion": "^4",
"next": "^12.0.0",
"react": "^17.0.2",
"react-datepicker": "^4.2.1",
"react-dom": "17.0.2",
- "react-hook-form": "^7.12.2"
+ "react-hook-form": "^7.12.2",
+ "yup": "^0.32.10"
},
"devDependencies": {
"@babel/core": "^7.15.0",
diff --git a/yarn.lock b/yarn.lock
index 88d68b1..52c2118 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -209,6 +209,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.15.4":
+ version "7.15.4"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
+ integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
@@ -1189,6 +1196,11 @@
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131"
integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==
+"@hookform/resolvers@^2.8.2":
+ version "2.8.2"
+ resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.8.2.tgz#590dcc23212a659bad08212138261c3950ef09f1"
+ integrity sha512-oDTGrm7yHxT4VIv4kJcfjvWvozCbdcL0/jrpbAkeo39FYn78XnKOrrGTNmrXdfu+EQVkNIdZ47IYRFManZ4jUA==
+
"@humanwhocodes/config-array@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
@@ -1441,6 +1453,11 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.172.tgz#aad774c28e7bfd7a67de25408e03ee5a8c3d028a"
integrity sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==
+"@types/lodash@^4.14.175":
+ version "4.14.175"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.175.tgz#b78dfa959192b01fae0ad90e166478769b215f45"
+ integrity sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==
+
"@types/long@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
@@ -3444,6 +3461,11 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
+lodash-es@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
+ integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@@ -3473,7 +3495,10 @@ lodash.truncate@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
-
+lodash@^4.17.13, lodash@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
long@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
@@ -3572,10 +3597,15 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-nanoid@^3.1.23:
- version "3.1.30"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
- integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
+nanoclone@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4"
+ integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==
+
+nanoid@^3.1.22:
+ version "3.1.23"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
+ integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
native-url@0.3.4:
version "0.3.4"
@@ -4026,6 +4056,11 @@ prop-types@^15.6.2, prop-types@^15.7.2:
object-assign "^4.1.1"
react-is "^16.8.1"
+property-expr@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.4.tgz#37b925478e58965031bb612ec5b3260f8241e910"
+ integrity sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==
+
protobufjs@^6.10.0:
version "6.11.2"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b"
@@ -4714,6 +4749,11 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
+toposort@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330"
+ integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=
+
tr46@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
@@ -4995,3 +5035,16 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+yup@^0.32.10:
+ version "0.32.10"
+ resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.10.tgz#b8809bb9a5c4782672b86651cae41adef1decbb8"
+ integrity sha512-xRZnd0EEXz+zNQ3mIN5p5r9FbSeK811oKXT3SKU+yml0NiqEd5qj+Roy37kkMYVaOM6TTQs/D/sfWHS/JxXeTg==
+ dependencies:
+ "@babel/runtime" "^7.15.4"
+ "@types/lodash" "^4.14.175"
+ lodash "^4.17.21"
+ lodash-es "^4.17.21"
+ nanoclone "^0.2.1"
+ property-expr "^2.0.4"
+ toposort "^2.0.2"
From 58349dde6c919de52acb3e836558787e934c0e7b Mon Sep 17 00:00:00 2001
From: Victor Lucas <11355873+victorlucss@users.noreply.github.com>
Date: Thu, 11 Nov 2021 17:07:55 -0300
Subject: [PATCH 05/39] fix: start next with esm false (#9)
---
next.config.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/next.config.js b/next.config.js
index 0d60710..25617c2 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,3 +1,6 @@
module.exports = {
reactStrictMode: true,
+ experimental: {
+ esmExternals: false
+ }
}
From 4b3a151d727cbeeaad73aea91da5ee8eb34badcc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcos=20G=C3=AAnesis=20da=20Silva?=
Date: Thu, 23 Dec 2021 13:48:41 -0300
Subject: [PATCH 06/39] feat: sign in page with facelift
---
configs/theme.tsx | 12 +++-
.../container/FormLogin/index.tsx | 57 ++++++++++---------
pages/_app.tsx | 2 +-
pages/login.tsx | 2 +-
yarn.lock | 37 ++++--------
5 files changed, 53 insertions(+), 57 deletions(-)
diff --git a/configs/theme.tsx b/configs/theme.tsx
index 4a365e4..1b98928 100644
--- a/configs/theme.tsx
+++ b/configs/theme.tsx
@@ -5,6 +5,16 @@ const config: ThemeConfig = {
useSystemColorMode: false,
};
-const theme = extendTheme({ config });
+const theme = extendTheme({
+ config,
+ colors: { red: { 500: '#FF1033', 700: '#93002A' }, gray: { 100: '#f8f9fa' } },
+ styles: {
+ global: {
+ 'html, body': {
+ background: 'gray.100',
+ },
+ },
+ },
+});
export default theme;
diff --git a/modules/Authentication/container/FormLogin/index.tsx b/modules/Authentication/container/FormLogin/index.tsx
index ce5ed91..1dc80ee 100644
--- a/modules/Authentication/container/FormLogin/index.tsx
+++ b/modules/Authentication/container/FormLogin/index.tsx
@@ -1,6 +1,6 @@
import { useForm } from 'react-hook-form';
import { Button } from '@chakra-ui/button';
-import { Flex, Box, useToast } from '@chakra-ui/react';
+import { Flex, Box, useToast, Text } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { useEffect } from 'react';
@@ -42,7 +42,7 @@ const FormLogin = () => {
};
return (
-
+
diff --git a/pages/_app.tsx b/pages/_app.tsx
index e973145..5aedd1d 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -9,7 +9,7 @@ import './styles.css';
function MyApp({ Component, pageProps }: AppProps) {
return (
-
+
diff --git a/pages/login.tsx b/pages/login.tsx
index 7be72d8..3c36da6 100644
--- a/pages/login.tsx
+++ b/pages/login.tsx
@@ -8,7 +8,7 @@ export default function Home() {
const router = useRouter();
return (
-
+
);
diff --git a/yarn.lock b/yarn.lock
index 52c2118..c271d22 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -195,6 +195,7 @@
dependencies:
core-js-pure "^3.16.0"
regenerator-runtime "^0.13.4"
+
"@babel/runtime@7.15.4", "@babel/runtime@^7.15.4":
version "7.15.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
@@ -209,13 +210,6 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.15.4":
- version "7.15.4"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
- integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
- dependencies:
- regenerator-runtime "^0.13.4"
-
"@babel/template@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
@@ -1239,7 +1233,6 @@
version "12.0.0"
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-12.0.0.tgz#ddad018afa1ebc9fa79d3a3ef09103e1901a0983"
integrity sha512-sGDNFQFV6H+KAi6yQRIv4LtZ8Mg8zu1CwyVimwgYboai4eVIOg4rigZADV2xp4YEtwkgvQEijDh6J7rLCKPDXA==
-
dependencies:
"@babel/code-frame" "7.12.11"
anser "1.4.9"
@@ -1664,12 +1657,7 @@ ansi-colors@^4.1.1:
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
-ansi-regex@^5.0.0:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
- integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
-
-ansi-regex@^5.0.1:
+ansi-regex@^5.0.0, ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
@@ -3495,10 +3483,12 @@ lodash.truncate@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
-lodash@^4.17.13, lodash@^4.17.21:
+
+lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
long@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
@@ -3602,17 +3592,10 @@ nanoclone@^0.2.1:
resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4"
integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==
-nanoid@^3.1.22:
- version "3.1.23"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
- integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
-
-native-url@0.3.4:
- version "0.3.4"
- resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8"
- integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==
- dependencies:
- querystring "^0.2.0"
+nanoid@^3.1.23:
+ version "3.1.30"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
+ integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
natural-compare@^1.4.0:
version "1.4.0"
@@ -4158,7 +4141,7 @@ react-datepicker@^4.2.1:
react-onclickoutside "^6.10.0"
react-popper "^2.2.5"
-react-dom@^17.0.2:
+react-dom@17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
From f83b432be51e01475b85696da3e39b3edc22cf24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcos=20G=C3=AAnesis=20da=20Silva?=
Date: Thu, 23 Dec 2021 13:52:20 -0300
Subject: [PATCH 07/39] feat: facelift register page
---
modules/Authentication/container/FormSignUp/index.tsx | 8 ++++----
pages/signup.tsx | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/modules/Authentication/container/FormSignUp/index.tsx b/modules/Authentication/container/FormSignUp/index.tsx
index 8e47736..081fe1b 100644
--- a/modules/Authentication/container/FormSignUp/index.tsx
+++ b/modules/Authentication/container/FormSignUp/index.tsx
@@ -35,7 +35,7 @@ const FormSignUp = () => {
};
return (
-
+
diff --git a/pages/signup.tsx b/pages/signup.tsx
index ed9e21a..3bbf749 100644
--- a/pages/signup.tsx
+++ b/pages/signup.tsx
@@ -7,7 +7,7 @@ export default function Home() {
const router = useRouter();
return (
-
+
);
From 1306ac3ff3e37ce0462873b91c5a00f74259652d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcos=20G=C3=AAnesis=20da=20Silva?=
Date: Thu, 23 Dec 2021 13:54:56 -0300
Subject: [PATCH 08/39] feat: facelift forgot password page
---
.../container/FormForgotPassword/index.tsx | 10 +++++-----
pages/forgot.tsx | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/modules/Authentication/container/FormForgotPassword/index.tsx b/modules/Authentication/container/FormForgotPassword/index.tsx
index 28dcdeb..16cfa7e 100644
--- a/modules/Authentication/container/FormForgotPassword/index.tsx
+++ b/modules/Authentication/container/FormForgotPassword/index.tsx
@@ -36,7 +36,7 @@ const FormForgotPassword = () => {
};
return (
-
+
diff --git a/pages/forgot.tsx b/pages/forgot.tsx
index 43a21ba..08e2e5a 100644
--- a/pages/forgot.tsx
+++ b/pages/forgot.tsx
@@ -7,7 +7,7 @@ export default function Home() {
const router = useRouter();
return (
-
+
);
From b86bb4b5e7edb41027515d3a002d960166542fa3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcos=20G=C3=AAnesis=20da=20Silva?=
Date: Thu, 23 Dec 2021 15:32:40 -0300
Subject: [PATCH 09/39] fix: empty space linting
---
pages/signup.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pages/signup.tsx b/pages/signup.tsx
index 3bbf749..074b2ab 100644
--- a/pages/signup.tsx
+++ b/pages/signup.tsx
@@ -7,7 +7,7 @@ export default function Home() {
const router = useRouter();
return (
-
+
);
From 35aedd663fd9e0f41d8490847cb1ae70fb38b942 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Fri, 17 Nov 2023 22:14:19 -0500
Subject: [PATCH 10/39] feat: a LOT of new stuff
---
.DS_Store | Bin 6148 -> 12292 bytes
.vscode/settings.json | 3 +
components/Box/index.tsx | 21 +++
components/DatePicker/index.tsx | 5 +-
components/LateralMenu/index.tsx | 156 ++++++++++++++++++
components/MoneyInput/index.tsx | 5 +-
components/RadioCard/radio-card.component.tsx | 33 ++++
components/index.ts | 3 +
configs/Firebase.ts | 3 +
configs/theme.tsx | 8 -
hoc/withLateralMenu.tsx | 11 ++
.../container/FormLogin/index.tsx | 73 +++-----
.../Authentication/context/UserContext.tsx | 7 -
.../services/AuthenticationService.ts | 6 +-
modules/Bill/constants/Types.ts | 2 +
modules/Bill/container/FormBill/index.tsx | 63 +------
modules/Bill/container/ListBills/index.tsx | 15 +-
modules/Bill/interfaces/Bill.interface.ts | 4 +-
package.json | 1 +
pages/_app.tsx | 5 +
pages/bill/[billId].tsx | 7 +-
pages/bill/index.tsx | 5 +-
pages/index.tsx | 22 +--
pages/logout.tsx | 21 +++
public/favicon.ico | Bin 25931 -> 719 bytes
public/logo.png | Bin 0 -> 1218 bytes
public/vercel.svg | 4 -
yarn.lock | 5 +
28 files changed, 331 insertions(+), 157 deletions(-)
create mode 100644 .vscode/settings.json
create mode 100644 components/Box/index.tsx
create mode 100644 components/LateralMenu/index.tsx
create mode 100644 components/RadioCard/radio-card.component.tsx
create mode 100644 hoc/withLateralMenu.tsx
create mode 100644 pages/logout.tsx
create mode 100644 public/logo.png
delete mode 100644 public/vercel.svg
diff --git a/.DS_Store b/.DS_Store
index 9f24cd0e68f13a98a3a6a19d9ca8f92e31ebcccb..7b548ba6ffef463a1c53aacad40a894ba4edf7f3 100644
GIT binary patch
literal 12292
zcmeHNeQX>@6@Tyial2=aRT7Nm}BMb3>`yq;c%nNn7Xcc4Ke6
zw|l+aJLdyai;oD}O0+^P2vwC36vRKJpsFeopdg?^sA{34AqA=bz#lDtA|yUkC~s!=
z%+B5&QIP`3$d-pqTyd9(9ocL4y$%KA=#J^)ZCvRrGYp_o6jQBLpG@{;v^W&xaI6mXG-Ps>u1HgA(S#vwr5n
z^FU>C*?C*a&qw@xRpgwNcsMKNf))KM1`2j+Pcd@JNBn$MYdOOxH`NFJr8!xurF(#FaMXfvH7jdCJRr
zWp^xFI>Bm39mmR5%h}wFX)MocUE_}JWlh^CaRyU2h~)lbrmZ{6V@}!DUCuitIuun=
z=e5n}&+km9_Y9&Z9yP^q&RL5z_0i
zuu|5-&Z)dpC2q1*5|WUzHDVZW7M)3u{-M-XFOIq?m8uJoDFOZ8@Jz*zIES6#tzXz|^M50y>t
ztk$b2Vve5V4XXBS<$j%nyvNbmh&t~{_9V9{$_ds!UNR^Z&56Ebzp7=Gqb{i|h8Rrj
zP&HRQx<1zGxT38mIjSfR
zvS}x?u6L+t*j0ft$vYM8r^<16Fh)XyJC{9(^?3VS9(YK#gcGD)h<5%%(_$LsyUWgr_OnO3C
zZpD8>#1`vqmhQ|%;^6;uv%J~Pw#WL;Yr8gV>FpcbwP*iS2eSs`ErYu?3`OH
zU+1vBiG7slo+gtv&NSLiTAXb?PE48qI
zHZJ2?veb{0tzN*-;^*)Y`~p6SPvIBwOZXN1I({Q$gCCV`5MK)0V8O{`{8NfKet$jn
zsh^D2(&$&EDJ}*Nh7=7U+j?cHWLu8CK<#XQsBi=(U=%WN59LEp0G++-{^z@De4D6-
zrFYdX7*K)=doNBUS3Zi+C3*!yG$HM*7vK32)2O44L!zsdZfmYx&wNPEw
z0Iv^e&_dr9JmRpz_``l0H_+QadWoX0>;Vc{a*no2NN33kY?9a_dGoLolK9UdiJ87p
zh!BVnh!BVnh!FTsA+VbUZl+UdflfzHI@?>GX5Zb{`a&n;mHtn2k1NnGor^X7(y7>X
zlIhbz^V;NpoRMelSo!&Oxi>WT>089y0sev`&0dEhIDf}y4zu~=G=IhSD0DC+?E&`G
zQUvALa{anDE#Y;B#tF*Om?|ib|IReQeVYRP3Bf!ZgChAmvY$Y{C%{m^H>=AdYjV?8
z;;Bm))Q4ymeOw#RN(fKfEY_edt*qPQG&Ery^xMK(k;f@%6{42)X?m}AJXw>~UoKTw
zMw&IaG61VTd-;>xhC{Q-(x+&$HR(NJt@4^MZ?mrSKD8`;Y^HX+ko57tbpM#Gb5$;X
zoRIVlsATE6_t^xC%;yYA{YXe^pGuY%e@#?=PXj5}dL{d)O6T|1k*b6H?!onG;LY>@
ze}Xn2r+b$}Z&u26Z!ZkF;NLwK^zCX
zK6Z{Yqzxf@dO%?HFX)4|1XraGqP*|b6p2Ez6zRrA_bf^mNb3f+g=`lDacbdwj3e}n
zLb{|3P=FC)Pj8wx0>alO_DT*g4GMbANS)ej!p@e^qr<{L|
xr<}c&Wu5GN<$=m0tU&py$f-o(zy2eD^eHep|7E{{-7li^U!2M^G9R?_{~svy|0@6h
delta 207
zcmZokXfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~3gIoUvmMH0vd3o?SKe1<%RR3I*4
zDBgH+IWwcc8{hiIa6ETZ$V^
zW|q*Iyj{X-bD<;~<6?FW4nby+;Xre_frKl_-i;T(Gf(E%(bWM718rnzfY2Z&h|dI~
SK>)}AxfbLBhRyLjbC>~6? {
+ return (
+
+ {title && (
+
+ {title}
+
+ )}
+
+ {children}
+
+ );
+};
diff --git a/components/DatePicker/index.tsx b/components/DatePicker/index.tsx
index aa8e024..839c2e8 100644
--- a/components/DatePicker/index.tsx
+++ b/components/DatePicker/index.tsx
@@ -1,6 +1,6 @@
import React, { HTMLAttributes } from 'react';
-import { FormControl, FormLabel, FormErrorMessage, useColorMode } from '@chakra-ui/react';
import ReactDatePicker from 'react-datepicker';
+import { FormControl, FormLabel, FormErrorMessage, useColorMode } from '@chakra-ui/react';
interface Props {
isClearable?: boolean;
@@ -28,14 +28,13 @@ export const DatePicker = ({
return (
{label && {label}}
-
+
{error &&
{error}}
diff --git a/components/LateralMenu/index.tsx b/components/LateralMenu/index.tsx
new file mode 100644
index 0000000..d28d332
--- /dev/null
+++ b/components/LateralMenu/index.tsx
@@ -0,0 +1,156 @@
+import React, { ReactNode, ReactText } from 'react';
+import {
+ IconButton,
+ Box,
+ CloseButton,
+ Flex,
+ Icon,
+ useColorModeValue,
+ Button,
+ Link,
+ Drawer,
+ DrawerContent,
+ Text,
+ useDisclosure,
+ BoxProps,
+ FlexProps,
+} from '@chakra-ui/react';
+import { FiHome, FiPower, FiTrendingUp, FiMenu } from 'react-icons/fi';
+import { IconType } from 'react-icons';
+import Image from 'next/image';
+
+import { auth } from '@Configs/Firebase';
+
+interface LinkItemProps {
+ name: string;
+ icon: IconType;
+ link: string;
+}
+const LinkItems: Array
= [
+ { name: 'Home', icon: FiHome, link: '/' },
+ { name: 'Create bill', icon: FiTrendingUp, link: '/bill' },
+ {
+ name: 'Logout',
+ icon: FiPower,
+ link: '/logout',
+ },
+];
+
+export const LateralMenu = ({ children }: { children: ReactNode }) => {
+ const { isOpen, onOpen, onClose } = useDisclosure();
+ return (
+
+ onClose} display={{ base: 'none', md: 'block' }} />
+
+
+
+
+
+ {/* mobilenav */}
+
+
+ {children}
+
+
+ );
+};
+
+interface SidebarProps extends BoxProps {
+ onClose: () => void;
+}
+
+const SidebarContent = ({ onClose, ...rest }: SidebarProps) => {
+ return (
+
+
+
+
+
+ {LinkItems.map(({ name, icon, link }) => (
+
+ {name}
+
+ ))}
+
+ );
+};
+
+interface NavItemProps extends FlexProps {
+ icon: IconType;
+ children: ReactText;
+ link: string;
+}
+const NavItem = ({ icon, link, children, ...rest }: NavItemProps) => {
+ return (
+
+
+ {icon && (
+
+ )}
+ {children}
+
+
+ );
+};
+
+interface MobileProps extends FlexProps {
+ onOpen: () => void;
+}
+const MobileNav = ({ onOpen, ...rest }: MobileProps) => {
+ return (
+
+ } />
+
+
+
+
+
+
+
+ );
+};
diff --git a/components/MoneyInput/index.tsx b/components/MoneyInput/index.tsx
index cf40d71..9b3a736 100644
--- a/components/MoneyInput/index.tsx
+++ b/components/MoneyInput/index.tsx
@@ -2,7 +2,6 @@ import {
FormControl,
FormLabel,
FormErrorMessage,
- NumberInputProps,
NumberInput,
NumberInputField,
NumberInputStepper,
@@ -24,8 +23,8 @@ export const MoneyInput = forwardRef(
{label && {label}}
- }>
-
+
+ } />
diff --git a/components/RadioCard/radio-card.component.tsx b/components/RadioCard/radio-card.component.tsx
new file mode 100644
index 0000000..685652a
--- /dev/null
+++ b/components/RadioCard/radio-card.component.tsx
@@ -0,0 +1,33 @@
+import { Box, useRadio } from '@chakra-ui/react';
+
+export const RadioCard = props => {
+ const { getInputProps, getCheckboxProps } = useRadio(props);
+
+ const input = getInputProps();
+ const checkbox = getCheckboxProps();
+
+ return (
+
+
+
+ {props.children}
+
+
+ );
+};
diff --git a/components/index.ts b/components/index.ts
index 9a1f7f4..971e167 100644
--- a/components/index.ts
+++ b/components/index.ts
@@ -3,3 +3,6 @@ export * from './Input';
export * from './Select';
export * from './DatePicker';
export * from './Modal';
+export * from './LateralMenu';
+export * from './Box';
+export * from './RadioCard/radio-card.component';
diff --git a/configs/Firebase.ts b/configs/Firebase.ts
index 9829e38..8c5d3a9 100644
--- a/configs/Firebase.ts
+++ b/configs/Firebase.ts
@@ -16,6 +16,9 @@ if (!firebase.apps.length) {
} else {
firebase.app();
}
+
export default firebase;
export const firestore = firebase.firestore();
export const auth = firebase.auth();
+
+export const googleProvider = new firebase.auth.GoogleAuthProvider();
diff --git a/configs/theme.tsx b/configs/theme.tsx
index 1b98928..3a4bc4a 100644
--- a/configs/theme.tsx
+++ b/configs/theme.tsx
@@ -7,14 +7,6 @@ const config: ThemeConfig = {
const theme = extendTheme({
config,
- colors: { red: { 500: '#FF1033', 700: '#93002A' }, gray: { 100: '#f8f9fa' } },
- styles: {
- global: {
- 'html, body': {
- background: 'gray.100',
- },
- },
- },
});
export default theme;
diff --git a/hoc/withLateralMenu.tsx b/hoc/withLateralMenu.tsx
new file mode 100644
index 0000000..7bdc016
--- /dev/null
+++ b/hoc/withLateralMenu.tsx
@@ -0,0 +1,11 @@
+import { LateralMenu } from '@Components/LateralMenu';
+
+const withLateralMenu = Children => {
+ return props => (
+
+
+
+ );
+};
+
+export default withLateralMenu;
diff --git a/modules/Authentication/container/FormLogin/index.tsx b/modules/Authentication/container/FormLogin/index.tsx
index 1dc80ee..f35bdc3 100644
--- a/modules/Authentication/container/FormLogin/index.tsx
+++ b/modules/Authentication/container/FormLogin/index.tsx
@@ -1,9 +1,10 @@
import { useForm } from 'react-hook-form';
-import { Button } from '@chakra-ui/button';
+import { Button, IconButton } from '@chakra-ui/button';
import { Flex, Box, useToast, Text } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { useEffect } from 'react';
+import { FcGoogle } from 'react-icons/fc';
import AuthenticationService from '@Authentication/services/AuthenticationService';
import User from '@Authentication/interfaces/User.interface';
@@ -24,7 +25,7 @@ const FormLogin = () => {
if (userId) {
Router.replace('/');
}
- }, [userId]);
+ }, [Router, userId]);
const onSubmit = async values => {
try {
@@ -41,51 +42,31 @@ const FormLogin = () => {
}
};
- return (
-
-
+ return (
+
+
);
};
diff --git a/modules/Authentication/context/UserContext.tsx b/modules/Authentication/context/UserContext.tsx
index 77f2142..df6a3a6 100644
--- a/modules/Authentication/context/UserContext.tsx
+++ b/modules/Authentication/context/UserContext.tsx
@@ -15,11 +15,6 @@ interface UserProviderProps {
children: React.ReactNode;
}
-const formatAuthUser = user => ({
- uid: user.uid,
- email: user.email,
-});
-
export const UserProvider = ({ children }: UserProviderProps) => {
const [userId, setUserId] = useState(null);
const [user, setUser] = useState(null);
@@ -31,9 +26,7 @@ export const UserProvider = ({ children }: UserProviderProps) => {
return;
}
- // var formattedUser = formatAuthUser(authState);
setUserId(authState.uid);
- // setUser(formatAuthUser);
};
useEffect(() => {
diff --git a/modules/Authentication/services/AuthenticationService.ts b/modules/Authentication/services/AuthenticationService.ts
index 9de8d30..e325074 100644
--- a/modules/Authentication/services/AuthenticationService.ts
+++ b/modules/Authentication/services/AuthenticationService.ts
@@ -1,4 +1,4 @@
-import { auth } from '@Configs/Firebase';
+import { auth, googleProvider } from '@Configs/Firebase';
import User from '../interfaces/User.interface';
@@ -26,4 +26,8 @@ export default class AuthenticationService {
static forgotPassword(email: string): Promise {
return auth.sendPasswordResetEmail(email).then(_ => true);
}
+
+ static signInWithGoogle() {
+ return auth.signInWithPopup(googleProvider);
+ }
}
diff --git a/modules/Bill/constants/Types.ts b/modules/Bill/constants/Types.ts
index 88b4641..b6abd8a 100644
--- a/modules/Bill/constants/Types.ts
+++ b/modules/Bill/constants/Types.ts
@@ -1,6 +1,8 @@
export const BillTypes = {
EXPENSE: 'EXPENSE',
INCOME: 'INCOME',
+ REPEATED_INCOME: 'REPEATED_INCOME',
+ REPEATED_EXPENSE: 'REPEATED_EXPENSE',
};
export const BillStatus = {
diff --git a/modules/Bill/container/FormBill/index.tsx b/modules/Bill/container/FormBill/index.tsx
index 86416b1..ef511d7 100644
--- a/modules/Bill/container/FormBill/index.tsx
+++ b/modules/Bill/container/FormBill/index.tsx
@@ -2,29 +2,14 @@ import { useMemo, useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import { useForm, Controller } from 'react-hook-form';
import { Button } from '@chakra-ui/button';
-import { useToast, Flex, Spacer, Box } from '@chakra-ui/react';
+import { useToast, Flex } from '@chakra-ui/react';
import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
-import { Input, MoneyInput, Select, DatePicker } from '@Components';
+import { Input, MoneyInput, Select, DatePicker, Box } from '@Components';
import { useUser } from '@Modules/Authentication/context/UserContext';
-const MONTHS_DICT = {
- 0: 'Janeiro',
- 1: 'Fevereiro',
- 2: 'Março',
- 3: 'Abril',
- 4: 'Maio',
- 5: 'Junho',
- 6: 'Julho',
- 7: 'Agosto',
- 8: 'Setembro',
- 9: 'Outubro',
- 10: 'Novembro',
- 11: 'Dezembro',
-};
-
interface FormBillProps {
billId?: string;
}
@@ -50,14 +35,13 @@ const FormBill = ({ billId }: FormBillProps) => {
const dueDate = new Date(values.dueDate);
dueDate.setHours(3, 0, 0, 0);
+ console.log(values);
const bill: Bill = {
name: values.name,
description: values.description ?? '',
value: Number(values.value),
dueDate: dueDate.getTime(),
- year: +values.year,
status: billId ? foundBill?.status : BillStatus.PENDING,
- month: +values.month,
type: values.type,
createdAt: new Date().getTime(),
userId,
@@ -99,13 +83,13 @@ const FormBill = ({ billId }: FormBillProps) => {
}, [billId, toast]);
useEffect(() => {
+ console.log(foundBill);
setValue('name', foundBill?.name);
+ setValue('description', foundBill?.description);
setValue('dueDate', foundBill?.dueDate);
- setValue('year', foundBill?.year);
- setValue('month', foundBill?.month);
setValue('type', foundBill?.type);
- setValue('value', foundBill?.value);
- }, [foundBill]);
+ setValue('value', String(foundBill?.value));
+ }, [foundBill, setValue]);
const years = useMemo(() => {
const finalYears = [];
@@ -121,19 +105,6 @@ const FormBill = ({ billId }: FormBillProps) => {
return finalYears;
}, []);
- const months = useMemo(() => {
- const finalMonths = [];
-
- for (let monthCount = 0; monthCount <= 11; monthCount++) {
- finalMonths.push({
- label: `${MONTHS_DICT[monthCount]}`,
- value: monthCount,
- });
- }
-
- return finalMonths;
- }, []);
-
const types = [
{
label: 'Expense',
@@ -146,7 +117,7 @@ const FormBill = ({ billId }: FormBillProps) => {
];
return (
-
+
);
-}
+};
+
+export default withLateralMenu(EditBillPage);
diff --git a/pages/bill/index.tsx b/pages/bill/index.tsx
index 3811379..0377a66 100644
--- a/pages/bill/index.tsx
+++ b/pages/bill/index.tsx
@@ -1,9 +1,10 @@
import FormBill from '@Modules/Bill/container/FormBill';
+import { LateralMenu } from '@Components';
export default function NewBillPage() {
return (
-
+
-
+
);
}
diff --git a/pages/index.tsx b/pages/index.tsx
index b8f9a6c..611a2d4 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,26 +1,12 @@
-import { useRouter } from 'next/router';
-import { Button } from '@chakra-ui/button';
-import { Box } from '@chakra-ui/react';
-
import withAuth from '@/hoc/withAuth';
-import { auth } from '@Configs/Firebase';
-
-import ListBills from '../modules/Bill/container/ListBills';
+import { LateralMenu } from '@Components/LateralMenu';
+import ListBills from '@Modules/Bill/container/ListBills';
const Dashboard = () => {
- const router = useRouter();
-
return (
-
-
-
-
+
-
+
);
};
diff --git a/pages/logout.tsx b/pages/logout.tsx
new file mode 100644
index 0000000..845d32e
--- /dev/null
+++ b/pages/logout.tsx
@@ -0,0 +1,21 @@
+import { useEffect } from 'react';
+import { useRouter } from 'next/router';
+import { Box } from '@chakra-ui/react';
+
+import FormSignUp from '@Modules/Authentication/container/FormSignUp';
+import { auth } from '@Configs/Firebase';
+
+export default function Home() {
+ const router = useRouter();
+
+ useEffect(() => {
+ auth.signOut();
+ router.push('/');
+ }, [router]);
+
+ return (
+
+ Loading...
+
+ );
+}
diff --git a/public/favicon.ico b/public/favicon.ico
index 718d6fea4835ec2d246af9800eddb7ffb276240c..c678ea8ebfa6f2ce22dd908a6ba1ac060fa25ed8 100644
GIT binary patch
literal 719
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
LrJugUA?W`A8`#=m
diff --git a/public/logo.png b/public/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..51063fbfc2e9ae3efcde6692d381d26e1de194ea
GIT binary patch
literal 1218
zcmV;z1U>tSP)9DUpa0Audv?O$FIamgN%wrjJ7ng)JHg4fG(}3e=EK5Pt(U>2XM%6ho}F
zah0XO5}ktyU>Wu>&x%2gameM|-gkWdlI8Wc{L|6qxSgim#^W_zsn!AWL^c?RPP}N_l!2|DQZC;HGJ(T
zDnTAMbj>L0K%R8iT2WMiJnfJ*qNo9R*5PVHQ32vRR81)2K|&2v3yNrv&_mRKA{Hdp
z@T8-N1c^N~$tdDLQVmNgiYSoOLz0Lh1|-*Tq@joa$vqTFDA_@z3`5E~vVusvxsb4)
zY#>q}<>X#h77*!A&T_6VIf$0mlya>zDTub0!gH)Q8Hm<*@KUck35fPTJV?3z=pfoL
zno?~?RFJk{G^N;{XdrFFXo|gEQ9#;?(G+w0f`hajqbb&Q1_e1P7)>#@HyFrK!)OY<
z-9bQ(Dn?Vt?e{)DB*bENR#)qf?~tn(-hU6rUwaikaSqJ)_!MuD2e)r~gPfe5#m=`k
zvm9*m;^hy$G1%VL7Jj>P2fodG{PHVH@M!mk&FNw|RG&`1GmE{Swy?XoiBu8erOO||
zH*Wur3m;6^@0&LW(}*Gwg9QO$noy)-uwWoe1Bzq}78Ha@Mv;!ef`c%LC>k(W6c8o}
zMGFRt2ErtuXu@DoL0C={Z5S*%2+M(@5rZWGVJT6xVz6W&ECq^Y43-px#YEAL!IFcp
z7$|MPU}nA7cgWPKOBZqGi!1Q$*VUVNe)etnmK%d*1!193e3O8|vL8Wpe|Q61pM8#;
zNx@(ujxo%MA_;?uISMxiiZl!+>Nxe3C=xN4xHCDVK#_{UM4sy;CW>SXCiZMVF;Jvq
zFwy7B3W=ftgNZ+*TnH2`7)-@E7kyAPVK5aS>{(E>VK6ly>}gOmVlY)8>`73xVlZ_e
z?Eg?SV=$E<>@XDV7)&h)+mF%)45t1+>=0%0%MSji-^SIB!Lq+&Sb8|sH(710fC#IA
z2&;eytAGfrfC!5qW0a&cw$7LeB@sD?@2zp}7D^(r#t!Z7F}qS<-bN{NW_)f`t=KoJ
zY8%!rpp-QOv&_%aM_JvqYB({tic*&9`;KMq9lUJze`9pMzhoR1QA(G?)$aP;Pns{y
z!S8SM2J;TCMsXdK;$_S>{xS>QjcWMN)sOo5DU5M*^=tE;`jOZGr2v_6J@E?8+&b|9
gD`&^me;!Qz4O1={hOD~nwg3PC07*qoM6N<$f{e%^WB>pF
literal 0
HcmV?d00001
diff --git a/public/vercel.svg b/public/vercel.svg
deleted file mode 100644
index fbf0e25..0000000
--- a/public/vercel.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index c271d22..5fe81f9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4172,6 +4172,11 @@ react-hook-form@^7.12.2:
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.12.2.tgz#2660afbf03c4ef360a9314ebf46ce3d972296c77"
integrity sha512-cpxocjrgpMAJCMJQR51BQhMoEx80/EQqePNihMTgoTYTqCRbd2GExi+N4GJIr+cFqrmbwNj9wxk5oLWYQsUefg==
+react-icons@^4.12.0:
+ version "4.12.0"
+ resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.12.0.tgz#54806159a966961bfd5cdb26e492f4dafd6a8d78"
+ integrity sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==
+
react-is@17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
From 356a9ca8bd25c622dfaaa696bd6e969e6fb28714 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Fri, 17 Nov 2023 22:18:12 -0500
Subject: [PATCH 11/39] fix: specify node version
---
package.json | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 8d96f2d..c20bd27 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,9 @@
"start": "next start",
"lint": "eslint \"**/*.{ts,tsx}\""
},
+ "engines": {
+ "node": ">=16"
+ },
"dependencies": {
"@chakra-ui/button": "^1.4.2",
"@chakra-ui/icons": "^1.0.15",
@@ -39,4 +42,4 @@
"prettier": "^2.3.2",
"typescript": "^4.3.5"
}
-}
+}
\ No newline at end of file
From cd0eb4d8524ba508db63a75413bf45435e53ae09 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Fri, 17 Nov 2023 22:21:36 -0500
Subject: [PATCH 12/39] fix: node version
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index c20bd27..cde7259 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"lint": "eslint \"**/*.{ts,tsx}\""
},
"engines": {
- "node": ">=16"
+ "node": ">=16 <17"
},
"dependencies": {
"@chakra-ui/button": "^1.4.2",
From 210c8bfb50cb0b9732ae6e9cfdc106f5330643df Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sat, 18 Nov 2023 08:12:04 -0500
Subject: [PATCH 13/39] fix: datepicker, stats, and more
---
.gitignore | 2 +-
components/Box/index.tsx | 22 ++++++--
.../{index.tsx => date-picker.component.tsx} | 0
components/LateralMenu/index.tsx | 17 ++++--
components/index.ts | 2 +-
.../container/FormLogin/index.tsx | 1 +
modules/Bill/components/StateMonth/index.tsx | 56 -------------------
.../StatsMonth/stats-month.component.tsx | 48 ++++++++++++++++
modules/Bill/container/FormBill/index.tsx | 23 +++++---
.../{index.tsx => list-bills.container.tsx} | 23 ++++++--
package.json | 6 +-
pages/_app.tsx | 2 +-
pages/index.tsx | 4 +-
pages/{styles.css => styles.scss} | 49 +++++++++-------
yarn.lock | 56 ++++++++++++++++++-
15 files changed, 201 insertions(+), 110 deletions(-)
rename components/DatePicker/{index.tsx => date-picker.component.tsx} (100%)
delete mode 100644 modules/Bill/components/StateMonth/index.tsx
create mode 100644 modules/Bill/components/StatsMonth/stats-month.component.tsx
rename modules/Bill/container/ListBills/{index.tsx => list-bills.container.tsx} (70%)
rename pages/{styles.css => styles.scss} (83%)
diff --git a/.gitignore b/.gitignore
index 74b7586..cb034b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,4 +32,4 @@ yarn-error.log*
.env.production.local
# vercel
-.vercel
+.vercel
\ No newline at end of file
diff --git a/components/Box/index.tsx b/components/Box/index.tsx
index d3c8ae5..bf905a2 100644
--- a/components/Box/index.tsx
+++ b/components/Box/index.tsx
@@ -1,18 +1,28 @@
-import { Box as ChakraBox, BoxProps as ChakraBoxProps, Text } from '@chakra-ui/react';
+import { Box as ChakraBox, BoxProps as ChakraBoxProps, Text, Flex } from '@chakra-ui/react';
import { ReactNode } from 'react';
type BoxProps = {
title?: string;
+ description?: string;
children: ReactNode;
} & ChakraBoxProps;
-export const Box = ({ title, children, ...rest }: BoxProps) => {
+export const Box = ({ title, description, children, ...rest }: BoxProps) => {
return (
- {title && (
-
- {title}
-
+ {(title || description) && (
+
+ {title && (
+
+ {title}
+
+ )}
+ {description && (
+
+ {description}
+
+ )}
+
)}
{children}
diff --git a/components/DatePicker/index.tsx b/components/DatePicker/date-picker.component.tsx
similarity index 100%
rename from components/DatePicker/index.tsx
rename to components/DatePicker/date-picker.component.tsx
diff --git a/components/LateralMenu/index.tsx b/components/LateralMenu/index.tsx
index d28d332..9d15e91 100644
--- a/components/LateralMenu/index.tsx
+++ b/components/LateralMenu/index.tsx
@@ -14,6 +14,7 @@ import {
useDisclosure,
BoxProps,
FlexProps,
+ Badge,
} from '@chakra-ui/react';
import { FiHome, FiPower, FiTrendingUp, FiMenu } from 'react-icons/fi';
import { IconType } from 'react-icons';
@@ -80,6 +81,11 @@ const SidebarContent = ({ onClose, ...rest }: SidebarProps) => {
>
+
+
+ Beta
+
+
{LinkItems.map(({ name, icon, link }) => (
@@ -146,10 +152,13 @@ const MobileNav = ({ onOpen, ...rest }: MobileProps) => {
>
} />
-
-
-
-
+
+
+
+
+ Beta
+
+
);
diff --git a/components/index.ts b/components/index.ts
index 971e167..51d33a2 100644
--- a/components/index.ts
+++ b/components/index.ts
@@ -1,7 +1,7 @@
export * from './MoneyInput';
export * from './Input';
export * from './Select';
-export * from './DatePicker';
+export * from './DatePicker/date-picker.component';
export * from './Modal';
export * from './LateralMenu';
export * from './Box';
diff --git a/modules/Authentication/container/FormLogin/index.tsx b/modules/Authentication/container/FormLogin/index.tsx
index f35bdc3..7ecd071 100644
--- a/modules/Authentication/container/FormLogin/index.tsx
+++ b/modules/Authentication/container/FormLogin/index.tsx
@@ -61,6 +61,7 @@ const FormLogin = () => {
return (
+ Desbrave o caminho para a estabilidade financeira. Faça login e conquiste o controle total das suas finanças!
}
onClick={() => router.push(`/bill/${bill.id}`)}
variant="outline"
@@ -145,7 +193,7 @@ export default function BillItem({ bill }: BillItemProps) {
/>
deleteBill()}
@@ -158,4 +206,4 @@ export default function BillItem({ bill }: BillItemProps) {
);
-}
+};
diff --git a/modules/Bill/components/StatsMonth/stats-month.component.tsx b/modules/Bill/components/StatsMonth/stats-month.component.tsx
index be37134..b3c9d7a 100644
--- a/modules/Bill/components/StatsMonth/stats-month.component.tsx
+++ b/modules/Bill/components/StatsMonth/stats-month.component.tsx
@@ -18,27 +18,27 @@ export const StatsMonth = ({ income, expense, balance }: StateMonthProps) => {
return (
-
+
- Income
+ Receita
{formatValue(income)}
-
+
- Expense
+ Despesas
{formatValue(expense)}
-
+
- Balance
+ Restante
{formatValue(balance)}
diff --git a/modules/Bill/container/FormBill/index.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
similarity index 86%
rename from modules/Bill/container/FormBill/index.tsx
rename to modules/Bill/container/FormBill/form-bill.container.tsx
index 4ab86f1..befe80c 100644
--- a/modules/Bill/container/FormBill/index.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -14,7 +14,7 @@ interface FormBillProps {
billId?: string;
}
-const FormBill = ({ billId }: FormBillProps) => {
+export const FormBillContainer = ({ billId }: FormBillProps) => {
const {
handleSubmit,
register,
@@ -35,7 +35,6 @@ const FormBill = ({ billId }: FormBillProps) => {
const dueDate = new Date(values.dueDate);
dueDate.setHours(3, 0, 0, 0);
- console.log(values);
const bill: Bill = {
name: values.name,
description: values.description ?? '',
@@ -54,7 +53,7 @@ const FormBill = ({ billId }: FormBillProps) => {
await billsCollection.add(bill);
}
toast({
- description: 'Bill successful submited!',
+ description: 'Conta criada com sucesso!',
status: 'success',
});
@@ -72,18 +71,18 @@ const FormBill = ({ billId }: FormBillProps) => {
if (billDoc.exists) {
setFoundBill({ id: billDoc.id, ...billDoc.data() } as Bill);
} else {
+ router.push('/');
toast({
- description: 'Bill not found!',
+ description: 'Conta não encontrada!',
status: 'error',
});
}
};
findBill();
- }, [billId, toast]);
+ }, [billId, router, toast]);
useEffect(() => {
- console.log(foundBill);
setValue('name', foundBill?.name);
setValue('description', foundBill?.description);
setValue('dueDate', foundBill?.dueDate);
@@ -91,20 +90,6 @@ const FormBill = ({ billId }: FormBillProps) => {
setValue('value', String(foundBill?.value));
}, [foundBill, setValue]);
- const years = useMemo(() => {
- const finalYears = [];
- const beginYear = 2020;
-
- for (let yearCount = 0; yearCount < 5; yearCount++) {
- finalYears.push({
- value: beginYear + yearCount,
- label: `${beginYear + yearCount}`,
- });
- }
-
- return finalYears;
- }, []);
-
const types = [
{
label: 'Despesa',
@@ -119,7 +104,7 @@ const FormBill = ({ billId }: FormBillProps) => {
return (
{
label="Data de vencimento"
onChange={date => field.onChange(date)}
selected={field.value}
+ defaultValue={new Date().getTime()}
style={{ marginBottom: '10px' }}
/>
)}
@@ -175,12 +161,10 @@ const FormBill = ({ billId }: FormBillProps) => {
/>
);
};
-
-export default FormBill;
diff --git a/modules/Bill/container/ListBills/list-bills.container.tsx b/modules/Bill/container/ListBills/list-bills.container.tsx
index 44912ce..fdf4779 100644
--- a/modules/Bill/container/ListBills/list-bills.container.tsx
+++ b/modules/Bill/container/ListBills/list-bills.container.tsx
@@ -3,7 +3,7 @@ import { useToast } from '@chakra-ui/react';
import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
-import BillItem from '@Modules/Bill/components/BillItem';
+import { BillItem } from '@Modules/Bill/components/BillItem/bill-item.component';
import BillFilters from '@Modules/Bill/components/BillFilters';
import { StatsMonth } from '@Modules/Bill/components/StatsMonth/stats-month.component';
import { useUser } from '@Modules/Authentication/context/UserContext';
diff --git a/pages/bill/[billId].tsx b/pages/bill/[billId].tsx
index eff4b1d..1390395 100644
--- a/pages/bill/[billId].tsx
+++ b/pages/bill/[billId].tsx
@@ -1,6 +1,6 @@
import { useRouter } from 'next/router';
-import FormBill from '@Modules/Bill/container/FormBill';
+import { FormBillContainer } from '@Modules/Bill/container/FormBill/form-bill.container';
import withLateralMenu from '@/hoc/withLateralMenu';
const EditBillPage = () => {
@@ -8,7 +8,7 @@ const EditBillPage = () => {
const billId: string = String(router.query.billId);
return (
-
+
);
};
diff --git a/pages/bill/index.tsx b/pages/bill/index.tsx
index 0377a66..74e90d4 100644
--- a/pages/bill/index.tsx
+++ b/pages/bill/index.tsx
@@ -1,10 +1,10 @@
-import FormBill from '@Modules/Bill/container/FormBill';
+import { FormBillContainer } from '@Modules/Bill/container/FormBill/form-bill.container';
import { LateralMenu } from '@Components';
export default function NewBillPage() {
return (
-
+
);
}
From fa5d29e9b9c542533e19b1e4ca0c7c7c0436189f Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sat, 18 Nov 2023 12:17:19 -0500
Subject: [PATCH 18/39] feat: use popover to improve visibility
---
components/If/if.component.tsx | 6 +
components/index.ts | 1 +
.../BillItem/bill-item.component.tsx | 182 +++++++++++++-----
3 files changed, 136 insertions(+), 53 deletions(-)
create mode 100644 components/If/if.component.tsx
diff --git a/components/If/if.component.tsx b/components/If/if.component.tsx
new file mode 100644
index 0000000..1e461c8
--- /dev/null
+++ b/components/If/if.component.tsx
@@ -0,0 +1,6 @@
+import { ReactElement, ReactNode } from 'react';
+
+export const If = ({ condition, children }: { condition: boolean; children: ReactElement }) => {
+ if (condition) return children;
+ return null;
+};
diff --git a/components/index.ts b/components/index.ts
index 51d33a2..16b44ae 100644
--- a/components/index.ts
+++ b/components/index.ts
@@ -6,3 +6,4 @@ export * from './Modal';
export * from './LateralMenu';
export * from './Box';
export * from './RadioCard/radio-card.component';
+export * from './If/if.component';
diff --git a/modules/Bill/components/BillItem/bill-item.component.tsx b/modules/Bill/components/BillItem/bill-item.component.tsx
index 1ac19a6..989db2c 100644
--- a/modules/Bill/components/BillItem/bill-item.component.tsx
+++ b/modules/Bill/components/BillItem/bill-item.component.tsx
@@ -1,11 +1,30 @@
import React, { useState, useMemo } from 'react';
import { useRouter } from 'next/router';
-import { Button, IconButton, Box, Text, Tag, Flex, Stack, Center } from '@chakra-ui/react';
+import {
+ Button,
+ IconButton,
+ Box,
+ Text,
+ Center,
+ Popover,
+ PopoverTrigger,
+ PopoverContent,
+ PopoverBody,
+ PopoverArrow,
+ Stack,
+ Tag,
+ Flex,
+ Badge,
+} from '@chakra-ui/react';
import { EditIcon, DeleteIcon, ArrowUpIcon, ArrowDownIcon, InfoIcon, WarningTwoIcon } from '@chakra-ui/icons';
+import { BsThreeDotsVertical } from 'react-icons/bs';
+import { MdOutlineMoneyOffCsred, MdOutlineAttachMoney } from 'react-icons/md';
+import { IoMdCalendar } from 'react-icons/io';
import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { If } from '@Components';
interface BillItemProps {
bill: Bill;
@@ -125,6 +144,29 @@ export const BillItem = ({ bill }: BillItemProps) => {
return '';
}, [isExpiring, isPassDueDate]);
+ const billStatus = useMemo(() => {
+ const props = {
+ color: 'yellow',
+ text: 'Pendente',
+ };
+
+ if (bill.status === BillStatus.NOT_PAID) {
+ props.color = 'red';
+ props.text = 'Não pago';
+ }
+
+ if (bill.status === BillStatus.PAID) {
+ props.color = 'green';
+ props.text = 'Pago';
+ }
+
+ return (
+
+ {props.text}
+
+ );
+ }, [bill.status]);
+
return (
{billSituation}
@@ -133,7 +175,7 @@ export const BillItem = ({ bill }: BillItemProps) => {
- {bill.name}
+ {bill.name} {billStatus}
Vencimento {formatDate(bill.dueDate)}
@@ -150,58 +192,92 @@ export const BillItem = ({ bill }: BillItemProps) => {
-
-
-
-
-
-
-
+
+
+ }
+ variant="outline"
+ size="sm"
+ w="fit-content"
+ />
+
+
+
+
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.NOT_PAID)}
+ isLoading={loadings?.changingStatus === BillStatus.NOT_PAID}
+ >
+ Marcar como não pago
+
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.PAID)}
+ isLoading={loadings?.changingStatus === BillStatus.PAID}
+ >
+ Marcar como pago
+
+
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.PENDING)}
+ isLoading={loadings?.changingStatus === BillStatus.PENDING}
+ >
+ Marcar como pendente
+
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => router.replace(`/bill/${bill.id}`)}
+ >
+ Editar conta
+
- }
- onClick={() => router.push(`/bill/${bill.id}`)}
- variant="outline"
- size="sm"
- />
-
- deleteBill()}
- icon={}
- variant="outline"
- marginLeft="10px"
- size="sm"
- />
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ colorScheme="red"
+ fontSize="sm"
+ onClick={() => deleteBill()}
+ >
+ Deletar conta
+
+
+
+
+
From 988380f5a854d016cad59d0d15d094c77b28c7eb Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sat, 18 Nov 2023 13:36:01 -0500
Subject: [PATCH 19/39] feat: new way of handling status and categories
---
components/RadioCard/radio-card.component.tsx | 5 +-
.../BillItem/bill-item.component.tsx | 147 ++++++++++--------
.../StatsMonth/stats-month.component.tsx | 33 ++--
.../FormBill/form-bill.container.tsx | 37 ++++-
.../ListBills/list-bills.container.tsx | 19 ++-
modules/Bill/interfaces/Bill.interface.ts | 1 +
6 files changed, 155 insertions(+), 87 deletions(-)
diff --git a/components/RadioCard/radio-card.component.tsx b/components/RadioCard/radio-card.component.tsx
index 685652a..7c9f6c4 100644
--- a/components/RadioCard/radio-card.component.tsx
+++ b/components/RadioCard/radio-card.component.tsx
@@ -16,9 +16,10 @@ export const RadioCard = props => {
borderRadius="md"
boxShadow="md"
_checked={{
- bg: 'teal.600',
+ bg: 'gray.600',
color: 'white',
- borderColor: 'teal.600',
+ borderColor: 'gray.600',
+ transition: 'all var(--chakra-transition-duration-normal)',
}}
_focus={{
boxShadow: 'outline',
diff --git a/modules/Bill/components/BillItem/bill-item.component.tsx b/modules/Bill/components/BillItem/bill-item.component.tsx
index 989db2c..28c4b33 100644
--- a/modules/Bill/components/BillItem/bill-item.component.tsx
+++ b/modules/Bill/components/BillItem/bill-item.component.tsx
@@ -20,12 +20,19 @@ import { EditIcon, DeleteIcon, ArrowUpIcon, ArrowDownIcon, InfoIcon, WarningTwoI
import { BsThreeDotsVertical } from 'react-icons/bs';
import { MdOutlineMoneyOffCsred, MdOutlineAttachMoney } from 'react-icons/md';
import { IoMdCalendar } from 'react-icons/io';
+import { FaAngleDown } from 'react-icons/fa6';
import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
import { If } from '@Components';
+const textsBillStatus = {
+ [BillStatus.NOT_PAID]: 'Não pago',
+ [BillStatus.PAID]: 'Pago',
+ [BillStatus.PENDING]: 'Pendente',
+};
+
interface BillItemProps {
bill: Bill;
}
@@ -144,27 +151,18 @@ export const BillItem = ({ bill }: BillItemProps) => {
return '';
}, [isExpiring, isPassDueDate]);
- const billStatus = useMemo(() => {
- const props = {
- color: 'yellow',
- text: 'Pendente',
- };
+ const billStatusColor = useMemo(() => {
+ let color = 'yellow';
if (bill.status === BillStatus.NOT_PAID) {
- props.color = 'red';
- props.text = 'Não pago';
+ color = 'red';
}
if (bill.status === BillStatus.PAID) {
- props.color = 'green';
- props.text = 'Pago';
+ color = 'green';
}
- return (
-
- {props.text}
-
- );
+ return color;
}, [bill.status]);
return (
@@ -174,9 +172,16 @@ export const BillItem = ({ bill }: BillItemProps) => {
-
- {bill.name} {billStatus}
-
+
+
+ {bill.name}
+
+
+
+ ({bill.category})
+
+
+
Vencimento {formatDate(bill.dueDate)}
@@ -192,6 +197,70 @@ export const BillItem = ({ bill }: BillItemProps) => {
+
+
+ }
+ variant="outline"
+ size="sm"
+ w="fit-content"
+ mr={5}
+ colorScheme={billStatusColor}
+ >
+ {textsBillStatus[bill.status]}
+
+
+
+
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.NOT_PAID)}
+ isLoading={loadings?.changingStatus === BillStatus.NOT_PAID}
+ colorScheme="red"
+ >
+ Não pago
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.PAID)}
+ isLoading={loadings?.changingStatus === BillStatus.PAID}
+ colorScheme="green"
+ >
+ Pago
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.PENDING)}
+ isLoading={loadings?.changingStatus === BillStatus.PENDING}
+ colorScheme="yellow"
+ >
+ Pendente
+
+
+
+
+
+
{
-
- }
- justifyContent="flex-start"
- fontWeight="normal"
- fontSize="sm"
- onClick={() => changeBillStatus(BillStatus.NOT_PAID)}
- isLoading={loadings?.changingStatus === BillStatus.NOT_PAID}
- >
- Marcar como não pago
-
-
-
- }
- justifyContent="flex-start"
- fontWeight="normal"
- fontSize="sm"
- onClick={() => changeBillStatus(BillStatus.PAID)}
- isLoading={loadings?.changingStatus === BillStatus.PAID}
- >
- Marcar como pago
-
-
-
-
- }
- justifyContent="flex-start"
- fontWeight="normal"
- fontSize="sm"
- onClick={() => changeBillStatus(BillStatus.PENDING)}
- isLoading={loadings?.changingStatus === BillStatus.PENDING}
- >
- Marcar como pendente
-
-
-
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => onCopyBill(bill.id)}
+ >
+ Copiar conta
+
{
+ const {
+ handleSubmit,
+ register,
+ formState: { errors, isSubmitting },
+ setValue,
+ watch,
+ } = useForm();
+
+ const toast = useToast();
+
+ useEffect(() => {
+ setValue('month', new Date().getMonth());
+ setValue('year', new Date().getFullYear());
+ }, [setValue]);
+
+ const years = useMemo(() => {
+ const finalYears = [];
+
+ if (FROM_YEAR > TO_YEAR) {
+ throw new Error('From must be lower than to');
+ }
+
+ if (TO_YEAR - FROM_YEAR <= 0) {
+ throw new Error('To minus from must be over 0');
+ }
+
+ for (let yearCount = 0; yearCount <= TO_YEAR - FROM_YEAR; yearCount++) {
+ finalYears.push({
+ label: `${FROM_YEAR + yearCount}`,
+ to: FROM_YEAR + yearCount,
+ });
+ }
+
+ return finalYears;
+ }, []);
+
+ const months = useMemo(() => {
+ const finalMonths = [];
+
+ for (let monthCount = 0; monthCount <= 11; monthCount++) {
+ finalMonths.push({
+ label: `${MONTHS_DICT[monthCount]}`,
+ value: monthCount,
+ });
+ }
+
+ return finalMonths;
+ }, []);
+
+ const month = watch('month', false);
+ const year = watch('year', false);
+
+ const onSubmit = async values => {
+ const billDoc = await billsCollection.doc(billId).get();
+ if (billDoc.exists) {
+ const billData = billDoc.data() as Bill;
+
+ const day = new Date(billData.dueDate).getDay();
+ const newDueDate = new Date(values.year, values.month, day);
+
+ try {
+ await billsCollection.add({
+ ...billData,
+ status: BillStatus.PENDING,
+ dueDate: newDueDate.getTime(),
+ createdAt: new Date().getTime(),
+ });
+
+ onClose();
+
+ toast({
+ description: 'Conta copiada com sucesso!',
+ status: 'success',
+ });
+ } catch (error) {
+ console.error(error);
+ }
+ }
+ };
+
+ return (
+
+ <>
+
+
+ Copiar conta
+
+
+
+
+ Você tem certeza que deseja copiar essa conta para o mês de {month}/{year}?
+
+
+
+ Cancelar
+
+ Copiar conta
+
+
+
+ >
+
+ );
+};
diff --git a/modules/Bill/constants/BillConsts.ts b/modules/Bill/constants/BillConsts.ts
new file mode 100644
index 0000000..a7d25ae
--- /dev/null
+++ b/modules/Bill/constants/BillConsts.ts
@@ -0,0 +1,18 @@
+export const MONTHS_DICT = {
+ 0: 'Janeiro',
+ 1: 'Fevereiro',
+ 2: 'Março',
+ 3: 'Abril',
+ 4: 'Maio',
+ 5: 'Junho',
+ 6: 'Julho',
+ 7: 'Agosto',
+ 8: 'Setembro',
+ 9: 'Outubro',
+ 10: 'Novembro',
+ 11: 'Dezembro',
+};
+
+export const FROM_YEAR = 2020;
+
+export const TO_YEAR = 2023;
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index 97d9df2..7f77a12 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -174,19 +174,21 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
/>
-
- Categoria
-
-
- {categoriesExpense.map(value => {
- const radio = getRadioProps({ value });
- return (
-
- {value}
-
- );
- })}
-
+ <>
+
+ Categoria
+
+
+ {categoriesExpense.map(value => {
+ const radio = getRadioProps({ value });
+ return (
+
+ {value}
+
+ );
+ })}
+
+ >
diff --git a/modules/Bill/container/ListBills/list-bills.container.tsx b/modules/Bill/container/ListBills/list-bills.container.tsx
index cd0ea55..46aae7e 100644
--- a/modules/Bill/container/ListBills/list-bills.container.tsx
+++ b/modules/Bill/container/ListBills/list-bills.container.tsx
@@ -1,4 +1,4 @@
-import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Box, Button, Skeleton, Stack, useToast } from '@chakra-ui/react';
import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
@@ -8,6 +8,7 @@ import BillFilters from '@Modules/Bill/components/BillFilters';
import { StatsMonth } from '@Modules/Bill/components/StatsMonth/stats-month.component';
import { useUser } from '@Modules/Authentication/context/UserContext';
import { BillTypes } from '@Modules/Bill/constants/Types';
+import { CopyBill } from '@Modules/Bill/components/CopyBill/copy-bill.component';
export const ListBillsContainer = () => {
const { userId } = useUser();
@@ -17,6 +18,9 @@ export const ListBillsContainer = () => {
year: new Date().getFullYear(),
month: new Date().getMonth(),
});
+ const [billId, setBillId] = useState();
+
+ const copyBillModal = useRef(false);
const loadBills = useCallback(() => {
if (!userId) return;
@@ -65,15 +69,26 @@ export const ListBillsContainer = () => {
);
}, [bills]);
+ const onCopyBill = billId => {
+ copyBillModal.current = true;
+ setBillId(billId);
+ };
+
+ const onCloseCopyBill = () => {
+ copyBillModal.current = false;
+ setBillId(undefined);
+ };
+
return (
+
onChange(target, value)} from={2020} to={2024} />
{bills.map(bill => (
-
+
))}
diff --git a/tsconfig.json b/tsconfig.json
index eef1fa1..d4285b4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -45,7 +45,5 @@
"**/*.ts",
"**/*.tsx"
],
- "exclude": [
- "node_modules"
- ]
+ "exclude": ["node_modules", ".next"]
}
From 29a2595a74d715069cac9c5af0610b6b15c9d66c Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sat, 18 Nov 2023 15:16:16 -0500
Subject: [PATCH 21/39] feat: go to form bill already with value
---
components/LateralMenu/index.tsx | 7 +-
.../FormBill/form-bill.container.tsx | 71 +++++++++++++------
2 files changed, 51 insertions(+), 27 deletions(-)
diff --git a/components/LateralMenu/index.tsx b/components/LateralMenu/index.tsx
index 980aa0b..cda7833 100644
--- a/components/LateralMenu/index.tsx
+++ b/components/LateralMenu/index.tsx
@@ -16,12 +16,10 @@ import {
FlexProps,
Badge,
} from '@chakra-ui/react';
-import { FiHome, FiPower, FiTrendingUp, FiMenu } from 'react-icons/fi';
+import { FiHome, FiPower, FiTrendingUp, FiTrendingDown, FiMenu } from 'react-icons/fi';
import { IconType } from 'react-icons';
import Image from 'next/image';
-import { auth } from '@Configs/Firebase';
-
interface LinkItemProps {
name: string;
icon: IconType;
@@ -29,7 +27,8 @@ interface LinkItemProps {
}
const LinkItems: Array = [
{ name: 'Início', icon: FiHome, link: '/' },
- { name: 'Criar conta', icon: FiTrendingUp, link: '/bill' },
+ { name: 'Criar receita', icon: FiTrendingUp, link: '/bill?type=INCOME' },
+ { name: 'Criar despesa', icon: FiTrendingDown, link: '/bill?type=EXPENSE' },
{
name: 'Sair',
icon: FiPower,
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index 7f77a12..14c1bb3 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -1,8 +1,8 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/router';
import { useForm, Controller } from 'react-hook-form';
import { Button } from '@chakra-ui/button';
-import { useToast, Flex, useRadioGroup, HStack, Text } from '@chakra-ui/react';
+import { useToast, Flex, useRadioGroup, Stack, Text, Spacer } from '@chakra-ui/react';
import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
@@ -10,6 +10,16 @@ import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
import { Input, MoneyInput, Select, DatePicker, Box, RadioCard, If } from '@Components';
import { useUser } from '@Modules/Authentication/context/UserContext';
+const types = [
+ {
+ label: 'Despesa',
+ value: BillTypes.EXPENSE,
+ },
+ {
+ label: 'Receita',
+ value: BillTypes.INCOME,
+ },
+];
interface FormBillProps {
billId?: string;
}
@@ -38,7 +48,17 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
onChange: category => setValue('category', category),
});
+ useEffect(() => {
+ try {
+ const queryBillType = router.query?.type as keyof typeof BillTypes;
+ setValue('type', queryBillType);
+ } catch (error) {
+ console.error(error);
+ }
+ }, [router.query.type, setValue]);
+
const group = getRootProps();
+
const onSubmit = async values => {
if (!userId) return;
@@ -103,20 +123,23 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
setValue('category', foundBill?.category);
}, [foundBill, setValue]);
- const types = [
- {
- label: 'Despesa',
- value: BillTypes.EXPENSE,
- },
- {
- label: 'Receita',
- value: BillTypes.INCOME,
- },
- ];
const billType = watch('type', false);
+
+ const title = useMemo(() => {
+ const prefix = billId ? 'Editar' : 'Criar nova';
+ if (router.query.type) {
+ const foundType = types.find(type => type.value === router.query.type);
+
+ if (!foundType) return `${prefix} conta`;
+
+ return `${prefix} ${foundType.label.toLocaleLowerCase()}`;
+ }
+
+ return `${prefix} conta`;
+ }, [billId, router.query.type]);
return (
{
)}
/>
-
+
+
+
{
Categoria
-
+
{categoriesExpense.map(value => {
const radio = getRadioProps({ value });
return (
@@ -187,7 +212,7 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
);
})}
-
+
>
From 4c09c65c005caeb401c431e33312195cb5c156c5 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sat, 18 Nov 2023 15:26:26 -0500
Subject: [PATCH 22/39] fix: layout issues
---
modules/Bill/components/CopyBill/copy-bill.component.tsx | 2 +-
modules/Bill/container/FormBill/form-bill.container.tsx | 8 ++++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/modules/Bill/components/CopyBill/copy-bill.component.tsx b/modules/Bill/components/CopyBill/copy-bill.component.tsx
index aaf2535..14eaaf8 100644
--- a/modules/Bill/components/CopyBill/copy-bill.component.tsx
+++ b/modules/Bill/components/CopyBill/copy-bill.component.tsx
@@ -106,7 +106,7 @@ export const CopyBill = ({ isOpen, onClose, billId }) => {
<>
-
+
Copiar conta
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index 14c1bb3..3d6a9fb 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -20,6 +20,8 @@ const types = [
value: BillTypes.INCOME,
},
];
+
+const categoriesExpense = ['💳 Cartão de crédito', '💰 Investimento', '💸 Fixo', '🔁 Flexível', '💲 Outro'];
interface FormBillProps {
billId?: string;
}
@@ -40,8 +42,6 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
const [foundBill, setFoundBill] = useState();
- const categoriesExpense = ['💳 Cartão de crédito', '💰 Investimento', '💸 Fixo', '🔁 Flexível', '💲 Outro'];
-
const { getRootProps, getRadioProps } = useRadioGroup({
name: 'category',
defaultValue: categoriesExpense[0],
@@ -57,6 +57,10 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
}
}, [router.query.type, setValue]);
+ useEffect(() => {
+ setValue('category', categoriesExpense[0]);
+ }, [setValue]);
+
const group = getRootProps();
const onSubmit = async values => {
From 60e93e02f0f8fd18ca781a6cf7db64c4355f31f6 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sat, 18 Nov 2023 15:45:12 -0500
Subject: [PATCH 23/39] fix: missing cancel action
---
modules/Bill/components/CopyBill/copy-bill.component.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/modules/Bill/components/CopyBill/copy-bill.component.tsx b/modules/Bill/components/CopyBill/copy-bill.component.tsx
index 14eaaf8..ed348e6 100644
--- a/modules/Bill/components/CopyBill/copy-bill.component.tsx
+++ b/modules/Bill/components/CopyBill/copy-bill.component.tsx
@@ -134,7 +134,9 @@ export const CopyBill = ({ isOpen, onClose, billId }) => {
- Cancelar
+
+ Cancelar
+
Copiar conta
From f3c31543c5b5a7f0d6d456ccb4d0d780d2994452 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 11:14:18 -0500
Subject: [PATCH 24/39] feat: datePicker max and min dates and hasError
---
components/DatePicker/date-picker.component.tsx | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/components/DatePicker/date-picker.component.tsx b/components/DatePicker/date-picker.component.tsx
index 839c2e8..9a7c25a 100644
--- a/components/DatePicker/date-picker.component.tsx
+++ b/components/DatePicker/date-picker.component.tsx
@@ -11,6 +11,8 @@ interface Props {
label?: string;
error?: string;
value?: string;
+ maxDate?: Date;
+ minDate?: Date;
}
export const DatePicker = ({
@@ -22,6 +24,8 @@ export const DatePicker = ({
label,
error,
value,
+ maxDate,
+ minDate,
...rest
}: Props & HTMLAttributes) => {
const isLight = useColorMode().colorMode === 'light';
@@ -35,6 +39,9 @@ export const DatePicker = ({
onChange={onChange}
isClearable={isClearable}
showPopperArrow={showPopperArrow}
+ maxDate={maxDate}
+ minDate={minDate}
+ className={!!error ? 'hasError' : ''}
/>
{error && {error}}
From cf712a55c708832e95323ded305fd7db1455cdb7 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 11:14:29 -0500
Subject: [PATCH 25/39] feat: new money input
---
components/MoneyInput/index.tsx | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/components/MoneyInput/index.tsx b/components/MoneyInput/index.tsx
index 9b3a736..106183b 100644
--- a/components/MoneyInput/index.tsx
+++ b/components/MoneyInput/index.tsx
@@ -4,10 +4,9 @@ import {
FormErrorMessage,
NumberInput,
NumberInputField,
- NumberInputStepper,
- NumberIncrementStepper,
- NumberDecrementStepper,
FormControlProps,
+ InputLeftAddon,
+ InputGroup,
} from '@chakra-ui/react';
import { forwardRef, LegacyRef } from 'react';
@@ -18,18 +17,17 @@ type MoneyInputProps = FormControlProps & {
};
export const MoneyInput = forwardRef(
- ({ name, label, error, ...rest }: MoneyInputProps, ref) => {
+ ({ name, label, error, isRequired, ...rest }: MoneyInputProps, ref) => {
return (
{label && {label}}
-
- } />
-
-
-
-
-
+
+ R$
+
+ } borderLeftRadius={0} />
+
+
{error && {error}}
);
From 8a3570428ab1df68cbacfb79dcffbfa04380ab4a Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 11:14:51 -0500
Subject: [PATCH 26/39] feat: defaultRequiredMessage
---
modules/Bill/constants/BillConsts.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/modules/Bill/constants/BillConsts.ts b/modules/Bill/constants/BillConsts.ts
index a7d25ae..5733c12 100644
--- a/modules/Bill/constants/BillConsts.ts
+++ b/modules/Bill/constants/BillConsts.ts
@@ -15,4 +15,8 @@ export const MONTHS_DICT = {
export const FROM_YEAR = 2020;
-export const TO_YEAR = 2023;
+export const TO_YEAR = 2024;
+
+export const defaultRequiredMessage = {
+ required: 'Este campo é obrigatório!',
+};
From 622353fad0ea38d597cd48e2f418327c90ca17ed Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 11:15:00 -0500
Subject: [PATCH 27/39] feat: billsRecurrenceCollection
---
modules/Bill/constants/FirestoreCollections.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/modules/Bill/constants/FirestoreCollections.ts b/modules/Bill/constants/FirestoreCollections.ts
index 02cde81..694a38d 100644
--- a/modules/Bill/constants/FirestoreCollections.ts
+++ b/modules/Bill/constants/FirestoreCollections.ts
@@ -1,3 +1,5 @@
import { firestore } from '@Configs/Firebase';
export const billsCollection = firestore.collection('bills');
+
+export const billsRecurrenceCollection = firestore.collection('bills-recurrence');
From b8556acbb768c18e144b2ba0b28efaea0ee154c2 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 11:15:15 -0500
Subject: [PATCH 28/39] feat: recurrence feature
---
.../FormBill/form-bill.container.tsx | 176 ++++++++++---
pages/styles.scss | 234 +++++++++---------
2 files changed, 257 insertions(+), 153 deletions(-)
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index 3d6a9fb..11516a2 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -2,13 +2,14 @@ import React, { useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/router';
import { useForm, Controller } from 'react-hook-form';
import { Button } from '@chakra-ui/button';
-import { useToast, Flex, useRadioGroup, Stack, Text, Spacer } from '@chakra-ui/react';
+import { useToast, Flex, Text, Switch } from '@chakra-ui/react';
-import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { billsCollection, billsRecurrenceCollection } from '@Modules/Bill/constants/FirestoreCollections';
import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
-import { Input, MoneyInput, Select, DatePicker, Box, RadioCard, If } from '@Components';
+import { Input, MoneyInput, Select, DatePicker, Box, If } from '@Components';
import { useUser } from '@Modules/Authentication/context/UserContext';
+import { defaultRequiredMessage, TO_YEAR } from '@Modules/Bill/constants/BillConsts';
const types = [
{
@@ -21,7 +22,40 @@ const types = [
},
];
-const categoriesExpense = ['💳 Cartão de crédito', '💰 Investimento', '💸 Fixo', '🔁 Flexível', '💲 Outro'];
+const recurrenceTypes = [
+ {
+ label: 'Cada mês',
+ value: 'EVERY_MONTH',
+ },
+ {
+ label: 'Cada ano',
+ value: 'EVERY_YEAR',
+ },
+];
+
+const categoriesExpense = [
+ {
+ label: '💳 Cartão de crédito',
+ value: 'CREDIT_CARD',
+ },
+ {
+ label: '💰 Investimento',
+ value: 'INVESTING',
+ },
+ {
+ label: '💸 Fixo',
+ value: 'FIXED',
+ },
+ {
+ label: '🔁 Flexível',
+ value: 'FLEX',
+ },
+ {
+ label: '💲 Outro',
+ value: 'OTHER',
+ },
+];
+
interface FormBillProps {
billId?: string;
}
@@ -42,12 +76,6 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
const [foundBill, setFoundBill] = useState();
- const { getRootProps, getRadioProps } = useRadioGroup({
- name: 'category',
- defaultValue: categoriesExpense[0],
- onChange: category => setValue('category', category),
- });
-
useEffect(() => {
try {
const queryBillType = router.query?.type as keyof typeof BillTypes;
@@ -58,11 +86,9 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
}, [router.query.type, setValue]);
useEffect(() => {
- setValue('category', categoriesExpense[0]);
+ setValue('category', categoriesExpense[0].value);
}, [setValue]);
- const group = getRootProps();
-
const onSubmit = async values => {
if (!userId) return;
@@ -72,7 +98,7 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
const bill: Bill = {
name: values.name,
description: values.description ?? '',
- value: Number(values.value),
+ value: +values.value,
dueDate: dueDate.getTime(),
status: billId ? foundBill?.status : BillStatus.PENDING,
type: values.type,
@@ -85,6 +111,39 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
if (billId) {
await billsCollection.doc(billId).update(bill);
} else {
+ console.log(values);
+ if (values.recurrence) {
+ let endOcurrence = new Date(values.recurrenceDueDate);
+ let indexOcurrence = new Date();
+ indexOcurrence.setDate(endOcurrence.getDate());
+
+ let billsToAdd = [billsCollection.add(bill)];
+ const billDateDay = new Date(bill.dueDate).getDate();
+ while (endOcurrence >= indexOcurrence) {
+ indexOcurrence.setMonth(indexOcurrence.getMonth() + 1);
+
+ billsToAdd.push(
+ billsCollection.add({
+ ...bill,
+ dueDate: new Date(indexOcurrence.getFullYear(), indexOcurrence.getMonth(), billDateDay).getTime(),
+ })
+ );
+ }
+
+ const addedBills = await Promise.all(billsToAdd);
+
+ await billsRecurrenceCollection.add({
+ type: values.recurrenceType,
+ ends_in: values.recurrenceDueDate,
+ bills: addedBills.map(({ id }) => `bills/${id}`),
+ });
+
+ return toast({
+ description: 'Conta e recorrência criados com sucesso!',
+ status: 'success',
+ });
+ }
+
await billsCollection.add(bill);
}
toast({
@@ -94,7 +153,7 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
router.push('/');
} catch (error) {
- console.log(error);
+ console.error(error);
}
};
@@ -128,6 +187,7 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
}, [foundBill, setValue]);
const billType = watch('type', false);
+ const billRecurrence = watch('recurrence', false);
const title = useMemo(() => {
const prefix = billId ? 'Editar' : 'Criar nova';
@@ -141,6 +201,9 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
return `${prefix} conta`;
}, [billId, router.query.type]);
+
+ console.log(errors);
+
return (
{
{
label="Descrição"
{...register('description')}
error={errors.description?.message}
- marginBottom="10px"
+ mb={5}
/>
(
{
selected={field.value}
defaultValue={new Date().getTime()}
style={{ marginBottom: '10px' }}
+ error={errors.dueDate?.message}
/>
)}
/>
@@ -187,37 +252,70 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
-
- <>
-
- Categoria
-
-
- {categoriesExpense.map(value => {
- const radio = getRadioProps({ value });
- return (
-
- {value}
-
- );
- })}
-
- >
+
+
+
+
+ Recorrência
+
+
+
+
+
+ Contas reccorentes serão criadas com a frequência que você determinar.
+
+
+
+
+
+
+ (
+ field.onChange(date)}
+ selected={field.value}
+ defaultValue={new Date().getTime()}
+ minDate={new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1)}
+ maxDate={new Date(TO_YEAR, 11, 31)}
+ />
+ )}
+ />
+
diff --git a/pages/styles.scss b/pages/styles.scss
index 4aced1b..d3c7a32 100644
--- a/pages/styles.scss
+++ b/pages/styles.scss
@@ -1,180 +1,186 @@
-.light-theme{
- --light-gray: var(--chakra-colors-gray-200);
- --gray: var(--chakra-colors-gray-300);
- --blue700:var(--chakra-colors-blue-600);
- --blue600: var(--chakra-colors-blue-500);
- --blue500: var(--chakra-colors-gray-400);
- --blue400: var(--chakra-colors-gray-300);
- --blue300: var(--chakra-colors-gray-200);
- --blue200: var(--chakra-colors-gray-200);
- --blue100: var(--chakra-colors-gray-100);
- --monthBackground: var(--chakra-colors-white);
- --text:var(--chakra-colors-black);
- --negative-text:var(--chakra-colors-white);
-}
-.dark-theme{
- --light-gray: var(--chakra-colors-gray-600);
- --gray: var(--chakra-colors-gray-500);
- --blue700: var(--chakra-colors-blue-600);
- --blue600: var(--chakra-colors-blue-300);
- --blue500: var(--chakra-colors-gray-500);
- --blue400: var(--chakra-colors-gray-600);
- --blue300: var(--chakra-colors-gray-700);
- --blue200: var(--chakra-colors-gray-600);
- --blue100: var(--chakra-colors-gray-800);
- --monthBackground: var(--chakra-colors-gray-700);
- --text:var(--chakra-colors-gray-200);
- --negative-text:var(--chakra-colors-black);
+.light-theme {
+ --light-gray: var(--chakra-colors-gray-200);
+ --gray: var(--chakra-colors-gray-300);
+ --blue700: var(--chakra-colors-blue-600);
+ --blue600: var(--chakra-colors-blue-500);
+ --blue500: var(--chakra-colors-gray-400);
+ --blue400: var(--chakra-colors-gray-300);
+ --blue300: var(--chakra-colors-gray-200);
+ --blue200: var(--chakra-colors-gray-200);
+ --blue100: var(--chakra-colors-gray-100);
+ --monthBackground: var(--chakra-colors-white);
+ --text: var(--chakra-colors-black);
+ --negative-text: var(--chakra-colors-white);
+}
+
+.dark-theme {
+ --light-gray: var(--chakra-colors-gray-600);
+ --gray: var(--chakra-colors-gray-500);
+ --blue700: var(--chakra-colors-blue-600);
+ --blue600: var(--chakra-colors-blue-300);
+ --blue500: var(--chakra-colors-gray-500);
+ --blue400: var(--chakra-colors-gray-600);
+ --blue300: var(--chakra-colors-gray-700);
+ --blue200: var(--chakra-colors-gray-600);
+ --blue100: var(--chakra-colors-gray-800);
+ --monthBackground: var(--chakra-colors-gray-700);
+ --text: var(--chakra-colors-gray-200);
+ --negative-text: var(--chakra-colors-black);
}
/* if you dont want to use chakra's theme use this class in the wrapping div. These are the exact original values */
-.light-theme-original{
- --light-gray: #cccccc;
- --gray: #b3b3b3;
- --blue700:#2a69ac;
- --blue600: #3182ce;
- --blue500: #a0aec0;
- --blue400: #cbd5e0;
- --blue300: #e2e8f0;
- --blue200: #edf2f7;
- --blue100: #f7fafc;
+.light-theme-original {
+ --light-gray: #cccccc;
+ --gray: #b3b3b3;
+ --blue700: #2a69ac;
+ --blue600: #3182ce;
+ --blue500: #a0aec0;
+ --blue400: #cbd5e0;
+ --blue300: #e2e8f0;
+ --blue200: #edf2f7;
+ --blue100: #f7fafc;
}
html {
- height: 100%;
+ height: 100%;
}
.react-datepicker {
- font-family: unset;
- font-size: 0.9rem;
- border-color: var(--light-gray);
+ font-family: unset;
+ font-size: 0.9rem;
+ border-color: var(--light-gray);
}
-.react-datepicker.dark-theme,
+.react-datepicker.dark-theme,
.react-datepicker.light-theme {
- width: 100%;
+ width: 100%;
}
.react-datepicker-wrapper {
- width: 100%;
- display: block;
- border: 0px solid transparent;
+ width: 100%;
+ display: block;
+ border: 0px solid transparent;
}
-.react-datepicker-wrapper > .react-datepicker__input-container {
- width: 100%;
- display: block;
- border: 0px solid transparent;
+.react-datepicker-wrapper > .react-datepicker__input-container {
+ width: 100%;
+ display: block;
+ border: 0px solid transparent;
}
.react-datepicker__input-container {
-/* font-size: 1rem;
-height: 2.5rem;
-border-radius: 0.25rem;
-border: 1px solid;
-border-color: var(--light-gray); */
+ /* font-size: 1rem;
+ height: 2.5rem;
+ border-radius: 0.25rem;
+ border: 1px solid;
+ border-color: var(--light-gray); */
}
.react-datepicker__input-container > input {
- width: 100%;
- min-width: 0px;
- outline: 2px solid transparent;
- outline-offset: 2px;
- position: relative;
- -webkit-appearance: none;
- -moz-appearance: none;
- -ms-appearance: none;
- appearance: none;
- transition-property: var(--chakra-transition-property-common);
- transition-duration: var(--chakra-transition-duration-normal);
- font-size: var(--chakra-fontSizes-md);
- -webkit-padding-start: var(--chakra-space-4);
- padding-inline-start: var(--chakra-space-4);
- -webkit-padding-end: var(--chakra-space-4);
- padding-inline-end: var(--chakra-space-4);
- height: var(--chakra-sizes-10);
- border-radius: var(--chakra-radii-md);
- border: 1px solid var(--chakra-colors-whiteAlpha-300);
- background: transparent;
-
- &:focus {
- z-index: 1;
- border-color: #63b3ed;
- box-shadow: 0 0 0 1px #63b3ed;
- }
+ width: 100%;
+ min-width: 0px;
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ position: relative;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ -ms-appearance: none;
+ appearance: none;
+ transition-property: var(--chakra-transition-property-common);
+ transition-duration: var(--chakra-transition-duration-normal);
+ font-size: var(--chakra-fontSizes-md);
+ -webkit-padding-start: var(--chakra-space-4);
+ padding-inline-start: var(--chakra-space-4);
+ -webkit-padding-end: var(--chakra-space-4);
+ padding-inline-end: var(--chakra-space-4);
+ height: var(--chakra-sizes-10);
+ border-radius: var(--chakra-radii-md);
+ border: 1px solid var(--chakra-colors-whiteAlpha-300);
+ background: transparent;
+
+ &:focus {
+ z-index: 1;
+ border-color: #63b3ed;
+ box-shadow: 0 0 0 1px #63b3ed;
+ }
+
+ &.hasError {
+ border-color: #FC8181;
+ box-shadow: 0 0 0 1px #FC8181;
+ }
}
.react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button) {
-right: 90px;
+ right: 90px;
}
.react-datepicker__navigation--previous,
.react-datepicker__navigation--next {
-height: 45px;
+ height: 45px;
}
.react-datepicker__navigation--previous {
-border-right-color: var(--blue400);
+ border-right-color: var(--blue400);
}
.react-datepicker__navigation--previous:hover {
-border-right-color: var(--blue500);
+ border-right-color: var(--blue500);
}
.react-datepicker__navigation--next {
-border-left-color: var(--blue400);
+ border-left-color: var(--blue400);
}
.react-datepicker__navigation--next:hover {
-border-left-color: var(--blue500);
+ border-left-color: var(--blue500);
}
.react-datepicker__header {
-background-color: var(--blue100);
+ background-color: var(--blue100);
}
.react-datepicker__header,
.react-datepicker__time-container {
-border-color: var(--blue300);
+ border-color: var(--blue300);
}
.react-datepicker__current-month,
.react-datepicker-time__header,
.react-datepicker-year-header {
-font-size: inherit;
-font-weight: 600;
-color: var(--text)
+ font-size: inherit;
+ font-weight: 600;
+ color: var(--text)
}
-.react-datepicker__month{
- background-color: var(--monthBackground);
- margin:0;
- padding:0.4rem;
+.react-datepicker__month {
+ background-color: var(--monthBackground);
+ margin: 0;
+ padding: 0.4rem;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item {
-margin: 0 1px 0 0;
+ margin: 0 1px 0 0;
height: auto;
- padding: 7px 10px;
+ padding: 7px 10px;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover {
- background: var(--blue200);
+ background: var(--blue200);
}
.react-datepicker__day {
- color: var(--text)
+ color: var(--text)
}
.react-datepicker__day:hover {
- background: var(--blue200);
+ background: var(--blue200);
}
.react-datepicker__day-name {
- color:var(--text)
+ color: var(--text)
}
.react-datepicker__day--selected,
@@ -184,25 +190,25 @@ margin: 0 1px 0 0;
.react-datepicker__month-text--in-selecting-range,
.react-datepicker__month-text--in-range,
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected {
-background: var(--blue600);
-font-weight: normal;
-color:var(--negative-text);
+ background: var(--blue600);
+ font-weight: normal;
+ color: var(--negative-text);
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected:hover {
-background: var(--blue700);
+ background: var(--blue700);
}
.react-datepicker__close-icon::after {
- background-color: unset;
- border-radius: unset;
- font-size: 1.5rem;
- font-weight: bold;
- color: var(--light-gray);
- height: 20px;
- width: 20px;
+ background-color: unset;
+ border-radius: unset;
+ font-size: 1.5rem;
+ font-weight: bold;
+ color: var(--light-gray);
+ height: 20px;
+ width: 20px;
}
.react-datepicker__close-icon::after:hover {
- color: var(--gray)
+ color: var(--gray)
}
\ No newline at end of file
From 83359421ebd20e455795410afe200d0c70f25c88 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 11:17:00 -0500
Subject: [PATCH 29/39] fix: remove every year recurrence
---
.../components/BillItem/bill-item.component.tsx | 14 +++-----------
.../container/FormBill/form-bill.container.tsx | 9 +++++----
2 files changed, 8 insertions(+), 15 deletions(-)
diff --git a/modules/Bill/components/BillItem/bill-item.component.tsx b/modules/Bill/components/BillItem/bill-item.component.tsx
index 954bd11..47f64eb 100644
--- a/modules/Bill/components/BillItem/bill-item.component.tsx
+++ b/modules/Bill/components/BillItem/bill-item.component.tsx
@@ -116,7 +116,6 @@ export const BillItem = ({ bill, onCopyBill }: BillItemProps) => {
}, [bill.dueDate, bill.status, bill.type]);
const billSituation = useMemo(() => {
- console.log('isPassDueDate', isPassDueDate);
if (isPassDueDate) {
return (
@@ -172,16 +171,9 @@ export const BillItem = ({ bill, onCopyBill }: BillItemProps) => {
-
-
- {bill.name}
-
-
-
- ({bill.category})
-
-
-
+
+ {bill.name}
+
Vencimento {formatDate(bill.dueDate)}
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index 11516a2..cd2749e 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -27,10 +27,11 @@ const recurrenceTypes = [
label: 'Cada mês',
value: 'EVERY_MONTH',
},
- {
- label: 'Cada ano',
- value: 'EVERY_YEAR',
- },
+ // TODO: every year recurrence
+ // {
+ // label: 'Cada ano',
+ // value: 'EVERY_YEAR',
+ // },
];
const categoriesExpense = [
From fbe530db867e15d17848ba2ef0c2df5708d74309 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 11:19:21 -0500
Subject: [PATCH 30/39] fix: show category only for expense
---
.../container/FormBill/form-bill.container.tsx | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index cd2749e..677079b 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -269,14 +269,16 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
isRequired
/>
-
+
+
+
From bf97957bbec6238bdd3f068326ee0577cf92dfdf Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 12:01:16 -0500
Subject: [PATCH 31/39] feat: allow deleting recurrence
---
.../BillItem/bill-item.component.tsx | 32 +++---
.../DeleteBill/delete-bill.component.tsx | 105 ++++++++++++++++++
.../FormBill/form-bill.container.tsx | 8 +-
.../ListBills/list-bills.container.tsx | 15 ++-
4 files changed, 141 insertions(+), 19 deletions(-)
create mode 100644 modules/Bill/components/DeleteBill/delete-bill.component.tsx
diff --git a/modules/Bill/components/BillItem/bill-item.component.tsx b/modules/Bill/components/BillItem/bill-item.component.tsx
index 47f64eb..04b4bcc 100644
--- a/modules/Bill/components/BillItem/bill-item.component.tsx
+++ b/modules/Bill/components/BillItem/bill-item.component.tsx
@@ -23,7 +23,7 @@ import { FaAngleDown } from 'react-icons/fa6';
import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
-import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { billsCollection, billsRecurrenceCollection } from '@Modules/Bill/constants/FirestoreCollections';
import { If } from '@Components';
const textsBillStatus = {
@@ -35,9 +35,10 @@ const textsBillStatus = {
interface BillItemProps {
bill: Bill;
onCopyBill: (billId: string) => void;
+ onDeleteBill: (billId: string) => void;
}
-export const BillItem = ({ bill, onCopyBill }: BillItemProps) => {
+export const BillItem = ({ bill, onCopyBill, onDeleteBill }: BillItemProps) => {
const router = useRouter();
const [loadings, setLoadings] = useState({
changingStatus: null,
@@ -88,17 +89,20 @@ export const BillItem = ({ bill, onCopyBill }: BillItemProps) => {
};
const deleteBill = async () => {
- setLoadings({
- ...loadings,
- deleting: true,
- });
-
- await billsCollection.doc(bill.id).delete();
-
- setLoadings({
- ...loadings,
- changingStatus: false,
- });
+ const hasRecurrence = await (await billsRecurrenceCollection.where('bills', 'array-contains', bill.id)).get();
+
+ console.log(bill.id, hasRecurrence);
+ // setLoadings({
+ // ...loadings,
+ // deleting: true,
+ // });
+ //
+ // await billsCollection.doc(bill.id).delete();
+ //
+ // setLoadings({
+ // ...loadings,
+ // changingStatus: false,
+ // });
};
const isExpiring = useMemo(() => {
@@ -298,7 +302,7 @@ export const BillItem = ({ bill, onCopyBill }: BillItemProps) => {
fontWeight="normal"
colorScheme="red"
fontSize="sm"
- onClick={() => deleteBill()}
+ onClick={() => onDeleteBill(bill.id)}
>
Deletar conta
diff --git a/modules/Bill/components/DeleteBill/delete-bill.component.tsx b/modules/Bill/components/DeleteBill/delete-bill.component.tsx
new file mode 100644
index 0000000..6d4983d
--- /dev/null
+++ b/modules/Bill/components/DeleteBill/delete-bill.component.tsx
@@ -0,0 +1,105 @@
+import React, { useEffect, useState, useCallback } from 'react';
+import { Button } from '@chakra-ui/button';
+import {
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalCloseButton,
+ ModalBody,
+ ModalFooter,
+ useToast,
+} from '@chakra-ui/react';
+
+import { Modal } from '@Components/Modal';
+import { billsCollection, billsRecurrenceCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
+import { BillStatus } from '@Modules/Bill/constants/Types';
+
+export const DeleteBill = ({ isOpen, onClose, billId }) => {
+ const toast = useToast();
+ const [isRecurrence, setIsRecurrence] = useState(false);
+
+ const checkRecurrence = useCallback(async () => {
+ if (!billId) return;
+
+ const hasRecurrence = await (await billsRecurrenceCollection.where('bills', 'array-contains', billId)).get();
+
+ setIsRecurrence(!hasRecurrence.empty);
+ }, [billId]);
+
+ useEffect(() => {
+ checkRecurrence();
+ }, [checkRecurrence]);
+ const deleteBill = async (deleteRecurrence = false) => {
+ try {
+ if (deleteRecurrence) {
+ const recurrenceDoc = (
+ await (await billsRecurrenceCollection.where('bills', 'array-contains', billId).limit(1)).get()
+ )?.docs[0];
+
+ let execution = [billsRecurrenceCollection.doc(recurrenceDoc.id).delete()];
+
+ recurrenceDoc.data().bills.forEach(id => billsCollection.doc(id).delete());
+
+ await Promise.all(execution);
+
+ return toast({
+ description: 'Conta e recorrências deletadas com sucesso!',
+ status: 'success',
+ });
+ }
+
+ await billsCollection.doc(billId).delete();
+ toast({
+ description: 'Conta deletada com sucesso!',
+ status: 'success',
+ });
+ } catch (error) {
+ console.error(error);
+ } finally {
+ onClose();
+ }
+ };
+
+ return (
+
+ <>
+
+
+ Deletar conta
+
+
+ {isRecurrence
+ ? 'Você deseja deletar somente esta conta ou toda recorrência?'
+ : 'Deseja realmente deletar esta conta?'}
+
+
+
+ {isRecurrence ? (
+ <>
+
+ Cancelar
+
+ deleteBill()}>
+ Deletar conta
+
+ deleteBill(true)}>
+ Deletar recorrência
+
+ >
+ ) : (
+ <>
+
+ Cancelar
+
+ deleteBill()}>
+ Deletar conta
+
+ >
+ )}
+
+
+ >
+
+ );
+};
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index 677079b..0d1451f 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -112,13 +112,12 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
if (billId) {
await billsCollection.doc(billId).update(bill);
} else {
- console.log(values);
if (values.recurrence) {
+ let billsToAdd = [billsCollection.add(bill)];
let endOcurrence = new Date(values.recurrenceDueDate);
let indexOcurrence = new Date();
indexOcurrence.setDate(endOcurrence.getDate());
- let billsToAdd = [billsCollection.add(bill)];
const billDateDay = new Date(bill.dueDate).getDate();
while (endOcurrence >= indexOcurrence) {
indexOcurrence.setMonth(indexOcurrence.getMonth() + 1);
@@ -136,11 +135,12 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
await billsRecurrenceCollection.add({
type: values.recurrenceType,
ends_in: values.recurrenceDueDate,
- bills: addedBills.map(({ id }) => `bills/${id}`),
+ bills: addedBills.map(({ id }) => id),
});
+ router.push('/');
return toast({
- description: 'Conta e recorrência criados com sucesso!',
+ description: 'Conta e recorrências criados com sucesso!',
status: 'success',
});
}
diff --git a/modules/Bill/container/ListBills/list-bills.container.tsx b/modules/Bill/container/ListBills/list-bills.container.tsx
index 46aae7e..fde4906 100644
--- a/modules/Bill/container/ListBills/list-bills.container.tsx
+++ b/modules/Bill/container/ListBills/list-bills.container.tsx
@@ -9,6 +9,7 @@ import { StatsMonth } from '@Modules/Bill/components/StatsMonth/stats-month.comp
import { useUser } from '@Modules/Authentication/context/UserContext';
import { BillTypes } from '@Modules/Bill/constants/Types';
import { CopyBill } from '@Modules/Bill/components/CopyBill/copy-bill.component';
+import { DeleteBill } from '@Modules/Bill/components/DeleteBill/delete-bill.component';
export const ListBillsContainer = () => {
const { userId } = useUser();
@@ -21,6 +22,7 @@ export const ListBillsContainer = () => {
const [billId, setBillId] = useState();
const copyBillModal = useRef(false);
+ const deleteBillModal = useRef(false);
const loadBills = useCallback(() => {
if (!userId) return;
@@ -79,16 +81,27 @@ export const ListBillsContainer = () => {
setBillId(undefined);
};
+ const onDeleteBill = billId => {
+ deleteBillModal.current = true;
+ setBillId(billId);
+ };
+
+ const onCloseDeleteBill = () => {
+ deleteBillModal.current = false;
+ setBillId(undefined);
+ };
+
return (
+
onChange(target, value)} from={2020} to={2024} />
{bills.map(bill => (
-
+
))}
From e621b7aec001732958298759fb8c7a3c8281bfe3 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Sun, 19 Nov 2023 12:02:03 -0500
Subject: [PATCH 32/39] fix: remove consoles and old code
---
.../container/FormLogin/index.tsx | 2 +-
.../components/BillItem/bill-item.component.tsx | 17 -----------------
.../container/FormBill/form-bill.container.tsx | 2 --
3 files changed, 1 insertion(+), 20 deletions(-)
diff --git a/modules/Authentication/container/FormLogin/index.tsx b/modules/Authentication/container/FormLogin/index.tsx
index 7fff929..633bace 100644
--- a/modules/Authentication/container/FormLogin/index.tsx
+++ b/modules/Authentication/container/FormLogin/index.tsx
@@ -21,7 +21,7 @@ const FormLogin = () => {
const onLoginWithGoogle = async values => {
try {
const res = await AuthenticationService.signInWithGoogle();
- console.log(res);
+
const { uid } = res.user;
if (uid) {
setUserId(uid);
diff --git a/modules/Bill/components/BillItem/bill-item.component.tsx b/modules/Bill/components/BillItem/bill-item.component.tsx
index 04b4bcc..5bc3184 100644
--- a/modules/Bill/components/BillItem/bill-item.component.tsx
+++ b/modules/Bill/components/BillItem/bill-item.component.tsx
@@ -88,23 +88,6 @@ export const BillItem = ({ bill, onCopyBill, onDeleteBill }: BillItemProps) => {
});
};
- const deleteBill = async () => {
- const hasRecurrence = await (await billsRecurrenceCollection.where('bills', 'array-contains', bill.id)).get();
-
- console.log(bill.id, hasRecurrence);
- // setLoadings({
- // ...loadings,
- // deleting: true,
- // });
- //
- // await billsCollection.doc(bill.id).delete();
- //
- // setLoadings({
- // ...loadings,
- // changingStatus: false,
- // });
- };
-
const isExpiring = useMemo(() => {
const currentDate = new Date();
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
index 0d1451f..6816481 100644
--- a/modules/Bill/container/FormBill/form-bill.container.tsx
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -203,8 +203,6 @@ export const FormBillContainer = ({ billId }: FormBillProps) => {
return `${prefix} conta`;
}, [billId, router.query.type]);
- console.log(errors);
-
return (
Date: Mon, 20 Nov 2023 08:03:58 -0500
Subject: [PATCH 33/39] feat: datepicker mobile nad save user when first login
---
.../DatePicker/date-picker.component.tsx | 5 +++
.../{index.tsx => form-login.container.tsx} | 19 +++++------
.../services/AuthenticationService.ts | 33 -------------------
.../services/authentication.service.ts | 28 ++++++++++++++++
modules/BaseModule/hooks/useIsMobile.tsx | 14 ++++++++
pages/login.tsx | 5 ++-
6 files changed, 57 insertions(+), 47 deletions(-)
rename modules/Authentication/container/FormLogin/{index.tsx => form-login.container.tsx} (75%)
delete mode 100644 modules/Authentication/services/AuthenticationService.ts
create mode 100644 modules/Authentication/services/authentication.service.ts
create mode 100644 modules/BaseModule/hooks/useIsMobile.tsx
diff --git a/components/DatePicker/date-picker.component.tsx b/components/DatePicker/date-picker.component.tsx
index 9a7c25a..a823e99 100644
--- a/components/DatePicker/date-picker.component.tsx
+++ b/components/DatePicker/date-picker.component.tsx
@@ -2,6 +2,8 @@ import React, { HTMLAttributes } from 'react';
import ReactDatePicker from 'react-datepicker';
import { FormControl, FormLabel, FormErrorMessage, useColorMode } from '@chakra-ui/react';
+import { useIsMobile } from '@Modules/BaseModule/hooks/useIsMobile';
+
interface Props {
isClearable?: boolean;
onChange: (date: Date) => any;
@@ -29,6 +31,8 @@ export const DatePicker = ({
...rest
}: Props & HTMLAttributes) => {
const isLight = useColorMode().colorMode === 'light';
+ const isMobile = useIsMobile();
+
return (
{label && {label}}
@@ -42,6 +46,7 @@ export const DatePicker = ({
maxDate={maxDate}
minDate={minDate}
className={!!error ? 'hasError' : ''}
+ withPortal={isMobile}
/>
{error && {error}}
diff --git a/modules/Authentication/container/FormLogin/index.tsx b/modules/Authentication/container/FormLogin/form-login.container.tsx
similarity index 75%
rename from modules/Authentication/container/FormLogin/index.tsx
rename to modules/Authentication/container/FormLogin/form-login.container.tsx
index 633bace..daee7e1 100644
--- a/modules/Authentication/container/FormLogin/index.tsx
+++ b/modules/Authentication/container/FormLogin/form-login.container.tsx
@@ -4,28 +4,27 @@ import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { FcGoogle } from 'react-icons/fc';
-import AuthenticationService from '@Authentication/services/AuthenticationService';
+import { signInWithGoogle } from '@Authentication/services/authentication.service';
import { useUser } from '@Modules/Authentication/context/UserContext';
-const FormLogin = () => {
+export const FormLoginContainer = () => {
const toast = useToast();
- const Router = useRouter();
+ const router = useRouter();
const { userId, setUserId } = useUser();
useEffect(() => {
if (userId) {
- Router.replace('/');
+ router.push('/');
}
- }, [Router, userId]);
+ }, [router, userId]);
- const onLoginWithGoogle = async values => {
+ const onLoginWithGoogle = async () => {
try {
- const res = await AuthenticationService.signInWithGoogle();
+ const uid = await signInWithGoogle();
- const { uid } = res.user;
if (uid) {
setUserId(uid);
- Router.replace('/');
+ router.push('/');
}
} catch (err) {
toast({
@@ -52,5 +51,3 @@ const FormLogin = () => {
);
};
-
-export default FormLogin;
diff --git a/modules/Authentication/services/AuthenticationService.ts b/modules/Authentication/services/AuthenticationService.ts
deleted file mode 100644
index e325074..0000000
--- a/modules/Authentication/services/AuthenticationService.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { auth, googleProvider } from '@Configs/Firebase';
-
-import User from '../interfaces/User.interface';
-
-export default class AuthenticationService {
- constructor() {}
-
- static signIn(email: string, password: string): Promise {
- return auth.signInWithEmailAndPassword(email, password).then(
- ({ user }) =>
- ({
- uid: user.uid,
- } as User)
- );
- }
-
- static signUp(email: string, password: string): Promise {
- return auth.createUserWithEmailAndPassword(email, password).then(
- ({ user }) =>
- ({
- uid: user.uid,
- } as User)
- );
- }
-
- static forgotPassword(email: string): Promise {
- return auth.sendPasswordResetEmail(email).then(_ => true);
- }
-
- static signInWithGoogle() {
- return auth.signInWithPopup(googleProvider);
- }
-}
diff --git a/modules/Authentication/services/authentication.service.ts b/modules/Authentication/services/authentication.service.ts
new file mode 100644
index 0000000..5452137
--- /dev/null
+++ b/modules/Authentication/services/authentication.service.ts
@@ -0,0 +1,28 @@
+import { auth, firestore, googleProvider } from '@Configs/Firebase';
+
+interface IGoogleProviderProfile {
+ email?: string;
+ family_name?: string;
+ given_name?: string;
+ granted_scopes?: string;
+ id?: string;
+ locale?: string;
+ name?: string;
+ picture?: string;
+}
+
+export const signInWithGoogle = () => {
+ return auth.signInWithPopup(googleProvider).then(({ additionalUserInfo, user }) => {
+ if (additionalUserInfo.isNewUser) {
+ const profile = additionalUserInfo.profile as IGoogleProviderProfile;
+
+ firestore.collection('user').add({
+ email: profile?.email,
+ name: `${profile?.given_name} ${profile?.family_name}`,
+ locale: profile?.locale,
+ image: profile?.picture,
+ });
+ }
+ return user.uid;
+ });
+};
diff --git a/modules/BaseModule/hooks/useIsMobile.tsx b/modules/BaseModule/hooks/useIsMobile.tsx
new file mode 100644
index 0000000..70a9c3f
--- /dev/null
+++ b/modules/BaseModule/hooks/useIsMobile.tsx
@@ -0,0 +1,14 @@
+import { useState, useEffect } from 'react';
+
+export const useIsMobile = () => {
+ const [width, setWidth] = useState(0);
+
+ useEffect(() => {
+ const handleWindowSizeChange = () => setWidth(window.innerWidth);
+ handleWindowSizeChange();
+ window.addEventListener('resize', handleWindowSizeChange);
+ return () => window.removeEventListener('resize', handleWindowSizeChange);
+ }, []);
+
+ return width <= 576;
+};
diff --git a/pages/login.tsx b/pages/login.tsx
index 3c36da6..5b0ed3c 100644
--- a/pages/login.tsx
+++ b/pages/login.tsx
@@ -1,15 +1,14 @@
import { useRouter } from 'next/router';
-import { Button } from '@chakra-ui/button';
import { Box } from '@chakra-ui/react';
-import FormLogin from '@Authentication/container/FormLogin';
+import { FormLoginContainer } from '@Authentication/container/FormLogin/form-login.container';
export default function Home() {
const router = useRouter();
return (
-
+
);
}
From 72ecb4b98c77a7db0925610bde02d333c16cc003 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Mon, 20 Nov 2023 08:11:35 -0500
Subject: [PATCH 34/39] fix: remove unused modules
---
.../container/FormForgotPassword/index.tsx | 65 -----------------
.../container/FormSignUp/index.tsx | 70 -------------------
pages/forgot.tsx | 14 ----
pages/signup.tsx | 14 ----
4 files changed, 163 deletions(-)
delete mode 100644 modules/Authentication/container/FormForgotPassword/index.tsx
delete mode 100644 modules/Authentication/container/FormSignUp/index.tsx
delete mode 100644 pages/forgot.tsx
delete mode 100644 pages/signup.tsx
diff --git a/modules/Authentication/container/FormForgotPassword/index.tsx b/modules/Authentication/container/FormForgotPassword/index.tsx
deleted file mode 100644
index 16cfa7e..0000000
--- a/modules/Authentication/container/FormForgotPassword/index.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { useForm } from 'react-hook-form';
-import { Button } from '@chakra-ui/button';
-import { Flex, Box, useToast } from '@chakra-ui/react';
-import { useRouter } from 'next/router';
-
-import AuthenticationService from '@Authentication/services/AuthenticationService';
-import { Input } from '@Components';
-
-const FormForgotPassword = () => {
- const toast = useToast();
-
- const {
- handleSubmit,
- register,
- formState: { errors, isSubmitting },
- } = useForm();
- const Router = useRouter();
-
- const onSubmit = async values => {
- try {
- const haveSentMail = await AuthenticationService.forgotPassword(values?.email);
- if (haveSentMail) {
- toast({
- description: 'An e-mail with password recovery link has been sent!',
- status: 'success',
- });
-
- Router.replace('/');
- }
- } catch (err) {
- toast({
- description: err.message,
- status: 'error',
- });
- }
- };
-
- return (
-
-
-
- );
-};
-
-export default FormForgotPassword;
diff --git a/modules/Authentication/container/FormSignUp/index.tsx b/modules/Authentication/container/FormSignUp/index.tsx
deleted file mode 100644
index 081fe1b..0000000
--- a/modules/Authentication/container/FormSignUp/index.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import { useForm } from 'react-hook-form';
-import { Button } from '@chakra-ui/button';
-import { useToast, Flex, Box } from '@chakra-ui/react';
-import { useRouter } from 'next/router';
-
-import { Input } from '@Components';
-import { auth } from '@Configs/Firebase';
-import { useUser } from '@Modules/Authentication/context/UserContext';
-
-const FormSignUp = () => {
- const {
- handleSubmit,
- register,
- formState: { errors, isSubmitting },
- } = useForm();
- const Router = useRouter();
- const toast = useToast();
- const { setUserId } = useUser();
-
- const onSubmit = async values => {
- try {
- const { user } = await auth.createUserWithEmailAndPassword(values.email, values.password);
-
- localStorage.setItem('USER_UID', user.uid);
- setUserId(user.uid);
- Router.replace('/');
-
- toast({
- description: 'User successful created!',
- status: 'success',
- });
- } catch (error) {
- console.error(error);
- }
- };
-
- return (
-
-
-
- );
-};
-
-export default FormSignUp;
diff --git a/pages/forgot.tsx b/pages/forgot.tsx
deleted file mode 100644
index 08e2e5a..0000000
--- a/pages/forgot.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useRouter } from 'next/router';
-import { Box } from '@chakra-ui/react';
-
-import FormForgotPassword from '@Authentication/container/FormForgotPassword';
-
-export default function Home() {
- const router = useRouter();
-
- return (
-
-
-
- );
-}
diff --git a/pages/signup.tsx b/pages/signup.tsx
deleted file mode 100644
index 074b2ab..0000000
--- a/pages/signup.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useRouter } from 'next/router';
-import { Box } from '@chakra-ui/react';
-
-import FormSignUp from '@Modules/Authentication/container/FormSignUp';
-
-export default function Home() {
- const router = useRouter();
-
- return (
-
-
-
- );
-}
From 30642639798be47e1fab97626939c656fe72bfe7 Mon Sep 17 00:00:00 2001
From: Victor Lucas
Date: Mon, 20 Nov 2023 08:17:47 -0500
Subject: [PATCH 35/39] fix: remove unused module
---
pages/logout.tsx | 21 ---------------------
1 file changed, 21 deletions(-)
delete mode 100644 pages/logout.tsx
diff --git a/pages/logout.tsx b/pages/logout.tsx
deleted file mode 100644
index 845d32e..0000000
--- a/pages/logout.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { useEffect } from 'react';
-import { useRouter } from 'next/router';
-import { Box } from '@chakra-ui/react';
-
-import FormSignUp from '@Modules/Authentication/container/FormSignUp';
-import { auth } from '@Configs/Firebase';
-
-export default function Home() {
- const router = useRouter();
-
- useEffect(() => {
- auth.signOut();
- router.push('/');
- }, [router]);
-
- return (
-
- Loading...
-
- );
-}
From 9bcf0eb441071d5cba4aa0bdf55625055864690b Mon Sep 17 00:00:00 2001
From: Victor Lucas <11355873+victorlucss@users.noreply.github.com>
Date: Mon, 20 Nov 2023 08:19:43 -0500
Subject: [PATCH 36/39] Sync up (#14)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* build(deps): bump ansi-regex from 5.0.0 to 5.0.1
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)
---
updated-dependencies:
- dependency-name: ansi-regex
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
* build(deps): bump next from 11.0.1 to 11.1.1
Bumps [next](https://github.com/vercel/next.js) from 11.0.1 to 11.1.1.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v11.0.1...v11.1.1)
---
updated-dependencies:
- dependency-name: next
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
* feat: Migrating to Next 12 (#8)
* Feature/BaseModule (#7)
* feat: Modal component
* feat: Bubble types
* feat: added yup
* feat: Bubble component to render fields
* feat: 🤘🏽 BaseForm component
* feat: 🤘🏽 BaseList component
* feat: BaseField and SelectOption types
* feat: 🤘🏽 renderFields method
* fix: start next with esm false (#9)
* feat: sign in page with facelift
* feat: facelift register page
* feat: facelift forgot password page
* fix: empty space linting
* feat: a LOT of new stuff
* fix: specify node version
* fix: node version
* fix: datepicker, stats, and more
* fix: some translations and pipeline
* fix: build with openssl-legacy-provider
* fix: translations
* feat: new stats, billitem with exprs
* feat: use popover to improve visibility
* feat: new way of handling status and categories
* feat: copy bill
* feat: go to form bill already with value
* fix: layout issues
* fix: missing cancel action
* feat: datePicker max and min dates and hasError
* feat: new money input
* feat: defaultRequiredMessage
* feat: billsRecurrenceCollection
* feat: recurrence feature
* fix: remove every year recurrence
* fix: show category only for expense
* feat: allow deleting recurrence
* fix: remove consoles and old code
* feat: datepicker mobile nad save user when first login
* fix: remove unused modules
* fix: remove unused module
---------
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marcos Gênesis da Silva
Co-authored-by: Marcos Gênesis <49327985+marcosgenesis@users.noreply.github.com>
---
.DS_Store | Bin 6148 -> 12292 bytes
.gitignore | 2 +-
.vscode/settings.json | 3 +
components/Box/index.tsx | 31 +
.../{index.tsx => date-picker.component.tsx} | 17 +-
components/If/if.component.tsx | 6 +
components/LateralMenu/index.tsx | 164 ++++
components/Modal/index.tsx | 18 +
components/MoneyInput/index.tsx | 21 +-
components/RadioCard/radio-card.component.tsx | 34 +
components/index.ts | 7 +-
configs/Firebase.ts | 3 +
configs/theme.tsx | 4 +-
hoc/withLateralMenu.tsx | 11 +
.../container/FormForgotPassword/index.tsx | 65 --
.../FormLogin/form-login.container.tsx | 53 ++
.../container/FormLogin/index.tsx | 90 --
.../container/FormSignUp/index.tsx | 70 --
.../Authentication/context/UserContext.tsx | 7 -
.../services/AuthenticationService.ts | 29 -
.../services/authentication.service.ts | 28 +
.../BaseModule/components/Bubble/index.tsx | 62 ++
modules/BaseModule/constants/Bubble.ts | 6 +
.../BaseModule/container/BaseForm/index.tsx | 82 ++
.../BaseModule/container/BaseList/index.tsx | 115 +++
modules/BaseModule/hooks/useIsMobile.tsx | 14 +
modules/BaseModule/interfaces/BaseField.ts | 11 +
modules/BaseModule/interfaces/SelectOption.ts | 4 +
modules/BaseModule/shared/renderFields.tsx | 20 +
modules/Bill/components/BillFilters/index.tsx | 22 +-
.../BillItem/bill-item.component.tsx | 300 +++++++
modules/Bill/components/BillItem/index.tsx | 161 ----
.../CopyBill/copy-bill.component.tsx | 148 +++
.../DeleteBill/delete-bill.component.tsx | 105 +++
modules/Bill/components/StateMonth/index.tsx | 56 --
.../StatsMonth/stats-month.component.tsx | 57 ++
modules/Bill/constants/BillConsts.ts | 22 +
.../Bill/constants/FirestoreCollections.ts | 2 +
modules/Bill/constants/Types.ts | 2 +
.../FormBill/form-bill.container.tsx | 329 +++++++
modules/Bill/container/FormBill/index.tsx | 226 -----
modules/Bill/container/ListBills/index.tsx | 62 --
.../ListBills/list-bills.container.tsx | 109 +++
modules/Bill/interfaces/Bill.interface.ts | 5 +-
modules/Category/.gitkeep | 0
next-env.d.ts | 3 +
next.config.js | 3 +
package.json | 14 +-
pages/_app.tsx | 9 +-
pages/bill/[billId].tsx | 11 +-
pages/bill/index.tsx | 9 +-
pages/forgot.tsx | 14 -
pages/index.tsx | 24 +-
pages/login.tsx | 7 +-
pages/signup.tsx | 14 -
pages/styles.css | 194 ----
pages/styles.scss | 214 +++++
public/favicon.ico | Bin 25931 -> 719 bytes
public/logo.png | Bin 0 -> 1218 bytes
public/vercel.svg | 4 -
tsconfig.json | 4 +-
yarn.lock | 840 ++++++++++--------
62 files changed, 2489 insertions(+), 1458 deletions(-)
create mode 100644 .vscode/settings.json
create mode 100644 components/Box/index.tsx
rename components/DatePicker/{index.tsx => date-picker.component.tsx} (74%)
create mode 100644 components/If/if.component.tsx
create mode 100644 components/LateralMenu/index.tsx
create mode 100644 components/Modal/index.tsx
create mode 100644 components/RadioCard/radio-card.component.tsx
create mode 100644 hoc/withLateralMenu.tsx
delete mode 100644 modules/Authentication/container/FormForgotPassword/index.tsx
create mode 100644 modules/Authentication/container/FormLogin/form-login.container.tsx
delete mode 100644 modules/Authentication/container/FormLogin/index.tsx
delete mode 100644 modules/Authentication/container/FormSignUp/index.tsx
delete mode 100644 modules/Authentication/services/AuthenticationService.ts
create mode 100644 modules/Authentication/services/authentication.service.ts
create mode 100644 modules/BaseModule/components/Bubble/index.tsx
create mode 100644 modules/BaseModule/constants/Bubble.ts
create mode 100644 modules/BaseModule/container/BaseForm/index.tsx
create mode 100644 modules/BaseModule/container/BaseList/index.tsx
create mode 100644 modules/BaseModule/hooks/useIsMobile.tsx
create mode 100644 modules/BaseModule/interfaces/BaseField.ts
create mode 100644 modules/BaseModule/interfaces/SelectOption.ts
create mode 100644 modules/BaseModule/shared/renderFields.tsx
create mode 100644 modules/Bill/components/BillItem/bill-item.component.tsx
delete mode 100644 modules/Bill/components/BillItem/index.tsx
create mode 100644 modules/Bill/components/CopyBill/copy-bill.component.tsx
create mode 100644 modules/Bill/components/DeleteBill/delete-bill.component.tsx
delete mode 100644 modules/Bill/components/StateMonth/index.tsx
create mode 100644 modules/Bill/components/StatsMonth/stats-month.component.tsx
create mode 100644 modules/Bill/constants/BillConsts.ts
create mode 100644 modules/Bill/container/FormBill/form-bill.container.tsx
delete mode 100644 modules/Bill/container/FormBill/index.tsx
delete mode 100644 modules/Bill/container/ListBills/index.tsx
create mode 100644 modules/Bill/container/ListBills/list-bills.container.tsx
delete mode 100644 modules/Category/.gitkeep
delete mode 100644 pages/forgot.tsx
delete mode 100644 pages/signup.tsx
delete mode 100644 pages/styles.css
create mode 100644 pages/styles.scss
create mode 100644 public/logo.png
delete mode 100644 public/vercel.svg
diff --git a/.DS_Store b/.DS_Store
index 9f24cd0e68f13a98a3a6a19d9ca8f92e31ebcccb..7b548ba6ffef463a1c53aacad40a894ba4edf7f3 100644
GIT binary patch
literal 12292
zcmeHNeQX>@6@Tyial2=aRT7Nm}BMb3>`yq;c%nNn7Xcc4Ke6
zw|l+aJLdyai;oD}O0+^P2vwC36vRKJpsFeopdg?^sA{34AqA=bz#lDtA|yUkC~s!=
z%+B5&QIP`3$d-pqTyd9(9ocL4y$%KA=#J^)ZCvRrGYp_o6jQBLpG@{;v^W&xaI6mXG-Ps>u1HgA(S#vwr5n
z^FU>C*?C*a&qw@xRpgwNcsMKNf))KM1`2j+Pcd@JNBn$MYdOOxH`NFJr8!xurF(#FaMXfvH7jdCJRr
zWp^xFI>Bm39mmR5%h}wFX)MocUE_}JWlh^CaRyU2h~)lbrmZ{6V@}!DUCuitIuun=
z=e5n}&+km9_Y9&Z9yP^q&RL5z_0i
zuu|5-&Z)dpC2q1*5|WUzHDVZW7M)3u{-M-XFOIq?m8uJoDFOZ8@Jz*zIES6#tzXz|^M50y>t
ztk$b2Vve5V4XXBS<$j%nyvNbmh&t~{_9V9{$_ds!UNR^Z&56Ebzp7=Gqb{i|h8Rrj
zP&HRQx<1zGxT38mIjSfR
zvS}x?u6L+t*j0ft$vYM8r^<16Fh)XyJC{9(^?3VS9(YK#gcGD)h<5%%(_$LsyUWgr_OnO3C
zZpD8>#1`vqmhQ|%;^6;uv%J~Pw#WL;Yr8gV>FpcbwP*iS2eSs`ErYu?3`OH
zU+1vBiG7slo+gtv&NSLiTAXb?PE48qI
zHZJ2?veb{0tzN*-;^*)Y`~p6SPvIBwOZXN1I({Q$gCCV`5MK)0V8O{`{8NfKet$jn
zsh^D2(&$&EDJ}*Nh7=7U+j?cHWLu8CK<#XQsBi=(U=%WN59LEp0G++-{^z@De4D6-
zrFYdX7*K)=doNBUS3Zi+C3*!yG$HM*7vK32)2O44L!zsdZfmYx&wNPEw
z0Iv^e&_dr9JmRpz_``l0H_+QadWoX0>;Vc{a*no2NN33kY?9a_dGoLolK9UdiJ87p
zh!BVnh!BVnh!FTsA+VbUZl+UdflfzHI@?>GX5Zb{`a&n;mHtn2k1NnGor^X7(y7>X
zlIhbz^V;NpoRMelSo!&Oxi>WT>089y0sev`&0dEhIDf}y4zu~=G=IhSD0DC+?E&`G
zQUvALa{anDE#Y;B#tF*Om?|ib|IReQeVYRP3Bf!ZgChAmvY$Y{C%{m^H>=AdYjV?8
z;;Bm))Q4ymeOw#RN(fKfEY_edt*qPQG&Ery^xMK(k;f@%6{42)X?m}AJXw>~UoKTw
zMw&IaG61VTd-;>xhC{Q-(x+&$HR(NJt@4^MZ?mrSKD8`;Y^HX+ko57tbpM#Gb5$;X
zoRIVlsATE6_t^xC%;yYA{YXe^pGuY%e@#?=PXj5}dL{d)O6T|1k*b6H?!onG;LY>@
ze}Xn2r+b$}Z&u26Z!ZkF;NLwK^zCX
zK6Z{Yqzxf@dO%?HFX)4|1XraGqP*|b6p2Ez6zRrA_bf^mNb3f+g=`lDacbdwj3e}n
zLb{|3P=FC)Pj8wx0>alO_DT*g4GMbANS)ej!p@e^qr<{L|
xr<}c&Wu5GN<$=m0tU&py$f-o(zy2eD^eHep|7E{{-7li^U!2M^G9R?_{~svy|0@6h
delta 207
zcmZokXfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~3gIoUvmMH0vd3o?SKe1<%RR3I*4
zDBgH+IWwcc8{hiIa6ETZ$V^
zW|q*Iyj{X-bD<;~<6?FW4nby+;Xre_frKl_-i;T(Gf(E%(bWM718rnzfY2Z&h|dI~
SK>)}AxfbLBhRyLjbC>~6? {
+ return (
+
+ {(title || description) && (
+
+ {title && (
+
+ {title}
+
+ )}
+ {description && (
+
+ {description}
+
+ )}
+
+ )}
+
+ {children}
+
+ );
+};
diff --git a/components/DatePicker/index.tsx b/components/DatePicker/date-picker.component.tsx
similarity index 74%
rename from components/DatePicker/index.tsx
rename to components/DatePicker/date-picker.component.tsx
index aa8e024..a823e99 100644
--- a/components/DatePicker/index.tsx
+++ b/components/DatePicker/date-picker.component.tsx
@@ -1,6 +1,8 @@
import React, { HTMLAttributes } from 'react';
-import { FormControl, FormLabel, FormErrorMessage, useColorMode } from '@chakra-ui/react';
import ReactDatePicker from 'react-datepicker';
+import { FormControl, FormLabel, FormErrorMessage, useColorMode } from '@chakra-ui/react';
+
+import { useIsMobile } from '@Modules/BaseModule/hooks/useIsMobile';
interface Props {
isClearable?: boolean;
@@ -11,6 +13,8 @@ interface Props {
label?: string;
error?: string;
value?: string;
+ maxDate?: Date;
+ minDate?: Date;
}
export const DatePicker = ({
@@ -22,20 +26,27 @@ export const DatePicker = ({
label,
error,
value,
+ maxDate,
+ minDate,
...rest
}: Props & HTMLAttributes) => {
const isLight = useColorMode().colorMode === 'light';
+ const isMobile = useIsMobile();
+
return (
{label && {label}}
-
+
{error && {error}}
diff --git a/components/If/if.component.tsx b/components/If/if.component.tsx
new file mode 100644
index 0000000..1e461c8
--- /dev/null
+++ b/components/If/if.component.tsx
@@ -0,0 +1,6 @@
+import { ReactElement, ReactNode } from 'react';
+
+export const If = ({ condition, children }: { condition: boolean; children: ReactElement }) => {
+ if (condition) return children;
+ return null;
+};
diff --git a/components/LateralMenu/index.tsx b/components/LateralMenu/index.tsx
new file mode 100644
index 0000000..cda7833
--- /dev/null
+++ b/components/LateralMenu/index.tsx
@@ -0,0 +1,164 @@
+import React, { ReactNode, ReactText } from 'react';
+import {
+ IconButton,
+ Box,
+ CloseButton,
+ Flex,
+ Icon,
+ useColorModeValue,
+ Button,
+ Link,
+ Drawer,
+ DrawerContent,
+ Text,
+ useDisclosure,
+ BoxProps,
+ FlexProps,
+ Badge,
+} from '@chakra-ui/react';
+import { FiHome, FiPower, FiTrendingUp, FiTrendingDown, FiMenu } from 'react-icons/fi';
+import { IconType } from 'react-icons';
+import Image from 'next/image';
+
+interface LinkItemProps {
+ name: string;
+ icon: IconType;
+ link: string;
+}
+const LinkItems: Array = [
+ { name: 'Início', icon: FiHome, link: '/' },
+ { name: 'Criar receita', icon: FiTrendingUp, link: '/bill?type=INCOME' },
+ { name: 'Criar despesa', icon: FiTrendingDown, link: '/bill?type=EXPENSE' },
+ {
+ name: 'Sair',
+ icon: FiPower,
+ link: '/logout',
+ },
+];
+
+export const LateralMenu = ({ children }: { children: ReactNode }) => {
+ const { isOpen, onOpen, onClose } = useDisclosure();
+ return (
+
+ onClose} display={{ base: 'none', md: 'block' }} />
+
+
+
+
+
+ {/* mobilenav */}
+
+
+ {children}
+
+
+ );
+};
+
+interface SidebarProps extends BoxProps {
+ onClose: () => void;
+}
+
+const SidebarContent = ({ onClose, ...rest }: SidebarProps) => {
+ return (
+
+
+
+
+
+ Beta
+
+
+
+
+ {LinkItems.map(({ name, icon, link }) => (
+
+ {name}
+
+ ))}
+
+ );
+};
+
+interface NavItemProps extends FlexProps {
+ icon: IconType;
+ children: ReactText;
+ link: string;
+}
+const NavItem = ({ icon, link, children, ...rest }: NavItemProps) => {
+ return (
+
+
+ {icon && (
+
+ )}
+ {children}
+
+
+ );
+};
+
+interface MobileProps extends FlexProps {
+ onOpen: () => void;
+}
+const MobileNav = ({ onOpen, ...rest }: MobileProps) => {
+ return (
+
+ } />
+
+
+
+
+
+ Beta
+
+
+
+
+ );
+};
diff --git a/components/Modal/index.tsx b/components/Modal/index.tsx
new file mode 100644
index 0000000..36ee630
--- /dev/null
+++ b/components/Modal/index.tsx
@@ -0,0 +1,18 @@
+import { Modal as ModalChakra, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
+
+interface ModalInterface {
+ onClose: () => void;
+ isOpen: boolean;
+ children: React.ReactElement;
+}
+
+export const Modal = ({ onClose, isOpen, children }: ModalInterface) => {
+ return (
+
+
+
+ {children}
+
+
+ );
+};
diff --git a/components/MoneyInput/index.tsx b/components/MoneyInput/index.tsx
index cf40d71..106183b 100644
--- a/components/MoneyInput/index.tsx
+++ b/components/MoneyInput/index.tsx
@@ -2,13 +2,11 @@ import {
FormControl,
FormLabel,
FormErrorMessage,
- NumberInputProps,
NumberInput,
NumberInputField,
- NumberInputStepper,
- NumberIncrementStepper,
- NumberDecrementStepper,
FormControlProps,
+ InputLeftAddon,
+ InputGroup,
} from '@chakra-ui/react';
import { forwardRef, LegacyRef } from 'react';
@@ -19,18 +17,17 @@ type MoneyInputProps = FormControlProps & {
};
export const MoneyInput = forwardRef(
- ({ name, label, error, ...rest }: MoneyInputProps, ref) => {
+ ({ name, label, error, isRequired, ...rest }: MoneyInputProps, ref) => {
return (
{label && {label}}
- }>
-
-
-
-
-
-
+
+ R$
+
+ } borderLeftRadius={0} />
+
+
{error && {error}}
);
diff --git a/components/RadioCard/radio-card.component.tsx b/components/RadioCard/radio-card.component.tsx
new file mode 100644
index 0000000..7c9f6c4
--- /dev/null
+++ b/components/RadioCard/radio-card.component.tsx
@@ -0,0 +1,34 @@
+import { Box, useRadio } from '@chakra-ui/react';
+
+export const RadioCard = props => {
+ const { getInputProps, getCheckboxProps } = useRadio(props);
+
+ const input = getInputProps();
+ const checkbox = getCheckboxProps();
+
+ return (
+
+
+
+ {props.children}
+
+
+ );
+};
diff --git a/components/index.ts b/components/index.ts
index 0653a6d..16b44ae 100644
--- a/components/index.ts
+++ b/components/index.ts
@@ -1,4 +1,9 @@
export * from './MoneyInput';
export * from './Input';
export * from './Select';
-export * from './DatePicker';
+export * from './DatePicker/date-picker.component';
+export * from './Modal';
+export * from './LateralMenu';
+export * from './Box';
+export * from './RadioCard/radio-card.component';
+export * from './If/if.component';
diff --git a/configs/Firebase.ts b/configs/Firebase.ts
index 9829e38..8c5d3a9 100644
--- a/configs/Firebase.ts
+++ b/configs/Firebase.ts
@@ -16,6 +16,9 @@ if (!firebase.apps.length) {
} else {
firebase.app();
}
+
export default firebase;
export const firestore = firebase.firestore();
export const auth = firebase.auth();
+
+export const googleProvider = new firebase.auth.GoogleAuthProvider();
diff --git a/configs/theme.tsx b/configs/theme.tsx
index 4a365e4..3a4bc4a 100644
--- a/configs/theme.tsx
+++ b/configs/theme.tsx
@@ -5,6 +5,8 @@ const config: ThemeConfig = {
useSystemColorMode: false,
};
-const theme = extendTheme({ config });
+const theme = extendTheme({
+ config,
+});
export default theme;
diff --git a/hoc/withLateralMenu.tsx b/hoc/withLateralMenu.tsx
new file mode 100644
index 0000000..7bdc016
--- /dev/null
+++ b/hoc/withLateralMenu.tsx
@@ -0,0 +1,11 @@
+import { LateralMenu } from '@Components/LateralMenu';
+
+const withLateralMenu = Children => {
+ return props => (
+
+
+
+ );
+};
+
+export default withLateralMenu;
diff --git a/modules/Authentication/container/FormForgotPassword/index.tsx b/modules/Authentication/container/FormForgotPassword/index.tsx
deleted file mode 100644
index 28dcdeb..0000000
--- a/modules/Authentication/container/FormForgotPassword/index.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { useForm } from 'react-hook-form';
-import { Button } from '@chakra-ui/button';
-import { Flex, Box, useToast } from '@chakra-ui/react';
-import { useRouter } from 'next/router';
-
-import AuthenticationService from '@Authentication/services/AuthenticationService';
-import { Input } from '@Components';
-
-const FormForgotPassword = () => {
- const toast = useToast();
-
- const {
- handleSubmit,
- register,
- formState: { errors, isSubmitting },
- } = useForm();
- const Router = useRouter();
-
- const onSubmit = async values => {
- try {
- const haveSentMail = await AuthenticationService.forgotPassword(values?.email);
- if (haveSentMail) {
- toast({
- description: 'An e-mail with password recovery link has been sent!',
- status: 'success',
- });
-
- Router.replace('/');
- }
- } catch (err) {
- toast({
- description: err.message,
- status: 'error',
- });
- }
- };
-
- return (
-
-
-
- );
-};
-
-export default FormForgotPassword;
diff --git a/modules/Authentication/container/FormLogin/form-login.container.tsx b/modules/Authentication/container/FormLogin/form-login.container.tsx
new file mode 100644
index 0000000..daee7e1
--- /dev/null
+++ b/modules/Authentication/container/FormLogin/form-login.container.tsx
@@ -0,0 +1,53 @@
+import { Button } from '@chakra-ui/button';
+import { Flex, Box, useToast, Text, Spacer, Image, AbsoluteCenter } from '@chakra-ui/react';
+import { useRouter } from 'next/router';
+import { useEffect } from 'react';
+import { FcGoogle } from 'react-icons/fc';
+
+import { signInWithGoogle } from '@Authentication/services/authentication.service';
+import { useUser } from '@Modules/Authentication/context/UserContext';
+
+export const FormLoginContainer = () => {
+ const toast = useToast();
+ const router = useRouter();
+ const { userId, setUserId } = useUser();
+
+ useEffect(() => {
+ if (userId) {
+ router.push('/');
+ }
+ }, [router, userId]);
+
+ const onLoginWithGoogle = async () => {
+ try {
+ const uid = await signInWithGoogle();
+
+ if (uid) {
+ setUserId(uid);
+ router.push('/');
+ }
+ } catch (err) {
+ toast({
+ description: err.message,
+ status: 'error',
+ });
+ }
+ };
+
+ return (
+
+
+
+
+ Desbrave o caminho para a estabilidade financeira e saia do vermelho.
+
+
+
+
+
+ Login com Google
+
+
+
+ );
+};
diff --git a/modules/Authentication/container/FormLogin/index.tsx b/modules/Authentication/container/FormLogin/index.tsx
deleted file mode 100644
index ce5ed91..0000000
--- a/modules/Authentication/container/FormLogin/index.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { useForm } from 'react-hook-form';
-import { Button } from '@chakra-ui/button';
-import { Flex, Box, useToast } from '@chakra-ui/react';
-import { useRouter } from 'next/router';
-import Link from 'next/link';
-import { useEffect } from 'react';
-
-import AuthenticationService from '@Authentication/services/AuthenticationService';
-import User from '@Authentication/interfaces/User.interface';
-import { useUser } from '@Modules/Authentication/context/UserContext';
-import { Input } from '@Components';
-
-const FormLogin = () => {
- const toast = useToast();
- const {
- handleSubmit,
- register,
- formState: { errors, isSubmitting },
- } = useForm();
- const Router = useRouter();
- const { userId, setUserId } = useUser();
-
- useEffect(() => {
- if (userId) {
- Router.replace('/');
- }
- }, [userId]);
-
- const onSubmit = async values => {
- try {
- const { uid } = (await AuthenticationService.signIn(values?.email, values?.password)) as User;
- if (uid) {
- setUserId(uid);
- Router.replace('/');
- }
- } catch (err) {
- toast({
- description: err.message,
- status: 'error',
- });
- }
- };
-
- return (
-
-
-
- );
-};
-
-export default FormLogin;
diff --git a/modules/Authentication/container/FormSignUp/index.tsx b/modules/Authentication/container/FormSignUp/index.tsx
deleted file mode 100644
index 8e47736..0000000
--- a/modules/Authentication/container/FormSignUp/index.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import { useForm } from 'react-hook-form';
-import { Button } from '@chakra-ui/button';
-import { useToast, Flex, Box } from '@chakra-ui/react';
-import { useRouter } from 'next/router';
-
-import { Input } from '@Components';
-import { auth } from '@Configs/Firebase';
-import { useUser } from '@Modules/Authentication/context/UserContext';
-
-const FormSignUp = () => {
- const {
- handleSubmit,
- register,
- formState: { errors, isSubmitting },
- } = useForm();
- const Router = useRouter();
- const toast = useToast();
- const { setUserId } = useUser();
-
- const onSubmit = async values => {
- try {
- const { user } = await auth.createUserWithEmailAndPassword(values.email, values.password);
-
- localStorage.setItem('USER_UID', user.uid);
- setUserId(user.uid);
- Router.replace('/');
-
- toast({
- description: 'User successful created!',
- status: 'success',
- });
- } catch (error) {
- console.error(error);
- }
- };
-
- return (
-
-
-
- );
-};
-
-export default FormSignUp;
diff --git a/modules/Authentication/context/UserContext.tsx b/modules/Authentication/context/UserContext.tsx
index 77f2142..df6a3a6 100644
--- a/modules/Authentication/context/UserContext.tsx
+++ b/modules/Authentication/context/UserContext.tsx
@@ -15,11 +15,6 @@ interface UserProviderProps {
children: React.ReactNode;
}
-const formatAuthUser = user => ({
- uid: user.uid,
- email: user.email,
-});
-
export const UserProvider = ({ children }: UserProviderProps) => {
const [userId, setUserId] = useState(null);
const [user, setUser] = useState(null);
@@ -31,9 +26,7 @@ export const UserProvider = ({ children }: UserProviderProps) => {
return;
}
- // var formattedUser = formatAuthUser(authState);
setUserId(authState.uid);
- // setUser(formatAuthUser);
};
useEffect(() => {
diff --git a/modules/Authentication/services/AuthenticationService.ts b/modules/Authentication/services/AuthenticationService.ts
deleted file mode 100644
index 9de8d30..0000000
--- a/modules/Authentication/services/AuthenticationService.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { auth } from '@Configs/Firebase';
-
-import User from '../interfaces/User.interface';
-
-export default class AuthenticationService {
- constructor() {}
-
- static signIn(email: string, password: string): Promise {
- return auth.signInWithEmailAndPassword(email, password).then(
- ({ user }) =>
- ({
- uid: user.uid,
- } as User)
- );
- }
-
- static signUp(email: string, password: string): Promise {
- return auth.createUserWithEmailAndPassword(email, password).then(
- ({ user }) =>
- ({
- uid: user.uid,
- } as User)
- );
- }
-
- static forgotPassword(email: string): Promise {
- return auth.sendPasswordResetEmail(email).then(_ => true);
- }
-}
diff --git a/modules/Authentication/services/authentication.service.ts b/modules/Authentication/services/authentication.service.ts
new file mode 100644
index 0000000..5452137
--- /dev/null
+++ b/modules/Authentication/services/authentication.service.ts
@@ -0,0 +1,28 @@
+import { auth, firestore, googleProvider } from '@Configs/Firebase';
+
+interface IGoogleProviderProfile {
+ email?: string;
+ family_name?: string;
+ given_name?: string;
+ granted_scopes?: string;
+ id?: string;
+ locale?: string;
+ name?: string;
+ picture?: string;
+}
+
+export const signInWithGoogle = () => {
+ return auth.signInWithPopup(googleProvider).then(({ additionalUserInfo, user }) => {
+ if (additionalUserInfo.isNewUser) {
+ const profile = additionalUserInfo.profile as IGoogleProviderProfile;
+
+ firestore.collection('user').add({
+ email: profile?.email,
+ name: `${profile?.given_name} ${profile?.family_name}`,
+ locale: profile?.locale,
+ image: profile?.picture,
+ });
+ }
+ return user.uid;
+ });
+};
diff --git a/modules/BaseModule/components/Bubble/index.tsx b/modules/BaseModule/components/Bubble/index.tsx
new file mode 100644
index 0000000..14968c2
--- /dev/null
+++ b/modules/BaseModule/components/Bubble/index.tsx
@@ -0,0 +1,62 @@
+import React from 'react';
+import { FieldErrors, FieldValues, UseFormRegister } from 'react-hook-form';
+
+import { Input, Select } from '@Components';
+import SelectOption from '@Modules/BaseModule/interfaces/SelectOption';
+
+import { BubbleEnum, BUBBLE_TYPES } from '../../constants/Bubble';
+
+interface BubbleInterface {
+ type: BubbleEnum;
+ name: string;
+ label: string;
+ register: UseFormRegister;
+ errors: FieldErrors;
+ required?: boolean;
+ props?: object;
+ options?: SelectOption[];
+ value?: (string | number | readonly string[]) & string;
+}
+
+const Bubble = ({
+ type,
+ name,
+ label,
+ register,
+ errors,
+ required = false,
+ options = [],
+ value,
+ props = {},
+}: BubbleInterface) => {
+ switch (type) {
+ case BUBBLE_TYPES.INPUT:
+ return (
+
+ );
+
+ case BUBBLE_TYPES.SELECT:
+ return (
+
+ );
+
+ default:
+ return <>>;
+ }
+};
+
+export default Bubble;
diff --git a/modules/BaseModule/constants/Bubble.ts b/modules/BaseModule/constants/Bubble.ts
new file mode 100644
index 0000000..c547777
--- /dev/null
+++ b/modules/BaseModule/constants/Bubble.ts
@@ -0,0 +1,6 @@
+export const BUBBLE_TYPES = {
+ INPUT: 'INPUT',
+ SELECT: 'SELECT',
+};
+
+export type BubbleEnum = keyof typeof BUBBLE_TYPES;
diff --git a/modules/BaseModule/container/BaseForm/index.tsx b/modules/BaseModule/container/BaseForm/index.tsx
new file mode 100644
index 0000000..0bf8709
--- /dev/null
+++ b/modules/BaseModule/container/BaseForm/index.tsx
@@ -0,0 +1,82 @@
+import React, { useCallback, useEffect } from 'react';
+import { useForm } from 'react-hook-form';
+import { Button } from '@chakra-ui/button';
+import { Flex } from '@chakra-ui/react';
+import { yupResolver } from '@hookform/resolvers/yup';
+import * as Yup from 'yup';
+
+import BaseField from '@Modules/BaseModule/interfaces/BaseField';
+import renderFields from '@Modules/BaseModule/shared/renderFields';
+
+interface BaseFormInterface {
+ id?: string | number;
+ fetch?: (id: string | number) => Promise;
+ fields: BaseField[];
+ onSubmit: (element: T) => T | Promise | Promise;
+ submitLabel?: string;
+ schema: Yup.AnyObjectSchema;
+}
+
+const BaseForm = ({
+ id,
+ fetch,
+ onSubmit,
+ fields,
+ submitLabel = 'Submit',
+ schema,
+}: BaseFormInterface) => {
+ const {
+ handleSubmit,
+ register,
+ setValue,
+ formState: { errors, isSubmitting },
+ } = useForm({
+ resolver: yupResolver(schema),
+ });
+
+ const wrapperOnSubmit = values => {
+ const element = values as T;
+
+ onSubmit(element);
+ };
+
+ const fetchData = useCallback(
+ async (id): Promise => {
+ if (id && !!fetch) {
+ const model = await fetch(id);
+
+ if (model) {
+ fields.forEach(({ name }) => {
+ if (model[name]) {
+ setValue(name, model[name]);
+ }
+ });
+ }
+
+ return model;
+ }
+ },
+ [fetch, fields, setValue]
+ );
+
+ useEffect(() => {
+ if (id) {
+ fetchData(id);
+ }
+ }, [fetchData, id]);
+
+ return (
+
+ );
+};
+
+export { BaseForm };
+export default BaseForm;
diff --git a/modules/BaseModule/container/BaseList/index.tsx b/modules/BaseModule/container/BaseList/index.tsx
new file mode 100644
index 0000000..416013e
--- /dev/null
+++ b/modules/BaseModule/container/BaseList/index.tsx
@@ -0,0 +1,115 @@
+import React, { useEffect, useMemo, useState } from 'react';
+import { Box, Table, Thead, Tbody, Tr, Th, Td, Spinner, Button } from '@chakra-ui/react';
+
+import { Modal } from '@Components';
+
+const MODAL_TYPES = {
+ EDIT_MODAL: 'EDIT_MODAL',
+ DELETE_MODAL: 'DELETE_MODAL',
+};
+
+interface BaseHeader {
+ label: string;
+ field: string;
+}
+
+interface BaseListInterface {
+ headers: BaseHeader[];
+ items: T[];
+ isLoading: boolean;
+ optionsEnabled?: boolean;
+ onDeleteItem?: (id: string | number) => void;
+ onCloseOption?: () => void;
+ editComponent?: (id: string | number) => React.ReactElement;
+}
+
+const BaseList = ({
+ headers,
+ items,
+ isLoading,
+ optionsEnabled = false,
+ editComponent,
+ onCloseOption,
+ onDeleteItem,
+}: BaseListInterface) => {
+ const [modalType, setModalType] = useState(null);
+ const [id, setId] = useState();
+
+ useEffect(() => {
+ if (!modalType) {
+ onCloseOption();
+ }
+ }, [modalType]);
+
+ const handleOpenModalWithId = (id, type) => {
+ setId(id);
+ setModalType(type);
+ };
+
+ const tableItems = useMemo(() => {
+ const fields = headers.map(({ field }) => field);
+
+ return items.map((item: T, index) => (
+
+ {fields.map(field => {
+ if (!item[field]) return;
+ return | {item[field]} | ;
+ })}
+ {optionsEnabled && (
+
+ handleOpenModalWithId(item.id, MODAL_TYPES.EDIT_MODAL)}>Edit
+ handleOpenModalWithId(item.id, MODAL_TYPES.DELETE_MODAL)}>Delete
+ |
+ )}
+
+ ));
+ }, [headers, items, optionsEnabled]);
+
+ const modalContent = useMemo(() => {
+ switch (modalType) {
+ case MODAL_TYPES.DELETE_MODAL:
+ return (
+ <>
+ Are you sure about this action?
+ onDeleteItem(id)}>Yes, I'm
+ setModalType(null)}>Cancel
+ >
+ );
+
+ case MODAL_TYPES.EDIT_MODAL:
+ return <>{editComponent(id)}>;
+
+ default:
+ return <>>;
+ }
+ }, [editComponent, id, modalType]);
+
+ return (
+ <>
+ setModalType(null)}>
+ {modalContent}
+
+
+
+
+
+ {headers.map(({ label }) => (
+ | {label} |
+ ))}
+ {optionsEnabled && Options | }
+
+
+
+ <>
+ {isLoading && }
+ {!isLoading && tableItems}
+ >
+
+
+
+ >
+ );
+};
+
+export { BaseList };
+export default BaseList;
diff --git a/modules/BaseModule/hooks/useIsMobile.tsx b/modules/BaseModule/hooks/useIsMobile.tsx
new file mode 100644
index 0000000..70a9c3f
--- /dev/null
+++ b/modules/BaseModule/hooks/useIsMobile.tsx
@@ -0,0 +1,14 @@
+import { useState, useEffect } from 'react';
+
+export const useIsMobile = () => {
+ const [width, setWidth] = useState(0);
+
+ useEffect(() => {
+ const handleWindowSizeChange = () => setWidth(window.innerWidth);
+ handleWindowSizeChange();
+ window.addEventListener('resize', handleWindowSizeChange);
+ return () => window.removeEventListener('resize', handleWindowSizeChange);
+ }, []);
+
+ return width <= 576;
+};
diff --git a/modules/BaseModule/interfaces/BaseField.ts b/modules/BaseModule/interfaces/BaseField.ts
new file mode 100644
index 0000000..a2cb787
--- /dev/null
+++ b/modules/BaseModule/interfaces/BaseField.ts
@@ -0,0 +1,11 @@
+import { BubbleEnum } from '@Modules/BaseModule/constants/Bubble';
+
+import SelectOption from './SelectOption';
+
+export default interface BaseField {
+ name: string;
+ type: BubbleEnum;
+ label: string;
+ options?: SelectOption[];
+ value?: (string | number | readonly string[]) & string;
+}
diff --git a/modules/BaseModule/interfaces/SelectOption.ts b/modules/BaseModule/interfaces/SelectOption.ts
new file mode 100644
index 0000000..3a585d5
--- /dev/null
+++ b/modules/BaseModule/interfaces/SelectOption.ts
@@ -0,0 +1,4 @@
+export default interface SelectOption {
+ label: string;
+ value: string | number;
+}
diff --git a/modules/BaseModule/shared/renderFields.tsx b/modules/BaseModule/shared/renderFields.tsx
new file mode 100644
index 0000000..88c29a2
--- /dev/null
+++ b/modules/BaseModule/shared/renderFields.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+
+import Bubble from '../components/Bubble';
+import BaseField from '../interfaces/BaseField';
+
+const renderFields = (fields: BaseField[], errors, register) =>
+ fields.map(({ name, type, label, options, value }) => (
+
+ ));
+
+export default renderFields;
diff --git a/modules/Bill/components/BillFilters/index.tsx b/modules/Bill/components/BillFilters/index.tsx
index 461409c..a43ce2c 100644
--- a/modules/Bill/components/BillFilters/index.tsx
+++ b/modules/Bill/components/BillFilters/index.tsx
@@ -3,6 +3,7 @@ import { useForm } from 'react-hook-form';
import { Flex, Spacer, Box } from '@chakra-ui/react';
import { Select } from '@Components/Select';
+import { MONTHS_DICT } from '@Modules/Bill/constants/BillConsts';
type BillFiltersType = {
year?: number;
@@ -16,21 +17,6 @@ interface BillFiltersProps {
to: number;
}
-const MONTHS_DICT = {
- 0: 'Janeiro',
- 1: 'Fevereiro',
- 2: 'Março',
- 3: 'Abril',
- 4: 'Maio',
- 5: 'Junho',
- 6: 'Julho',
- 7: 'Agosto',
- 8: 'Setembro',
- 9: 'Outubro',
- 10: 'Novembro',
- 11: 'Dezembro',
-};
-
const BillFilters = ({ filters, onChange, from, to }: BillFiltersProps) => {
const {
handleSubmit,
@@ -77,7 +63,7 @@ const BillFilters = ({ filters, onChange, from, to }: BillFiltersProps) => {
}
return finalMonths;
- }, [filters.year]);
+ }, []);
return (
@@ -85,7 +71,7 @@ const BillFilters = ({ filters, onChange, from, to }: BillFiltersProps) => {
{
void;
+ onDeleteBill: (billId: string) => void;
+}
+
+export const BillItem = ({ bill, onCopyBill, onDeleteBill }: BillItemProps) => {
+ const router = useRouter();
+ const [loadings, setLoadings] = useState({
+ changingStatus: null,
+ deleting: false,
+ });
+
+ const formatValue = value => {
+ return `R$${Number(value).toFixed(2).replace('.', ',')}`;
+ };
+
+ const formatDate = value => {
+ const date = new Date(value).toLocaleString('pt-BR').substr(0, 10);
+ return `${date}`;
+ };
+
+ const billValue = useMemo(() => {
+ const typesScheme = {
+ [BillTypes.EXPENSE]: 'red',
+ [BillTypes.INCOME]: 'green',
+ };
+
+ const icon = {
+ [BillTypes.EXPENSE]: ,
+ [BillTypes.INCOME]: ,
+ };
+
+ return (
+
+ {icon[bill.type] ?? <>>} {formatValue(bill.value)}
+
+ );
+ }, [bill]);
+
+ const changeBillStatus = async status => {
+ setLoadings({
+ ...loadings,
+ changingStatus: status,
+ });
+
+ await billsCollection.doc(bill.id).update({
+ status,
+ });
+
+ setLoadings({
+ ...loadings,
+ changingStatus: null,
+ });
+ };
+
+ const isExpiring = useMemo(() => {
+ const currentDate = new Date();
+
+ currentDate.setDate(currentDate.getDate() + 5);
+
+ return (
+ currentDate.getTime() - bill.dueDate >= 0 && bill.status !== BillStatus.PAID && bill.type === BillTypes.EXPENSE
+ );
+ }, [bill.dueDate, bill.status, bill.type]);
+
+ const isPassDueDate = useMemo(() => {
+ return new Date(bill.dueDate) < new Date() && bill.status !== BillStatus.PAID && bill.type === BillTypes.EXPENSE;
+ }, [bill.dueDate, bill.status, bill.type]);
+
+ const billSituation = useMemo(() => {
+ if (isPassDueDate) {
+ return (
+
+
+
+
+ Conta vencida
+
+
+
+ );
+ }
+
+ if (isExpiring) {
+ return (
+
+
+
+
+ Prestes a expirar
+
+
+
+ );
+ }
+ }, [isExpiring, isPassDueDate]);
+
+ const itemBorderColor = useMemo(() => {
+ if (isPassDueDate) return 'red.500';
+ if (isExpiring) return 'yellow.500';
+
+ return '';
+ }, [isExpiring, isPassDueDate]);
+
+ const billStatusColor = useMemo(() => {
+ let color = 'yellow';
+
+ if (bill.status === BillStatus.NOT_PAID) {
+ color = 'red';
+ }
+
+ if (bill.status === BillStatus.PAID) {
+ color = 'green';
+ }
+
+ return color;
+ }, [bill.status]);
+
+ return (
+
+ {billSituation}
+
+
+
+
+
+ {bill.name}
+
+
+ Vencimento {formatDate(bill.dueDate)}
+
+
+
+ {bill.description && (
+
+ {bill.description}
+
+ )}
+
+ {billValue}
+
+
+
+
+
+ }
+ variant="outline"
+ size="sm"
+ w="fit-content"
+ mr={5}
+ colorScheme={billStatusColor}
+ >
+ {textsBillStatus[bill.status]}
+
+
+
+
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.NOT_PAID)}
+ isLoading={loadings?.changingStatus === BillStatus.NOT_PAID}
+ colorScheme="red"
+ >
+ Não pago
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.PAID)}
+ isLoading={loadings?.changingStatus === BillStatus.PAID}
+ colorScheme="green"
+ >
+ Pago
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => changeBillStatus(BillStatus.PENDING)}
+ isLoading={loadings?.changingStatus === BillStatus.PENDING}
+ colorScheme="yellow"
+ >
+ Pendente
+
+
+
+
+
+
+
+
+ }
+ variant="outline"
+ size="sm"
+ w="fit-content"
+ />
+
+
+
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => router.replace(`/bill/${bill.id}`)}
+ >
+ Editar conta
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ fontSize="sm"
+ onClick={() => onCopyBill(bill.id)}
+ >
+ Copiar conta
+
+
+ }
+ justifyContent="flex-start"
+ fontWeight="normal"
+ colorScheme="red"
+ fontSize="sm"
+ onClick={() => onDeleteBill(bill.id)}
+ >
+ Deletar conta
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/modules/Bill/components/BillItem/index.tsx b/modules/Bill/components/BillItem/index.tsx
deleted file mode 100644
index 60db723..0000000
--- a/modules/Bill/components/BillItem/index.tsx
+++ /dev/null
@@ -1,161 +0,0 @@
-import { useState, useMemo } from 'react';
-import { useRouter } from 'next/router';
-import { Button, IconButton, Box, Text, Tag, Flex, Stack, Spacer } from '@chakra-ui/react';
-import { EditIcon, DeleteIcon, ArrowUpIcon, ArrowDownIcon } from '@chakra-ui/icons';
-
-import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
-import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
-import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
-
-interface BillItemProps {
- bill: Bill;
-}
-
-export default function BillItem({ bill }: BillItemProps) {
- const router = useRouter();
- const [loadings, setLoadings] = useState({
- changingStatus: null,
- deleting: false,
- });
-
- const formatValue = value => {
- return `R$${Number(value).toFixed(2).replace('.', ',')}`;
- };
-
- const formatDate = value => {
- const date = new Date(value).toLocaleString('pt-BR').substr(0, 10);
- return `${date}`;
- };
-
- const billValue = useMemo(() => {
- const typesScheme = {
- [BillTypes.EXPENSE]: 'red',
- [BillTypes.INCOME]: 'green',
- };
-
- const icon = {
- [BillTypes.EXPENSE]: ,
- [BillTypes.INCOME]: ,
- };
-
- return (
-
- {icon[bill.type] ?? <>>} {formatValue(bill.value)}
-
- );
- }, [bill]);
-
- const changeBillStatus = async status => {
- setLoadings({
- ...loadings,
- changingStatus: status,
- });
-
- await billsCollection.doc(bill.id).update({
- status,
- });
-
- setLoadings({
- ...loadings,
- changingStatus: null,
- });
- };
-
- const deleteBill = async () => {
- setLoadings({
- ...loadings,
- deleting: true,
- });
-
- await billsCollection.doc(bill.id).delete();
-
- setLoadings({
- ...loadings,
- changingStatus: false,
- });
- };
-
- return (
-
-
-
-
-
- {bill.name}
-
-
- Due date {formatDate(bill.dueDate)}
-
-
-
- {bill.description && (
-
- {bill.description}
-
- )}
-
- {billValue}
-
-
- Created at {formatDate(bill.createdAt)}
-
-
-
-
-
- changeBillStatus(BillStatus.PENDING)}
- isLoading={loadings?.changingStatus === BillStatus.PENDING}
- colorScheme="yellow"
- >
- Pending
-
-
- changeBillStatus(BillStatus.PAID)}
- isLoading={loadings?.changingStatus === BillStatus.PAID}
- colorScheme="green"
- marginTop="5px"
- >
- Paid
-
-
- changeBillStatus(BillStatus.NOT_PAID)}
- isLoading={loadings?.changingStatus === BillStatus.NOT_PAID}
- colorScheme="red"
- marginTop="5px"
- >
- Not paid
-
-
-
- }
- onClick={() => router.push(`/bill/${bill.id}`)}
- variant="outline"
- size="sm"
- />
-
- deleteBill()}
- icon={}
- variant="outline"
- marginLeft="10px"
- size="sm"
- />
-
-
-
- );
-}
diff --git a/modules/Bill/components/CopyBill/copy-bill.component.tsx b/modules/Bill/components/CopyBill/copy-bill.component.tsx
new file mode 100644
index 0000000..ed348e6
--- /dev/null
+++ b/modules/Bill/components/CopyBill/copy-bill.component.tsx
@@ -0,0 +1,148 @@
+import React, { useMemo, useEffect } from 'react';
+import { Button } from '@chakra-ui/button';
+import { useForm } from 'react-hook-form';
+import {
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalCloseButton,
+ ModalBody,
+ ModalFooter,
+ Flex,
+ Spacer,
+ Box,
+ useToast,
+} from '@chakra-ui/react';
+
+import { Select } from '@Components/Select';
+import { MONTHS_DICT, TO_YEAR, FROM_YEAR } from '@Modules/Bill/constants/BillConsts';
+import { Modal } from '@Components/Modal';
+import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
+import { BillStatus } from '@Modules/Bill/constants/Types';
+
+export const CopyBill = ({ isOpen, onClose, billId }) => {
+ const {
+ handleSubmit,
+ register,
+ formState: { errors, isSubmitting },
+ setValue,
+ watch,
+ } = useForm();
+
+ const toast = useToast();
+
+ useEffect(() => {
+ setValue('month', new Date().getMonth());
+ setValue('year', new Date().getFullYear());
+ }, [setValue]);
+
+ const years = useMemo(() => {
+ const finalYears = [];
+
+ if (FROM_YEAR > TO_YEAR) {
+ throw new Error('From must be lower than to');
+ }
+
+ if (TO_YEAR - FROM_YEAR <= 0) {
+ throw new Error('To minus from must be over 0');
+ }
+
+ for (let yearCount = 0; yearCount <= TO_YEAR - FROM_YEAR; yearCount++) {
+ finalYears.push({
+ label: `${FROM_YEAR + yearCount}`,
+ to: FROM_YEAR + yearCount,
+ });
+ }
+
+ return finalYears;
+ }, []);
+
+ const months = useMemo(() => {
+ const finalMonths = [];
+
+ for (let monthCount = 0; monthCount <= 11; monthCount++) {
+ finalMonths.push({
+ label: `${MONTHS_DICT[monthCount]}`,
+ value: monthCount,
+ });
+ }
+
+ return finalMonths;
+ }, []);
+
+ const month = watch('month', false);
+ const year = watch('year', false);
+
+ const onSubmit = async values => {
+ const billDoc = await billsCollection.doc(billId).get();
+ if (billDoc.exists) {
+ const billData = billDoc.data() as Bill;
+
+ const day = new Date(billData.dueDate).getDay();
+ const newDueDate = new Date(values.year, values.month, day);
+
+ try {
+ await billsCollection.add({
+ ...billData,
+ status: BillStatus.PENDING,
+ dueDate: newDueDate.getTime(),
+ createdAt: new Date().getTime(),
+ });
+
+ onClose();
+
+ toast({
+ description: 'Conta copiada com sucesso!',
+ status: 'success',
+ });
+ } catch (error) {
+ console.error(error);
+ }
+ }
+ };
+
+ return (
+
+ <>
+
+
+ Copiar conta
+
+
+
+ setValue('year', +select.target.value)}
+ error={errors.year?.message}
+ mb={2}
+ />
+
+ setValue('month', +select.target.value)}
+ error={errors.month?.message}
+ />
+
+ Você tem certeza que deseja copiar essa conta para o mês de {month}/{year}?
+
+
+
+
+ Cancelar
+
+
+ Copiar conta
+
+
+
+ >
+
+ );
+};
diff --git a/modules/Bill/components/DeleteBill/delete-bill.component.tsx b/modules/Bill/components/DeleteBill/delete-bill.component.tsx
new file mode 100644
index 0000000..6d4983d
--- /dev/null
+++ b/modules/Bill/components/DeleteBill/delete-bill.component.tsx
@@ -0,0 +1,105 @@
+import React, { useEffect, useState, useCallback } from 'react';
+import { Button } from '@chakra-ui/button';
+import {
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalCloseButton,
+ ModalBody,
+ ModalFooter,
+ useToast,
+} from '@chakra-ui/react';
+
+import { Modal } from '@Components/Modal';
+import { billsCollection, billsRecurrenceCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
+import { BillStatus } from '@Modules/Bill/constants/Types';
+
+export const DeleteBill = ({ isOpen, onClose, billId }) => {
+ const toast = useToast();
+ const [isRecurrence, setIsRecurrence] = useState(false);
+
+ const checkRecurrence = useCallback(async () => {
+ if (!billId) return;
+
+ const hasRecurrence = await (await billsRecurrenceCollection.where('bills', 'array-contains', billId)).get();
+
+ setIsRecurrence(!hasRecurrence.empty);
+ }, [billId]);
+
+ useEffect(() => {
+ checkRecurrence();
+ }, [checkRecurrence]);
+ const deleteBill = async (deleteRecurrence = false) => {
+ try {
+ if (deleteRecurrence) {
+ const recurrenceDoc = (
+ await (await billsRecurrenceCollection.where('bills', 'array-contains', billId).limit(1)).get()
+ )?.docs[0];
+
+ let execution = [billsRecurrenceCollection.doc(recurrenceDoc.id).delete()];
+
+ recurrenceDoc.data().bills.forEach(id => billsCollection.doc(id).delete());
+
+ await Promise.all(execution);
+
+ return toast({
+ description: 'Conta e recorrências deletadas com sucesso!',
+ status: 'success',
+ });
+ }
+
+ await billsCollection.doc(billId).delete();
+ toast({
+ description: 'Conta deletada com sucesso!',
+ status: 'success',
+ });
+ } catch (error) {
+ console.error(error);
+ } finally {
+ onClose();
+ }
+ };
+
+ return (
+
+ <>
+
+
+ Deletar conta
+
+
+ {isRecurrence
+ ? 'Você deseja deletar somente esta conta ou toda recorrência?'
+ : 'Deseja realmente deletar esta conta?'}
+
+
+
+ {isRecurrence ? (
+ <>
+
+ Cancelar
+
+ deleteBill()}>
+ Deletar conta
+
+ deleteBill(true)}>
+ Deletar recorrência
+
+ >
+ ) : (
+ <>
+
+ Cancelar
+
+ deleteBill()}>
+ Deletar conta
+
+ >
+ )}
+
+
+ >
+
+ );
+};
diff --git a/modules/Bill/components/StateMonth/index.tsx b/modules/Bill/components/StateMonth/index.tsx
deleted file mode 100644
index c4ad655..0000000
--- a/modules/Bill/components/StateMonth/index.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { useMemo } from 'react';
-import { Stat, StatLabel, StatNumber, Box, Flex } from '@chakra-ui/react';
-
-import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
-import { BillTypes } from '@Modules/Bill/constants/Types';
-
-interface StateMonthProps {
- bills: Bill[];
-}
-
-export default function StateMonth({ bills }: StateMonthProps) {
- const formatValue = value => {
- return `R$${Number(value).toFixed(2).replace('.', ',')}`;
- };
-
- const income = useMemo(() => {
- const reduceRevenue =
- bills.filter(bill => bill.type === BillTypes.INCOME).reduce((prev, current) => (prev += current.value), 0) ?? 0;
- return formatValue(reduceRevenue);
- }, [bills]);
-
- const expense = useMemo(() => {
- const reduceExpense =
- bills.filter(bill => bill.type === BillTypes.EXPENSE).reduce((prev, current) => (prev += current.value), 0) ?? 0;
- return formatValue(reduceExpense);
- }, [bills]);
-
- const balance = useMemo(() => {
- const reduceRevenue =
- bills.filter(bill => bill.type === BillTypes.INCOME).reduce((prev, current) => (prev += current.value), 0) ?? 0;
- const reduceExpense =
- bills.filter(bill => bill.type === BillTypes.EXPENSE).reduce((prev, current) => (prev += current.value), 0) ?? 0;
- return formatValue(reduceRevenue - reduceExpense);
- }, [bills]);
-
- return (
-
-
-
- Income
- {income}
-
-
-
- Expense
- {expense}
-
-
-
- Balance
- {balance}
-
-
-
- );
-}
diff --git a/modules/Bill/components/StatsMonth/stats-month.component.tsx b/modules/Bill/components/StatsMonth/stats-month.component.tsx
new file mode 100644
index 0000000..15f76c8
--- /dev/null
+++ b/modules/Bill/components/StatsMonth/stats-month.component.tsx
@@ -0,0 +1,57 @@
+import { Stat, StatLabel, StatNumber, Box, Grid, GridItem, Skeleton } from '@chakra-ui/react';
+
+interface StateMonthProps {
+ income?: number;
+ expense?: number;
+ balance?: number;
+ isLoaded: boolean;
+}
+
+export const StatsMonth = ({ income, expense, balance, isLoaded }: StateMonthProps) => {
+ const formatValue = value => {
+ return `R$${Number(value).toFixed(2).replace('.', ',')}`;
+ };
+
+ return (
+
+
+
+
+
+ Receita
+
+
+ {formatValue(income)}
+
+
+
+
+
+
+
+
+
+ Despesas
+
+
+ {formatValue(expense)}
+
+
+
+
+
+
+
+
+
+ Restante
+
+
+ {formatValue(balance)}
+
+
+
+
+
+ );
+};
diff --git a/modules/Bill/constants/BillConsts.ts b/modules/Bill/constants/BillConsts.ts
new file mode 100644
index 0000000..5733c12
--- /dev/null
+++ b/modules/Bill/constants/BillConsts.ts
@@ -0,0 +1,22 @@
+export const MONTHS_DICT = {
+ 0: 'Janeiro',
+ 1: 'Fevereiro',
+ 2: 'Março',
+ 3: 'Abril',
+ 4: 'Maio',
+ 5: 'Junho',
+ 6: 'Julho',
+ 7: 'Agosto',
+ 8: 'Setembro',
+ 9: 'Outubro',
+ 10: 'Novembro',
+ 11: 'Dezembro',
+};
+
+export const FROM_YEAR = 2020;
+
+export const TO_YEAR = 2024;
+
+export const defaultRequiredMessage = {
+ required: 'Este campo é obrigatório!',
+};
diff --git a/modules/Bill/constants/FirestoreCollections.ts b/modules/Bill/constants/FirestoreCollections.ts
index 02cde81..694a38d 100644
--- a/modules/Bill/constants/FirestoreCollections.ts
+++ b/modules/Bill/constants/FirestoreCollections.ts
@@ -1,3 +1,5 @@
import { firestore } from '@Configs/Firebase';
export const billsCollection = firestore.collection('bills');
+
+export const billsRecurrenceCollection = firestore.collection('bills-recurrence');
diff --git a/modules/Bill/constants/Types.ts b/modules/Bill/constants/Types.ts
index 88b4641..b6abd8a 100644
--- a/modules/Bill/constants/Types.ts
+++ b/modules/Bill/constants/Types.ts
@@ -1,6 +1,8 @@
export const BillTypes = {
EXPENSE: 'EXPENSE',
INCOME: 'INCOME',
+ REPEATED_INCOME: 'REPEATED_INCOME',
+ REPEATED_EXPENSE: 'REPEATED_EXPENSE',
};
export const BillStatus = {
diff --git a/modules/Bill/container/FormBill/form-bill.container.tsx b/modules/Bill/container/FormBill/form-bill.container.tsx
new file mode 100644
index 0000000..6816481
--- /dev/null
+++ b/modules/Bill/container/FormBill/form-bill.container.tsx
@@ -0,0 +1,329 @@
+import React, { useEffect, useMemo, useState } from 'react';
+import { useRouter } from 'next/router';
+import { useForm, Controller } from 'react-hook-form';
+import { Button } from '@chakra-ui/button';
+import { useToast, Flex, Text, Switch } from '@chakra-ui/react';
+
+import { billsCollection, billsRecurrenceCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
+import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
+import { Input, MoneyInput, Select, DatePicker, Box, If } from '@Components';
+import { useUser } from '@Modules/Authentication/context/UserContext';
+import { defaultRequiredMessage, TO_YEAR } from '@Modules/Bill/constants/BillConsts';
+
+const types = [
+ {
+ label: 'Despesa',
+ value: BillTypes.EXPENSE,
+ },
+ {
+ label: 'Receita',
+ value: BillTypes.INCOME,
+ },
+];
+
+const recurrenceTypes = [
+ {
+ label: 'Cada mês',
+ value: 'EVERY_MONTH',
+ },
+ // TODO: every year recurrence
+ // {
+ // label: 'Cada ano',
+ // value: 'EVERY_YEAR',
+ // },
+];
+
+const categoriesExpense = [
+ {
+ label: '💳 Cartão de crédito',
+ value: 'CREDIT_CARD',
+ },
+ {
+ label: '💰 Investimento',
+ value: 'INVESTING',
+ },
+ {
+ label: '💸 Fixo',
+ value: 'FIXED',
+ },
+ {
+ label: '🔁 Flexível',
+ value: 'FLEX',
+ },
+ {
+ label: '💲 Outro',
+ value: 'OTHER',
+ },
+];
+
+interface FormBillProps {
+ billId?: string;
+}
+
+export const FormBillContainer = ({ billId }: FormBillProps) => {
+ const {
+ handleSubmit,
+ register,
+ setValue,
+ control,
+ watch,
+ formState: { errors, isSubmitting },
+ } = useForm();
+
+ const router = useRouter();
+ const toast = useToast();
+ const { userId } = useUser();
+
+ const [foundBill, setFoundBill] = useState();
+
+ useEffect(() => {
+ try {
+ const queryBillType = router.query?.type as keyof typeof BillTypes;
+ setValue('type', queryBillType);
+ } catch (error) {
+ console.error(error);
+ }
+ }, [router.query.type, setValue]);
+
+ useEffect(() => {
+ setValue('category', categoriesExpense[0].value);
+ }, [setValue]);
+
+ const onSubmit = async values => {
+ if (!userId) return;
+
+ const dueDate = new Date(values.dueDate);
+ dueDate.setHours(3, 0, 0, 0);
+
+ const bill: Bill = {
+ name: values.name,
+ description: values.description ?? '',
+ value: +values.value,
+ dueDate: dueDate.getTime(),
+ status: billId ? foundBill?.status : BillStatus.PENDING,
+ type: values.type,
+ createdAt: new Date().getTime(),
+ userId,
+ category: values.type === BillTypes.EXPENSE ? values.category : '',
+ };
+
+ try {
+ if (billId) {
+ await billsCollection.doc(billId).update(bill);
+ } else {
+ if (values.recurrence) {
+ let billsToAdd = [billsCollection.add(bill)];
+ let endOcurrence = new Date(values.recurrenceDueDate);
+ let indexOcurrence = new Date();
+ indexOcurrence.setDate(endOcurrence.getDate());
+
+ const billDateDay = new Date(bill.dueDate).getDate();
+ while (endOcurrence >= indexOcurrence) {
+ indexOcurrence.setMonth(indexOcurrence.getMonth() + 1);
+
+ billsToAdd.push(
+ billsCollection.add({
+ ...bill,
+ dueDate: new Date(indexOcurrence.getFullYear(), indexOcurrence.getMonth(), billDateDay).getTime(),
+ })
+ );
+ }
+
+ const addedBills = await Promise.all(billsToAdd);
+
+ await billsRecurrenceCollection.add({
+ type: values.recurrenceType,
+ ends_in: values.recurrenceDueDate,
+ bills: addedBills.map(({ id }) => id),
+ });
+
+ router.push('/');
+ return toast({
+ description: 'Conta e recorrências criados com sucesso!',
+ status: 'success',
+ });
+ }
+
+ await billsCollection.add(bill);
+ }
+ toast({
+ description: 'Conta criada com sucesso!',
+ status: 'success',
+ });
+
+ router.push('/');
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ useEffect(() => {
+ const findBill = async () => {
+ if (!billId) return;
+
+ const billDoc = await billsCollection.doc(billId).get();
+ if (billDoc.exists) {
+ setFoundBill({ id: billDoc.id, ...billDoc.data() } as Bill);
+ } else {
+ router.push('/');
+ toast({
+ description: 'Conta não encontrada!',
+ status: 'error',
+ });
+ }
+ };
+
+ findBill();
+ }, [billId, router, toast]);
+
+ useEffect(() => {
+ setValue('name', foundBill?.name);
+ setValue('description', foundBill?.description);
+ setValue('dueDate', foundBill?.dueDate);
+ setValue('type', foundBill?.type);
+ setValue('value', String(foundBill?.value));
+ setValue('type', foundBill?.type);
+ setValue('category', foundBill?.category);
+ }, [foundBill, setValue]);
+
+ const billType = watch('type', false);
+ const billRecurrence = watch('recurrence', false);
+
+ const title = useMemo(() => {
+ const prefix = billId ? 'Editar' : 'Criar nova';
+ if (router.query.type) {
+ const foundType = types.find(type => type.value === router.query.type);
+
+ if (!foundType) return `${prefix} conta`;
+
+ return `${prefix} ${foundType.label.toLocaleLowerCase()}`;
+ }
+
+ return `${prefix} conta`;
+ }, [billId, router.query.type]);
+
+ return (
+
+
+
+ );
+};
diff --git a/modules/Bill/container/FormBill/index.tsx b/modules/Bill/container/FormBill/index.tsx
deleted file mode 100644
index 86416b1..0000000
--- a/modules/Bill/container/FormBill/index.tsx
+++ /dev/null
@@ -1,226 +0,0 @@
-import { useMemo, useEffect, useState } from 'react';
-import { useRouter } from 'next/router';
-import { useForm, Controller } from 'react-hook-form';
-import { Button } from '@chakra-ui/button';
-import { useToast, Flex, Spacer, Box } from '@chakra-ui/react';
-
-import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
-import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
-import { BillTypes, BillStatus } from '@Modules/Bill/constants/Types';
-import { Input, MoneyInput, Select, DatePicker } from '@Components';
-import { useUser } from '@Modules/Authentication/context/UserContext';
-
-const MONTHS_DICT = {
- 0: 'Janeiro',
- 1: 'Fevereiro',
- 2: 'Março',
- 3: 'Abril',
- 4: 'Maio',
- 5: 'Junho',
- 6: 'Julho',
- 7: 'Agosto',
- 8: 'Setembro',
- 9: 'Outubro',
- 10: 'Novembro',
- 11: 'Dezembro',
-};
-
-interface FormBillProps {
- billId?: string;
-}
-
-const FormBill = ({ billId }: FormBillProps) => {
- const {
- handleSubmit,
- register,
- setValue,
- control,
- formState: { errors, isSubmitting },
- } = useForm();
-
- const router = useRouter();
- const toast = useToast();
- const { userId } = useUser();
-
- const [foundBill, setFoundBill] = useState();
-
- const onSubmit = async values => {
- if (!userId) return;
-
- const dueDate = new Date(values.dueDate);
- dueDate.setHours(3, 0, 0, 0);
-
- const bill: Bill = {
- name: values.name,
- description: values.description ?? '',
- value: Number(values.value),
- dueDate: dueDate.getTime(),
- year: +values.year,
- status: billId ? foundBill?.status : BillStatus.PENDING,
- month: +values.month,
- type: values.type,
- createdAt: new Date().getTime(),
- userId,
- };
-
- try {
- if (billId) {
- await billsCollection.doc(billId).update(bill);
- } else {
- await billsCollection.add(bill);
- }
- toast({
- description: 'Bill successful submited!',
- status: 'success',
- });
-
- router.push('/');
- } catch (error) {
- console.log(error);
- }
- };
-
- useEffect(() => {
- const findBill = async () => {
- if (!billId) return;
-
- const billDoc = await billsCollection.doc(billId).get();
- if (billDoc.exists) {
- setFoundBill({ id: billDoc.id, ...billDoc.data() } as Bill);
- } else {
- toast({
- description: 'Bill not found!',
- status: 'error',
- });
- }
- };
-
- findBill();
- }, [billId, toast]);
-
- useEffect(() => {
- setValue('name', foundBill?.name);
- setValue('dueDate', foundBill?.dueDate);
- setValue('year', foundBill?.year);
- setValue('month', foundBill?.month);
- setValue('type', foundBill?.type);
- setValue('value', foundBill?.value);
- }, [foundBill]);
-
- const years = useMemo(() => {
- const finalYears = [];
- const beginYear = 2020;
-
- for (let yearCount = 0; yearCount < 5; yearCount++) {
- finalYears.push({
- value: beginYear + yearCount,
- label: `${beginYear + yearCount}`,
- });
- }
-
- return finalYears;
- }, []);
-
- const months = useMemo(() => {
- const finalMonths = [];
-
- for (let monthCount = 0; monthCount <= 11; monthCount++) {
- finalMonths.push({
- label: `${MONTHS_DICT[monthCount]}`,
- value: monthCount,
- });
- }
-
- return finalMonths;
- }, []);
-
- const types = [
- {
- label: 'Expense',
- value: BillTypes.EXPENSE,
- },
- {
- label: 'Income',
- value: BillTypes.INCOME,
- },
- ];
-
- return (
-
-
-
- );
-};
-
-export default FormBill;
diff --git a/modules/Bill/container/ListBills/index.tsx b/modules/Bill/container/ListBills/index.tsx
deleted file mode 100644
index 5ccce41..0000000
--- a/modules/Bill/container/ListBills/index.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import { useCallback, useEffect, useState } from 'react';
-import { useToast } from '@chakra-ui/react';
-
-import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
-import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
-import BillItem from '@Modules/Bill/components/BillItem';
-import BillFilters from '@Modules/Bill/components/BillFilters';
-import StateMonth from '@Modules/Bill/components/StateMonth';
-import { useUser } from '@Modules/Authentication/context/UserContext';
-
-const ListBills = () => {
- const { userId } = useUser();
-
- const [bills, setBills] = useState([]);
- const [filters, setFilters] = useState({
- year: new Date().getFullYear(),
- month: new Date().getMonth(),
- });
-
- const loadBills = useCallback(() => {
- if (!userId) return;
-
- billsCollection
- .where('userId', '==', userId)
- .where('year', '==', filters?.year)
- .where('month', '==', filters?.month)
- .onSnapshot(({ docs }) => {
- setBills(docs.map(bill => ({ id: bill.id, ...bill.data() } as Bill)));
- });
- }, [filters]);
-
- useEffect(() => {
- loadBills();
- }, [filters]);
-
- useEffect(() => {
- loadBills();
- }, []);
-
- const onChange = (target, value) => {
- setFilters(oldFilters => ({
- ...oldFilters,
- [target]: value,
- }));
- };
-
- const toast = useToast();
-
- return (
-
- onChange(target, value)} from={2020} to={2024} />
-
-
-
- {bills.map(bill => (
-
- ))}
-
- );
-};
-
-export default ListBills;
diff --git a/modules/Bill/container/ListBills/list-bills.container.tsx b/modules/Bill/container/ListBills/list-bills.container.tsx
new file mode 100644
index 0000000..fde4906
--- /dev/null
+++ b/modules/Bill/container/ListBills/list-bills.container.tsx
@@ -0,0 +1,109 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { Box, Button, Skeleton, Stack, useToast } from '@chakra-ui/react';
+
+import { billsCollection } from '@Modules/Bill/constants/FirestoreCollections';
+import { Bill } from '@Modules/Bill/interfaces/Bill.interface';
+import { BillItem } from '@Modules/Bill/components/BillItem/bill-item.component';
+import BillFilters from '@Modules/Bill/components/BillFilters';
+import { StatsMonth } from '@Modules/Bill/components/StatsMonth/stats-month.component';
+import { useUser } from '@Modules/Authentication/context/UserContext';
+import { BillTypes } from '@Modules/Bill/constants/Types';
+import { CopyBill } from '@Modules/Bill/components/CopyBill/copy-bill.component';
+import { DeleteBill } from '@Modules/Bill/components/DeleteBill/delete-bill.component';
+
+export const ListBillsContainer = () => {
+ const { userId } = useUser();
+ const [isLoaded, setIsLoaded] = useState(false);
+ const [bills, setBills] = useState([]);
+ const [filters, setFilters] = useState({
+ year: new Date().getFullYear(),
+ month: new Date().getMonth(),
+ });
+ const [billId, setBillId] = useState();
+
+ const copyBillModal = useRef(false);
+ const deleteBillModal = useRef(false);
+
+ const loadBills = useCallback(() => {
+ if (!userId) return;
+
+ const { year, month } = filters;
+ const startDate = new Date(year, month, 1);
+ const endDate = new Date(year, month + 1, 0);
+
+ billsCollection
+ .where('userId', '==', userId)
+ .where('dueDate', '>=', startDate.getTime())
+ .where('dueDate', '<=', endDate.getTime())
+ .orderBy('dueDate', 'desc')
+ .onSnapshot(({ docs }) => {
+ setIsLoaded(true);
+ setBills(docs.map(bill => ({ id: bill.id, ...bill.data() } as Bill)));
+ });
+ }, [filters, userId]);
+
+ useEffect(() => {
+ loadBills();
+ }, [filters, loadBills]);
+
+ useEffect(() => {
+ loadBills();
+ }, [loadBills]);
+
+ const onChange = (target, value) => {
+ setFilters(oldFilters => ({
+ ...oldFilters,
+ [target]: value,
+ }));
+ };
+
+ const toast = useToast();
+
+ const income = useMemo(() => {
+ return (
+ bills.filter(bill => bill.type === BillTypes.INCOME).reduce((prev, current) => (prev += current.value), 0) ?? 0
+ );
+ }, [bills]);
+
+ const expense = useMemo(() => {
+ return (
+ bills.filter(bill => bill.type === BillTypes.EXPENSE).reduce((prev, current) => (prev += current.value), 0) ?? 0
+ );
+ }, [bills]);
+
+ const onCopyBill = billId => {
+ copyBillModal.current = true;
+ setBillId(billId);
+ };
+
+ const onCloseCopyBill = () => {
+ copyBillModal.current = false;
+ setBillId(undefined);
+ };
+
+ const onDeleteBill = billId => {
+ deleteBillModal.current = true;
+ setBillId(billId);
+ };
+
+ const onCloseDeleteBill = () => {
+ deleteBillModal.current = false;
+ setBillId(undefined);
+ };
+
+ return (
+
+
+
+ onChange(target, value)} from={2020} to={2024} />
+
+
+
+
+ {bills.map(bill => (
+
+ ))}
+
+
+ );
+};
diff --git a/modules/Bill/interfaces/Bill.interface.ts b/modules/Bill/interfaces/Bill.interface.ts
index e095fa1..e691c80 100644
--- a/modules/Bill/interfaces/Bill.interface.ts
+++ b/modules/Bill/interfaces/Bill.interface.ts
@@ -6,14 +6,13 @@ interface BillMetadata {
export interface Bill {
id?: string;
name: string;
- description: string;
+ description?: string;
value: number;
type: 'INCOME' | 'EXPENSE';
status: string;
dueDate: number;
- year: number;
- month: number;
metadata?: BillMetadata;
createdAt: number;
userId: string;
+ category?: string;
}
diff --git a/modules/Category/.gitkeep b/modules/Category/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/next-env.d.ts b/next-env.d.ts
index c6643fd..9bc3dd4 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,3 +1,6 @@
///
///
///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/next.config.js b/next.config.js
index 0d60710..25617c2 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,3 +1,6 @@
module.exports = {
reactStrictMode: true,
+ experimental: {
+ esmExternals: false
+ }
}
diff --git a/package.json b/package.json
index 02d3e62..a959826 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"private": true,
"scripts": {
"dev": "next dev",
- "build": "next build",
+ "build": "NODE_OPTIONS=--openssl-legacy-provider next build",
"start": "next start",
"lint": "eslint \"**/*.{ts,tsx}\""
},
@@ -14,13 +14,16 @@
"@chakra-ui/react": "^1.6.6",
"@emotion/react": "^11",
"@emotion/styled": "^11",
+ "@hookform/resolvers": "^2.8.2",
"firebase": "^8.9.1",
"framer-motion": "^4",
- "next": "11.0.1",
- "react": "17.0.2",
+ "next": "^12.0.0",
+ "react": "^17.0.2",
"react-datepicker": "^4.2.1",
"react-dom": "17.0.2",
- "react-hook-form": "^7.12.2"
+ "react-hook-form": "^7.12.2",
+ "react-icons": "^4.12.0",
+ "yup": "^0.32.10"
},
"devDependencies": {
"@babel/core": "^7.15.0",
@@ -34,6 +37,7 @@
"eslint-import-resolver-babel-module": "^5.3.1",
"eslint-plugin-prettier": "^3.4.0",
"prettier": "^2.3.2",
+ "sass": "^1.69.5",
"typescript": "^4.3.5"
}
-}
+}
\ No newline at end of file
diff --git a/pages/_app.tsx b/pages/_app.tsx
index e973145..246a96c 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -1,16 +1,21 @@
import '../styles/globals.css';
import type { AppProps } from 'next/app';
+import Head from 'next/head';
import { ChakraProvider } from '@chakra-ui/react';
import theme from '@Configs/theme';
import { UserProvider } from '@Modules/Authentication/context/UserContext';
+
import 'react-datepicker/dist/react-datepicker.css';
-import './styles.css';
+import './styles.scss';
function MyApp({ Component, pageProps }: AppProps) {
return (
-
+
+
+ ToNoVermelho
+
diff --git a/pages/bill/[billId].tsx b/pages/bill/[billId].tsx
index d3c3522..1390395 100644
--- a/pages/bill/[billId].tsx
+++ b/pages/bill/[billId].tsx
@@ -1,13 +1,16 @@
import { useRouter } from 'next/router';
-import FormBill from '@Modules/Bill/container/FormBill';
+import { FormBillContainer } from '@Modules/Bill/container/FormBill/form-bill.container';
+import withLateralMenu from '@/hoc/withLateralMenu';
-export default function EditBillPage() {
+const EditBillPage = () => {
const router = useRouter();
const billId: string = String(router.query.billId);
return (
-
+
);
-}
+};
+
+export default withLateralMenu(EditBillPage);
diff --git a/pages/bill/index.tsx b/pages/bill/index.tsx
index 3811379..74e90d4 100644
--- a/pages/bill/index.tsx
+++ b/pages/bill/index.tsx
@@ -1,9 +1,10 @@
-import FormBill from '@Modules/Bill/container/FormBill';
+import { FormBillContainer } from '@Modules/Bill/container/FormBill/form-bill.container';
+import { LateralMenu } from '@Components';
export default function NewBillPage() {
return (
-
-
-
+
+
+
);
}
diff --git a/pages/forgot.tsx b/pages/forgot.tsx
deleted file mode 100644
index 43a21ba..0000000
--- a/pages/forgot.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useRouter } from 'next/router';
-import { Box } from '@chakra-ui/react';
-
-import FormForgotPassword from '@Authentication/container/FormForgotPassword';
-
-export default function Home() {
- const router = useRouter();
-
- return (
-
-
-
- );
-}
diff --git a/pages/index.tsx b/pages/index.tsx
index b8f9a6c..d7056c1 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,26 +1,12 @@
-import { useRouter } from 'next/router';
-import { Button } from '@chakra-ui/button';
-import { Box } from '@chakra-ui/react';
-
import withAuth from '@/hoc/withAuth';
-import { auth } from '@Configs/Firebase';
-
-import ListBills from '../modules/Bill/container/ListBills';
+import { LateralMenu } from '@Components/LateralMenu';
+import { ListBillsContainer } from '@Modules/Bill/container/ListBills/list-bills.container';
const Dashboard = () => {
- const router = useRouter();
-
return (
-
- router.push('bill')}>
- Create new bill
-
-
- auth.signOut()}>
- SignOut
-
-
-
+
+
+
);
};
diff --git a/pages/login.tsx b/pages/login.tsx
index 7be72d8..5b0ed3c 100644
--- a/pages/login.tsx
+++ b/pages/login.tsx
@@ -1,15 +1,14 @@
import { useRouter } from 'next/router';
-import { Button } from '@chakra-ui/button';
import { Box } from '@chakra-ui/react';
-import FormLogin from '@Authentication/container/FormLogin';
+import { FormLoginContainer } from '@Authentication/container/FormLogin/form-login.container';
export default function Home() {
const router = useRouter();
return (
-
-
+
+
);
}
diff --git a/pages/signup.tsx b/pages/signup.tsx
deleted file mode 100644
index ed9e21a..0000000
--- a/pages/signup.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useRouter } from 'next/router';
-import { Box } from '@chakra-ui/react';
-
-import FormSignUp from '@Modules/Authentication/container/FormSignUp';
-
-export default function Home() {
- const router = useRouter();
-
- return (
-
-
-
- );
-}
diff --git a/pages/styles.css b/pages/styles.css
deleted file mode 100644
index 38c8365..0000000
--- a/pages/styles.css
+++ /dev/null
@@ -1,194 +0,0 @@
-.light-theme{
- --light-gray: var(--chakra-colors-gray-200);
- --gray: var(--chakra-colors-gray-300);
- --blue700:var(--chakra-colors-blue-600);
- --blue600: var(--chakra-colors-blue-500);
- --blue500: var(--chakra-colors-gray-400);
- --blue400: var(--chakra-colors-gray-300);
- --blue300: var(--chakra-colors-gray-200);
- --blue200: var(--chakra-colors-gray-200);
- --blue100: var(--chakra-colors-gray-100);
- --monthBackground: var(--chakra-colors-white);
- --text:var(--chakra-colors-black);
- --negative-text:var(--chakra-colors-white);
-}
-.dark-theme{
- --light-gray: var(--chakra-colors-gray-600);
- --gray: var(--chakra-colors-gray-500);
- --blue700: var(--chakra-colors-blue-600);
- --blue600: var(--chakra-colors-blue-300);
- --blue500: var(--chakra-colors-gray-500);
- --blue400: var(--chakra-colors-gray-600);
- --blue300: var(--chakra-colors-gray-700);
- --blue200: var(--chakra-colors-gray-600);
- --blue100: var(--chakra-colors-gray-800);
- --monthBackground: var(--chakra-colors-gray-700);
- --text:var(--chakra-colors-gray-200);
- --negative-text:var(--chakra-colors-black);
-}
-
-/* if you dont want to use chakra's theme use this class in the wrapping div. These are the exact original values */
-.light-theme-original{
- --light-gray: #cccccc;
- --gray: #b3b3b3;
- --blue700:#2a69ac;
- --blue600: #3182ce;
- --blue500: #a0aec0;
- --blue400: #cbd5e0;
- --blue300: #e2e8f0;
- --blue200: #edf2f7;
- --blue100: #f7fafc;
-}
-.react-datepicker {
- font-family: unset;
- font-size: 0.9rem;
- border-color: var(--light-gray);
-}
-
-
-.react-datepicker.dark-theme,
-.react-datepicker.light-theme {
- width: 100%;
-}
-
-.react-datepicker-wrapper {
- width: 100%;
- display: block;
- border: 0px solid transparent;
-}
-
-.react-datepicker-wrapper > .react-datepicker__input-container {
- width: 100%;
- display: block;
- border: 0px solid transparent;
-}
-
-.react-datepicker__input-container {
-font-size: 1rem;
-padding-left: 1rem;
-padding-right: 1rem;
-height: 2.5rem;
-border-radius: 0.25rem;
-border: 1px solid;
-border-color: var(--light-gray);
-}
-.react-datapicker__input-text {
- background-color: transparent;
-}
-
-.react-datepicker__input-container:hover {
-border-color: var(--gray)
-}
-.react-datepicker__input-container:focus-within {
-z-index: 1;
-border-color: var(--blue600);
-border-width: 1.5px;
-box-shadow: 0 0 0 1px var(--blue600);
-}
-
-.react-datepicker__input-container > input {
-width: 100%;
-height: 100%;
-outline: 0;
-}
-
-.react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button) {
-right: 90px;
-}
-
-.react-datepicker__navigation--previous,
-.react-datepicker__navigation--next {
-height: 8px;
-}
-
-.react-datepicker__navigation--previous {
-border-right-color: var(--blue400);
-}
-
-.react-datepicker__navigation--previous:hover {
-border-right-color: var(--blue500);
-}
-
-.react-datepicker__navigation--next {
-border-left-color: var(--blue400);
-
-}
-
-.react-datepicker__navigation--next:hover {
-border-left-color: var(--blue500);
-}
-
-.react-datepicker__header {
-background-color: var(--blue100);
-}
-
-.react-datepicker__header,
-.react-datepicker__time-container {
-border-color: var(--blue300);
-}
-
-.react-datepicker__current-month,
-.react-datepicker-time__header,
-.react-datepicker-year-header {
-font-size: inherit;
-font-weight: 600;
-color: var(--text)
-}
-
-.react-datepicker__month{
- background-color: var(--monthBackground);
- margin:0;
- padding:0.4rem;
-}
-
-.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item {
-margin: 0 1px 0 0;
- height: auto;
- padding: 7px 10px;
-}
-
-.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover {
- background: var(--blue200);
-}
-
-.react-datepicker__day {
- color: var(--text)
-}
-
-.react-datepicker__day:hover {
- background: var(--blue200);
-}
-
-.react-datepicker__day-name {
- color:var(--text)
-}
-
-.react-datepicker__day--selected,
-.react-datepicker__day--in-selecting-range,
-.react-datepicker__day--in-range,
-.react-datepicker__month-text--selected,
-.react-datepicker__month-text--in-selecting-range,
-.react-datepicker__month-text--in-range,
-.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected {
-background: var(--blue600);
-font-weight: normal;
-color:var(--negative-text);
-}
-
-.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected:hover {
-background: var(--blue700);
-}
-
-.react-datepicker__close-icon::after {
- background-color: unset;
- border-radius: unset;
- font-size: 1.5rem;
- font-weight: bold;
- color: var(--light-gray);
- height: 20px;
- width: 20px;
-}
-
-.react-datepicker__close-icon::after:hover {
- color: var(--gray)
-}
\ No newline at end of file
diff --git a/pages/styles.scss b/pages/styles.scss
new file mode 100644
index 0000000..d3c7a32
--- /dev/null
+++ b/pages/styles.scss
@@ -0,0 +1,214 @@
+.light-theme {
+ --light-gray: var(--chakra-colors-gray-200);
+ --gray: var(--chakra-colors-gray-300);
+ --blue700: var(--chakra-colors-blue-600);
+ --blue600: var(--chakra-colors-blue-500);
+ --blue500: var(--chakra-colors-gray-400);
+ --blue400: var(--chakra-colors-gray-300);
+ --blue300: var(--chakra-colors-gray-200);
+ --blue200: var(--chakra-colors-gray-200);
+ --blue100: var(--chakra-colors-gray-100);
+ --monthBackground: var(--chakra-colors-white);
+ --text: var(--chakra-colors-black);
+ --negative-text: var(--chakra-colors-white);
+}
+
+.dark-theme {
+ --light-gray: var(--chakra-colors-gray-600);
+ --gray: var(--chakra-colors-gray-500);
+ --blue700: var(--chakra-colors-blue-600);
+ --blue600: var(--chakra-colors-blue-300);
+ --blue500: var(--chakra-colors-gray-500);
+ --blue400: var(--chakra-colors-gray-600);
+ --blue300: var(--chakra-colors-gray-700);
+ --blue200: var(--chakra-colors-gray-600);
+ --blue100: var(--chakra-colors-gray-800);
+ --monthBackground: var(--chakra-colors-gray-700);
+ --text: var(--chakra-colors-gray-200);
+ --negative-text: var(--chakra-colors-black);
+}
+
+/* if you dont want to use chakra's theme use this class in the wrapping div. These are the exact original values */
+.light-theme-original {
+ --light-gray: #cccccc;
+ --gray: #b3b3b3;
+ --blue700: #2a69ac;
+ --blue600: #3182ce;
+ --blue500: #a0aec0;
+ --blue400: #cbd5e0;
+ --blue300: #e2e8f0;
+ --blue200: #edf2f7;
+ --blue100: #f7fafc;
+}
+
+html {
+ height: 100%;
+}
+
+.react-datepicker {
+ font-family: unset;
+ font-size: 0.9rem;
+ border-color: var(--light-gray);
+}
+
+
+.react-datepicker.dark-theme,
+.react-datepicker.light-theme {
+ width: 100%;
+}
+
+.react-datepicker-wrapper {
+ width: 100%;
+ display: block;
+ border: 0px solid transparent;
+}
+
+.react-datepicker-wrapper > .react-datepicker__input-container {
+ width: 100%;
+ display: block;
+ border: 0px solid transparent;
+}
+
+.react-datepicker__input-container {
+ /* font-size: 1rem;
+ height: 2.5rem;
+ border-radius: 0.25rem;
+ border: 1px solid;
+ border-color: var(--light-gray); */
+
+}
+
+.react-datepicker__input-container > input {
+ width: 100%;
+ min-width: 0px;
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ position: relative;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ -ms-appearance: none;
+ appearance: none;
+ transition-property: var(--chakra-transition-property-common);
+ transition-duration: var(--chakra-transition-duration-normal);
+ font-size: var(--chakra-fontSizes-md);
+ -webkit-padding-start: var(--chakra-space-4);
+ padding-inline-start: var(--chakra-space-4);
+ -webkit-padding-end: var(--chakra-space-4);
+ padding-inline-end: var(--chakra-space-4);
+ height: var(--chakra-sizes-10);
+ border-radius: var(--chakra-radii-md);
+ border: 1px solid var(--chakra-colors-whiteAlpha-300);
+ background: transparent;
+
+ &:focus {
+ z-index: 1;
+ border-color: #63b3ed;
+ box-shadow: 0 0 0 1px #63b3ed;
+ }
+
+ &.hasError {
+ border-color: #FC8181;
+ box-shadow: 0 0 0 1px #FC8181;
+ }
+}
+
+.react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button) {
+ right: 90px;
+}
+
+.react-datepicker__navigation--previous,
+.react-datepicker__navigation--next {
+ height: 45px;
+}
+
+.react-datepicker__navigation--previous {
+ border-right-color: var(--blue400);
+}
+
+.react-datepicker__navigation--previous:hover {
+ border-right-color: var(--blue500);
+}
+
+.react-datepicker__navigation--next {
+ border-left-color: var(--blue400);
+
+}
+
+.react-datepicker__navigation--next:hover {
+ border-left-color: var(--blue500);
+}
+
+.react-datepicker__header {
+ background-color: var(--blue100);
+}
+
+.react-datepicker__header,
+.react-datepicker__time-container {
+ border-color: var(--blue300);
+}
+
+.react-datepicker__current-month,
+.react-datepicker-time__header,
+.react-datepicker-year-header {
+ font-size: inherit;
+ font-weight: 600;
+ color: var(--text)
+}
+
+.react-datepicker__month {
+ background-color: var(--monthBackground);
+ margin: 0;
+ padding: 0.4rem;
+}
+
+.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item {
+ margin: 0 1px 0 0;
+ height: auto;
+ padding: 7px 10px;
+}
+
+.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover {
+ background: var(--blue200);
+}
+
+.react-datepicker__day {
+ color: var(--text)
+}
+
+.react-datepicker__day:hover {
+ background: var(--blue200);
+}
+
+.react-datepicker__day-name {
+ color: var(--text)
+}
+
+.react-datepicker__day--selected,
+.react-datepicker__day--in-selecting-range,
+.react-datepicker__day--in-range,
+.react-datepicker__month-text--selected,
+.react-datepicker__month-text--in-selecting-range,
+.react-datepicker__month-text--in-range,
+.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected {
+ background: var(--blue600);
+ font-weight: normal;
+ color: var(--negative-text);
+}
+
+.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected:hover {
+ background: var(--blue700);
+}
+
+.react-datepicker__close-icon::after {
+ background-color: unset;
+ border-radius: unset;
+ font-size: 1.5rem;
+ font-weight: bold;
+ color: var(--light-gray);
+ height: 20px;
+ width: 20px;
+}
+
+.react-datepicker__close-icon::after:hover {
+ color: var(--gray)
+}
\ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
index 718d6fea4835ec2d246af9800eddb7ffb276240c..c678ea8ebfa6f2ce22dd908a6ba1ac060fa25ed8 100644
GIT binary patch
literal 719
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 |