From 2bc7f0a51c7fe3684467412bfcbe61d9643c76d4 Mon Sep 17 00:00:00 2001 From: VanyaMate Date: Mon, 29 Jul 2024 06:35:38 +0300 Subject: [PATCH] add lng page temp --- .firebase/hosting.ZGlzdA.cache | 78 +++---- package-lock.json | 8 +- package.json | 2 +- public/locales/en/site-app.json | 1 + public/locales/ru/site-app.json | 1 + .../createLanguage/createLanguage.action.ts | 20 ++ .../createLanguageFolder.action.ts | 16 ++ .../createLanguageWord.action.ts | 16 ++ .../getMyLanguageFolderWords.action.ts | 15 ++ .../getMyLanguages/getMyLanguages.action.ts | 16 ++ src/app/model/languages/languages.model.ts | 79 +++++++ src/app/routes/main-site/config/routes.tsx | 9 + .../LanguagesPage/ui/LanguagesPage.async.tsx | 22 ++ src/pages/LanguagesPage/ui/LanguagesPage.tsx | 15 ++ .../ui/LanguagesContainer.module.scss | 5 + .../ui/LanguagesContainer.tsx | 200 ++++++++++++++++++ .../SiteNavigationMenu/SiteNavigationMenu.tsx | 14 +- 17 files changed, 472 insertions(+), 45 deletions(-) create mode 100644 src/app/action/languages/createLanguage/createLanguage.action.ts create mode 100644 src/app/action/languages/createLanguageFolder/createLanguageFolder.action.ts create mode 100644 src/app/action/languages/createLanguageWord/createLanguageWord.action.ts create mode 100644 src/app/action/languages/getMyLanguageFolderWords/getMyLanguageFolderWords.action.ts create mode 100644 src/app/action/languages/getMyLanguages/getMyLanguages.action.ts create mode 100644 src/app/model/languages/languages.model.ts create mode 100644 src/pages/LanguagesPage/ui/LanguagesPage.async.tsx create mode 100644 src/pages/LanguagesPage/ui/LanguagesPage.tsx create mode 100644 src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.module.scss create mode 100644 src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.tsx diff --git a/.firebase/hosting.ZGlzdA.cache b/.firebase/hosting.ZGlzdA.cache index 0c169c64..36814b3a 100644 --- a/.firebase/hosting.ZGlzdA.cache +++ b/.firebase/hosting.ZGlzdA.cache @@ -31,42 +31,42 @@ locales/ru/posts.json,1720840649553,e5331a713de811ca626035e172dd279d6050db4213fb locales/ru/site-app.json,1721016621450,e60f1db7d6672c66b2f50fbcba1cc69d9368e81a6f7aa01287ae8053acf98af7 locales/ru/translation.json,1720138557249,a90362966bbafb6169e327c9a26519fa9a44710e65903d4d02b975385a9ef2e1 locales/ru/validation-messages.json,1720138557249,8fd4439f5798da6dc8874d810348e60b0831a68dfbe9202ceb9bd5109e3b7aa3 -index.html,1722200809417,4d72734e1f935e2115eb84e9b45e0309e118545e2e65f6d764f96f3d58b11254 -assets/AboutPage-S10VBFY1.js,1722200809416,73ac7b4133f35230e599a915409c560fb52a37dc151ce04330c4f31be732cd2d -assets/CancelFriendRequestButton-CXWbaxJV.js,1722200809412,f48f021d084189901b2e4abde951cd0318fe6d79e86afd5ce67d2d71001df706 -assets/Col-CG_r2Sqg.js,1722200809416,38889ae9748b876ce8561ecccf6d1d97f191aec41b5c81aa05fc69d2e57f4ed7 -assets/Col-Dcn0nAZz.css,1722200809412,b0169bff5c69f064a01adaf98d8336de8acbb5928568d5ade4aa523870bd1ed2 -assets/DetailsBody-CiW4sEwW.js,1722200809416,4eed15d41d2737c83f86b78730710ffe1107abfdcf22912cbcdd3a5fed69c551 -assets/DetailsBody-CZ11f3x2.css,1722200809412,48d353f49e4bad4369ee63e7bd030dbd37954ce921257b6df3d172aab1d7a7fd -assets/DomainSearchItem-CPT-G6QN.js,1722200809414,77f7ee31a06c35ab87ac68e9ead96746cba5fe2b1bc06758447629e8e40f20f7 -assets/FilesPage-DsLhs2H8.css,1722200809412,7f03f9b8dfc3e946325275ce306771723e4f8b4969c30c705ec91118d680e7db -assets/FilesPage-B0B4GAta.js,1722200809416,a91ef6d269eadef1f70243dbc701fce6512e307275a349e7367a37f5b02139b3 -assets/FriendsPage-B6sQKjI0.js,1722200809416,1ae4729b17d7722e022ea6bb22c4091a4f873cd14124a9b0fe3423ba76d058a5 -assets/DialoguesPage-Bzmsv_FI.js,1722200809417,b496776b7846757b30b5d92df0dc2514509bfe8fbea2a143b747bed5d50a6377 -assets/DialoguesPage-BtmD_gaA.css,1722200809412,cc2f329fdaf3d4eb006c0547ba7d18bdd2d3e44e4242c018613df7d1c43d26e7 -assets/getStringDeltaByDates-BCu_by4x.js,1722200809412,1770e712fd186296ba2c545b7e9968f12b3ce6ff753360d77f0bb707f18aad00 -assets/GlobalNotifications-DBQlkVUN.css,1722200809412,3e746c35b42c1364b1b3ab9ca8678890496af82a9a4958ab613710ef032ecef4 -assets/GoToPrivateDialogue-Dt2HNXLz.js,1722200809416,9df7733396fa0ab34fc3e33a61b7ee571c1e7adcd57f329c2b6c84aaa65d5d98 -assets/HomePage-3rmtPU0O.js,1722200809416,252fca709de0a71692cf110ace7be729b50ab8ed769c2173c12b8669d8501692 -assets/GlobalNotifications-wRmLLh3e.js,1722200809417,b1a5cc60b231725afddda5c9dfdc3d269dcbb4125bb82468922d70d04026619f -assets/private-dialogues.model-B4i09uj6.js,1722200809412,f169881b0c6f18d180f7dafa79fc43021b2b373c653ec57936d3885273790980 -assets/index-D-FobWiA.css,1722200809411,a87647425706b6e7f73007e92e460c431aa121f5e13afec77976938526212b7c -assets/ProfilePage-Bb8TQpx2.js,1722200809412,b57257282de3bfea395e5ce395e226fe3f26ac31710dd770a1cb3c7f7dbd45cf -assets/Row-C63st5aI.css,1722200809412,124b5168dec1501e3e13b75f82fab1c9b34007923aff212042e6d9a0a51f4353 -assets/Row-D9GPxwbY.js,1722200809416,df9b0d3756362e453d9c7b78e8cbf57bac32d73cc03544f32d0fe1ac517f1737 -assets/GoToPrivateDialogue-D1h0wYIM.css,1722200809412,fac0d4187bd0cbdc14992af3b23d46938f4006b14c1e62c5fbdb67745f5db8d7 -assets/SearchPage-CB9DbVNb.css,1722200809412,692f6d19fe571f2d0e86f525ac3e6ca8769716fffdc4fb214fcaf19def5d87a9 -assets/SearchPage-DYDFR5id.js,1722200809416,18c2dea17bfa8172f4f647baa9e529f7cb255328f75685d725eaff52f8a76465 -assets/useDropdownController-BOzKRw5o.css,1722200809412,2757ffee441452fdea1610da57d51ac2a4c0a87e399e89a29e9d438a69066ea8 -assets/useDropdownController-D7dC0DuW.js,1722200809416,773ca9e711d80b56d5d1512f74e6501299933a41c88fe3fbf50c32e9a50e5475 -assets/UserAvatar-32jSFIVn.js,1722200809416,f624cb7d9181837c59fa687099c6df7fc6d3eec24a93654cf9c1e4dd4e6d06b4 -assets/UserAvatar-DQtQI0ov.css,1722200809412,8d97b33cd30166a4fe29b066914d212bfa3db656288342196cfeb9d7f10b1db7 -assets/UserContainer-F13HVtWJ.css,1722200809412,6314e5c18b2a5f851950229b83263947f9607a87c0f91836ae0d85a9d35007c9 -assets/UserHeaderControlMenu-9RXEbQXz.js,1722200809416,18372c342579f87909664752438f4857bc9d6ae83a4f13bf9327c0c20358e6c6 -assets/UserContainer-CddWhy1b.js,1722200809417,b603541bc3ce47da994566924e3098e22485604b80feca38bf137385c41e91fe -assets/UserHeaderControlMenu-pg-d7lCs.css,1722200809412,1a82bf08219ea9b0e58d5ebe87e1a4b41401084530075888e680b6c37814f618 -assets/UserPreviewItem-3usWu65o.js,1722200809417,647ec7f57c97d90c55e34ce0c9e63a5d3f7f7a0f7d05b1310bb5f26afe407a80 -assets/UserPreviewItem-zAugQ05Z.css,1722200809412,388b460157f95c19e002e8399ec60cef9c766985c755950d8ff5e9e56cf48423 -assets/Virtual-Bzty7uwm.css,1722200809412,8b2540806a87f3f6bfb17fcafb3b6798db9bc6de730d1deb7e74a1b3ccec179e -assets/Virtual-B-emgYws.js,1722200809417,6745970e540b739687cf289475832bd20f0778f8dac2ae475d95cf5beb1996e4 -assets/index-5AJwG0oe.js,1722200809418,7bb15b41b222c1151761eaef1f295d7ebe2c10f23cb085b8382741654d04e28a +index.html,1722201805197,e9292a5d4d238df2f9523841022bee4f4c54c075bebdd4e450a355bfcd1b7760 +assets/AboutPage-NtLXLNbk.js,1722201805171,0a0e40c73df6c8619c09a6769bac811cf294251fdbe4948dc263e441fe19ab2b +assets/CancelFriendRequestButton-cKHTXaFF.js,1722201805195,32593fd33d7a904e7e558b547f9e2a6c1c249cb861da4cfdb73111d71fd84b89 +assets/Col-Dcn0nAZz.css,1722201805170,b0169bff5c69f064a01adaf98d8336de8acbb5928568d5ade4aa523870bd1ed2 +assets/Col-D-sUW80Y.js,1722201805195,3b4c6a19c10c8f81bce15f3076a75e191e362776a00f2b8cc316c3fe4a26480f +assets/DetailsBody-DX46B92B.js,1722201805195,057450a2c43457d314f9da43598118fbcb08537756c9b7eab7fb55cfd90a8c76 +assets/DetailsBody-CZ11f3x2.css,1722201805170,48d353f49e4bad4369ee63e7bd030dbd37954ce921257b6df3d172aab1d7a7fd +assets/DialoguesPage-Bq1iMKTb.css,1722201805170,bb55bb63dc3d28ccb3047edc7fabc1315c1459d441678e5e544fdc0f26167bad +assets/DomainSearchItem-CKwtyOTg.js,1722201805171,b33aaef88edc4eafed56e56939248fc4123e653988787dc5cb778a05c79587b7 +assets/getStringDeltaByDates-WIgkz46-.js,1722201805172,f3c36288cf36d47fc732615fac52d10470e0f4f6054d2f929d2922ba2cc64de3 +assets/DialoguesPage-Cs17Dlsy.js,1722201805195,97bcaa03c25c86ed437ff4fa769470f4631c71fe9169193b06d4a7ab24b44c78 +assets/FilesPage-DsLhs2H8.css,1722201805170,7f03f9b8dfc3e946325275ce306771723e4f8b4969c30c705ec91118d680e7db +assets/FilesPage-Dtc9O9IP.js,1722201805195,65985dd694449aa20cf9eb15b6c6e86dad2df2a54ca32d10024d5b010dae12c5 +assets/FriendsPage-CY-FWNXE.js,1722201805194,1de3d038ea6837bec902d3c85b7ab962f514b7faf78d8187fc159f9185f6f358 +assets/GlobalNotifications-DBQlkVUN.css,1722201805170,3e746c35b42c1364b1b3ab9ca8678890496af82a9a4958ab613710ef032ecef4 +assets/GoToPrivateDialogue-D1h0wYIM.css,1722201805170,fac0d4187bd0cbdc14992af3b23d46938f4006b14c1e62c5fbdb67745f5db8d7 +assets/GoToPrivateDialogue-CEXsERLS.js,1722201805195,f977701eac52fb7caa99fd4250e343fa2771679f0f58f1d70d9465b6e433017c +assets/HomePage-CSoZ_2cF.js,1722201805171,29b716c67f24b24201f495db9f505fec05592ec5929dca7acc66b286f9c12692 +assets/private-dialogues.model-C5HlACR0.js,1722201805195,3a5cce17c9308e1256a964881beb5edbcf71d7b6b864a76a3de5becceb7c72de +assets/index-CPyXN1Hw.css,1722201805166,6d6e20a59ae62605a5f03eac517870b47042b16ddfb82b6953a7a71aac37e6e3 +assets/ProfilePage-4DfNAWpE.js,1722201805171,7339795e28aba5482dd4811c6a7ee847025fbd554706bbc07210ad2d966c00d5 +assets/GlobalNotifications-pAl_PFqO.js,1722201805197,da4e27b8d6c1f2127515f48e63baa343bdf487a67e577d5fc024550be223482a +assets/Row-B4wD0URi.js,1722201805195,afaeae34ef0a8e46953b0ed05a79eb57f8cde12a7183ed1f339d6875e36703a7 +assets/Row-C63st5aI.css,1722201805171,124b5168dec1501e3e13b75f82fab1c9b34007923aff212042e6d9a0a51f4353 +assets/SearchPage-CB9DbVNb.css,1722201805170,692f6d19fe571f2d0e86f525ac3e6ca8769716fffdc4fb214fcaf19def5d87a9 +assets/SearchPage-CgS6sLFl.js,1722201805195,c244c81a82f90a9cb4be089f253125b2c170f077d754d1cc55239b7a5729a6b2 +assets/useDropdownController-ChoWwB2c.js,1722201805195,edc3678091f154d1460f41491b3eae03ecb0fbda9f0a93380c416bf345f9d926 +assets/useDropdownController-BOzKRw5o.css,1722201805171,2757ffee441452fdea1610da57d51ac2a4c0a87e399e89a29e9d438a69066ea8 +assets/UserAvatar-DTdeV7In.js,1722201805195,1f4dcec28c4baea6925908458ec30f6348173eb8171e2b30255063b15598ad84 +assets/UserAvatar-DQtQI0ov.css,1722201805170,8d97b33cd30166a4fe29b066914d212bfa3db656288342196cfeb9d7f10b1db7 +assets/UserContainer-F13HVtWJ.css,1722201805170,6314e5c18b2a5f851950229b83263947f9607a87c0f91836ae0d85a9d35007c9 +assets/UserContainer-BvQVNJvT.js,1722201805195,f62bd43894f2e9b051ac9aae02a746886b117706449c412209ad3666ca646d22 +assets/UserHeaderControlMenu-DzMAAMui.js,1722201805195,1b5426600d0a05fc3235dfcab799e30ec21ba2e089c0acf06784058de23bf6b7 +assets/UserHeaderControlMenu-pg-d7lCs.css,1722201805170,1a82bf08219ea9b0e58d5ebe87e1a4b41401084530075888e680b6c37814f618 +assets/UserPreviewItem-Csa5ItJQ.js,1722201805195,7934a5dea7ebb0fd0ed91e51dcf6d4186d07a21a17a9a1f26550f94c543dee52 +assets/UserPreviewItem-zAugQ05Z.css,1722201805170,388b460157f95c19e002e8399ec60cef9c766985c755950d8ff5e9e56cf48423 +assets/Virtual-Bzty7uwm.css,1722201805170,8b2540806a87f3f6bfb17fcafb3b6798db9bc6de730d1deb7e74a1b3ccec179e +assets/Virtual-DizNlMpa.js,1722201805196,d6a3e41600815aa7137cd6550907730c81c9f3417c9c278c672d937c957995a7 +assets/index-CkJsoBt_.js,1722201805196,9b746eb9779ebb05f1e3be22beb0af22c07a9b66dcb02922ea89796c41c60b93 diff --git a/package-lock.json b/package-lock.json index 4a29dc16..40aad8ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "i18next": "^23.10.1", "i18next-browser-languagedetector": "^7.2.0", "i18next-http-backend": "^2.5.0", - "product-types": "^0.3.63", + "product-types": "^0.3.70", "react": "^18.2.0", "react-dom": "^18.2.0", "react-i18next": "^14.1.0", @@ -16443,9 +16443,9 @@ "dev": true }, "node_modules/product-types": { - "version": "0.3.63", - "resolved": "https://registry.npmjs.org/product-types/-/product-types-0.3.63.tgz", - "integrity": "sha512-jbpQ/aK4Ha8fqE7LsMndVQXCbUv0ah9dUBEvBWSQWoMjXH+bMU/XWYUytN421qk+MsmssifbecCOX4v8I5vxcg==" + "version": "0.3.70", + "resolved": "https://registry.npmjs.org/product-types/-/product-types-0.3.70.tgz", + "integrity": "sha512-Mun4DQWGCTKrv3rW+cw1iZqYoEzBpXBxd7zJfbOPsxGh1R/aaLGVohjwhsoiF3shDZYAvbynS5SaO23yTkMiBw==" }, "node_modules/prompts": { "version": "2.4.2", diff --git a/package.json b/package.json index 46451ba1..b8e97e1a 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "i18next": "^23.10.1", "i18next-browser-languagedetector": "^7.2.0", "i18next-http-backend": "^2.5.0", - "product-types": "^0.3.63", + "product-types": "^0.3.70", "react": "^18.2.0", "react-dom": "^18.2.0", "react-i18next": "^14.1.0", diff --git a/public/locales/en/site-app.json b/public/locales/en/site-app.json index 9136ad8e..533e1e43 100644 --- a/public/locales/en/site-app.json +++ b/public/locales/en/site-app.json @@ -9,6 +9,7 @@ "friends_page": "Friends", "dialogues_page": "Dialogues", "files_page": "Files", + "languages_page": "Languages", "open_navigation_menu": "Open menu", "close_navigation_menu": "Close menu", "open_user_menu": "Open user menu", diff --git a/public/locales/ru/site-app.json b/public/locales/ru/site-app.json index c13a0be2..5779738a 100644 --- a/public/locales/ru/site-app.json +++ b/public/locales/ru/site-app.json @@ -9,6 +9,7 @@ "friends_page": "Друзья", "dialogues_page": "Диалоги", "files_page": "Файлы", + "languages_page": "Языки", "open_navigation_menu": "Открыть меню", "close_navigation_menu": "Закрыть меню", "open_user_menu": "Открыть меню пользователя", diff --git a/src/app/action/languages/createLanguage/createLanguage.action.ts b/src/app/action/languages/createLanguage/createLanguage.action.ts new file mode 100644 index 00000000..bdadeae4 --- /dev/null +++ b/src/app/action/languages/createLanguage/createLanguage.action.ts @@ -0,0 +1,20 @@ +import { + DomainLanguageCreateData, +} from 'product-types/dist/language/DomainLanguageCreateData'; +import { request } from '@/app/lib/fetch/request.ts'; +import { + isDomainNotificationLanguageCreateData, +} from 'product-types/dist/notification/notification-data-types/language/DomainNotificationLanguageCreateData'; + + +export const createLanguageAction = function (createData: DomainLanguageCreateData) { + return request( + `v1/language`, + { + method: 'POST', + body : JSON.stringify(createData), + isJson: true, + }, + isDomainNotificationLanguageCreateData, + ); +}; \ No newline at end of file diff --git a/src/app/action/languages/createLanguageFolder/createLanguageFolder.action.ts b/src/app/action/languages/createLanguageFolder/createLanguageFolder.action.ts new file mode 100644 index 00000000..5a0c2f7e --- /dev/null +++ b/src/app/action/languages/createLanguageFolder/createLanguageFolder.action.ts @@ -0,0 +1,16 @@ +import { + DomainLanguageFolderCreateData, +} from 'product-types/dist/language/DomainLanguageFolderCreateData'; +import { request } from '@/app/lib/fetch/request.ts'; +import { + isDomainNotificationLanguageFolderCreateData, +} from 'product-types/dist/notification/notification-data-types/language/DomainNotificationLanguageFolderCreateData'; + + +export const createLanguageFolderAction = function (languageId: string, createData: DomainLanguageFolderCreateData) { + return request( + `v1/language/folder/${ languageId }`, + { method: 'POST', body: JSON.stringify(createData), isJson: true }, + isDomainNotificationLanguageFolderCreateData, + ); +}; \ No newline at end of file diff --git a/src/app/action/languages/createLanguageWord/createLanguageWord.action.ts b/src/app/action/languages/createLanguageWord/createLanguageWord.action.ts new file mode 100644 index 00000000..08c355fa --- /dev/null +++ b/src/app/action/languages/createLanguageWord/createLanguageWord.action.ts @@ -0,0 +1,16 @@ +import { + DomainLanguageWordCreateData, +} from 'product-types/dist/language/DomainLanguageWordCreateData'; +import { request } from '@/app/lib/fetch/request.ts'; +import { + isDomainNotificationLanguageWordCreateData, +} from 'product-types/dist/notification/notification-data-types/language/DomainNotificationLanguageWordCreateData'; + + +export const createLanguageWordAction = function (folderId: string, createData: DomainLanguageWordCreateData) { + return request( + `v1/language/word/${ folderId }`, + { method: 'POST', isJson: true, body: JSON.stringify(createData) }, + isDomainNotificationLanguageWordCreateData, + ); +}; \ No newline at end of file diff --git a/src/app/action/languages/getMyLanguageFolderWords/getMyLanguageFolderWords.action.ts b/src/app/action/languages/getMyLanguageFolderWords/getMyLanguageFolderWords.action.ts new file mode 100644 index 00000000..aa7e4d50 --- /dev/null +++ b/src/app/action/languages/getMyLanguageFolderWords/getMyLanguageFolderWords.action.ts @@ -0,0 +1,15 @@ +import { request } from '@/app/lib/fetch/request.ts'; +import { + DomainLanguageWord, isDomainLanguageWord, +} from 'product-types/dist/language/DomainLanguageWord'; + + +export const getMyLanguageFolderWordsAction = function (folderId: string) { + return request( + `v1/languages/folder/${ folderId }`, + { method: 'GET' }, + (data: unknown): data is Array => { + return Array.isArray(data) && data.every(isDomainLanguageWord); + }, + ); +}; \ No newline at end of file diff --git a/src/app/action/languages/getMyLanguages/getMyLanguages.action.ts b/src/app/action/languages/getMyLanguages/getMyLanguages.action.ts new file mode 100644 index 00000000..4df6af37 --- /dev/null +++ b/src/app/action/languages/getMyLanguages/getMyLanguages.action.ts @@ -0,0 +1,16 @@ +import { request } from '@/app/lib/fetch/request.ts'; +import { + DomainLanguageWithFolders, + isDomainLanguageWithFolders, +} from 'product-types/dist/language/DomainLanguageWithFolders'; + + +export const getMyLanguagesAction = function () { + return request( + `v1/languages`, + { method: 'GET' }, + (data: unknown): data is Array => { + return Array.isArray(data) && data.every(isDomainLanguageWithFolders); + }, + ); +}; \ No newline at end of file diff --git a/src/app/model/languages/languages.model.ts b/src/app/model/languages/languages.model.ts new file mode 100644 index 00000000..9f56fbf9 --- /dev/null +++ b/src/app/model/languages/languages.model.ts @@ -0,0 +1,79 @@ +import { effect, store } from '@vanyamate/sec'; +import { + createLanguageAction, +} from '@/app/action/languages/createLanguage/createLanguage.action.ts'; +import { + DomainLanguageWithFolders, +} from 'product-types/dist/language/DomainLanguageWithFolders'; +import { + getMyLanguagesAction, +} from '@/app/action/languages/getMyLanguages/getMyLanguages.action.ts'; +import { + createLanguageWordAction, +} from '@/app/action/languages/createLanguageWord/createLanguageWord.action.ts'; +import { + createLanguageFolderAction, +} from '@/app/action/languages/createLanguageFolder/createLanguageFolder.action.ts'; +import { + DomainLanguageWord, +} from 'product-types/dist/language/DomainLanguageWord'; +import { + getMyLanguageFolderWordsAction, +} from '@/app/action/languages/getMyLanguageFolderWords/getMyLanguageFolderWords.action.ts'; + + +export const createLanguageEffect = effect(createLanguageAction); +export const createLanguageFolderEffect = effect(createLanguageFolderAction); +export const createLanguageWordEffect = effect(createLanguageWordAction); +export const getMyLanguagesEffect = effect(getMyLanguagesAction); +export const getMyLanguageFolderWordsEffect = effect(getMyLanguageFolderWordsAction); + + +export const $isUserLanguages = store(true) + .on(getMyLanguagesEffect, 'onBefore', () => true); + +export const $languagesLoading = store(false) + .on(getMyLanguagesEffect, 'onBefore', () => true) + .on(getMyLanguagesEffect, 'onSuccess', () => false); + +export const $languagesList = store>([]) + .on(getMyLanguagesEffect, 'onSuccess', (_, { result }) => result) + .on(createLanguageEffect, 'onSuccess', (state, { result }) => { + return $isUserLanguages.get() + ? [ ...state, + { + folders: [], + id : result.language.id, + title : result.language.title, + } ] + : state; + }) + .on(createLanguageFolderEffect, 'onSuccess', (state, { result }) => { + return $isUserLanguages.get() + ? state.map( + (language) => + language.id === result.language.id + ? { + ...language, + folders: [ ...language.folders, result.folder ], + } + : language, + ) + : state; + }); + +export const $currentFolderId = store('') + .on(getMyLanguageFolderWordsEffect, 'onSuccess', (_, { args: [ folderId ] }) => folderId); + +export const $languageFolderWordsList = store>([]) + .on(getMyLanguageFolderWordsEffect, 'onSuccess', (_, { result }) => result) + .on( + createLanguageWordEffect, + 'onSuccess', + (state, { result, args: [ folderId ] }) => { + if ($currentFolderId.get() === folderId) { + return [ ...state, result.word ]; + } + return state; + }, + ); \ No newline at end of file diff --git a/src/app/routes/main-site/config/routes.tsx b/src/app/routes/main-site/config/routes.tsx index fda0d423..4b5d888b 100644 --- a/src/app/routes/main-site/config/routes.tsx +++ b/src/app/routes/main-site/config/routes.tsx @@ -9,6 +9,9 @@ import { import { FriendsPageAsync } from '@/pages/FriendsPage/ui/FriendsPage.async.tsx'; import { SearchPageAsync } from '@/pages/SearchPage/ui/SearchPage.async.tsx'; import { FilesPageAsync } from '@/pages/FilesPage/ui/FilesPage.async.tsx'; +import { + LanguagesPageAsync, +} from '@/pages/LanguagesPage/ui/LanguagesPage.async.tsx'; export const SITE_ROUTE_DIALOGUE_ID = 'dialogueId'; @@ -25,6 +28,7 @@ export enum SiteAppRoute { DIALOGUES = 'dialogues', FILE = 'file', FILES = 'files', + LANGUAGES = 'languages', NOT_FOUND = 'not_found', } @@ -38,6 +42,7 @@ export const SiteAppRoutePath: Record = { [SiteAppRoute.USER] : `/user/:${ SITE_ROUTE_USER_LOGIN }`, [SiteAppRoute.FILE] : `/file/:${ SITE_ROUTE_FILE_ID }`, [SiteAppRoute.FILES] : `/files`, + [SiteAppRoute.LANGUAGES]: `/languages`, [SiteAppRoute.NOT_FOUND]: '*', }; @@ -78,6 +83,10 @@ export const SiteAppRouteConfig: Record = { path : SiteAppRoutePath[SiteAppRoute.FILES], element: , }, + [SiteAppRoute.LANGUAGES]: { + path : SiteAppRoutePath[SiteAppRoute.LANGUAGES], + element: , + }, [SiteAppRoute.NOT_FOUND]: { path : SiteAppRoutePath[SiteAppRoute.NOT_FOUND], element: , diff --git a/src/pages/LanguagesPage/ui/LanguagesPage.async.tsx b/src/pages/LanguagesPage/ui/LanguagesPage.async.tsx new file mode 100644 index 00000000..3ababd91 --- /dev/null +++ b/src/pages/LanguagesPage/ui/LanguagesPage.async.tsx @@ -0,0 +1,22 @@ +import { FC, lazy, memo, Suspense } from 'react'; +import { + PageLoader, +} from '@/shared/ui-kit/loaders/PageLoader/ui/PageLoader.tsx'; +import { + ErrorBoundary, +} from '@/shared/ui-kit/errors/ErrorBoundary/ui/ErrorBoundary.tsx'; + + +const LanguagesPage = lazy(() => import('./LanguagesPage.tsx').then((data) => ({ + default: data.LanguagesPage, +}))); + +export const LanguagesPageAsync: FC = memo(function LanguagesPageAsync () { + return ( + }> + + + + + ); +}); \ No newline at end of file diff --git a/src/pages/LanguagesPage/ui/LanguagesPage.tsx b/src/pages/LanguagesPage/ui/LanguagesPage.tsx new file mode 100644 index 00000000..cc1832fc --- /dev/null +++ b/src/pages/LanguagesPage/ui/LanguagesPage.tsx @@ -0,0 +1,15 @@ +import { FC, memo } from 'react'; +import { + LanguagesContainer, +} from '@/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.tsx'; +import { useStore } from '@vanyamate/sec-react'; +import { $authUser } from '@/app/model/auth/auth.model.ts'; + + +export const LanguagesPage: FC = memo(function LanguagesPage () { + const user = useStore($authUser); + + return ( + + ); +}); \ No newline at end of file diff --git a/src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.module.scss b/src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.module.scss new file mode 100644 index 00000000..05cc189f --- /dev/null +++ b/src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.module.scss @@ -0,0 +1,5 @@ +.container { + li { + padding-left : 30px; + } +} \ No newline at end of file diff --git a/src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.tsx b/src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.tsx new file mode 100644 index 00000000..74d1a08d --- /dev/null +++ b/src/widgets/language/container/LanguagesContainer/ui/LanguagesContainer.tsx @@ -0,0 +1,200 @@ +import { ComponentPropsWithoutRef, FC, memo, useLayoutEffect } from 'react'; +import classNames from 'classnames'; +import css from './LanguagesContainer.module.scss'; +import { useStore } from '@vanyamate/sec-react'; +import { + $languageFolderWordsList, + $languagesList, + createLanguageEffect, + createLanguageFolderEffect, + createLanguageWordEffect, + getMyLanguageFolderWordsEffect, + getMyLanguagesEffect, +} from '@/app/model/languages/languages.model.ts'; +import { + InputWithError, +} from '@/shared/ui-kit/inputs/InputWithError/ui/InputWithError.tsx'; +import { + useInputWithError, +} from '@/shared/ui-kit/inputs/InputWithError/hooks/useInputWithError.ts'; +import { Form } from '@/shared/ui-kit/forms/Form/ui/Form.tsx'; +import { useForm } from '@/shared/ui-kit/forms/Form/hooks/useForm.ts'; +import { + ButtonWithLoading, +} from '@/shared/ui-kit/buttons/ButtonWithLoading/ui/ButtonWithLoading.tsx'; +import { Details } from '@/shared/ui-kit/details/Details/ui/Details.tsx'; +import { + DetailsTitle, +} from '@/shared/ui-kit/details/Details/ui/DetailsTitle/DetailsTitle.tsx'; +import { + DetailsBody, +} from '@/shared/ui-kit/details/Details/ui/DetailsBody/DetailsBody.tsx'; + +/* eslint-disable */ + +export type LanguagesContainerProps = + { + userId: string; + } + & ComponentPropsWithoutRef<'section'>; + +export const LanguagesContainer: FC = memo(function LanguagesContainer (props) { + const { className, userId, ...other } = props; + const languages = useStore($languagesList); + const words = useStore($languageFolderWordsList); + const createLanguageInput = useInputWithError({ + name: 'title', + }); + const createLanguageForm = useForm<{ title: string }>({ + inputs : [ createLanguageInput ], + onSubmit: async (data) => createLanguageEffect(data).then(), + }); + + const createLanguageFolderInput = useInputWithError({ + name: 'title', + }); + const createLanguageIdFolderInput = useInputWithError({ + name: 'id', + }); + const createLanguageFolderForm = useForm<{ title: string, id: string }>({ + inputs : [ createLanguageFolderInput, createLanguageIdFolderInput ], + onSubmit: async (data) => createLanguageFolderEffect(data.id, { title: data.title }).then(), + }); + + const createLanguageWordInput = useInputWithError({ + name: 'original', + }); + const createLanguageWordTranlation1Input = useInputWithError({ + name: 'translation1', + }); + const createLanguageWordTranlation2Input = useInputWithError({ + name: 'translation2', + }); + const createLanguageWordNoticeInput = useInputWithError({ + name: 'notice', + }); + const createLanguageWordFormIdInput = useInputWithError({ + name: 'id', + }); + const createLanguageWordForm = useForm<{ + original: string, + translation1: string, + translation2: string, + notice: string, + id: string + }>({ + inputs : [ + createLanguageWordInput, + createLanguageWordTranlation1Input, + createLanguageWordTranlation2Input, + createLanguageWordNoticeInput, + createLanguageWordFormIdInput, + ], + onSubmit: async (data) => createLanguageWordEffect(data.id, { + notice : data.notice, + translations: [ data.translation1, data.translation2 ], + original : data.original, + }).then(), + }); + + useLayoutEffect(() => { + getMyLanguagesEffect(); + }, []); + + return ( +
+
+

create language

+
+ + + Создать + + +
+
+

create folder

+
+ + + + Создать + + +
+
+

create word

+
+ + + + + + + Создать + + +
+

languages

+
    + { + languages.map((language) => ( +
  • +

    { language.title }

    +

    { language.id }

    +
      + { language.folders.map((folder) => ( +
    • getMyLanguageFolderWordsEffect(folder.id) }> +

      { folder.title }

      +

      { folder.id }

      +
    • + )) } +
    +
  • + )) + } +
+

words

+
    + { + words.map((word) => ( +
  • +

    { word.original }

    +

    { word.notice }

    +
    + Перевод + + { + word.translations.map((t, index) => ( +
    { t }
    )) + } +
    +
    +
  • + )) + } +
+
+ ); +}); \ No newline at end of file diff --git a/src/widgets/site/navigation/SiteNavigationMenu/ui/SiteNavigationMenu/SiteNavigationMenu.tsx b/src/widgets/site/navigation/SiteNavigationMenu/ui/SiteNavigationMenu/SiteNavigationMenu.tsx index fb476ef3..ec3c9200 100644 --- a/src/widgets/site/navigation/SiteNavigationMenu/ui/SiteNavigationMenu/SiteNavigationMenu.tsx +++ b/src/widgets/site/navigation/SiteNavigationMenu/ui/SiteNavigationMenu/SiteNavigationMenu.tsx @@ -7,7 +7,7 @@ import { import { IoDesktop, IoDocuments, - IoHome, + IoHome, IoLanguage, IoLogoVk, IoMail, IoPeople, @@ -101,6 +101,18 @@ export const SiteNavigationMenu: FC = memo(function Sit > { t('files_page') } + } + onClick={ onCompleteAction } + styleType={ + pathname === SiteAppRoutePath[SiteAppRoute.LANGUAGES] + ? LinkStyleType.PRIMARY + : LinkStyleType.GHOST + } + to={ SiteAppRoutePath[SiteAppRoute.LANGUAGES] } + > + { t('languages_page') } + } onClick={ onCompleteAction }