mirror of
https://github.com/ershisan99/flashcards-example-project.git
synced 2025-12-16 12:33:18 +00:00
live lesson 21-01-24
This commit is contained in:
@@ -18,11 +18,13 @@
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-radio-group": "^1.1.3",
|
||||
"@reduxjs/toolkit": "^2.0.1",
|
||||
"@storybook/theming": "^7.2.1",
|
||||
"clsx": "^2.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.45.2",
|
||||
"react-redux": "^9.1.0",
|
||||
"react-router-dom": "^6.14.2",
|
||||
"react-toastify": "^9.1.3",
|
||||
"remeda": "^1.24.0",
|
||||
@@ -55,7 +57,7 @@
|
||||
"sass": "^1.64.1",
|
||||
"storybook": "^7.2.1",
|
||||
"stylelint": "^15.10.2",
|
||||
"typescript": "^5.0.2",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^4.4.5"
|
||||
}
|
||||
}
|
||||
|
||||
197
pnpm-lock.yaml
generated
197
pnpm-lock.yaml
generated
@@ -20,6 +20,9 @@ dependencies:
|
||||
'@radix-ui/react-radio-group':
|
||||
specifier: ^1.1.3
|
||||
version: 1.1.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@reduxjs/toolkit':
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1(react-redux@9.1.0)(react@18.2.0)
|
||||
'@storybook/theming':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -35,6 +38,9 @@ dependencies:
|
||||
react-hook-form:
|
||||
specifier: ^7.45.2
|
||||
version: 7.45.2(react@18.2.0)
|
||||
react-redux:
|
||||
specifier: ^9.1.0
|
||||
version: 9.1.0(@types/react@18.2.15)(react@18.2.0)(redux@5.0.1)
|
||||
react-router-dom:
|
||||
specifier: ^6.14.2
|
||||
version: 6.14.2(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -57,7 +63,7 @@ devDependencies:
|
||||
version: 4.3.1(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@it-incubator/eslint-config':
|
||||
specifier: ^0.1.3
|
||||
version: 0.1.3(prettier@3.0.0)(typescript@5.0.2)
|
||||
version: 0.1.3(prettier@3.0.0)(typescript@5.3.3)
|
||||
'@it-incubator/prettier-config':
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2
|
||||
@@ -81,10 +87,10 @@ devDependencies:
|
||||
version: 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@storybook/react':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.2)
|
||||
version: 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
|
||||
'@storybook/react-vite':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.2)(vite@4.4.5)
|
||||
version: 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(vite@4.4.5)
|
||||
'@storybook/testing-library':
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0
|
||||
@@ -99,10 +105,10 @@ devDependencies:
|
||||
version: 18.2.7
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.0.2)
|
||||
version: 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
version: 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3(vite@4.4.5)
|
||||
@@ -117,7 +123,7 @@ devDependencies:
|
||||
version: 0.4.3(eslint@8.45.0)
|
||||
eslint-plugin-storybook:
|
||||
specifier: ^0.6.13
|
||||
version: 0.6.13(eslint@8.45.0)(typescript@5.0.2)
|
||||
version: 0.6.13(eslint@8.45.0)(typescript@5.3.3)
|
||||
sass:
|
||||
specifier: ^1.64.1
|
||||
version: 1.64.1
|
||||
@@ -128,8 +134,8 @@ devDependencies:
|
||||
specifier: ^15.10.2
|
||||
version: 15.10.2
|
||||
typescript:
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2
|
||||
specifier: ^5.3.3
|
||||
version: 5.3.3
|
||||
vite:
|
||||
specifier: ^4.4.5
|
||||
version: 4.4.5(@types/node@20.4.5)(sass@1.64.1)
|
||||
@@ -1939,11 +1945,11 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/@it-incubator/eslint-config@0.1.3(prettier@3.0.0)(typescript@5.0.2):
|
||||
/@it-incubator/eslint-config@0.1.3(prettier@3.0.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-YABg8TFU/v514BWrHpFuJmqMLKF6wA+bHJJm1ZBhTAsm57GGcwGsz4xHrByoFF8Q/TbmzxF5DZ4WoKJPqupkmQ==}
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/eslint-plugin': 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
eslint: 8.45.0
|
||||
eslint-config-prettier: 8.8.0(eslint@8.45.0)
|
||||
eslint-import-resolver-node: 0.3.7
|
||||
@@ -2029,7 +2035,7 @@ packages:
|
||||
chalk: 4.1.2
|
||||
dev: true
|
||||
|
||||
/@joshwooding/vite-plugin-react-docgen-typescript@0.2.1(typescript@5.0.2)(vite@4.4.5):
|
||||
/@joshwooding/vite-plugin-react-docgen-typescript@0.2.1(typescript@5.3.3)(vite@4.4.5):
|
||||
resolution: {integrity: sha512-ou4ZJSXMMWHqGS4g8uNRbC5TiTWxAgQZiVucoUrOCWuPrTbkpJbmVyIi9jU72SBry7gQtuMEDp4YR8EEXAg7VQ==}
|
||||
peerDependencies:
|
||||
typescript: '>= 4.3.x'
|
||||
@@ -2041,8 +2047,8 @@ packages:
|
||||
glob: 7.2.3
|
||||
glob-promise: 4.2.2(glob@7.2.3)
|
||||
magic-string: 0.27.0
|
||||
react-docgen-typescript: 2.2.2(typescript@5.0.2)
|
||||
typescript: 5.0.2
|
||||
react-docgen-typescript: 2.2.2(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
vite: 4.4.5(@types/node@20.4.5)(sass@1.64.1)
|
||||
dev: true
|
||||
|
||||
@@ -2672,6 +2678,25 @@ packages:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.22.6
|
||||
|
||||
/@reduxjs/toolkit@2.0.1(react-redux@9.1.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA==}
|
||||
peerDependencies:
|
||||
react: ^16.9.0 || ^17.0.0 || ^18
|
||||
react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
react-redux:
|
||||
optional: true
|
||||
dependencies:
|
||||
immer: 10.0.3
|
||||
react: 18.2.0
|
||||
react-redux: 9.1.0(@types/react@18.2.15)(react@18.2.0)(redux@5.0.1)
|
||||
redux: 5.0.1
|
||||
redux-thunk: 3.1.0(redux@5.0.1)
|
||||
reselect: 5.1.0
|
||||
dev: false
|
||||
|
||||
/@remix-run/router@1.7.2:
|
||||
resolution: {integrity: sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -3113,7 +3138,7 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@storybook/builder-vite@7.2.1(typescript@5.0.2)(vite@4.4.5):
|
||||
/@storybook/builder-vite@7.2.1(typescript@5.3.3)(vite@4.4.5):
|
||||
resolution: {integrity: sha512-D/RNcH6WAxMAMmC3w9wwgDbYUJ9SjSwc6NPcxGrKk9o0SWDsKWWx4r6mM0W5FJ7Wh11Ca46LLnPC3cFfEg4YDQ==}
|
||||
peerDependencies:
|
||||
'@preact/preset-vite': '*'
|
||||
@@ -3147,7 +3172,7 @@ packages:
|
||||
remark-external-links: 8.0.0
|
||||
remark-slug: 6.1.0
|
||||
rollup: 3.26.3
|
||||
typescript: 5.0.2
|
||||
typescript: 5.3.3
|
||||
vite: 4.4.5(@types/node@20.4.5)(sass@1.64.1)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -3586,7 +3611,7 @@ packages:
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: true
|
||||
|
||||
/@storybook/react-vite@7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.2)(vite@4.4.5):
|
||||
/@storybook/react-vite@7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(vite@4.4.5):
|
||||
resolution: {integrity: sha512-sBMlrLf/zUDUk6bWQLu5/tERW82j9spGMD++O1mdum3eVfPwvsqjtGokTVx/eOLUYA9kqQFdUtjLSn0sS84bTQ==}
|
||||
engines: {node: '>=16'}
|
||||
peerDependencies:
|
||||
@@ -3594,10 +3619,10 @@ packages:
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
vite: ^3.0.0 || ^4.0.0
|
||||
dependencies:
|
||||
'@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@5.0.2)(vite@4.4.5)
|
||||
'@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@5.3.3)(vite@4.4.5)
|
||||
'@rollup/pluginutils': 5.0.2
|
||||
'@storybook/builder-vite': 7.2.1(typescript@5.0.2)(vite@4.4.5)
|
||||
'@storybook/react': 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.2)
|
||||
'@storybook/builder-vite': 7.2.1(typescript@5.3.3)(vite@4.4.5)
|
||||
'@storybook/react': 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
|
||||
'@vitejs/plugin-react': 3.1.0(vite@4.4.5)
|
||||
ast-types: 0.14.2
|
||||
magic-string: 0.30.2
|
||||
@@ -3614,7 +3639,7 @@ packages:
|
||||
- vite-plugin-glimmerx
|
||||
dev: true
|
||||
|
||||
/@storybook/react@7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.0.2):
|
||||
/@storybook/react@7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-WRAVrSQKAtCoypUrrIXWGOvyGRVkrh73hSkKVC0gEqxWDmjZIZJ1uc3VrUd/yHJdLsqNphcAyU8Ahu52yozubg==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
peerDependencies:
|
||||
@@ -3647,7 +3672,7 @@ packages:
|
||||
react-element-to-jsx-string: 15.0.0(react-dom@18.2.0)(react@18.2.0)
|
||||
ts-dedent: 2.2.0
|
||||
type-fest: 2.19.0
|
||||
typescript: 5.0.2
|
||||
typescript: 5.3.3
|
||||
util-deprecate: 1.0.2
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -4073,6 +4098,10 @@ packages:
|
||||
resolution: {integrity: sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==}
|
||||
dev: true
|
||||
|
||||
/@types/use-sync-external-store@0.0.3:
|
||||
resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==}
|
||||
dev: false
|
||||
|
||||
/@types/yargs-parser@21.0.0:
|
||||
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
|
||||
dev: true
|
||||
@@ -4089,7 +4118,7 @@ packages:
|
||||
'@types/yargs-parser': 21.0.0
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.0.2):
|
||||
/@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
@@ -4101,10 +4130,10 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.6.2
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/scope-manager': 6.0.0
|
||||
'@typescript-eslint/type-utils': 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/type-utils': 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 6.0.0
|
||||
debug: 4.3.4
|
||||
eslint: 8.45.0
|
||||
@@ -4114,13 +4143,13 @@ packages:
|
||||
natural-compare: 1.4.0
|
||||
natural-compare-lite: 1.4.0
|
||||
semver: 7.5.4
|
||||
ts-api-utils: 1.0.1(typescript@5.0.2)
|
||||
typescript: 5.0.2
|
||||
ts-api-utils: 1.0.1(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/parser@6.0.0(eslint@8.45.0)(typescript@5.0.2):
|
||||
/@typescript-eslint/parser@6.0.0(eslint@8.45.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
@@ -4132,11 +4161,11 @@ packages:
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 6.0.0
|
||||
'@typescript-eslint/types': 6.0.0
|
||||
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.0.2)
|
||||
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 6.0.0
|
||||
debug: 4.3.4
|
||||
eslint: 8.45.0
|
||||
typescript: 5.0.2
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -4157,7 +4186,7 @@ packages:
|
||||
'@typescript-eslint/visitor-keys': 6.0.0
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/type-utils@6.0.0(eslint@8.45.0)(typescript@5.0.2):
|
||||
/@typescript-eslint/type-utils@6.0.0(eslint@8.45.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
@@ -4167,12 +4196,12 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.0.2)
|
||||
'@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
debug: 4.3.4
|
||||
eslint: 8.45.0
|
||||
ts-api-utils: 1.0.1(typescript@5.0.2)
|
||||
typescript: 5.0.2
|
||||
ts-api-utils: 1.0.1(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -4187,7 +4216,7 @@ packages:
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/typescript-estree@5.62.0(typescript@5.0.2):
|
||||
/@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@@ -4202,13 +4231,13 @@ packages:
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.5.4
|
||||
tsutils: 3.21.0(typescript@5.0.2)
|
||||
typescript: 5.0.2
|
||||
tsutils: 3.21.0(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/typescript-estree@6.0.0(typescript@5.0.2):
|
||||
/@typescript-eslint/typescript-estree@6.0.0(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
@@ -4223,13 +4252,13 @@ packages:
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.5.4
|
||||
ts-api-utils: 1.0.1(typescript@5.0.2)
|
||||
typescript: 5.0.2
|
||||
ts-api-utils: 1.0.1(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/utils@5.62.0(eslint@8.45.0)(typescript@5.0.2):
|
||||
/@typescript-eslint/utils@5.62.0(eslint@8.45.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@@ -4240,7 +4269,7 @@ packages:
|
||||
'@types/semver': 7.5.0
|
||||
'@typescript-eslint/scope-manager': 5.62.0
|
||||
'@typescript-eslint/types': 5.62.0
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.2)
|
||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3)
|
||||
eslint: 8.45.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.5.4
|
||||
@@ -4249,7 +4278,7 @@ packages:
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/utils@6.0.0(eslint@8.45.0)(typescript@5.0.2):
|
||||
/@typescript-eslint/utils@6.0.0(eslint@8.45.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
@@ -4260,7 +4289,7 @@ packages:
|
||||
'@types/semver': 7.5.0
|
||||
'@typescript-eslint/scope-manager': 6.0.0
|
||||
'@typescript-eslint/types': 6.0.0
|
||||
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.0.2)
|
||||
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.3.3)
|
||||
eslint: 8.45.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.5.4
|
||||
@@ -5757,7 +5786,7 @@ packages:
|
||||
eslint-import-resolver-webpack:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
debug: 3.2.7
|
||||
eslint: 8.45.0
|
||||
eslint-import-resolver-node: 0.3.7
|
||||
@@ -5776,7 +5805,7 @@ packages:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
array-includes: 3.1.6
|
||||
array.prototype.flat: 1.3.1
|
||||
array.prototype.flatmap: 1.3.1
|
||||
@@ -5861,14 +5890,14 @@ packages:
|
||||
string.prototype.matchall: 4.0.8
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-storybook@0.6.13(eslint@8.45.0)(typescript@5.0.2):
|
||||
/eslint-plugin-storybook@0.6.13(eslint@8.45.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-smd+CS0WH1jBqUEJ3znGS7DU4ayBE9z6lkQAK2yrSUv1+rq8BT/tiI5C/rKE7rmiqiAfojtNYZRhzo5HrulccQ==}
|
||||
engines: {node: 12.x || 14.x || >= 16}
|
||||
peerDependencies:
|
||||
eslint: '>=6'
|
||||
dependencies:
|
||||
'@storybook/csf': 0.0.1
|
||||
'@typescript-eslint/utils': 5.62.0(eslint@8.45.0)(typescript@5.0.2)
|
||||
'@typescript-eslint/utils': 5.62.0(eslint@8.45.0)(typescript@5.3.3)
|
||||
eslint: 8.45.0
|
||||
requireindex: 1.2.0
|
||||
ts-dedent: 2.2.0
|
||||
@@ -6726,6 +6755,10 @@ packages:
|
||||
engines: {node: '>= 4'}
|
||||
dev: true
|
||||
|
||||
/immer@10.0.3:
|
||||
resolution: {integrity: sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==}
|
||||
dev: false
|
||||
|
||||
/immutable@4.3.1:
|
||||
resolution: {integrity: sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==}
|
||||
dev: true
|
||||
@@ -8291,12 +8324,12 @@ packages:
|
||||
tween-functions: 1.2.0
|
||||
dev: true
|
||||
|
||||
/react-docgen-typescript@2.2.2(typescript@5.0.2):
|
||||
/react-docgen-typescript@2.2.2(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==}
|
||||
peerDependencies:
|
||||
typescript: '>= 4.3.x'
|
||||
dependencies:
|
||||
typescript: 5.0.2
|
||||
typescript: 5.3.3
|
||||
dev: true
|
||||
|
||||
/react-docgen@6.0.0-alpha.3:
|
||||
@@ -8368,6 +8401,28 @@ packages:
|
||||
resolution: {integrity: sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==}
|
||||
dev: true
|
||||
|
||||
/react-redux@9.1.0(@types/react@18.2.15)(react@18.2.0)(redux@5.0.1):
|
||||
resolution: {integrity: sha512-6qoDzIO+gbrza8h3hjMA9aq4nwVFCKFtY2iLxCtVT38Swyy2C/dJCGBXHeHLtx6qlg/8qzc2MrhOeduf5K32wQ==}
|
||||
peerDependencies:
|
||||
'@types/react': ^18.2.25
|
||||
react: ^18.0
|
||||
react-native: '>=0.69'
|
||||
redux: ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
react-native:
|
||||
optional: true
|
||||
redux:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.15
|
||||
'@types/use-sync-external-store': 0.0.3
|
||||
react: 18.2.0
|
||||
redux: 5.0.1
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react-refresh@0.14.0:
|
||||
resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -8565,6 +8620,18 @@ packages:
|
||||
strip-indent: 4.0.0
|
||||
dev: true
|
||||
|
||||
/redux-thunk@3.1.0(redux@5.0.1):
|
||||
resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
|
||||
peerDependencies:
|
||||
redux: ^5.0.0
|
||||
dependencies:
|
||||
redux: 5.0.1
|
||||
dev: false
|
||||
|
||||
/redux@5.0.1:
|
||||
resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
|
||||
dev: false
|
||||
|
||||
/regenerate-unicode-properties@10.1.0:
|
||||
resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -8649,6 +8716,10 @@ packages:
|
||||
engines: {node: '>=0.10.5'}
|
||||
dev: true
|
||||
|
||||
/reselect@5.1.0:
|
||||
resolution: {integrity: sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==}
|
||||
dev: false
|
||||
|
||||
/resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -9527,13 +9598,13 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/ts-api-utils@1.0.1(typescript@5.0.2):
|
||||
/ts-api-utils@1.0.1(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==}
|
||||
engines: {node: '>=16.13.0'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.2.0'
|
||||
dependencies:
|
||||
typescript: 5.0.2
|
||||
typescript: 5.3.3
|
||||
dev: true
|
||||
|
||||
/ts-dedent@2.2.0:
|
||||
@@ -9556,14 +9627,14 @@ packages:
|
||||
/tslib@2.6.1:
|
||||
resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
|
||||
|
||||
/tsutils@3.21.0(typescript@5.0.2):
|
||||
/tsutils@3.21.0(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
||||
engines: {node: '>= 6'}
|
||||
peerDependencies:
|
||||
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
|
||||
dependencies:
|
||||
tslib: 1.14.1
|
||||
typescript: 5.0.2
|
||||
typescript: 5.3.3
|
||||
dev: true
|
||||
|
||||
/tween-functions@1.2.0:
|
||||
@@ -9652,9 +9723,9 @@ packages:
|
||||
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
|
||||
dev: true
|
||||
|
||||
/typescript@5.0.2:
|
||||
resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==}
|
||||
engines: {node: '>=12.20'}
|
||||
/typescript@5.3.3:
|
||||
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
@@ -9814,6 +9885,14 @@ packages:
|
||||
react: 18.2.0
|
||||
tslib: 2.6.1
|
||||
|
||||
/use-sync-external-store@1.2.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
|
||||
11
src/App.tsx
11
src/App.tsx
@@ -1,3 +1,12 @@
|
||||
import { Provider } from 'react-redux'
|
||||
|
||||
import { Router } from '@/router'
|
||||
import { store } from '@/services/store.ts'
|
||||
|
||||
export function App() {
|
||||
return <div>Hello</div>
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<Router />
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
|
||||
139
src/components/decks/decks.tsx
Normal file
139
src/components/decks/decks.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
import { Link, useSearchParams } from 'react-router-dom'
|
||||
|
||||
import { Button, TextField } from '@/components'
|
||||
import { Sort, Table, TableBody, TableCell, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import {
|
||||
useCreateDeckMutation,
|
||||
useDeleteDeckMutation,
|
||||
useGetDecksQuery,
|
||||
} from '@/services/decks/decks.service.ts'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
key: 'name',
|
||||
title: 'Name',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
key: 'cardsCount',
|
||||
title: 'Cards',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
key: 'updated',
|
||||
title: 'Last updated',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
key: 'author.name',
|
||||
title: 'Created by',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
key: '',
|
||||
title: '',
|
||||
sortable: false,
|
||||
},
|
||||
]
|
||||
|
||||
export const Decks = () => {
|
||||
const [search, setSearch] = useSearchParams()
|
||||
const [name, setName] = useState('')
|
||||
const orderBy = JSON.parse(search.get('orderBy') ?? 'null')
|
||||
const setOrderBy = (value: Sort) => {
|
||||
search.set('orderBy', JSON.stringify(value))
|
||||
setSearch(search)
|
||||
}
|
||||
const orderByString = useMemo(() => {
|
||||
if (!orderBy) return null
|
||||
|
||||
return `${orderBy.key}-${orderBy.direction}`
|
||||
}, [orderBy])
|
||||
|
||||
const { data, isLoading, error } = useGetDecksQuery({
|
||||
name,
|
||||
orderBy: orderByString,
|
||||
})
|
||||
|
||||
const [createDeck, { isLoading: isDeckBeingCreated }] = useCreateDeckMutation()
|
||||
const [deleteDeck, { isLoading: isDeckBeingDeleted }] = useDeleteDeckMutation()
|
||||
|
||||
if (isLoading) {
|
||||
return <h1>Loading...</h1>
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <h1>Error: {JSON.stringify(error)}...</h1>
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
maxWidth: 1280,
|
||||
padding: '24px 137px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '24px',
|
||||
alignItems: 'center',
|
||||
margin: '0 auto',
|
||||
}}
|
||||
>
|
||||
<Link to={'login'}>Login</Link>
|
||||
<TextField onValueChange={setName} value={name} label={'Search'} />
|
||||
<Button
|
||||
disabled={isDeckBeingCreated}
|
||||
onClick={() => {
|
||||
createDeck({
|
||||
name: '🥳 new card',
|
||||
})
|
||||
}}
|
||||
>
|
||||
Create deck
|
||||
</Button>
|
||||
<Table width={'100%'}>
|
||||
<TableHeader columns={columns} sort={orderBy} onSort={setOrderBy} />
|
||||
<TableBody>
|
||||
{data?.items?.map(deck => {
|
||||
return (
|
||||
<TableRow key={deck.id}>
|
||||
<TableCell>{deck.name}</TableCell>
|
||||
<TableCell>{deck.cardsCount}</TableCell>
|
||||
<TableCell>{new Date(deck.updated).toLocaleDateString('ru-RU')}</TableCell>
|
||||
<TableCell>{deck.author.name}</TableCell>
|
||||
<TableCell>
|
||||
<button
|
||||
style={{ all: 'unset' }}
|
||||
onClick={() => deleteDeck({ id: deck.id })}
|
||||
disabled={isDeckBeingDeleted}
|
||||
>
|
||||
<TrashOutline />
|
||||
</button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const TrashOutline = () => {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_53159_1173)">
|
||||
<path
|
||||
d="M13.9999 4.00011H10.6666V2.88677C10.6509 2.45998 10.4667 2.05681 10.1543 1.76563C9.84188 1.47446 9.42675 1.31903 8.99992 1.33344H6.99992C6.57309 1.31903 6.15796 1.47446 5.84554 1.76563C5.53312 2.05681 5.34889 2.45998 5.33325 2.88677V4.00011H1.99992C1.82311 4.00011 1.65354 4.07034 1.52851 4.19537C1.40349 4.32039 1.33325 4.48996 1.33325 4.66677C1.33325 4.84358 1.40349 5.01315 1.52851 5.13818C1.65354 5.2632 1.82311 5.33344 1.99992 5.33344H2.66659V12.6668C2.66659 13.1972 2.8773 13.7059 3.25237 14.081C3.62744 14.4561 4.13615 14.6668 4.66659 14.6668H11.3333C11.8637 14.6668 12.3724 14.4561 12.7475 14.081C13.1225 13.7059 13.3333 13.1972 13.3333 12.6668V5.33344H13.9999C14.1767 5.33344 14.3463 5.2632 14.4713 5.13818C14.5963 5.01315 14.6666 4.84358 14.6666 4.66677C14.6666 4.48996 14.5963 4.32039 14.4713 4.19537C14.3463 4.07034 14.1767 4.00011 13.9999 4.00011ZM6.66659 2.88677C6.66659 2.78011 6.80659 2.66677 6.99992 2.66677H8.99992C9.19325 2.66677 9.33325 2.78011 9.33325 2.88677V4.00011H6.66659V2.88677ZM11.9999 12.6668C11.9999 12.8436 11.9297 13.0132 11.8047 13.1382C11.6796 13.2632 11.5101 13.3334 11.3333 13.3334H4.66659C4.48977 13.3334 4.32021 13.2632 4.19518 13.1382C4.07016 13.0132 3.99992 12.8436 3.99992 12.6668V5.33344H11.9999V12.6668Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_53159_1173">
|
||||
<rect width="16" height="16" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -54,16 +54,16 @@ export const TableHeader: FC<
|
||||
}
|
||||
|
||||
return (
|
||||
<thead {...restProps}>
|
||||
<tr>
|
||||
<TableHead {...restProps}>
|
||||
<TableRow>
|
||||
{columns.map(({ title, key, sortable }) => (
|
||||
<th key={key} onClick={handleSort(key, sortable)}>
|
||||
<TableHeadCell key={key} onClick={handleSort(key, sortable)}>
|
||||
{title}
|
||||
{sort && sort.key === key && <span>{sort.direction === 'asc' ? '▲' : '▼'}</span>}
|
||||
</th>
|
||||
</TableHeadCell>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
)
|
||||
}
|
||||
export const TableBody = forwardRef<ElementRef<'tbody'>, ComponentPropsWithoutRef<'tbody'>>(
|
||||
|
||||
15
src/hooks/useDebounce.ts
Normal file
15
src/hooks/useDebounce.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export function useDebounce<T>(value: T, delay?: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setDebouncedValue(value), delay || 500)
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
}, [value, delay])
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
@@ -2,14 +2,12 @@ import '@fontsource/roboto/400.css'
|
||||
import '@fontsource/roboto/700.css'
|
||||
import './styles/index.scss'
|
||||
|
||||
import { StrictMode } from 'react'
|
||||
|
||||
import { createRoot } from 'react-dom/client'
|
||||
|
||||
import { App } from '@/App'
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
// <StrictMode>
|
||||
<App />
|
||||
// </StrictMode>
|
||||
)
|
||||
|
||||
40
src/router.tsx
Normal file
40
src/router.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
createBrowserRouter,
|
||||
Navigate,
|
||||
Outlet,
|
||||
RouteObject,
|
||||
RouterProvider,
|
||||
} from 'react-router-dom'
|
||||
|
||||
import { Decks } from '@/components/decks/decks.tsx'
|
||||
|
||||
const publicRoutes: RouteObject[] = [
|
||||
{
|
||||
path: '/login',
|
||||
element: <div>login</div>,
|
||||
},
|
||||
]
|
||||
|
||||
const privateRoutes: RouteObject[] = [
|
||||
{
|
||||
path: '/',
|
||||
element: <Decks />,
|
||||
},
|
||||
]
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
element: <PrivateRoutes />,
|
||||
children: privateRoutes,
|
||||
},
|
||||
...publicRoutes,
|
||||
])
|
||||
|
||||
export const Router = () => {
|
||||
return <RouterProvider router={router} />
|
||||
}
|
||||
|
||||
function PrivateRoutes() {
|
||||
const isAuthenticated = true
|
||||
|
||||
return isAuthenticated ? <Outlet /> : <Navigate to="/login" />
|
||||
}
|
||||
14
src/services/base-api.ts
Normal file
14
src/services/base-api.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
|
||||
|
||||
export const baseApi = createApi({
|
||||
reducerPath: 'baseApi',
|
||||
tagTypes: ['Decks'],
|
||||
baseQuery: fetchBaseQuery({
|
||||
baseUrl: 'https://api.flashcards.andrii.es',
|
||||
credentials: 'include',
|
||||
prepareHeaders: headers => {
|
||||
headers.append('x-auth-skip', 'true')
|
||||
},
|
||||
}),
|
||||
endpoints: () => ({}),
|
||||
})
|
||||
11
src/services/common.types.ts
Normal file
11
src/services/common.types.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export type Pagination = {
|
||||
totalItems: number
|
||||
totalPages: number
|
||||
currentPage: number
|
||||
itemsPerPage: number
|
||||
}
|
||||
|
||||
export type PaginatedResponse<T> = {
|
||||
items: T
|
||||
pagination: Pagination
|
||||
}
|
||||
33
src/services/decks/decks.service.ts
Normal file
33
src/services/decks/decks.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { CreateDeckArgs, Deck, DeckResponse, DeleteDeckArgs, GetDecksArgs } from './decks.types.ts'
|
||||
|
||||
import { baseApi } from '@/services/base-api.ts'
|
||||
|
||||
export const DecksService = baseApi.injectEndpoints({
|
||||
endpoints: builder => {
|
||||
return {
|
||||
getDecks: builder.query<DeckResponse, GetDecksArgs | void>({
|
||||
query: args => ({
|
||||
url: `v2/decks`,
|
||||
params: args ?? undefined,
|
||||
}),
|
||||
providesTags: ['Decks'],
|
||||
}),
|
||||
createDeck: builder.mutation<Deck, CreateDeckArgs>({
|
||||
query: args => ({
|
||||
url: 'v1/decks',
|
||||
body: args,
|
||||
method: 'POST',
|
||||
}),
|
||||
invalidatesTags: ['Decks'],
|
||||
}),
|
||||
deleteDeck: builder.mutation<void, DeleteDeckArgs>({
|
||||
query: args => ({
|
||||
url: `v1/decks/${args.id}`,
|
||||
method: 'DELETE',
|
||||
}),
|
||||
invalidatesTags: ['Decks'],
|
||||
}),
|
||||
}
|
||||
},
|
||||
})
|
||||
export const { useGetDecksQuery, useCreateDeckMutation, useDeleteDeckMutation } = DecksService
|
||||
40
src/services/decks/decks.types.ts
Normal file
40
src/services/decks/decks.types.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { PaginatedResponse } from '@/services/common.types.ts'
|
||||
|
||||
export type DeckResponse = PaginatedResponse<Deck[]>
|
||||
|
||||
export type Deck = {
|
||||
author: DeckAuthor
|
||||
id: string
|
||||
userId: string
|
||||
name: string
|
||||
isPrivate: boolean
|
||||
cover: string
|
||||
created: string
|
||||
updated: string
|
||||
cardsCount: number
|
||||
}
|
||||
|
||||
export type DeckAuthor = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type GetDecksArgs = {
|
||||
orderBy?: string | null
|
||||
minCardsCount?: number
|
||||
maxCardsCount?: number
|
||||
name?: string
|
||||
authorId?: string
|
||||
currentPage?: number
|
||||
itemsPerPage?: number
|
||||
}
|
||||
|
||||
export type CreateDeckArgs = {
|
||||
name: string
|
||||
cover?: File | null
|
||||
isPrivate?: boolean
|
||||
}
|
||||
|
||||
export type DeleteDeckArgs = {
|
||||
id: string
|
||||
}
|
||||
15
src/services/store.ts
Normal file
15
src/services/store.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { configureStore } from '@reduxjs/toolkit'
|
||||
import { setupListeners } from '@reduxjs/toolkit/query/react'
|
||||
|
||||
import { baseApi } from '@/services/base-api.ts'
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
[baseApi.reducerPath]: baseApi.reducer,
|
||||
},
|
||||
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(baseApi.middleware),
|
||||
})
|
||||
|
||||
export type AppDispatch = typeof store.dispatch
|
||||
export type RootState = ReturnType<typeof store.getState>
|
||||
setupListeners(store.dispatch)
|
||||
Reference in New Issue
Block a user