diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 054f91cfc8..2169009ec0 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -35,4 +35,80 @@ jobs:
verbose: true
fail_ci_if_error: false
name: '${{env.CODECOV_UNIQUE_NAME}}'
+
+ Generate-Documentation:
+ runs-on: ubuntu-latest
+ if: github.ref == 'refs/heads/automated-docs'
+ steps:
+ - name: Checkout the Repository
+ uses: actions/checkout@v3
+
+ - name: Install Dependencies
+ run: yarn install --legacy-peer-deps
+
+ - name: Install TypeScript Globally and add GraphQL tag
+ run: yarn global add typescript
+ - run: yarn add graphql-tag
+
+ - name: Update Dependencies
+ run: yarn upgrade
+
+ - name: Generate Documentation of Markdown pages
+ run: |
+ yarn global add typedoc
+ yarn add typedoc-plugin-markdown
+ yarn typedoc --entryPoints src/components src/screens --out talawa-admin-docs --plugin typedoc-plugin-markdown --theme markdown --entryPointStrategy expand --exclude "**/*.test.ts" --exclude "**/*.css"
+
+ - name: Checking doc updated
+ id: DocUpdated
+ run: |
+ if [ -n "$(git status --porcelain)" ]; then
+ echo "updateDoc=true" >> $GITHUB_OUTPUT
+ echo -e "Documentation has been updated!!"
+ else
+ Green='0;32'
+ NoColor='\033[0m'
+ echo -e "${Green}No documentation updated${NoColor}"
+ fi
+
+ - name: Set env variables
+ if: steps.DocUpdated.outputs.updateDoc
+ run: |
+ echo "commit_id=$(echo $(git rev-parse HEAD))" >> $GITHUB_ENV
+ echo "email=$(echo $(git log --pretty=format:"%ae" $commit_id))" >> $GITHUB_ENV
+
+ - name: Update Doc
+ if: steps.DocUpdated.outputs.updateDoc
+ run: |
+ Green='0;32'
+ NoColor='\033[0m'
+ git config --global user.name "${{github.actor}}"
+ git config --global user.email "${{env.email}}"
+ git add .
+ git commit -m "Update documentation"
+ git push
+ echo -e "🚀${Green} Hurrah! doc updated${NoColor}"
+
+ - name: Create Documentation Artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: documentation-admin
+ path: talawa-admin-docs
+
+ Copy-docs-to-talawa-docs:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dmnemec/copy_file_to_another_repo_action@v1.1.1
+ env:
+ API_TOKEN_GITHUB: ${{ secrets.TALAWA_DOCS_SYNC_NEW }}
+ with:
+ source_file: 'talawa-admin-docs/'
+ destination_repo: 'PalisadoesFoundation/talawa-docs'
+ destination_branch: 'develop'
+ destination_folder: 'docs/'
+ user_email: '${{env.email}}'
+ user_name: '${{github.actor}}'
+ commit_message: 'Talawa Admin docs updated'
+
diff --git a/README.md b/README.md
index 1fdb69e3a5..aebc481244 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
# Talawa Admin
💬 Join the community on Slack. The link can be found in the `Talawa` [README.md](https://github.com/PalisadoesFoundation/talawa) file.
-[![N|Solid](src/assets/images/talawa-logo-lite-200x200.png)](https://github.com/PalisadoesFoundation/talawa-admin)
-
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![GitHub stars](https://img.shields.io/github/stars/PalisadoesFoundation/talawa-admin.svg?style=social&label=Star&maxAge=2592000)](https://github.com/PalisadoesFoundation/talawa-admin)
[![GitHub forks](https://img.shields.io/github/forks/PalisadoesFoundation/talawa-admin.svg?style=social&label=Fork&maxAge=2592000)](https://github.com/PalisadoesFoundation/talawa-admin)
@@ -32,9 +30,9 @@ Core features include:
# Documentation
- The `talawa` documentation can be found [here](https://docs.talawa.io).
-- Want to contribute? Look at [CONTRIBUTING.md](CONTRIBUTING.md) to get started.
+- Want to contribute? Look at [CONTRIBUTING.md](https://github.com/PalisadoesFoundation/talawa-admin/blob/develop/CONTRIBUTING.md) to get started.
- Visit the [Talawa-Docs GitHub](https://github.com/PalisadoesFoundation/talawa-docs) to see the code.
# Installation
-[Follow this guide](./INSTALLATION.md)
+[Follow this guide](https://github.com/PalisadoesFoundation/talawa-admin/blob/develop/INSTALLATION.md)
diff --git a/package-lock.json b/package-lock.json
index 1795dfa860..d8a291c684 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -61,6 +61,8 @@
"react-toastify": "^9.0.3",
"redux": "^4.1.1",
"redux-thunk": "^2.3.0",
+ "typedoc": "^0.24.8",
+ "typedoc-plugin-markdown": "^3.15.4",
"typescript": "^4.3.5",
"web-vitals": "^1.0.1",
"yarn": "^1.22.17"
@@ -5896,6 +5898,11 @@
"node": ">=8"
}
},
+ "node_modules/ansi-sequence-parser": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
+ "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg=="
+ },
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -11465,6 +11472,34 @@
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
"integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg=="
},
+ "node_modules/handlebars": {
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "node_modules/handlebars/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
@@ -15686,6 +15721,11 @@
"node": ">=6"
}
},
+ "node_modules/jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
+ },
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -16053,6 +16093,11 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
+ },
"node_modules/lz-string": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
@@ -16186,6 +16231,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
"node_modules/mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@@ -21707,6 +21763,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/shiki": {
+ "version": "0.14.3",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz",
+ "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==",
+ "dependencies": {
+ "ansi-sequence-parser": "^1.1.0",
+ "jsonc-parser": "^3.2.0",
+ "vscode-oniguruma": "^1.7.0",
+ "vscode-textmate": "^8.0.0"
+ }
+ },
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -23433,6 +23500,59 @@
"is-typedarray": "^1.0.0"
}
},
+ "node_modules/typedoc": {
+ "version": "0.24.8",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.8.tgz",
+ "integrity": "sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==",
+ "dependencies": {
+ "lunr": "^2.3.9",
+ "marked": "^4.3.0",
+ "minimatch": "^9.0.0",
+ "shiki": "^0.14.1"
+ },
+ "bin": {
+ "typedoc": "bin/typedoc"
+ },
+ "engines": {
+ "node": ">= 14.14"
+ },
+ "peerDependencies": {
+ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x"
+ }
+ },
+ "node_modules/typedoc-plugin-markdown": {
+ "version": "3.15.4",
+ "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.15.4.tgz",
+ "integrity": "sha512-KpjFL/NDrQAbY147oIoOgob2vAdEchsMcTVd6+e6H2lC1l5xhi48bhP/fMJI7qYQ8th5nubervgqw51z7gY66A==",
+ "dependencies": {
+ "handlebars": "^4.7.7"
+ },
+ "peerDependencies": {
+ "typedoc": ">=0.24.0"
+ }
+ },
+ "node_modules/typedoc/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/typedoc/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
@@ -23445,6 +23565,18 @@
"node": ">=4.2.0"
}
},
+ "node_modules/uglify-js": {
+ "version": "3.17.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@@ -23902,6 +24034,16 @@
"node": ">=0.10.0"
}
},
+ "node_modules/vscode-oniguruma": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+ "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
+ },
+ "node_modules/vscode-textmate": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
+ "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg=="
+ },
"node_modules/w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
@@ -24378,6 +24520,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
+ },
"node_modules/workbox-background-sync": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz",
diff --git a/package.json b/package.json
index 6ce2624f54..a24962578a 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,8 @@
"react-toastify": "^9.0.3",
"redux": "^4.1.1",
"redux-thunk": "^2.3.0",
+ "typedoc": "^0.24.8",
+ "typedoc-plugin-markdown": "^3.16.0",
"typescript": "^4.3.5",
"web-vitals": "^1.0.1",
"yarn": "^1.22.17"
diff --git a/public/locales/en.json b/public/locales/en.json
index 3ab250aca1..6dd9156052 100644
--- a/public/locales/en.json
+++ b/public/locales/en.json
@@ -39,9 +39,33 @@
"menu": "Menu",
"organizations": "Organizations",
"requests": "Requests",
- "roles": "Roles",
+ "users": "Users",
"logout": "Logout"
},
+ "leftDrawerOrg": {
+ "talawaAdminPortal": "Talawa Admin Portal",
+ "menu": "Menu",
+ "logout": "Logout",
+ "talawa_portal": "Talawa Admin Portal",
+ "Dashboard": "Dashboard",
+ "People": "People",
+ "Events": "Events",
+ "Contributions": "Contributions",
+ "Posts": "Posts",
+ "Block/Unblock": "Block/Unblock",
+ "Plugins": "Plugins",
+ "Plugin Store": "Plugin Store",
+ "allOrganizations": "All Organizations",
+ "yourOrganization": "Your Organization",
+ "notification": "Notification",
+ "settings": "Settings",
+ "language": "Language",
+ "notifications": "Notifications",
+ "spamsThe": "spams the",
+ "group": "group",
+ "noNotifications": "No Notifications",
+ "close": "Close"
+ },
"orgList": {
"title": "Talawa Organizations",
"you": "You",
@@ -62,6 +86,11 @@
"cancel": "Cancel",
"noOrgErrorTitle": "Organizations Not Found",
"noOrgErrorDescription": "Please create an organization through dashboard",
+
+ "manageFeatures": "Manage Features",
+ "manageFeaturesInfo": "Creation Successful ! Please select features that you want to enale for this organization from the plugin store.",
+ "goToStore": "Go to Plugin Store",
+ "enableEverything": "Enable Everything",
"noResultsFoundFor": "No results found for "
},
"orgListCard": {
@@ -73,10 +102,10 @@
"rowsPerPage": "rows per page",
"all": "All"
},
- "roles": {
+ "users": {
"title": "Talawa Roles",
"searchByName": "Search By Name",
- "usersList": "Users List",
+ "users": "Users",
"name": "Name",
"email": "Email",
"roles_userType": "Role/User-Type",
@@ -112,30 +141,8 @@
"noResultsFoundFor": "No results found for ",
"talawaApiUnavailable": "Talawa-API service is unavailable. Is it running? Check your network connectivity too."
},
- "adminNavbar": {
- "talawa_portal": "Talawa Admin Portal",
- "Dashboard": "Dashboard",
- "People": "People",
- "Events": "Events",
- "Contributions": "Contributions",
- "Posts": "Posts",
- "Block/Unblock": "Block/Unblock",
- "Plugins": "Plugins",
- "Plugin Store": "Plugin Store",
- "allOrganizations": "All Organizations",
- "yourOrganization": "Your Organization",
- "notification": "Notification",
- "settings": "Settings",
- "language": "Language",
- "logout": "Logout",
- "notifications": "Notifications",
- "spamsThe": "spams the",
- "group": "group",
- "noNotifications": "No Notifications",
- "close": "Close"
- },
"dashboard": {
- "title": "Talawa Dashboard",
+ "title": "Dashboard",
"location": "Location",
"about": "About",
"deleteThisOrganization": "Delete This Organization",
@@ -145,11 +152,7 @@
"posts": "Posts",
"events": "Events",
"blockedUsers": "Blocked Users",
- "membershipRequests": "Membership Requests",
- "deleteOrganization": "Delete Organization",
- "deleteMsg": "Do you want to delete this organization?",
- "no": "No",
- "yes": "Yes",
+ "requests": "Requests",
"talawaApiUnavailable": "Talawa-API service is unavailable. Is it running? Check your network connectivity too."
},
"organizationPeople": {
@@ -297,6 +300,7 @@
},
"blockUnblockUser": {
"title": "Talawa Block/Unblock User",
+ "pageName": "Block/Unblock",
"searchByName": "Search By Name",
"listOfUsers": "List of Users who spammed",
"name": "Name",
@@ -310,8 +314,10 @@
"talawaApiUnavailable": "Talawa-API service is unavailable. Is it running? Check your network connectivity too.",
"allMembers": "All Members",
"blockedUsers": "Blocked Users",
- "searchFirstName": "Enter First Name",
- "searchLastName": "Enter Last Name"
+ "searchByFirstName": "Search By First Name",
+ "searchByLastName": "Search By Last Name",
+ "noResultsFoundFor": "No results found for",
+ "noSpammerFound": "No spammer found"
},
"forgotPassword": {
"title": "Talawa Forgot Password",
@@ -360,13 +366,20 @@
},
"orgSettings": {
"title": "Talawa Setting",
- "updateYourDetails": "Update Your Details",
- "updateYourPassword": "Update Your Password",
+ "pageName": "Settings",
"updateOrganization": "Update Organization",
- "deleteOrganization": "Delete Organization",
"seeRequest": "See Request",
"settings": "Settings",
- "noData": "No data"
+ "noData": "No data",
+ "otherSettings": "Other Settings",
+ "changeLanguage": "Change Language"
+ },
+ "deleteOrg": {
+ "deleteOrganization": "Delete Organization",
+ "deleteMsg": "Do you want to delete this organization?",
+ "no": "No",
+ "yes": "Yes",
+ "longDelOrgMsg": "By clicking on Delete organization button you will the organization will be permanently deleted along with its events, tags and all related data."
},
"userUpdate": {
"firstName": "First Name",
@@ -381,7 +394,6 @@
"saveChanges": "Save Changes",
"cancel": "Cancel"
},
-
"userPasswordUpdate": {
"previousPassword": "Previous Password",
"newPassword": "New Password",
@@ -389,7 +401,6 @@
"saveChanges": "Save Changes",
"cancel": "Cancel"
},
-
"orgDelete": {
"deleteOrg": "Delete Org"
},
@@ -405,10 +416,9 @@
"description": "Description",
"location": "Location",
"displayImage": "Display Image",
- "isPublic": "Is Public",
- "isRegistrable": "Is Registrable",
+ "isPublic": "Public",
+ "isVisibleInSearch": "Visible in Search",
"saveChanges": "Save Changes",
- "cancel": "Cancel",
"enterNameOrganization": "Enter Organization Name",
"successfulUpdated": "Organization updated successfully",
"talawaApiUnavailable": "Talawa-API service is unavailable. Is it running? Check your network connectivity too."
@@ -426,6 +436,7 @@
"pDesc": "This Plugin enables UI for"
},
"addOnStore": {
+ "title": "Add On Store",
"searchName": "Ex: Donations",
"enable": "Enabled",
"disable": "Disabled",
@@ -439,7 +450,9 @@
"addOnEntry": {
"enable": "Enabled",
"install": "Install",
- "uninstall": "Uninstall"
+ "uninstall": "Uninstall",
+ "uninstallMsg": "This feature is now removed from your organization",
+ "installMsg": "This feature is now enabled in your organization"
},
"memberDetail": {
"title": "User Details",
diff --git a/public/locales/fr.json b/public/locales/fr.json
index 82a494117c..78d3fade9b 100644
--- a/public/locales/fr.json
+++ b/public/locales/fr.json
@@ -39,9 +39,33 @@
"menu": "Menu",
"organizations": "Organisations",
"requests": "Demandes",
- "roles": "Rôles",
+ "users": "Utilisateurs",
"logout": "Déconnexion"
},
+ "leftDrawerOrg": {
+ "talawaAdminPortal": "Portail d'administration Talawa",
+ "menu": "Menu",
+ "talawa_portal": "Portail D'Administrateur Talawa",
+ "Dashboard": "Tableau de bord",
+ "People": "Personnes",
+ "Events": "Événements",
+ "Contributions": "Contributions",
+ "Posts": "Des postes",
+ "Block/Unblock": "Bloquer/Débloquer",
+ "Plugins": "Plugins",
+ "Plugin Store": "Magasin de plugins",
+ "allOrganizations": "Toutes les organisations",
+ "yourOrganization": "Votre organisation",
+ "notification": "Notification",
+ "settings": "Réglages",
+ "language": "Langue",
+ "logout": "Se déconnecter",
+ "notifications": "Notifications",
+ "spamsThe": "spam le",
+ "group": "groupe",
+ "noNotifications": "Aucune notification",
+ "close": "Proche"
+ },
"orgList": {
"title": "Organisations Talawa",
"you": "Tu",
@@ -73,10 +97,10 @@
"rowsPerPage": "lignes par page",
"all": "Tout"
},
- "roles": {
+ "users": {
"title": "Rôles Talawa",
"searchByName": "Recherche par nom",
- "usersList": "Liste des utilisateurs",
+ "users": "Utilisateurs",
"name": "Nom",
"email": "E-mail",
"roles_userType": "Rôle/Type d'utilisateur",
@@ -110,30 +134,8 @@
"noResultsFoundFor": "Aucun résultat trouvé pour ",
"talawaApiUnavailable": "Le service Talawa-API n'est pas disponible. Est-il en cours d'exécution ? Vérifiez également votre connectivité réseau."
},
- "adminNavbar": {
- "talawa_portal": "Portail D'Administrateur Talawa",
- "Dashboard": "Tableau de bord",
- "People": "Personnes",
- "Events": "Événements",
- "Contributions": "Contributions",
- "Posts": "Des postes",
- "Block/Unblock": "Bloquer/Débloquer",
- "Plugins": "Plugins",
- "Plugin Store": "Magasin de plugins",
- "allOrganizations": "Toutes les organisations",
- "yourOrganization": "Votre organisation",
- "notification": "Notification",
- "settings": "Réglages",
- "language": "Langue",
- "logout": "Se déconnecter",
- "notifications": "Notifications",
- "spamsThe": "spam le",
- "group": "groupe",
- "noNotifications": "Aucune notification",
- "close": "Proche"
- },
"dashboard": {
- "title": "Tableau de bord Talawa",
+ "title": "Tableau de bord",
"location": "Emplacement",
"about": "À propos de",
"deleteThisOrganization": "Supprimer cette organisation",
@@ -143,11 +145,7 @@
"posts": "Des postes",
"events": "Événements",
"blockedUsers": "Utilisateurs bloqués",
- "membershipRequests": "Demandes d'adhésion",
- "deleteOrganization": "Supprimer l'organisation",
- "deleteMsg": "Voulez-vous supprimer cette organisation ?",
- "no": "Non",
- "yes": "Oui",
+ "requests": "Demandes",
"talawaApiUnavailable": "Le service Talawa-API n'est pas disponible. Est-il en cours d'exécution ? Vérifiez également votre connectivité réseau."
},
"organizationPeople": {
@@ -295,6 +293,7 @@
},
"blockUnblockUser": {
"title": "Talawa Bloquer/Débloquer l'utilisateur",
+ "pageName": "Bloquer/Débloquer'",
"searchByName": "Recherche par nom",
"listOfUsers": "Liste des utilisateurs qui ont spammé",
"name": "Nom",
@@ -308,8 +307,10 @@
"talawaApiUnavailable": "Le service Talawa-API n'est pas disponible. Est-il en cours d'exécution ? Vérifiez également votre connectivité réseau.",
"allMembers": "Tous les membres",
"blockedUsers": "Utilisateurs bloqués",
- "searchFirstName": "Entrez votre prénom",
- "searchLastName": "Entrer le nom de famille"
+ "searchByFirstName": "Rechercher par prénom",
+ "searchByLastName": "Rechercher par nom de famille",
+ "noResultsFoundFor": "Aucun résultat trouvé pour ",
+ "noSpammerFound": "Aucun spammeur trouvé"
},
"forgotPassword": {
"title": "Mot de passe oublié Talawa",
@@ -358,13 +359,22 @@
},
"orgSettings": {
"title": "Paramètre Talawa",
+ "pageName": "Paramètres",
"updateYourDetails": "Mettre à jour vos informations",
"updateYourPassword": "Mettez à jour votre mot de passe",
"updateOrganization": "Mettre à jour l'organisation",
- "deleteOrganization": "Supprimer l'organisation",
"seeRequest": "Voir demande",
"settings": "Réglages",
- "noData": "Pas de données"
+ "noData": "Pas de données",
+ "otherSettings": "Autres paramètres",
+ "changeLanguage": "Changer la langue"
+ },
+ "deleteOrg": {
+ "deleteOrganization": "Supprimer l'organisation",
+ "deleteMsg": "Voulez-vous supprimer cette organisation ?",
+ "no": "Non",
+ "yes": "Oui",
+ "longDelOrgMsg": "En cliquant sur le bouton Supprimer l'organisation, l'organisation sera définitivement supprimée, ainsi que ses événements, étiquettes et toutes les données associées."
},
"userUpdate": {
"firstName": "Prénom",
@@ -401,10 +411,9 @@
"description": "La description",
"location": "emplacement",
"displayImage": "Afficher l'image",
- "isPublic": "Est publique",
- "isRegistrable": "Est enregistrable",
+ "isPublic": "Public",
+ "isVisibleInSearch": "Visible dans la recherche",
"saveChanges": "Sauvegarder les modifications",
- "cancel": "Annuler",
"enterNameOrganization": "Entrez le nom de l'organisation",
"successfulUpdated": "Mise à jour réussie",
"talawaApiUnavailable": "Le service Talawa-API n'est pas disponible. Est-il en cours d'exécution ? Vérifiez également votre connectivité réseau."
@@ -422,6 +431,7 @@
"pDesc": "Ce plugin active l'interface utilisateur pour"
},
"addOnStore": {
+ "title": "Add-On Store",
"searchName": "Ex:Des dons ",
"enable": "Activé",
"disable": "Désactivé",
diff --git a/public/locales/hi.json b/public/locales/hi.json
index 6fc8725f4a..29b449a0c9 100644
--- a/public/locales/hi.json
+++ b/public/locales/hi.json
@@ -39,9 +39,33 @@
"menu": "मेन्यू",
"organizations": "संगठन",
"requests": "अनुरोध",
- "roles": "भूमिकाएँ",
+ "users": "उपयोगकर्ता",
"logout": "लॉग आउट"
},
+ "leftDrawerOrg": {
+ "talawaAdminPortal": "तलावा व्यवस्थापक पोर्टल",
+ "menu": "मेन्यू",
+ "talawa_portal": "तलावा प्रशासन पोर्टल",
+ "Dashboard": "डैशबोर्ड",
+ "People": "लोग",
+ "Events": "आयोजन",
+ "Contributions": "योगदान",
+ "Posts": "पोस्ट",
+ "Block/Unblock": "ब्लॉक/अनब्लॉक करें",
+ "Plugins": "प्लगइन्स",
+ "Plugin Store": "प्लगइन स्टोर",
+ "allOrganizations": "सभी संगठन",
+ "yourOrganization": "आपका संगठन",
+ "notification": "अधिसूचना",
+ "settings": "समायोजन",
+ "language": "भाषा",
+ "logout": "लॉग आउट",
+ "notifications": "सूचनाएं",
+ "spamsThe": "स्पैम द",
+ "group": "समूह",
+ "noNotifications": "कोई सूचनाएं नहीं",
+ "close": "बंद करना"
+ },
"orgList": {
"title": "तलवा संगठन",
"you": "आप",
@@ -73,10 +97,10 @@
"rowsPerPage": "प्रति पृष्ठ पंक्तियाँ",
"all": "सभी"
},
- "roles": {
+ "users": {
"title": "तलावा भूमिकाएं",
"searchByName": "नाम से खोजें",
- "usersList": "उपयोगकर्ता सूची",
+ "users": "उपयोगकर्ता",
"name": "नाम",
"email": "ईमेल",
"roles_userType": "भूमिका/उपयोगकर्ता-प्रकार",
@@ -110,30 +134,8 @@
"noResultsFoundFor": "के लिए कोई परिणाम नहीं मिला ",
"talawaApiUnavailable": "तलवा-एपीआई सेवा उपलब्ध नहीं है। क्या यह चल रहा है? अपनी नेटवर्क कनेक्टिविटी भी जांचें।"
},
- "adminNavbar": {
- "talawa_portal": "तलावा प्रशासन पोर्टल",
- "Dashboard": "डैशबोर्ड",
- "People": "लोग",
- "Events": "आयोजन",
- "Contributions": "योगदान",
- "Posts": "पोस्ट",
- "Block/Unblock": "ब्लॉक/अनब्लॉक करें",
- "Plugins": "प्लगइन्स",
- "Plugin Store": "प्लगइन स्टोर",
- "allOrganizations": "सभी संगठन",
- "yourOrganization": "आपका संगठन",
- "notification": "अधिसूचना",
- "settings": "समायोजन",
- "language": "भाषा",
- "logout": "लॉग आउट",
- "notifications": "सूचनाएं",
- "spamsThe": "स्पैम द",
- "group": "समूह",
- "noNotifications": "कोई सूचनाएं नहीं",
- "close": "बंद करना"
- },
"dashboard": {
- "title": "तलावा डैशबोर्ड",
+ "title": "डैशबोर्ड",
"location": "स्थान",
"about": "के बारे में",
"deleteThisOrganization": "इस संगठन को हटाएं",
@@ -143,11 +145,7 @@
"posts": "पोस्ट",
"events": "आयोजन",
"blockedUsers": "रोके गए उपयोगकर्ता",
- "membershipRequests": "सदस्यता अनुरोध",
- "deleteOrganization": "संगठन हटाएं",
- "deleteMsg": "क्या आप इस संगठन को हटाना चाहते हैं?",
- "no": "नहीं",
- "yes": "हाँ",
+ "requests": "अनुरोध",
"talawaApiUnavailable": "तलवा-एपीआई सेवा उपलब्ध नहीं है। क्या यह चल रहा है? अपनी नेटवर्क कनेक्टिविटी भी जांचें।"
},
"organizationPeople": {
@@ -295,6 +293,7 @@
},
"blockUnblockUser": {
"title": "तलावा ब्लॉक/अनब्लॉक यूजर",
+ "pageName": "ब्लॉक/अनब्लॉक",
"searchByName": "नाम से खोजें",
"listOfUsers": "स्पैम करने वाले उपयोगकर्ताओं की सूची",
"name": "नाम",
@@ -308,8 +307,10 @@
"talawaApiUnavailable": "तलवा-एपीआई सेवा उपलब्ध नहीं है। क्या यह चल रहा है? अपनी नेटवर्क कनेक्टिविटी भी जांचें।",
"allMembers": "सभी सदस्य",
"blockedUsers": "रोके गए उपयोगकर्ता",
- "searchFirstName": "प्रथम नाम दर्ज करें",
- "searchLastName": "अंतिम नाम दर्ज करो"
+ "searchByFirstName": "पहले नाम से खोजें",
+ "searchByLastName": "उपनाम से खोजें",
+ "noResultsFoundFor": "के लिए कोई परिणाम नहीं मिला ",
+ "noSpammerFound": "कोई स्पैमर नहीं मिला"
},
"forgotPassword": {
"title": "तलवा पासवर्ड भूल गए",
@@ -358,13 +359,22 @@
},
"orgSettings": {
"title": "तलावा सेटिंग",
+ "pageName": "सेटिंग्स",
"updateYourDetails": "अपना विवरण अपडेट करें",
"updateYourPassword": "अपना पासवर्ड अपडेट करें",
"updateOrganization": "अद्यतन संगठन",
- "deleteOrganization": "संगठन हटाएं",
"seeRequest": "अनुरोध देखें",
"settings": "समायोजन",
- "noData": "कोई डेटा नहीं"
+ "noData": "कोई डेटा नहीं",
+ "otherSettings": "अन्य सेटिंग्स",
+ "changeLanguage": "भाषा बदलें"
+ },
+ "deleteOrg": {
+ "deleteOrganization": "संगठन हटाएं",
+ "deleteMsg": "क्या आप इस संगठन को हटाना चाहते हैं?",
+ "no": "नहीं",
+ "yes": "हां",
+ "longDelOrgMsg": "संगठन हटाने के बटन पर क्लिक करके, संगठन को स्थायित रूप से हटा दिया जाएगा, साथ ही उसके आयोजन, टैग और सभी संबंधित डेटा भी हटा दिया जाएगा।"
},
"userUpdate": {
"firstName": "पहला नाम",
@@ -401,8 +411,8 @@
"description": "विवरण",
"location": "जगह",
"displayImage": "प्रदर्शन छवि",
- "isPublic": "सार्वजनिक है",
- "isRegistrable": "पंजीकरण योग्य है",
+ "isPublic": "सार्वजनिक",
+ "isVisibleInSearch": "खोज में दिखाए जा सकते हैं",
"saveChanges": "परिवर्तनों को सुरक्षित करें",
"cancel": "रद्द करना",
"enterNameOrganization": "संगठन का नाम दर्ज करें",
@@ -422,6 +432,7 @@
"pDesc": "यह प्लगइन यूआई को सक्षम बनाता है"
},
"addOnStore": {
+ "title": "प्लगइन स्टोर",
"searchName": "जैसे: दान",
"enable": "सक्रिय",
"disable": "अक्षम",
diff --git a/public/locales/sp.json b/public/locales/sp.json
index 6ee06204cb..7fa6ccd04b 100644
--- a/public/locales/sp.json
+++ b/public/locales/sp.json
@@ -39,9 +39,33 @@
"menu": "Menú",
"organizations": "Organizaciones",
"requests": "Solicitudes",
- "roles": "Roles",
+ "users": "Usuarios",
"logout": "Cerrar sesión"
},
+ "leftDrawerOrg": {
+ "talawaAdminPortal": "Portal de administración de Talawa",
+ "menu": "Menú",
+ "talawa_portal": "Portal De Administración Talawa",
+ "Dashboard": "Tablero",
+ "People": "Gente",
+ "Events": "Eventos",
+ "Contributions": "Contribuciones",
+ "Posts": "Publicaciones",
+ "Block/Unblock": "Bloquear/Desbloquear",
+ "Plugins": "Complementos",
+ "Plugin Store": "Tienda de complementos",
+ "allOrganizations": "Todas las organizaciones",
+ "yourOrganization": "Tu organización",
+ "notification": "Notificación",
+ "settings": "Ajustes",
+ "language": "Idioma",
+ "logout": "Cerrar sesión",
+ "notifications": "Notificaciones",
+ "spamsThe": "envía correo no deseado",
+ "group": "grupo",
+ "noNotifications": "No Notificaciones",
+ "close": "Cerca"
+ },
"orgList": {
"title": "Organizaciones Talawa",
"you": "Tú",
@@ -73,10 +97,10 @@
"rowsPerPage": "filas por página",
"all": "Todos"
},
- "roles": {
+ "users": {
"title": "Roles Talawa",
"searchByName": "Buscar por nombre",
- "usersList": "Lista de usuarios",
+ "users": "Usuarios",
"name": "Nombre",
"email": "Correo electrónico",
"roles_userType": "Rol/Tipo de usuario",
@@ -110,30 +134,8 @@
"noResultsFoundFor": "No se encontraron resultados para ",
"talawaApiUnavailable": "El servicio Talawa-API no está disponible. ¿Está funcionando? Compruebe también la conectividad de su red."
},
- "adminNavbar": {
- "talawa_portal": "Portal De Administración Talawa",
- "Dashboard": "Tablero",
- "People": "Gente",
- "Events": "Eventos",
- "Contributions": "Contribuciones",
- "Posts": "Publicaciones",
- "Block/Unblock": "Bloquear/Desbloquear",
- "Plugins": "Complementos",
- "Plugin Store": "Tienda de complementos",
- "allOrganizations": "Todas las organizaciones",
- "yourOrganization": "Tu organización",
- "notification": "Notificación",
- "settings": "Ajustes",
- "language": "Idioma",
- "logout": "Cerrar sesión",
- "notifications": "Notificaciones",
- "spamsThe": "envía correo no deseado",
- "group": "grupo",
- "noNotifications": "No Notificaciones",
- "close": "Cerca"
- },
"dashboard": {
- "title": "Panel de Talawa",
+ "title": "Panel de",
"location": "Ubicación",
"about": "Sobre",
"deleteThisOrganization": "Eliminar esta organización",
@@ -143,11 +145,7 @@
"posts": "Publicaciones",
"events": "Eventos",
"blockedUsers": "Usuarios bloqueados",
- "membershipRequests": "Solicitudes de membresía",
- "deleteOrganization": "Eliminar Organización",
- "deleteMsg": "¿Desea eliminar esta organización?",
- "no": "No",
- "yes": "Sí",
+ "requests": "Solicitudes",
"talawaApiUnavailable": "El servicio Talawa-API no está disponible. ¿Está funcionando? Compruebe también la conectividad de su red."
},
"organizationPeople": {
@@ -295,6 +293,7 @@
},
"blockUnblockUser": {
"title": "Usuario de bloqueo/desbloqueo de Talawa",
+ "pageName": "Bloqueo/desbloqueo",
"searchByName": "Buscar por nombre",
"listOfUsers": "Lista de Usuarios que enviaron spam",
"name": "Nombre",
@@ -308,8 +307,10 @@
"talawaApiUnavailable": "El servicio Talawa-API no está disponible. ¿Está funcionando? Compruebe también la conectividad de su red.",
"allMembers": "Todos los miembros",
"blockedUsers": "Usuarios bloqueados",
- "searchFirstName": "Ingrese el nombre",
- "searchLastName": "Introduzca el apellido"
+ "searchByFirstName": "Buscar por nombre de pila",
+ "searchByLastName": "Buscar por apellido",
+ "noResultsFoundFor": "No se encontraron resultados para ",
+ "noSpammerFound": "No se encontró ningún spammer"
},
"forgotPassword": {
"title": "Talawa olvidó su contraseña",
@@ -358,13 +359,22 @@
},
"orgSettings": {
"title": "Configuración Talawa",
+ "pageName": "Configuración",
"updateYourDetails": "Actualiza tus datos",
"updateYourPassword": "Actualice su contraseña",
"updateOrganization": "Actualizar Organización",
- "deleteOrganization": "Eliminar Organización",
"seeRequest": "Ver Solicitud",
"settings": "Ajustes",
- "noData": "Sin datos"
+ "noData": "Sin datos",
+ "otherSettings": "Otras Configuraciones",
+ "changeLanguage": "Cambiar Idioma"
+ },
+ "deleteOrg": {
+ "deleteOrganization": "Eliminar organización",
+ "deleteMsg": "¿Desea eliminar esta organización?",
+ "no": "No",
+ "yes": "Sí",
+ "longDelOrgMsg": "Al hacer clic en el botón de Eliminar organización, se eliminará permanentemente la organización junto con sus eventos, etiquetas y todos los datos relacionados."
},
"userUpdate": {
"firstName": "Primer nombre",
@@ -401,8 +411,8 @@
"description": "Descripción",
"location": "ubicación",
"displayImage": "Mostrar imagen",
- "isPublic": "Es público",
- "isRegistrable": "Es registrable",
+ "isPublic": "Público",
+ "isVisibleInSearch": "Visible en la búsqueda",
"saveChanges": "Guardar cambios",
"cancel": "Cancelar",
"enterNameOrganization": "Ingrese el nombre de la organización",
@@ -422,6 +432,7 @@
"pDesc": "Este complemento habilita la interfaz de usuario para"
},
"addOnStore": {
+ "title": "Tienda de complementos",
"searchName": "Ej: Donaciones",
"enable": "Activada",
"disable": "Desactivada",
diff --git a/public/locales/zh.json b/public/locales/zh.json
index b762f994b2..a4232d43cf 100644
--- a/public/locales/zh.json
+++ b/public/locales/zh.json
@@ -39,9 +39,33 @@
"menu": "菜单",
"organizations": "组织",
"requests": "请求",
- "roles": "角色",
+ "users": "用户",
"logout": "退出登录"
},
+ "leftDrawerOrg": {
+ "talawaAdminPortal": "塔拉瓦管理门户",
+ "menu": "菜单",
+ "talawa_portal": "塔拉瓦管理門戶",
+ "Dashboard": "儀表板",
+ "People": "人們",
+ "Events": "事件",
+ "Contributions": "貢獻",
+ "Posts": "帖子",
+ "Block/Unblock": "阻止/解除阻止",
+ "Plugins": "插件",
+ "Plugin Store": "插件商店",
+ "allOrganizations": "所有组织",
+ "yourOrganization": "您的组织",
+ "notification": "通知",
+ "settings": "設置",
+ "language": "語",
+ "logout": "登出",
+ "notifications": "通知",
+ "spamsThe": "垃圾郵件",
+ "group": "團體",
+ "noNotifications": "沒有通知",
+ "close": "關"
+ },
"orgList": {
"title": "塔拉瓦組織",
"you": "你",
@@ -73,10 +97,10 @@
"rowsPerPage": "每頁行數",
"all": "全部"
},
- "roles": {
+ "users": {
"title": "塔拉瓦角色",
"searchByName": "按名稱搜索",
- "usersList": "用戶列表",
+ "users": "用户",
"name": "姓名",
"email": "電子郵件",
"roles_userType": "角色/用戶類型",
@@ -110,30 +134,8 @@
"noResultsFoundFor": "未找到结果 ",
"talawaApiUnavailable": "服務不可用。它在運行嗎?還要檢查您的網絡連接。"
},
- "adminNavbar": {
- "talawa_portal": "塔拉瓦管理門戶",
- "Dashboard": "儀表板",
- "People": "人們",
- "Events": "事件",
- "Contributions": "貢獻",
- "Posts": "帖子",
- "Block/Unblock": "阻止/解除阻止",
- "Plugins": "插件",
- "Plugin Store": "插件商店",
- "allOrganizations": "所有组织",
- "yourOrganization": "您的组织",
- "notification": "通知",
- "settings": "設置",
- "language": "語",
- "logout": "登出",
- "notifications": "通知",
- "spamsThe": "垃圾郵件",
- "group": "團體",
- "noNotifications": "沒有通知",
- "close": "關"
- },
"dashboard": {
- "title": "塔拉瓦儀表板",
+ "title": "儀表板",
"location": "地點",
"about": "關於",
"deleteThisOrganization": "刪除此組織",
@@ -143,11 +145,7 @@
"posts": "帖子",
"events": "事件",
"blockedUsers": "被阻止的用戶",
- "membershipRequests": "會員申請",
- "deleteOrganization": "刪除組織",
- "deleteMsg": "您要刪除此組織嗎?",
- "no": "不",
- "yes": "是的",
+ "requests": "请求",
"talawaApiUnavailable": "服務不可用。它在運行嗎?還要檢查您的網絡連接。"
},
"organizationPeople": {
@@ -295,6 +293,7 @@
},
"blockUnblockUser": {
"title": "塔拉瓦封鎖/解除封鎖用戶",
+ "pageName": "封锁/解封",
"searchByName": "按名稱搜索",
"listOfUsers": "發送垃圾郵件的用戶列表",
"name": "姓名",
@@ -308,8 +307,10 @@
"talawaApiUnavailable": "服務不可用。它在運行嗎?還要檢查您的網絡連接。",
"allMembers": "所有成员",
"blockedUsers": "被阻止的用户",
- "searchFirstName": "输入名字",
- "searchLastName": "输入姓氏"
+ "searchByFirstName": "按名字搜索",
+ "searchByLastName": "按姓氏搜索",
+ "noResultsFoundFor": "未找到结果 ",
+ "noSpammerFound": "未发现垃圾邮件发送者"
},
"forgotPassword": {
"title": "塔拉瓦忘記密碼",
@@ -358,13 +359,22 @@
},
"orgSettings": {
"title": "塔拉瓦設置",
+ "pageName": "设置",
"updateYourDetails": "更新您的詳細信息",
"updateYourPassword": "更新您的密碼",
"updateOrganization": "更新組織",
- "deleteOrganization": "刪除組織",
"seeRequest": "查看請求",
"settings": "設置",
- "noData": "沒有數據"
+ "noData": "沒有數據",
+ "otherSettings": "其他设置",
+ "changeLanguage": "更改语言"
+ },
+ "deleteOrg": {
+ "deleteOrganization": "删除组织",
+ "deleteMsg": "您是否要删除此组织?",
+ "no": "否",
+ "yes": "是",
+ "longDelOrgMsg": "点击删除组织按钮后,将永久删除该组织以及其活动、标签和所有相关数据。"
},
"userUpdate": {
"firstName": "名",
@@ -401,8 +411,8 @@
"description": "描述",
"location": "地點",
"displayImage": "顯示圖像",
- "isPublic": "是公開的",
- "isRegistrable": "可註冊",
+ "isPublic": "公开",
+ "isVisibleInSearch": "在搜索中可见",
"saveChanges": "保存更改",
"cancel": "取消",
"enterNameOrganization": "輸入組織名稱",
@@ -422,6 +432,7 @@
"pDesc": "此插件启用 UI"
},
"addOnStore": {
+ "title": "插件商店",
"searchName": "例如:捐赠",
"enable": "启用",
"disable": "残疾人",
diff --git a/src/App.tsx b/src/App.tsx
index 0d8cb059e8..517b6eebc7 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -16,7 +16,7 @@ import OrgSettings from 'screens/OrgSettings/OrgSettings';
import PageNotFound from 'screens/PageNotFound/PageNotFound';
import AddOnStore from 'components/AddOn/core/AddOnStore/AddOnStore';
import ForgotPassword from 'screens/ForgotPassword/ForgotPassword';
-import Roles from 'screens/Roles/Roles';
+import Users from 'screens/Users/Users';
import Requests from 'screens/Requests/Requests';
import BlockUser from 'screens/BlockUser/BlockUser';
import EventDashboard from 'screens/EventDashboard/EventDashboard';
@@ -85,6 +85,10 @@ function app(): JSX.Element {
localStorage.setItem('email', data.checkAuth.email);
localStorage.setItem('IsLoggedIn', 'TRUE');
localStorage.setItem('UserType', data.checkAuth.userType);
+ localStorage.setItem('FirstName', data.checkAuth.firstName);
+ localStorage.setItem('LastName', data.checkAuth.lastName);
+ localStorage.setItem('UserImage', data.checkAuth.image);
+ localStorage.setItem('Email', data.checkAuth.email);
} else {
localStorage.clear();
}
@@ -102,7 +106,7 @@ function app(): JSX.Element {
-
+
diff --git a/src/GraphQl/Mutations/mutations.ts b/src/GraphQl/Mutations/mutations.ts
index 040dea6344..550ad1e07d 100644
--- a/src/GraphQl/Mutations/mutations.ts
+++ b/src/GraphQl/Mutations/mutations.ts
@@ -351,8 +351,8 @@ export const REJECT_ADMIN_MUTATION = gql`
* @description used to toggle `installStatus` (boolean value) of a Plugin
*/
export const UPDATE_INSTALL_STATUS_PLUGIN_MUTATION = gql`
- mutation update_install_status_plugin_mutation($id: ID!, $orgId: ID!) {
- updatePluginStatus(orgId: $orgId, id: $id) {
+ mutation ($id: ID!, $orgId: ID!) {
+ updatePluginStatus(id: $id, orgId: $orgId) {
_id
pluginName
pluginCreatedBy
diff --git a/src/GraphQl/Queries/Queries.ts b/src/GraphQl/Queries/Queries.ts
index 49ac11df57..6efae00ed5 100644
--- a/src/GraphQl/Queries/Queries.ts
+++ b/src/GraphQl/Queries/Queries.ts
@@ -183,6 +183,8 @@ export const ORGANIZATIONS_LIST = gql`
name
description
location
+ isPublic
+ visibleInSearch
members {
_id
firstName
@@ -600,6 +602,7 @@ export const PLUGIN_GET = gql`
pluginName
pluginCreatedBy
pluginDesc
+ uninstalledOrgs
}
}
`;
diff --git a/src/assets/svgs/admin.svg b/src/assets/svgs/admin.svg
new file mode 100644
index 0000000000..8ee42f611d
--- /dev/null
+++ b/src/assets/svgs/admin.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/svgs/icons/angleRight.svg b/src/assets/svgs/angleRight.svg
similarity index 100%
rename from src/assets/svgs/icons/angleRight.svg
rename to src/assets/svgs/angleRight.svg
diff --git a/src/assets/svgs/blockUser.svg b/src/assets/svgs/blockUser.svg
new file mode 100644
index 0000000000..f9aef51775
--- /dev/null
+++ b/src/assets/svgs/blockUser.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svgs/blockedUser.svg b/src/assets/svgs/blockedUser.svg
new file mode 100644
index 0000000000..bbe0a51f84
--- /dev/null
+++ b/src/assets/svgs/blockedUser.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svgs/dashboard.svg b/src/assets/svgs/dashboard.svg
new file mode 100644
index 0000000000..12e8b0fe63
--- /dev/null
+++ b/src/assets/svgs/dashboard.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svgs/event.svg b/src/assets/svgs/event.svg
new file mode 100644
index 0000000000..3c73e7b04e
--- /dev/null
+++ b/src/assets/svgs/event.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svgs/events.svg b/src/assets/svgs/events.svg
new file mode 100644
index 0000000000..95b8a3b587
--- /dev/null
+++ b/src/assets/svgs/events.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svgs/icons/logout.svg b/src/assets/svgs/logout.svg
similarity index 100%
rename from src/assets/svgs/icons/logout.svg
rename to src/assets/svgs/logout.svg
diff --git a/src/assets/svgs/icons/organizations.svg b/src/assets/svgs/organizations.svg
similarity index 100%
rename from src/assets/svgs/icons/organizations.svg
rename to src/assets/svgs/organizations.svg
diff --git a/src/assets/svgs/people.svg b/src/assets/svgs/people.svg
new file mode 100644
index 0000000000..17c62eb14e
--- /dev/null
+++ b/src/assets/svgs/people.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/svgs/plugins.svg b/src/assets/svgs/plugins.svg
new file mode 100644
index 0000000000..7da1701dc1
--- /dev/null
+++ b/src/assets/svgs/plugins.svg
@@ -0,0 +1,7 @@
+
diff --git a/src/assets/svgs/post.svg b/src/assets/svgs/post.svg
new file mode 100644
index 0000000000..34e468523b
--- /dev/null
+++ b/src/assets/svgs/post.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svgs/posts.svg b/src/assets/svgs/posts.svg
new file mode 100644
index 0000000000..181e25855a
--- /dev/null
+++ b/src/assets/svgs/posts.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svgs/icons/requests.svg b/src/assets/svgs/requests.svg
similarity index 100%
rename from src/assets/svgs/icons/requests.svg
rename to src/assets/svgs/requests.svg
diff --git a/src/assets/svgs/icons/roles.svg b/src/assets/svgs/roles.svg
similarity index 100%
rename from src/assets/svgs/icons/roles.svg
rename to src/assets/svgs/roles.svg
diff --git a/src/assets/svgs/settings.svg b/src/assets/svgs/settings.svg
new file mode 100644
index 0000000000..064f6c9001
--- /dev/null
+++ b/src/assets/svgs/settings.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/svgs/tags.svg b/src/assets/svgs/tags.svg
new file mode 100644
index 0000000000..32cb76851a
--- /dev/null
+++ b/src/assets/svgs/tags.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/svgs/users.svg b/src/assets/svgs/users.svg
new file mode 100644
index 0000000000..a1a474206d
--- /dev/null
+++ b/src/assets/svgs/users.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/components/AddOn/AddOn.tsx b/src/components/AddOn/AddOn.tsx
index 7ac6466979..4e73c52b7c 100644
--- a/src/components/AddOn/AddOn.tsx
+++ b/src/components/AddOn/AddOn.tsx
@@ -1,8 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
-import AdminNavbar from 'components/AdminNavbar/AdminNavbar';
-import { useSelector } from 'react-redux';
-import type { RootState } from 'state/reducers';
interface InterfaceAddOnProps {
extras: any;
@@ -12,11 +9,8 @@ interface InterfaceAddOnProps {
// Validate Extras
function addOn({ children }: InterfaceAddOnProps): JSX.Element {
- const appRoutes = useSelector((state: RootState) => state.appRoutes);
- const { targets, configUrl } = appRoutes;
return (
<>
-
{children}
diff --git a/src/components/AddOn/core/AddOnEntry/AddOnEntry.test.tsx b/src/components/AddOn/core/AddOnEntry/AddOnEntry.test.tsx
index 1716323755..50e56adf1e 100644
--- a/src/components/AddOn/core/AddOnEntry/AddOnEntry.test.tsx
+++ b/src/components/AddOn/core/AddOnEntry/AddOnEntry.test.tsx
@@ -23,7 +23,7 @@ const httpLink = new HttpLink({
authorization: 'Bearer ' + localStorage.getItem('token') || '',
},
});
-
+console.error = jest.fn();
const client: ApolloClient = new ApolloClient({
cache: new InMemoryCache(),
link: ApolloLink.from([httpLink]),
@@ -52,7 +52,7 @@ describe('Testing AddOnEntry', () => {
- {}
+ {}
@@ -60,4 +60,39 @@ describe('Testing AddOnEntry', () => {
);
expect(getByTestId('AddOnEntry')).toBeInTheDocument();
});
+
+ it('renders correctly', () => {
+ const props = {
+ id: '1',
+ title: 'Test Addon',
+ description: 'Test addon description',
+ createdBy: 'Test User',
+ component: 'string',
+ installed: true,
+ configurable: true,
+ modified: true,
+ isInstalled: true,
+ uninstalledOrgs: [],
+ enabled: true,
+ getInstalledPlugins: (): { sample: string } => {
+ return { sample: 'sample' };
+ },
+ };
+
+ const { getByText } = render(
+
+
+
+
+ {}
+
+
+
+
+ );
+
+ expect(getByText('Test Addon')).toBeInTheDocument();
+ expect(getByText('Test addon description')).toBeInTheDocument();
+ expect(getByText('Test User')).toBeInTheDocument();
+ });
});
diff --git a/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx b/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx
index 9288c30af9..7503d0667d 100644
--- a/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx
+++ b/src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx
@@ -1,13 +1,11 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import styles from './AddOnEntry.module.css';
-import { Button, Card, Form, Spinner } from 'react-bootstrap';
-import {
- UPDATE_INSTALL_STATUS_PLUGIN_MUTATION,
- UPDATE_ORG_STATUS_PLUGIN_MUTATION,
-} from 'GraphQl/Mutations/mutations';
+import { Button, Card, Spinner } from 'react-bootstrap';
+import { UPDATE_INSTALL_STATUS_PLUGIN_MUTATION } from 'GraphQl/Mutations/mutations';
import { useMutation } from '@apollo/client';
import { useTranslation } from 'react-i18next';
+import { toast } from 'react-toastify';
interface InterfaceAddOnEntryProps {
id: string;
@@ -16,131 +14,52 @@ interface InterfaceAddOnEntryProps {
description: string;
createdBy: string;
component: string;
- installed?: boolean;
- configurable?: boolean;
modified: any;
- isInstalled: boolean;
+ uninstalledOrgs: string[];
getInstalledPlugins: () => any;
}
function addOnEntry({
id,
- enabled,
title,
description,
createdBy,
- installed,
- isInstalled,
+ uninstalledOrgs,
getInstalledPlugins,
}: InterfaceAddOnEntryProps): JSX.Element {
const { t } = useTranslation('translation', { keyPrefix: 'addOnEntry' });
-
+ //getting orgId from URL
+ const currentOrg = window.location.href.split('/id=')[1] + '';
const [buttonLoading, setButtonLoading] = useState(false);
- const [switchInProgress] = useState(false);
- const [isInstalledLocal, setIsInstalledLocal] = useState(isInstalled);
-
- const [updateInstallStatus] = useMutation(
+ const [isInstalledLocal, setIsInstalledLocal] = useState(
+ uninstalledOrgs.includes(currentOrg)
+ );
+ // const [addOrgAsUninstalled] = useMutation(UPDATE_ORG_STATUS_PLUGIN_MUTATION);
+ const [addOrgAsUninstalled] = useMutation(
UPDATE_INSTALL_STATUS_PLUGIN_MUTATION
);
- const [updateOrgStatus] = useMutation(UPDATE_ORG_STATUS_PLUGIN_MUTATION);
-
- const currentOrg = window.location.href.split('=')[1];
- const updateOrgList = async (): Promise => {
- await updateOrgStatus({
- variables: {
- id: id.toString(),
- orgId: currentOrg.toString(),
- },
- });
- };
-
- const updateInstallStatusFunc = async (): Promise => {
+ const togglePluginInstall = async (): Promise => {
setButtonLoading(true);
- await updateInstallStatus({
+ await addOrgAsUninstalled({
variables: {
id: id.toString(),
- status: !isInstalledLocal,
+ orgId: currentOrg.toString(),
},
});
setIsInstalledLocal(!isInstalledLocal);
setButtonLoading(false);
+ const dialog: string = isInstalledLocal
+ ? t('installMsg')
+ : t('uninstallMsg');
+ toast.success(dialog);
};
- // useEffect(() => {
- // // updateInstallStatusFunc();
- // }, []);
- // TODO: Install/Remove Effect
- // 1. Update Server to add to Org
- // 2. Validate Permissions
- // 3. Trigger Server Hook if Validated. (Stream to track progress)
- // const install = () => {
- // setButtonLoading(true);
- // fetch('http://localhost:3005/installed', {
- // method: 'POST',
- // headers: {
- // 'Content-type': 'application/json; charset=UTF-8',
- // },
- // body: JSON.stringify(
- // Object.assign(
- // {},
- // { ...entry },
- // {
- // installedDatetime: new Date(),
- // installedBy: 'Admin',
- // enabled: true,
- // }
- // )
- // ),
- // })
- // .then(() => {
- // setButtonLoading(false);
- // modified();
- // })
- // .finally(() => setButtonLoading(false));
- // };
-
- // const remove = () => {
- // setButtonLoading(true);
- // fetch(`http://localhost:3005/installed/${id}`, {
- // method: 'DELETE',
- // })
- // .then(() => {
- // setButtonLoading(false);
- // modified();
- // })
- // .finally(() => setButtonLoading(false));
- // };
-
- // const toggleActive = () => {
- // setSwitchState(true);
- // fetch(`http://localhost:3005/installed/${id}`, {
- // method: 'PUT',
- // headers: {
- // 'Content-type': 'application/json; charset=UTF-8',
- // },
- // body: JSON.stringify(
- // Object.assign(
- // {},
- // { ...entry },
- // {
- // enabled: !enabled,
- // }
- // )
- // ),
- // })
- // .then(() => {
- // modified();
- // setSwitchState(false);
- // })
- // .finally(() => setSwitchState(false));
- // };
-
return (
<>
- {installed && (
+ {/* {uninstalledOrgs.includes(currentOrg) && (
- )}
+ )} */}
{title}
@@ -163,22 +82,23 @@ function addOnEntry({
variant="primary"
// disabled={buttonLoading || !configurable}
disabled={buttonLoading}
+ data-testid="AddOnEntry_btn_install"
onClick={(): void => {
- updateOrgList();
- updateInstallStatusFunc();
+ togglePluginInstall();
getInstalledPlugins();
- // installed ? remove() : install();
}}
>
{buttonLoading ? (
) : (
)}
{/* {installed ? 'Remove' : configurable ? 'Installed' : 'Install'} */}
- {isInstalledLocal ? t('uninstall') : t('install')}
+ {uninstalledOrgs.includes(currentOrg)
+ ? t('install')
+ : t('uninstall')}
diff --git a/src/components/AddOn/core/AddOnStore/AddOnStore.tsx b/src/components/AddOn/core/AddOnStore/AddOnStore.tsx
index 148eea7cb4..2e3e511149 100644
--- a/src/components/AddOn/core/AddOnStore/AddOnStore.tsx
+++ b/src/components/AddOn/core/AddOnStore/AddOnStore.tsx
@@ -2,7 +2,6 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'react';
import styles from './AddOnStore.module.css';
-import AdminNavbar from 'components/AdminNavbar/AdminNavbar';
import AddOnEntry from '../AddOnEntry/AddOnEntry';
import Action from '../../support/components/Action/Action';
import SidePanel from 'components/AddOn/support/components/SidePanel/SidePanel';
@@ -16,15 +15,17 @@ import {
} from 'GraphQl/Queries/Queries'; // PLUGIN_LIST
import { useSelector } from 'react-redux';
import type { RootState } from '../../../../state/reducers';
-import { Form, Tab, Tabs } from 'react-bootstrap';
+import { Col, Form, Row, Tab, Tabs } from 'react-bootstrap';
import AddOnRegister from '../AddOnRegister/AddOnRegister';
import PluginHelper from 'components/AddOn/support/services/Plugin.helper';
import { store } from './../../../../state/store';
import { useTranslation } from 'react-i18next';
import Loader from 'components/Loader/Loader';
+import OrganizationScreen from 'components/OrganizationScreen/OrganizationScreen';
function addOnStore(): JSX.Element {
const { t } = useTranslation('translation', { keyPrefix: 'addOnStore' });
+ document.title = t('title');
const [isStore, setIsStore] = useState(true);
const [showEnabled, setShowEnabled] = useState(true);
@@ -106,115 +107,69 @@ function addOnStore(): JSX.Element {
}
return (
<>
-
-
-
-
- setSearchText(e.target.value)}
- />
-
- {!isStore && (
-
-
+
+
+
+
+ setSearchText(e.target.value)}
+ />
- )}
-
-
-
-
{t('pHeading')}
- {searchText ? (
-
- Search results for {searchText}
-
- ) : null}
-
-
-
- {console.log(
- data.getPlugins.filter(
- (val: {
- _id: string;
- pluginName: string | undefined;
- pluginDesc: string | undefined;
- pluginCreatedBy: string;
- pluginInstallStatus: boolean | undefined;
- getInstalledPlugins: () => any;
- }) => {
- if (searchText == '') {
- return val;
- } else if (
- val.pluginName
- ?.toLowerCase()
- .includes(searchText.toLowerCase())
- ) {
- return val;
- }
- }
- )
- )}
- {data.getPlugins.filter(
- (val: {
- _id: string;
- pluginName: string | undefined;
- pluginDesc: string | undefined;
- pluginCreatedBy: string;
- pluginInstallStatus: boolean | undefined;
- getInstalledPlugins: () => any;
- }) => {
- if (searchText == '') {
- return val;
- } else if (
- val.pluginName
- ?.toLowerCase()
- .includes(searchText.toLowerCase())
- ) {
- return val;
- }
- }
- ).length === 0 ? (
- {t('pMessage')}
- ) : (
- data.getPlugins
- .filter(
+ {!isStore && (
+
+
+
+ )}
+
+
+
+
{t('pHeading')}
+ {searchText ? (
+
+ Search results for {searchText}
+
+ ) : null}
+
+
+
+ {console.log(
+ data.getPlugins.filter(
(val: {
_id: string;
pluginName: string | undefined;
@@ -234,40 +189,8 @@ function addOnStore(): JSX.Element {
}
}
)
- .map(
- (
- plug: {
- _id: string;
- pluginName: string | undefined;
- pluginDesc: string | undefined;
- pluginCreatedBy: string;
- pluginInstallStatus: boolean | undefined;
- getInstalledPlugins: () => any;
- },
- i: React.Key | null | undefined
- ): JSX.Element => (
- {
- console.log('Plugin is modified');
- }}
- getInstalledPlugins={getInstalledPlugins}
- />
- )
- )
- )}
-
-
- {data.getPlugins
- .filter((plugin: any) => plugin.pluginInstallStatus == true)
- .filter(
+ )}
+ {data.getPlugins.filter(
(val: {
_id: string;
pluginName: string | undefined;
@@ -287,9 +210,62 @@ function addOnStore(): JSX.Element {
}
}
).length === 0 ? (
- {t('pMessage')}
// eslint-disable-line
- ) : (
- data.getPlugins
+ {t('pMessage')}
+ ) : (
+ data.getPlugins
+ .filter(
+ (val: {
+ _id: string;
+ pluginName: string | undefined;
+ pluginDesc: string | undefined;
+ pluginCreatedBy: string;
+ pluginInstallStatus: boolean | undefined;
+ getInstalledPlugins: () => any;
+ }) => {
+ if (searchText == '') {
+ return val;
+ } else if (
+ val.pluginName
+ ?.toLowerCase()
+ .includes(searchText.toLowerCase())
+ ) {
+ return val;
+ }
+ }
+ )
+ .map(
+ (
+ plug: {
+ _id: string;
+ pluginName: string | undefined;
+ pluginDesc: string | undefined;
+ pluginCreatedBy: string;
+ uninstalledOrgs: string[];
+ getInstalledPlugins: () => any;
+ },
+ i: React.Key | null | undefined
+ ): JSX.Element => (
+ {
+ console.log('Plugin is modified');
+ }}
+ getInstalledPlugins={getInstalledPlugins}
+ uninstalledOrgs={plug.uninstalledOrgs}
+ />
+ )
+ )
+ )}
+
+
+ {data.getPlugins
.filter((plugin: any) => plugin.pluginInstallStatus == true)
.filter(
(val: {
@@ -310,41 +286,69 @@ function addOnStore(): JSX.Element {
return val;
}
}
- )
- .map(
- (
- plug: {
+ ).length === 0 ? (
+ {t('pMessage')}
// eslint-disable-line
+ ) : (
+ data.getPlugins
+ .filter(
+ (plugin: any) => plugin.pluginInstallStatus == true
+ )
+ .filter(
+ (val: {
_id: string;
pluginName: string | undefined;
pluginDesc: string | undefined;
pluginCreatedBy: string;
pluginInstallStatus: boolean | undefined;
getInstalledPlugins: () => any;
- },
- i: React.Key | null | undefined
- ): JSX.Element => (
- {
- console.log('Plugin is modified');
- }}
- getInstalledPlugins={getInstalledPlugins}
- />
+ }) => {
+ if (searchText == '') {
+ return val;
+ } else if (
+ val.pluginName
+ ?.toLowerCase()
+ .includes(searchText.toLowerCase())
+ ) {
+ return val;
+ }
+ }
)
- )
- )}
-
-
-
-
-
+ .map(
+ (
+ plug: {
+ _id: string;
+ pluginName: string | undefined;
+ pluginDesc: string | undefined;
+ pluginCreatedBy: string;
+ uninstalledOrgs: string[];
+ getInstalledPlugins: () => any;
+ },
+ i: React.Key | null | undefined
+ ): JSX.Element => (
+ {
+ console.log('Plugin is modified');
+ }}
+ getInstalledPlugins={getInstalledPlugins}
+ uninstalledOrgs={plug.uninstalledOrgs}
+ />
+ )
+ )
+ )}
+
+
+
+
+
+
>
);
}
@@ -354,53 +358,3 @@ addOnStore.defaultProps = {};
addOnStore.propTypes = {};
export default addOnStore;
-
-// {addonStore.map((plugin: any, index: number) => {
-// return (
-// {
-// /* istanbul ignore next */
-// pluginModified().then((installedPlugins) => {
-// updateLinks(
-// new PluginHelper().generateLinks(installedPlugins)
-// );
-// });
-// }}
-// />
-// );
-// })}
-
-// {installed
-// .filter((plugin: any) =>
-// showEnabled ? plugin.enabled : !plugin.enabled
-// )
-// .map((plugin: any, index: number) => {
-// return (
-// {
-// /* istanbul ignore next */
-// pluginModified().then((installedPlugins) => {
-// updateLinks(
-// new PluginHelper().generateLinks(installedPlugins)
-// );
-// });
-// }}
-// />
-// );
-// })}
diff --git a/src/components/AdminNavbar/AdminNavbar.module.css b/src/components/AdminNavbar/AdminNavbar.module.css
deleted file mode 100644
index 8210a80337..0000000000
--- a/src/components/AdminNavbar/AdminNavbar.module.css
+++ /dev/null
@@ -1,236 +0,0 @@
-.navbarbg {
- position: relative !important;
- margin-bottom: 1.5rem;
- z-index: 1;
- box-shadow: 0px 0px 8px 2px #c8c8c8;
- padding-top: 0px;
- padding-bottom: 0px;
-}
-
-.logo {
- color: #707070;
- margin: 0.5rem 0;
- display: flex;
- align-items: center;
- text-decoration: none !important;
-}
-
-.logo img {
- margin-top: 0px;
- margin-left: 10px;
-}
-
-.logo > strong {
- text-decoration: none;
- line-height: 1.5rem;
- margin-left: 10px;
- font-family: sans-serif;
- font-size: 24px;
- color: #707070;
-}
-.userimage {
- align-items: right;
- float: right;
- text-align: right;
- justify-content: right;
- margin-right: 25px;
-}
-.roundedcircle {
- margin-right: 5px;
- border-radius: 50px;
- height: 45px;
- width: 45px;
- object-fit: cover;
-}
-.navitems > .navlinks {
- margin-top: 11px;
- cursor: pointer;
- margin-left: 28px;
- line-height: 1rem;
- font-size: 16px;
- color: #707070;
- z-index: 1;
- flex-direction: row;
- display: flex;
- text-align: center;
-}
-.navlinks_active {
- border-bottom: 3px solid #31bb6b;
-}
-.navitem {
- text-decoration: none;
- color: #707070 !important;
- transition: smooth;
- padding-bottom: 10px;
-}
-.navlinks_dropdown {
- margin-top: 5px !important;
- color: rgba(0, 0, 0, 0.5) !important;
- border-radius: 0px;
-}
-.navlinks:hover,
-.navlinks_dropdown:hover {
- text-decoration: none;
- border-bottom: 3px solid #31bb6b;
-}
-
-.navlinks_dropdown:hover {
- border-bottom: 3px solid #31bb6b;
- padding-bottom: 4px;
-}
-/*
-.navlinks.focus {
- border-bottom: 3px solid #31bb6b;
-}
-.navitems.focus {
- border-bottom: 3px solid #31bb6b;
-}
-:target{
- border-bottom: 3px solid #31bb6b;
-} */
-.dropdowns {
- text-decoration: none;
- margin-bottom: 8px;
-}
-.dropdownMenu {
- transform: scale(0.85);
- cursor: pointer;
- transform: translateX(-9vw) scale(0.9);
-}
-#dropdown-basic,
-.dropdowns.btn,
-.btn:focus,
-.btn.focus {
- box-shadow: none !important;
-}
-
-.dropdowntoggle {
- display: flex !important;
- align-items: center !important;
- margin-top: 10px;
- margin-left: 15px;
-}
-
-.dropdownitem i {
- margin-right: 8px;
-}
-
-.languageDropdown {
- margin-left: 11px;
-}
-
-@media screen and (max-width: 1024px) {
- .logo > strong {
- display: none;
- }
- .navitems {
- margin-left: 20px;
- }
- .navitems > a {
- margin-right: 20px;
- }
-}
-.sidebar {
- z-index: 0;
- padding-top: 50px;
- position: fixed;
- min-width: 160px;
- width: 10%;
- background-color: #f7f7f7;
- margin: 0;
- height: 100%;
-}
-.sidebarsticky {
- padding-top: 40%;
-}
-/* .notificationIcon {
- position: relative;
- top: 12px;
- right: 14px;
-} */
-.notificationList:hover {
- background-color: #dfe2e4;
- cursor: pointer;
-}
-
-@media screen and (max-width: 768px) {
- .sidebar {
- width: 15%;
- }
-}
-@media screen and (max-width: 680px) {
- body {
- overflow-x: hidden;
- }
- .logo {
- margin-left: 0%;
- }
-}
-
-@media screen and (max-width: 1199px) {
- /* .navbarbg {
- height: auto;
- } */
- .navitems > .navlinks {
- margin-left: 0;
- }
- .dropdowntoggle {
- margin-left: -12px;
- }
- .dropdownMenu {
- transform: translateX(0px) scale(0.9);
- }
- .notificationIcon {
- top: 0px;
- right: -8px;
- }
-}
-
-.navbarBrandLogo {
- padding: 0;
-}
-
-.allOrgBtn {
- margin: 0 10px;
- background-color: #31bb6b;
- padding: 5px 10px;
- color: white;
- border-radius: 10px;
- font-weight: 600;
- white-space: nowrap;
- display: flex;
- justify-content: center;
- margin: auto;
- min-width: 10rem;
- max-width: 30%;
-}
-
-.allOrgBtn:hover {
- color: #fff;
- background-color: #1e7e34;
- border-color: #1c7430;
-}
-
-.navitems > .navlinks {
- justify-content: center;
-}
-
-.dropdowns {
- display: flex;
- justify-content: center;
-}
-
-/* .dropdowns,
-#dropdown-basic::after {
- content: none;
-} */
-
-.dropdown-toggle:after {
- display: none;
-}
-
-.dropdowns,
-.navbar-toggler-icon {
- margin-top: 0.2rem;
- margin-right: 58px;
-}
diff --git a/src/components/AdminNavbar/AdminNavbar.test.tsx b/src/components/AdminNavbar/AdminNavbar.test.tsx
deleted file mode 100644
index 4a034d92f0..0000000000
--- a/src/components/AdminNavbar/AdminNavbar.test.tsx
+++ /dev/null
@@ -1,212 +0,0 @@
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import React from 'react';
-import { MockedProvider } from '@apollo/react-testing';
-import { act, fireEvent, render, screen } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import 'jest-localstorage-mock';
-import 'jest-location-mock';
-import { I18nextProvider } from 'react-i18next';
-import { Provider } from 'react-redux';
-import { BrowserRouter } from 'react-router-dom';
-
-import { store } from 'state/store';
-import { StaticMockLink } from 'utils/StaticMockLink';
-import i18nForTest from 'utils/i18nForTest';
-import AdminNavbar from './AdminNavbar';
-import { MOCKS } from './AdminNavbarMocks';
-const link1 = new StaticMockLink(MOCKS, true);
-async function wait(ms = 100): Promise {
- await act(() => {
- return new Promise((resolve) => {
- setTimeout(resolve, ms);
- });
- });
-}
-
-describe('Testing Admin Navbar', () => {
- // eslint-disable-next-line jest/expect-expect
-
- const targets = [
- {
- name: 'Dashboard',
- comp_id: 'orgdash',
- component: 'OrganizationDashboard',
- },
- { name: 'Posts', comp_id: 'orgpost', component: 'OrgPost' },
- { name: 'People', comp_id: 'orgpeople', component: 'OrganizationPeople' },
- { name: 'Events', comp_id: 'orgevents', component: 'OrganizationEvents' },
- { name: 'Block/Unblock', comp_id: 'blockuser', component: 'BlockUser' },
- {
- name: 'Contributions',
- comp_id: 'orgcontribution',
- component: 'OrgContribution',
- },
- {
- name: 'Plugins',
- comp_id: 'plugin',
- component: 'AddOnStore',
- subTargets: [
- {
- name: 'Plugin Store',
- comp_id: 'orgstore',
- url: '/plugin',
- component: 'AddOnStore',
- icon: 'fa-store',
- },
- ],
- },
- ];
-
- const props = {
- targets,
- url_1: 'string',
- };
-
- test('should render following text elements', async () => {
- render(
-
-
-
-
-
-
-
-
-
- );
-
- await wait();
-
- fireEvent.click(screen.getByText('Plugins'));
- fireEvent.click(screen.getByTestId('logoutDropdown'));
-
- expect(screen.getByText('Dashboard')).toBeInTheDocument();
- expect(screen.getByText('Posts')).toBeInTheDocument();
- expect(screen.getByText('People')).toBeInTheDocument();
- expect(screen.getByText('Events')).toBeInTheDocument();
- expect(screen.getByText('Contributions')).toBeInTheDocument();
- expect(screen.getByText('Plugins')).toBeInTheDocument();
- expect(screen.getByTestId('dropdownIcon')).toBeTruthy();
- expect(screen.getByText('Plugin Store')).toBeInTheDocument();
- expect(screen.getByTestId('logoutDropdown')).toBeTruthy();
- expect(screen.getByText('Settings')).toBeInTheDocument();
- expect(screen.getByText('Logout')).toBeInTheDocument();
-
- userEvent.click(screen.getByText('Logout'));
- });
-
- test('Testing the notification functionality', async () => {
- render(
-
-
-
-
-
-
-
-
-
- );
-
- await wait();
- });
-
- test('Testing, if spam id is present in local storage', async () => {
- localStorage.setItem('spamId', '6954');
-
- render(
-
-
-
-
-
-
-
-
-
- );
-
- await wait();
- });
-
- test('Testing, if no mock data provided', async () => {
- window.location.assign('/orglist');
-
- render(
-
-
-
-
-
-
-
-
-
- );
-
- await wait();
- expect(window.location).toBeAt('/orglist');
- });
-
- test('Testing change language functionality', async () => {
- render(
-
-
-
-
-
-
-
-
-
- );
-
- await wait();
-
- userEvent.click(screen.getByTestId('logoutDropdown'));
- userEvent.click(screen.getByTestId('languageDropdown'));
- userEvent.click(screen.getByTestId('changeLanguageBtn1'));
- userEvent.click(screen.getByTestId('changeLanguageBtn2'));
- userEvent.click(screen.getByTestId('changeLanguageBtn3'));
- userEvent.click(screen.getByTestId('changeLanguageBtn4'));
- });
-
- test('Testing when language cookie is not set', async () => {
- Object.defineProperty(window.document, 'cookie', {
- writable: true,
- value: 'i18next=',
- });
-
- render(
-
-
-
-
-
-
-
-
-
- );
-
- await wait();
- });
- test('Should check if organisation image is not present', async () => {
- const { container } = render(
-
-
-
-
-
-
-
-
-
- );
-
- expect(container.textContent).not.toBe('Loading data...');
- await wait();
- const imageLogo = screen.getByTestId(/orgLogoAbsent/i);
- expect(imageLogo).toBeInTheDocument();
- });
-});
diff --git a/src/components/AdminNavbar/AdminNavbar.tsx b/src/components/AdminNavbar/AdminNavbar.tsx
deleted file mode 100644
index 2a6ac7c78b..0000000000
--- a/src/components/AdminNavbar/AdminNavbar.tsx
+++ /dev/null
@@ -1,193 +0,0 @@
-import React from 'react';
-import Navbar from 'react-bootstrap/Navbar';
-import Dropdown from 'react-bootstrap/Dropdown';
-import Button from 'react-bootstrap/Button';
-import { Nav } from 'react-bootstrap';
-import { Link, NavLink } from 'react-router-dom';
-import { useQuery } from '@apollo/client';
-import { useTranslation } from 'react-i18next';
-import Cookies from 'js-cookie';
-import i18next from 'i18next';
-import MenuIcon from '@mui/icons-material/Menu';
-import styles from './AdminNavbar.module.css';
-import AboutImg from 'assets/images/defaultImg.png';
-import {
- ORGANIZATIONS_LIST,
- USER_ORGANIZATION_LIST,
-} from 'GraphQl/Queries/Queries';
-import { languages } from 'utils/languages';
-
-interface InterfaceNavbarProps {
- targets: {
- url?: string;
- name: string;
- subTargets?: {
- url: string;
- name: string;
- icon?: string;
- }[];
- }[];
- url1: string;
-}
-
-function adminNavbar({ targets, url1 }: InterfaceNavbarProps): JSX.Element {
- const { t } = useTranslation('translation', { keyPrefix: 'adminNavbar' });
- const currentUrl = window.location.href.split('=')[1];
-
- const { data: orgData, error: orgError } = useQuery(ORGANIZATIONS_LIST, {
- variables: { id: currentUrl },
- });
-
- const { data: data2 } = useQuery(USER_ORGANIZATION_LIST, {
- variables: { id: localStorage.getItem('id') },
- });
-
- const isSuperAdmin = data2?.user.userType === 'SUPERADMIN';
- const currentLanguageCode = Cookies.get('i18next') || 'en';
-
- /* istanbul ignore next */
- if (orgError) {
- window.location.replace('/orglist');
- }
-
- let orgName;
- if (orgData) {
- orgName = orgData?.organizations[0].name;
- }
-
- return (
- <>
-
-
-
- {orgData?.organizations[0].image ? (
-
- ) : (
-
- )}
-
{orgName}
-
-
-
-
-
-
- {isSuperAdmin ? t('allOrganizations') : t('yourOrganization')}
-
-
-
-
- >
- );
-}
-
-export default adminNavbar;
diff --git a/src/components/AdminNavbar/AdminNavbarMocks.ts b/src/components/AdminNavbar/AdminNavbarMocks.ts
deleted file mode 100644
index 1717807ddc..0000000000
--- a/src/components/AdminNavbar/AdminNavbarMocks.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-import { ORGANIZATIONS_LIST } from 'GraphQl/Queries/Queries';
-
-// Has no placeholder image
-export const MOCKS = [
- {
- request: {
- query: ORGANIZATIONS_LIST,
- },
- result: {
- data: {
- organizations: [
- {
- _id: 1,
- image: '',
- name: 'Dummy Organization',
- description: 'This is a Dummy Organization',
- creator: {
- firstName: '',
- lastName: '',
- email: '',
- },
- location: 'New Delhi',
- apiUrl: 'www.dummyWebsite.com',
- members: {
- _id: '123',
- firstName: 'John',
- lastName: 'Doe',
- email: 'johndoe@gmail.com',
- },
- admins: {
- _id: '123',
- firstName: 'John',
- lastName: 'Doe',
- email: 'johndoe@gmail.com',
- },
- membershipRequests: {
- _id: '456',
- user: {
- firstName: 'Sam',
- lastName: 'Smith',
- email: 'samsmith@gmail.com',
- },
- },
- blockedUsers: {
- _id: '789',
- firstName: 'Steve',
- lastName: 'Smith',
- email: 'stevesmith@gmail.com',
- },
- isPublic: true,
- visibleInSearch: false,
- spamCount: [
- {
- _id: '6954',
- user: {
- _id: '878',
- firstName: 'Joe',
- lastName: 'Root',
- email: 'joeroot@gmail.com',
- },
- isReaded: false,
- groupchat: {
- _id: '321',
- title: 'Dummy',
- },
- },
- ],
- },
- ],
- },
- },
- },
-];
-
-// Has a placeholder image
-export const MOCKS_WITH_IMAGE = [
- {
- request: {
- query: ORGANIZATIONS_LIST,
- },
- result: {
- data: {
- organizations: [
- {
- _id: 1,
- image: 'https://via.placeholder.com/45x45',
- name: 'Dummy Organization',
- description: 'This is a Dummy Organization',
- creator: {
- firstName: '',
- lastName: '',
- email: '',
- },
- location: 'New Delhi',
- apiUrl: 'www.dummyWebsite.com',
- members: {
- _id: '123',
- firstName: 'John',
- lastName: 'Doe',
- email: 'johndoe@gmail.com',
- },
- admins: {
- _id: '123',
- firstName: 'John',
- lastName: 'Doe',
- email: 'johndoe@gmail.com',
- },
- membershipRequests: {
- _id: '456',
- user: {
- firstName: 'Sam',
- lastName: 'Smith',
- email: 'samsmith@gmail.com',
- },
- },
- blockedUsers: {
- _id: '789',
- firstName: 'Steve',
- lastName: 'Smith',
- email: 'stevesmith@gmail.com',
- },
- isPublic: true,
- visibleInSearch: false,
- spamCount: [
- {
- _id: '6954',
- user: {
- _id: '878',
- firstName: 'Joe',
- lastName: 'Root',
- email: 'joeroot@gmail.com',
- },
- isReaded: false,
- groupchat: {
- _id: '321',
- title: 'Dummy',
- },
- },
- ],
- },
- ],
- },
- },
- },
-];
diff --git a/src/components/ChangeLanguageDropdown/ChangeLanguageDropDown.tsx b/src/components/ChangeLanguageDropdown/ChangeLanguageDropDown.tsx
index d80b8cb225..8f4fd945ed 100644
--- a/src/components/ChangeLanguageDropdown/ChangeLanguageDropDown.tsx
+++ b/src/components/ChangeLanguageDropdown/ChangeLanguageDropDown.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import { Dropdown } from 'react-bootstrap';
import i18next from 'i18next';
-import styles from './ChangeLanguageDropdown.module.css';
import { languages } from 'utils/languages';
import cookies from 'js-cookie';
@@ -23,9 +22,7 @@ const ChangeLanguageDropDown = (
return (
(
=> changeLanguage(language.code)}
disabled={currentLanguageCode === language.code}
data-testid={`change-language-btn-${language.code}`}
diff --git a/src/components/ChangeLanguageDropdown/ChangeLanguageDropdown.module.css b/src/components/ChangeLanguageDropdown/ChangeLanguageDropdown.module.css
deleted file mode 100644
index e72c604905..0000000000
--- a/src/components/ChangeLanguageDropdown/ChangeLanguageDropdown.module.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.parentContainer {
- margin: 0 1rem;
-}
-
-.dropdownItem {
- font-size: 0.9rem;
-}
diff --git a/src/components/ChangeLanguageDropdown/ChangeLanguageDropdown.test.tsx b/src/components/ChangeLanguageDropdown/ChangeLanguageDropdown.test.tsx
index fb2921bf31..79209107fa 100644
--- a/src/components/ChangeLanguageDropdown/ChangeLanguageDropdown.test.tsx
+++ b/src/components/ChangeLanguageDropdown/ChangeLanguageDropdown.test.tsx
@@ -1,8 +1,6 @@
import React from 'react';
import { act, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import 'jest-localstorage-mock';
-import 'jest-location-mock';
import { I18nextProvider } from 'react-i18next';
import { BrowserRouter } from 'react-router-dom';
import i18nForTest from 'utils/i18nForTest';
diff --git a/src/components/CheckIn/CheckInModal.tsx b/src/components/CheckIn/CheckInModal.tsx
index 280e213675..a370ebbb7e 100644
--- a/src/components/CheckIn/CheckInModal.tsx
+++ b/src/components/CheckIn/CheckInModal.tsx
@@ -9,7 +9,7 @@ import type {
InterfaceModalProp,
InterfaceTableData,
} from './types';
-import type { GridColDef } from '@mui/x-data-grid';
+import type { GridColDef, GridRowHeightReturnValue } from '@mui/x-data-grid';
import { DataGrid } from '@mui/x-data-grid';
import TextField from '@mui/material/TextField';
@@ -90,7 +90,7 @@ export const CheckInModal = (props: InterfaceModalProp): JSX.Element => {
label="Search Attendees"
variant="outlined"
value={userFilterQuery}
- onChange={(e) => {
+ onChange={(e): void => {
setUserFilterQuery(e.target.value);
setFilterQueryModel({
items: [
@@ -108,7 +108,7 @@ export const CheckInModal = (props: InterfaceModalProp): JSX.Element => {
'auto'}
+ getRowHeight={(): GridRowHeightReturnValue => 'auto'}
columns={columns}
filterModel={filterQueryModel}
/>
diff --git a/src/components/CheckIn/CheckInWrapper.tsx b/src/components/CheckIn/CheckInWrapper.tsx
index 132e7a02b1..a1dae1da42 100644
--- a/src/components/CheckIn/CheckInWrapper.tsx
+++ b/src/components/CheckIn/CheckInWrapper.tsx
@@ -16,7 +16,7 @@ export const CheckInWrapper = (props: PropType): JSX.Element => {
className="mt-3"
variant="success"
aria-label="checkInAttendees"
- onClick={() => {
+ onClick={(): void => {
setShowModal(true);
}}
>
@@ -25,7 +25,7 @@ export const CheckInWrapper = (props: PropType): JSX.Element => {
{showModal && (
setShowModal(false)}
+ handleClose={(): void => setShowModal(false)}
eventId={props.eventId}
/>
)}
diff --git a/src/components/CollapsibleDropdown/CollapsibleDropdown.module.css b/src/components/CollapsibleDropdown/CollapsibleDropdown.module.css
new file mode 100644
index 0000000000..4337742ecc
--- /dev/null
+++ b/src/components/CollapsibleDropdown/CollapsibleDropdown.module.css
@@ -0,0 +1,14 @@
+.iconWrapper {
+ width: 36px;
+}
+
+.collapseBtn {
+ height: 48px;
+}
+
+.iconWrapperSm {
+ width: 36px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
diff --git a/src/components/CollapsibleDropdown/CollapsibleDropdown.test.tsx b/src/components/CollapsibleDropdown/CollapsibleDropdown.test.tsx
new file mode 100644
index 0000000000..4f1916669a
--- /dev/null
+++ b/src/components/CollapsibleDropdown/CollapsibleDropdown.test.tsx
@@ -0,0 +1,77 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import { BrowserRouter } from 'react-router-dom';
+
+import CollapsibleDropdown from './CollapsibleDropdown';
+import type { InterfaceCollapsibleDropdown } from './CollapsibleDropdown';
+
+const props: InterfaceCollapsibleDropdown = {
+ screenName: 'SubCategory 1',
+ target: {
+ name: 'DropDown Category',
+ url: undefined,
+ subTargets: [
+ {
+ name: 'SubCategory 1',
+ url: '/sub-category-1',
+ icon: 'fa fa-home',
+ },
+ {
+ name: 'SubCategory 2',
+ url: '/sub-category-2',
+ icon: 'fa fa-home',
+ },
+ ],
+ },
+};
+
+describe('Testing CollapsibleDropdown component', () => {
+ test('Component should be rendered properly', () => {
+ render();
+ expect(screen.getByText('DropDown Category')).toBeInTheDocument();
+ expect(screen.getByText('SubCategory 1')).toBeInTheDocument();
+ expect(screen.getByText('SubCategory 2')).toBeInTheDocument();
+ });
+
+ test('Dropdown should be rendered and functioning correctly', () => {
+ render(
+
+
+
+ );
+ const parentDropdownBtn = screen.getByTestId('collapsible-dropdown');
+ const activeDropdownBtn = screen.getByText('SubCategory 1');
+ const nonActiveDropdownBtn = screen.getByText('SubCategory 2');
+
+ // Check if dropdown is rendered with correct classes
+ expect(parentDropdownBtn).toBeInTheDocument();
+ expect(parentDropdownBtn).toHaveClass('text-white');
+ expect(parentDropdownBtn).toHaveClass('btn-success');
+
+ // Check if active dropdown is rendered with correct classes
+ expect(activeDropdownBtn).toBeInTheDocument();
+ expect(activeDropdownBtn).toHaveClass('text-white');
+ expect(activeDropdownBtn).toHaveClass('btn-success');
+
+ // Check if inactive dropdown is rendered with correct classes
+ expect(nonActiveDropdownBtn).toBeInTheDocument();
+ expect(nonActiveDropdownBtn).toHaveClass('text-secondary');
+ expect(nonActiveDropdownBtn).toHaveClass('btn-light');
+
+ // Check if dropdown is expanded by default since the screenName prop passes
+ // the same value as the name prop of the subTarget
+ expect(parentDropdownBtn).toHaveAttribute('aria-expanded', 'true');
+
+ // Check if dropdown is collapsed after clicking on it
+ parentDropdownBtn.click();
+ expect(parentDropdownBtn).toHaveAttribute('aria-expanded', 'false');
+
+ // Check if dropdown is expanded after clicking on it again
+ parentDropdownBtn.click();
+ expect(parentDropdownBtn).toHaveAttribute('aria-expanded', 'true');
+
+ // Click on non active dropdown button and check if it navigates to the correct url
+ nonActiveDropdownBtn.click();
+ expect(window.location.pathname).toBe('/sub-category-2');
+ });
+});
diff --git a/src/components/CollapsibleDropdown/CollapsibleDropdown.tsx b/src/components/CollapsibleDropdown/CollapsibleDropdown.tsx
new file mode 100644
index 0000000000..81b82e220d
--- /dev/null
+++ b/src/components/CollapsibleDropdown/CollapsibleDropdown.tsx
@@ -0,0 +1,91 @@
+import React, { useEffect } from 'react';
+import { Button, Collapse } from 'react-bootstrap';
+import type { TargetsType } from 'state/reducers/routesReducer';
+import styles from './CollapsibleDropdown.module.css';
+import IconComponent from 'components/IconComponent/IconComponent';
+import { useHistory } from 'react-router-dom';
+
+export interface InterfaceCollapsibleDropdown {
+ screenName: string;
+ target: TargetsType;
+}
+
+const collapsibleDropdown = ({
+ screenName,
+ target,
+}: InterfaceCollapsibleDropdown): JSX.Element => {
+ const [showDropdown, setShowDropdown] = React.useState(false);
+ const [active, setActive] = React.useState(false);
+ const { name, subTargets } = target;
+ const history = useHistory();
+
+ useEffect(() => {
+ target.subTargets?.map(({ name }) => {
+ if (name === screenName) {
+ setActive(true);
+ setShowDropdown(true);
+ }
+ });
+ }, [target.subTargets]);
+
+ return (
+ <>
+
+
+
+ {subTargets &&
+ subTargets.map(({ name, icon: stringIcon, url }, index) => {
+ return (
+
+ );
+ })}
+
+
+ >
+ );
+};
+
+export default collapsibleDropdown;
diff --git a/src/components/DeleteOrg/DeleteOrg.module.css b/src/components/DeleteOrg/DeleteOrg.module.css
new file mode 100644
index 0000000000..2b15a2ac0c
--- /dev/null
+++ b/src/components/DeleteOrg/DeleteOrg.module.css
@@ -0,0 +1,25 @@
+.settingsBody {
+ margin: 2.5rem 0;
+}
+
+.cardHeader {
+ padding: 1.25rem 1rem 1rem 1rem;
+ border-bottom: 1px solid var(--bs-gray-200);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.cardHeader .cardTitle {
+ font-size: 1.2rem;
+ font-weight: 600;
+}
+
+.cardBody {
+ min-height: 180px;
+}
+
+.cardBody .textBox {
+ margin: 0 0 3rem 0;
+ color: var(--bs-secondary);
+}
diff --git a/src/components/DeleteOrg/DeleteOrg.test.tsx b/src/components/DeleteOrg/DeleteOrg.test.tsx
new file mode 100644
index 0000000000..936cf44e03
--- /dev/null
+++ b/src/components/DeleteOrg/DeleteOrg.test.tsx
@@ -0,0 +1,84 @@
+import React from 'react';
+import { MockedProvider } from '@apollo/react-testing';
+import { render, screen } from '@testing-library/react';
+import 'jest-location-mock';
+import { I18nextProvider } from 'react-i18next';
+import { Provider } from 'react-redux';
+import { BrowserRouter } from 'react-router-dom';
+
+import { DELETE_ORGANIZATION_MUTATION } from 'GraphQl/Mutations/mutations';
+import { act } from 'react-dom/test-utils';
+import { store } from 'state/store';
+import { StaticMockLink } from 'utils/StaticMockLink';
+import i18nForTest from 'utils/i18nForTest';
+import DeleteOrg from './DeleteOrg';
+
+const MOCKS = [
+ {
+ request: {
+ query: DELETE_ORGANIZATION_MUTATION,
+ variables: {
+ id: 123,
+ },
+ },
+ result: {
+ data: {
+ removeOrganization: [
+ {
+ _id: 123,
+ },
+ ],
+ },
+ },
+ },
+];
+
+const link = new StaticMockLink(MOCKS, true);
+
+afterEach(() => {
+ localStorage.clear();
+});
+
+describe('Delete Organization Component', () => {
+ test('should be able to Toggle Delete Organization Modal', async () => {
+ window.location.assign('/orgsetting/id=123');
+ localStorage.setItem('UserType', 'SUPERADMIN');
+ render(
+
+
+
+
+
+
+
+
+
+ );
+ screen.getByTestId(/openDeleteModalBtn/i).click();
+ expect(screen.getByTestId(/orgDeleteModal/i)).toBeInTheDocument();
+ screen.getByTestId(/closeDelOrgModalBtn/i).click();
+ await act(async () => {
+ expect(screen.queryByTestId(/orgDeleteModal/i)).not.toHaveFocus();
+ });
+ expect(window.location).toBeAt('/orgsetting/id=123');
+ });
+
+ test('Delete organization functionality should work properly', async () => {
+ window.location.assign('/orgsetting/id=123');
+ localStorage.setItem('UserType', 'SUPERADMIN');
+ render(
+
+
+
+
+
+
+
+
+
+ );
+ screen.getByTestId(/openDeleteModalBtn/i).click();
+ screen.getByTestId(/deleteOrganizationBtn/i).click();
+ expect(window.location).not.toBeNull();
+ });
+});
diff --git a/src/components/DeleteOrg/DeleteOrg.tsx b/src/components/DeleteOrg/DeleteOrg.tsx
new file mode 100644
index 0000000000..e6442d6558
--- /dev/null
+++ b/src/components/DeleteOrg/DeleteOrg.tsx
@@ -0,0 +1,89 @@
+import { useMutation } from '@apollo/client';
+import { DELETE_ORGANIZATION_MUTATION } from 'GraphQl/Mutations/mutations';
+import React, { useState } from 'react';
+import { Button, Card, Modal } from 'react-bootstrap';
+import { useTranslation } from 'react-i18next';
+import { errorHandler } from 'utils/errorHandler';
+import styles from './DeleteOrg.module.css';
+
+function deleteOrg(): JSX.Element {
+ const { t } = useTranslation('translation', {
+ keyPrefix: 'deleteOrg',
+ });
+ const [showDeleteModal, setShowDeleteModal] = useState(false);
+ const currentUrl = window.location.href.split('=')[1];
+ const canDelete = localStorage.getItem('UserType') === 'SUPERADMIN';
+ const toggleDeleteModal = (): void => setShowDeleteModal(!showDeleteModal);
+ const [del] = useMutation(DELETE_ORGANIZATION_MUTATION);
+
+ const deleteOrg = async (): Promise => {
+ try {
+ const { data } = await del({
+ variables: {
+ id: currentUrl,
+ },
+ });
+ /* istanbul ignore next */
+ if (data) {
+ window.location.replace('/orglist');
+ }
+ } catch (error: any) {
+ /* istanbul ignore next */
+ errorHandler(t, error);
+ }
+ };
+
+ return (
+ <>
+ {canDelete && (
+
+
+
{t('deleteOrganization')}
+
+
+ {t('longDelOrgMsg')}
+
+
+
+ )}
+ {/* Delete Organization Modal */}
+ {canDelete && (
+
+
+ {t('deleteOrganization')}
+
+ {t('deleteMsg')}
+
+
+
+
+
+ )}
+ >
+ );
+}
+
+export default deleteOrg;
diff --git a/src/components/EventListCard/EventListCard.tsx b/src/components/EventListCard/EventListCard.tsx
index bee2558a88..7f817890de 100644
--- a/src/components/EventListCard/EventListCard.tsx
+++ b/src/components/EventListCard/EventListCard.tsx
@@ -12,6 +12,7 @@ import {
} from 'GraphQl/Mutations/mutations';
import { Form } from 'react-bootstrap';
import { errorHandler } from 'utils/errorHandler';
+import { useHistory } from 'react-router-dom';
interface InterfaceEventListCardProps {
key: string;
@@ -37,6 +38,7 @@ function eventListCard(props: InterfaceEventListCardProps): JSX.Element {
const [recurringchecked, setRecurringChecked] = useState(false);
const [publicchecked, setPublicChecked] = useState(true);
const [registrablechecked, setRegistrableChecked] = React.useState(false);
+ const history = useHistory();
const [formState, setFormState] = useState({
title: '',
eventdescrip: '',
@@ -125,7 +127,7 @@ function eventListCard(props: InterfaceEventListCardProps): JSX.Element {
};
const openEventDashboard = (): void => {
- window.location.assign(`/event/${props.id}`);
+ history.push(`/event/${props.id}`);
};
return (
diff --git a/src/components/EventProjectModals/AddEventProjectModal.tsx b/src/components/EventProjectModals/AddEventProjectModal.tsx
index b33faeb4a7..3da5043c51 100644
--- a/src/components/EventProjectModals/AddEventProjectModal.tsx
+++ b/src/components/EventProjectModals/AddEventProjectModal.tsx
@@ -74,7 +74,7 @@ export const AddEventProjectModal = ({
required
placeholder="Enter title of the project"
value={title}
- onChange={(e) => setTitle(e.target.value)}
+ onChange={(e): void => setTitle(e.target.value)}
/>
@@ -86,7 +86,7 @@ export const AddEventProjectModal = ({
className="mb-3"
required
value={description}
- onChange={(e) => setDescription(e.target.value)}
+ onChange={(e): void => setDescription(e.target.value)}
/>
diff --git a/src/components/EventProjectModals/UpdateEventProjectModal.tsx b/src/components/EventProjectModals/UpdateEventProjectModal.tsx
index e2b98b6f6a..362d78645a 100644
--- a/src/components/EventProjectModals/UpdateEventProjectModal.tsx
+++ b/src/components/EventProjectModals/UpdateEventProjectModal.tsx
@@ -80,7 +80,7 @@ export const UpdateEventProjectModal = (props: ModalPropType): JSX.Element => {
className="mb-3"
placeholder="Enter title of the project"
value={title}
- onChange={(e) => setTitle(e.target.value)}
+ onChange={(e): void => setTitle(e.target.value)}
/>
@@ -91,7 +91,7 @@ export const UpdateEventProjectModal = (props: ModalPropType): JSX.Element => {
className="mb-3"
placeholder="A brief desciption of what the event is about!"
value={description}
- onChange={(e) => setDescription(e.target.value)}
+ onChange={(e): void => setDescription(e.target.value)}
/>
diff --git a/src/components/EventRegistrantsModal/EventRegistrantsModal.tsx b/src/components/EventRegistrantsModal/EventRegistrantsModal.tsx
index 850d50e109..a75c9d942d 100644
--- a/src/components/EventRegistrantsModal/EventRegistrantsModal.tsx
+++ b/src/components/EventRegistrantsModal/EventRegistrantsModal.tsx
@@ -120,7 +120,7 @@ export const EventRegistrantsModal = (props: ModalPropType): JSX.Element => {
label={`${attendee.firstName} ${attendee.lastName}`}
variant="outlined"
key={attendee._id}
- onDelete={() => deleteRegistrant(attendee._id)}
+ onDelete={(): void => deleteRegistrant(attendee._id)}
/>
))}
@@ -128,14 +128,14 @@ export const EventRegistrantsModal = (props: ModalPropType): JSX.Element => {
{
+ onChange={(_, newMember): void => {
setMember(newMember);
}}
options={memberData.organizations[0].members}
- getOptionLabel={(member: InterfaceUser) =>
+ getOptionLabel={(member: InterfaceUser): string =>
`${member.firstName} ${member.lastName}`
}
- renderInput={(params) => (
+ renderInput={(params): React.ReactNode => (
{
className="mt-3"
variant="success"
aria-label="showAttendees"
- onClick={() => {
+ onClick={(): void => {
setShowModal(true);
}}
>
@@ -26,7 +26,7 @@ export const EventRegistrantsWrapper = (props: PropType): JSX.Element => {
{showModal ? (
{
+ handleClose={(): void => {
setShowModal(false);
}}
eventId={props.eventId}
diff --git a/src/components/IconComponent/IconComponent.test.tsx b/src/components/IconComponent/IconComponent.test.tsx
new file mode 100644
index 0000000000..766a6576b8
--- /dev/null
+++ b/src/components/IconComponent/IconComponent.test.tsx
@@ -0,0 +1,99 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import IconComponent from './IconComponent';
+
+const screenTestIdMap = {
+ Dashboard: {
+ name: 'Dashboard',
+ testId: 'Icon-Component-DashboardIcon',
+ },
+ People: {
+ name: 'People',
+ testId: 'Icon-Component-PeopleIcon',
+ },
+ Events: {
+ name: 'Events',
+ testId: 'Icon-Component-EventsIcon',
+ },
+ Posts: {
+ name: 'Posts',
+ testId: 'Icon-Component-PostsIcon',
+ },
+ BlockUnblock: {
+ name: 'Block/Unblock',
+ testId: 'Block/Icon-Component-UnblockIcon',
+ },
+ Plugins: {
+ name: 'Plugins',
+ testId: 'Icon-Component-PluginsIcon',
+ },
+ Settings: {
+ name: 'Settings',
+ testId: 'Icon-Component-SettingsIcon',
+ },
+ AllOrganizations: {
+ name: 'All Organizations',
+ testId: 'Icon-Component-AllOrganizationsIcon',
+ },
+ default: {
+ name: 'default',
+ testId: 'Icon-Component-DefaultIcon',
+ },
+};
+
+describe('Testing CollapsibleDropdown component', () => {
+ it('renders the Dashboard icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.Dashboard.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the People icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.People.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the Events icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.Events.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the Posts icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.Posts.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the Block/Unblock icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.BlockUnblock.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the Plugins icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.Plugins.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the Settings icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.Settings.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the All Organizations icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.AllOrganizations.testId}`)
+ ).toBeInTheDocument();
+ });
+ it('renders the default icon', () => {
+ render();
+ expect(
+ screen.getByTestId(`${screenTestIdMap.default.testId}`)
+ ).toBeInTheDocument();
+ });
+});
diff --git a/src/components/IconComponent/IconComponent.tsx b/src/components/IconComponent/IconComponent.tsx
new file mode 100644
index 0000000000..a4648a6e03
--- /dev/null
+++ b/src/components/IconComponent/IconComponent.tsx
@@ -0,0 +1,69 @@
+import React from 'react';
+import { QuestionMarkOutlined } from '@mui/icons-material';
+import { ReactComponent as BlockUserIcon } from 'assets/svgs/blockUser.svg';
+import { ReactComponent as DashboardIcon } from 'assets/svgs/dashboard.svg';
+import { ReactComponent as EventsIcon } from 'assets/svgs/events.svg';
+import { ReactComponent as OrganizationsIcon } from 'assets/svgs/organizations.svg';
+import { ReactComponent as PeopleIcon } from 'assets/svgs/people.svg';
+import { ReactComponent as PluginsIcon } from 'assets/svgs/plugins.svg';
+import { ReactComponent as PostsIcon } from 'assets/svgs/posts.svg';
+import { ReactComponent as SettingsIcon } from 'assets/svgs/settings.svg';
+
+export interface InterfaceIconComponent {
+ name: string;
+ fill?: string;
+ height?: string;
+ width?: string;
+}
+
+const iconComponent = (props: InterfaceIconComponent): JSX.Element => {
+ switch (props.name) {
+ case 'Dashboard':
+ return (
+
+ );
+ case 'People':
+ return ;
+ case 'Events':
+ return ;
+ case 'Posts':
+ return ;
+ case 'Block/Unblock':
+ return (
+
+ );
+ case 'Plugins':
+ return (
+
+ );
+ case 'Settings':
+ return (
+
+ );
+ case 'All Organizations':
+ return (
+
+ );
+ default:
+ return (
+
+ );
+ }
+};
+
+export default iconComponent;
diff --git a/src/components/LeftDrawer/LeftDrawer.module.css b/src/components/LeftDrawer/LeftDrawer.module.css
index 379633fa5a..6818dc05fb 100644
--- a/src/components/LeftDrawer/LeftDrawer.module.css
+++ b/src/components/LeftDrawer/LeftDrawer.module.css
@@ -54,6 +54,7 @@
text-align: start;
margin-bottom: 0.8rem;
border-radius: 8px;
+ border: 1px solid var(--bs-gray-200);
}
.leftDrawer .optionList button .iconWrapper {
@@ -112,6 +113,10 @@
/* For tablets */
@media (max-width: 820px) {
+ .hideElemByDefault {
+ display: none;
+ }
+
.leftDrawer {
width: 100%;
left: 0;
diff --git a/src/components/LeftDrawer/LeftDrawer.test.tsx b/src/components/LeftDrawer/LeftDrawer.test.tsx
index b6bbcd5755..2a64d72f95 100644
--- a/src/components/LeftDrawer/LeftDrawer.test.tsx
+++ b/src/components/LeftDrawer/LeftDrawer.test.tsx
@@ -11,46 +11,8 @@ import type { InterfaceLeftDrawerProps } from './LeftDrawer';
import LeftDrawer from './LeftDrawer';
const props = {
- data: {
- user: {
- firstName: 'John',
- lastName: 'Doe',
- image: null,
- email: 'johndoe@gmail.com',
- userType: 'SUPERADMIN',
- adminFor: [
- {
- _id: '123',
- name: 'Palisadoes',
- image: null,
- },
- ],
- },
- },
- showDrawer: true,
- setShowDrawer: jest.fn(),
-};
-
-const propsAdmin: InterfaceLeftDrawerProps = {
- data: {
- user: {
- firstName: 'John',
- lastName: 'Doe',
- image: `https://api.dicebear.com/5.x/initials/svg?seed=John%20Doe`,
- email: 'johndoe@gmail.com',
- userType: 'ADMIN',
- adminFor: [
- {
- _id: '123',
- name: 'Palisadoes',
- image: null,
- },
- ],
- },
- },
- screenName: 'Organizations',
- showDrawer: true,
- setShowDrawer: jest.fn(),
+ hideDrawer: true,
+ setHideDrawer: jest.fn(),
};
const propsOrg: InterfaceLeftDrawerProps = {
@@ -59,12 +21,13 @@ const propsOrg: InterfaceLeftDrawerProps = {
};
const propsReq: InterfaceLeftDrawerProps = {
...props,
+ hideDrawer: false,
screenName: 'Requests',
};
-const propsRoles: InterfaceLeftDrawerProps = {
+const propsUsers: InterfaceLeftDrawerProps = {
...props,
- screenName: 'Roles',
- showDrawer: false,
+ hideDrawer: null,
+ screenName: 'Users',
};
jest.mock('react-toastify', () => ({
@@ -75,6 +38,15 @@ jest.mock('react-toastify', () => ({
},
}));
+beforeEach(() => {
+ localStorage.setItem('FirstName', 'John');
+ localStorage.setItem('LastName', 'Doe');
+ localStorage.setItem(
+ 'UserImage',
+ 'https://api.dicebear.com/5.x/initials/svg?seed=John%20Doe'
+ );
+});
+
afterEach(() => {
jest.clearAllMocks();
localStorage.clear();
@@ -82,6 +54,7 @@ afterEach(() => {
describe('Testing Left Drawer component for SUPERADMIN', () => {
test('Component should be rendered properly', () => {
+ localStorage.setItem('UserImage', '');
localStorage.setItem('UserType', 'SUPERADMIN');
render(
@@ -93,7 +66,7 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {
expect(screen.getByText('Organizations')).toBeInTheDocument();
expect(screen.getByText('Requests')).toBeInTheDocument();
- expect(screen.getByText('Roles')).toBeInTheDocument();
+ expect(screen.getByText('Users')).toBeInTheDocument();
expect(screen.getByText('Talawa Admin Portal')).toBeInTheDocument();
expect(screen.getByText(/John Doe/i)).toBeInTheDocument();
@@ -120,24 +93,7 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {
// Send to roles screen
userEvent.click(rolesBtn);
- expect(global.window.location.pathname).toContain('/roles');
- });
-
- test('Testing when user data is undefined', () => {
- localStorage.setItem('UserType', 'SUPERADMIN');
- const userUndefinedProps = {
- ...props,
- data: undefined,
- screenName: 'Organizations',
- };
- render(
-
-
-
-
-
- );
- expect(screen.getByTestId(/loadingProfile/i)).toBeInTheDocument();
+ expect(global.window.location.pathname).toContain('/users');
});
test('Testing in requests screen', () => {
@@ -174,7 +130,7 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {
render(
-
+
);
@@ -211,7 +167,30 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {
userEvent.click(closeModalBtn);
});
+ test('Testing Drawer when hideDrawer is null', () => {
+ localStorage.setItem('UserType', 'SUPERADMIN');
+ render(
+
+
+
+
+
+ );
+ });
+
+ test('Testing Drawer when hideDrawer is true', () => {
+ localStorage.setItem('UserType', 'SUPERADMIN');
+ render(
+
+
+
+
+
+ );
+ });
+
test('Testing logout functionality', async () => {
+ localStorage.setItem('UserType', 'SUPERADMIN');
render(
@@ -219,8 +198,9 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {
);
-
userEvent.click(screen.getByTestId('logoutBtn'));
+ expect(localStorage.clear).toHaveBeenCalled();
+ expect(global.window.location.pathname).toBe('/');
});
});
@@ -230,7 +210,7 @@ describe('Testing Left Drawer component for ADMIN', () => {
render(
-
+
);
diff --git a/src/components/LeftDrawer/LeftDrawer.tsx b/src/components/LeftDrawer/LeftDrawer.tsx
index f2f750ec85..e28f40d31a 100644
--- a/src/components/LeftDrawer/LeftDrawer.tsx
+++ b/src/components/LeftDrawer/LeftDrawer.tsx
@@ -1,33 +1,33 @@
import React from 'react';
import Button from 'react-bootstrap/Button';
-import type { InterfaceUserType } from 'utils/interfaces';
-import { ReactComponent as AngleRightIcon } from '../../assets/svgs/icons/angleRight.svg';
-import { ReactComponent as LogoutIcon } from '../../assets/svgs/icons/logout.svg';
-import { ReactComponent as OrganizationsIcon } from '../../assets/svgs/icons/organizations.svg';
-import { ReactComponent as RequestsIcon } from '../../assets/svgs/icons/requests.svg';
-import { ReactComponent as RolesIcon } from '../../assets/svgs/icons/roles.svg';
-import { ReactComponent as TalawaLogo } from '../../assets/svgs/talawa.svg';
-import styles from './LeftDrawer.module.css';
-import { toast } from 'react-toastify';
-import { useHistory } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
+import { useHistory } from 'react-router-dom';
+import { toast } from 'react-toastify';
+import { ReactComponent as AngleRightIcon } from 'assets/svgs/angleRight.svg';
+import { ReactComponent as LogoutIcon } from 'assets/svgs/logout.svg';
+import { ReactComponent as OrganizationsIcon } from 'assets/svgs/organizations.svg';
+import { ReactComponent as RequestsIcon } from 'assets/svgs/requests.svg';
+import { ReactComponent as RolesIcon } from 'assets/svgs/roles.svg';
+import { ReactComponent as TalawaLogo } from 'assets/svgs/talawa.svg';
+import styles from './LeftDrawer.module.css';
export interface InterfaceLeftDrawerProps {
- data: InterfaceUserType | undefined;
- showDrawer: boolean;
- setShowDrawer: React.Dispatch>;
+ hideDrawer: boolean | null;
+ setHideDrawer: React.Dispatch>;
screenName: string;
}
const leftDrawer = ({
- data,
screenName,
- showDrawer,
- setShowDrawer,
+ hideDrawer,
+ setHideDrawer,
}: InterfaceLeftDrawerProps): JSX.Element => {
const { t } = useTranslation('translation', { keyPrefix: 'leftDrawer' });
const userType = localStorage.getItem('UserType');
+ const firstName = localStorage.getItem('FirstName');
+ const lastName = localStorage.getItem('LastName');
+ const userImage = localStorage.getItem('UserImage');
const history = useHistory();
@@ -40,7 +40,11 @@ const leftDrawer = ({
<>
@@ -48,7 +52,7 @@ const leftDrawer = ({
variant="danger"
className={styles.closeModalBtn}
onClick={(): void => {
- setShowDrawer(!showDrawer);
+ setHideDrawer(false);
}}
data-testid="closeModalBtn"
>
@@ -104,63 +108,56 @@ const leftDrawer = ({
)}
{userType === 'SUPERADMIN' && (
)}
- {data === undefined ? (
-
- ) : (
-
- )}
+