diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a0dfff1d24..57ec1e3357 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -20,8 +20,10 @@ "postcss-cli": "^11.0.0", "react": "^18.2.0", "react-bootstrap": "^2.10.1", + "react-data-table-component": "^7.6.2", "react-dom": "^18.2.0", "react-intl": "^6.6.2", + "react-paginate": "^8.2.0", "react-router-bootstrap": "^0.26.2", "react-router-dom": "^6.22.0", "react-scripts": "5.0.1", @@ -48,6 +50,7 @@ "css-loader": "^6.10.0", "date-fns": "^3.6.0", "html-webpack-plugin": "^5.6.0", + "husky": "^9.0.11", "react-app-rewired": "^2.2.1", "react-bootstrap-icons": "^1.11.3", "react-query": "^3.39.3", @@ -2359,7 +2362,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", - "dev": true, "dependencies": { "@emotion/memoize": "^0.8.1" } @@ -2367,14 +2369,12 @@ "node_modules/@emotion/memoize": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", - "dev": true + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "node_modules/@emotion/unitless": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==", - "dev": true + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", @@ -4828,8 +4828,7 @@ "node_modules/@types/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==", - "dev": true + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.9", @@ -6411,7 +6410,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6983,7 +6981,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "dev": true, "engines": { "node": ">=4" } @@ -7182,7 +7179,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", - "dev": true, "dependencies": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", @@ -10053,6 +10049,21 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true, + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -15951,6 +15962,23 @@ "react": ">=16.8.6" } }, + "node_modules/react-data-table-component": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/react-data-table-component/-/react-data-table-component-7.6.2.tgz", + "integrity": "sha512-nHe7040fmtrJyQr/ieGrTfV0jBflYGK4sLokC6/AFOv3ThjmA9WzKz8Z8/2wMxzRqLU+Rn0CVFg+8+frKLepWQ==", + "dependencies": { + "deepmerge": "^4.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.3", + "styled-components": ">= 5.0.0" + }, + "peerDependenciesMeta": { + "styled-components": { + "optional": false + } + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -16121,6 +16149,17 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "node_modules/react-paginate": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/react-paginate/-/react-paginate-8.2.0.tgz", + "integrity": "sha512-sJCz1PW+9PNIjUSn919nlcRVuleN2YPoFBOvL+6TPgrH/3lwphqiSOgdrLafLdyLDxsgK+oSgviqacF4hxsDIw==", + "dependencies": { + "prop-types": "^15" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18" + } + }, "node_modules/react-query": { "version": "3.39.3", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", @@ -17114,8 +17153,7 @@ "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "dev": true + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -17666,7 +17704,6 @@ "version": "6.1.8", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz", "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==", - "dev": true, "dependencies": { "@emotion/is-prop-valid": "1.2.1", "@emotion/unitless": "0.8.0", @@ -17693,14 +17730,12 @@ "node_modules/styled-components/node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/styled-components/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -17727,8 +17762,7 @@ "node_modules/styled-components/node_modules/tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "dev": true + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "node_modules/stylehacks": { "version": "5.1.1", @@ -17748,8 +17782,7 @@ "node_modules/stylis": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", - "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==", - "dev": true + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" }, "node_modules/sucrase": { "version": "3.35.0", @@ -21394,7 +21427,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", - "dev": true, "requires": { "@emotion/memoize": "^0.8.1" } @@ -21402,14 +21434,12 @@ "@emotion/memoize": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", - "dev": true + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "@emotion/unitless": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==", - "dev": true + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, "@eslint-community/eslint-utils": { "version": "4.4.0", @@ -23257,8 +23287,7 @@ "@types/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==", - "dev": true + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" }, "@types/testing-library__jest-dom": { "version": "5.14.9", @@ -24399,8 +24428,7 @@ "camelize": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", - "dev": true + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" }, "caniuse-api": { "version": "3.0.0", @@ -24813,8 +24841,7 @@ "css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "dev": true + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" }, "css-declaration-sorter": { "version": "6.4.1", @@ -24927,7 +24954,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", - "dev": true, "requires": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", @@ -27009,6 +27035,12 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, + "husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -31053,6 +31085,14 @@ "prop-types": "^15.7.2" } }, + "react-data-table-component": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/react-data-table-component/-/react-data-table-component-7.6.2.tgz", + "integrity": "sha512-nHe7040fmtrJyQr/ieGrTfV0jBflYGK4sLokC6/AFOv3ThjmA9WzKz8Z8/2wMxzRqLU+Rn0CVFg+8+frKLepWQ==", + "requires": { + "deepmerge": "^4.3.1" + } + }, "react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -31180,6 +31220,14 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-paginate": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/react-paginate/-/react-paginate-8.2.0.tgz", + "integrity": "sha512-sJCz1PW+9PNIjUSn919nlcRVuleN2YPoFBOvL+6TPgrH/3lwphqiSOgdrLafLdyLDxsgK+oSgviqacF4hxsDIw==", + "requires": { + "prop-types": "^15" + } + }, "react-query": { "version": "3.39.3", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", @@ -31888,8 +31936,7 @@ "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "dev": true + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "shebang-command": { "version": "2.0.0", @@ -32304,7 +32351,6 @@ "version": "6.1.8", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz", "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==", - "dev": true, "requires": { "@emotion/is-prop-valid": "1.2.1", "@emotion/unitless": "0.8.0", @@ -32320,14 +32366,12 @@ "csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "dev": true, "requires": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -32337,8 +32381,7 @@ "tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "dev": true + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" } } }, @@ -32354,8 +32397,7 @@ "stylis": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", - "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==", - "dev": true + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" }, "sucrase": { "version": "3.35.0", diff --git a/frontend/package.json b/frontend/package.json index 8d9a6f15fe..69c77ac2d3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,8 +15,10 @@ "postcss-cli": "^11.0.0", "react": "^18.2.0", "react-bootstrap": "^2.10.1", + "react-data-table-component": "^7.6.2", "react-dom": "^18.2.0", "react-intl": "^6.6.2", + "react-paginate": "^8.2.0", "react-router-bootstrap": "^0.26.2", "react-router-dom": "^6.22.0", "react-scripts": "5.0.1", diff --git a/frontend/src/About.jsx b/frontend/src/About.jsx index d1c0f327a0..ebd99c4e9b 100644 --- a/frontend/src/About.jsx +++ b/frontend/src/About.jsx @@ -1,17 +1,90 @@ - -import React from 'react'; -import { Alert } from 'react-bootstrap'; - +import React, { useEffect, useState } from "react"; +import { Alert } from "react-bootstrap"; +import DataTable from "./components/DataTable"; export default function About() { - - return ( -
-

About

- - This is a simple page about wildbook. - + const columnNames = ["age", "name", "location"]; + + const [page, setPage] = useState(0); + const [perPage, setPerPage] = useState(10); + useEffect(() => { + console.log("Page: ", page); + console.log("PerPage: ", perPage); + }, [page, perPage]); + const data = [ + { + age: 232, + name: "John Doe", + location: "New York", + }, + { + age: 25, + name: "Jane Doe", + location: "Los Angeles", + }, + { + age: 27, + name: "John Smith", + location: "Chicago", + }, + { + age: 232, + name: "John Doe", + location: "New York", + }, + { + age: 25, + name: "Jane Doe", + location: "Los Angeles", + }, + { + age: 27, + name: "John Smith", + location: "Chicago", + }, + { + age: 232, + name: "John Doe", + location: "New York", + }, + { + age: 25, + name: "Jane Doe", + location: "Los Angeles", + }, + { + age: 27, + name: "John Smith", + location: "Chicago", + }, + { + age: 232, + name: "John Doe", + location: "New York", + }, + ]; -
- ); + return ( +
+

About

+ This is a simple page about wildbook. + { + console.log("Selected Rows: ", selectedRows); + }} + /> +
+ ); } diff --git a/frontend/src/FrontDesk.jsx b/frontend/src/FrontDesk.jsx index af60b64efb..55cad1a5cb 100644 --- a/frontend/src/FrontDesk.jsx +++ b/frontend/src/FrontDesk.jsx @@ -8,7 +8,7 @@ import getCollaborationNotifications from "./models/notifications/getCollaborati import NotFound from "./pages/errorPages/NotFound"; import ServerError from "./pages/errorPages/ServerError"; import LoadingScreen from "./components/LoadingScreen"; -import GoogleTagMnager from "./GoogleTagManager"; +import GoogleTagManager from "./GoogleTagManager"; export default function FrontDesk() { const [isLoggedIn, setIsLoggedIn] = useState(false); @@ -72,7 +72,7 @@ export default function FrontDesk() { getAllNotifications, }} > - + - + - {/* } /> */} + {/* } /> */} } /> } /> } /> diff --git a/frontend/src/components/DataTable.jsx b/frontend/src/components/DataTable.jsx new file mode 100644 index 0000000000..275d7ec56c --- /dev/null +++ b/frontend/src/components/DataTable.jsx @@ -0,0 +1,192 @@ +import React, { useState, useEffect, useMemo } from "react"; +import DataTable from "react-data-table-component"; +import ReactPaginate from "react-paginate"; +import { InputGroup, Form, Button, Container, Row, Col } from "react-bootstrap"; +import "bootstrap/dist/css/bootstrap.min.css"; +import "../css/dataTable.css"; + +const columns = [ + { name: "ID", selector: (row) => row.id, sortable: true }, + { name: "Name", selector: (row) => row.name, sortable: true }, + { name: "Age", selector: (row) => row.age, sortable: true }, +]; + +const customStyles = { + rows: { + style: { + border: "none !important", + borderRadius: "5px", + }, + }, +}; + +const conditionalRowStyles = [ + { + when: (row) => row.tableID % 2 === 0, + style: { + backgroundColor: "#ffffff", // Light gray color + }, + }, + { + when: (row) => row.tableID % 2 !== 0, + style: { + backgroundColor: "#f2f2f2", // White color + }, + }, +]; + +const MyDataTable = ({ + columnNames = [], + totalItems = 0, + tableData = [], + page, + perPage, + onPageChange, + onPerPageChange, + onSelectedRowsChange = () => {}, +}) => { + const [data, setData] = useState([]); + const [filterText, setFilterText] = useState(""); + const [goToPage, setGoToPage] = useState(""); + const perPageOptions = [10, 20, 30, 40, 45]; + + const wrappedColumns = useMemo( + () => + columnNames.map((col) => ({ + name: col.charAt(0).toUpperCase() + col.slice(1), // Capitalize the column header + selector: (row) => row[col], // Accessor function for the column data + sortable: true, // Make the column sortable + })), + [columnNames], + ); + + useEffect(() => { + setData(tableData.map((row, index) => ({ tableID: index, ...row }))); + }, [tableData]); + + const handlePageChange = ({ selected }) => { + onPageChange(selected); + }; + + const handleGoToPageChange = (event) => { + setGoToPage(event.target.value); + }; + + const handleGoToPageSubmit = () => { + const pageNumber = Number(goToPage) - 1; + if ( + !isNaN(pageNumber) && + pageNumber >= 0 && + pageNumber < Math.ceil(totalItems / perPage) + ) { + onPageChange(pageNumber); + } + }; + + const handlePerPageChange = (event) => { + const newPerPage = Number(event.target.value); + if (!isNaN(newPerPage) && newPerPage > 0) { + onPerPageChange(newPerPage); + } + }; + + const handleFilterChange = (event) => { + setFilterText(event.target.value); + }; + + const clearFilterResult = () => { + setFilterText(""); + }; + + const filteredData = data.filter((item) => + Object.values(item).some( + (value) => + value && + value.toString().toLowerCase().includes(filterText.toLowerCase()), + ), + ); + + return ( + + + + + + + + + +
+ Total Items: {totalItems} +
+ + Per page + + {perPageOptions.map((option) => ( + + ))} + + + "} + breakLabel={"..."} + breakClassName={"page-item"} + breakLinkClassName={"page-link"} + pageCount={Math.ceil(totalItems / perPage)} + marginPagesDisplayed={2} + pageRangeDisplayed={2} + onPageChange={handlePageChange} + containerClassName={"pagination"} + pageClassName={"page-item"} + pageLinkClassName={"page-link"} + previousClassName={"page-item"} + previousLinkClassName={"page-link"} + nextClassName={"page-item"} + nextLinkClassName={"page-link"} + activeClassName={"active-page"} + forcePage={page} + /> + + Go to + + + + +
+
+ ); +}; + +export default MyDataTable; diff --git a/frontend/src/css/dataTable.css b/frontend/src/css/dataTable.css new file mode 100644 index 0000000000..ccfb72a02b --- /dev/null +++ b/frontend/src/css/dataTable.css @@ -0,0 +1,15 @@ +.pagination .active-page a { + background-color: #007DA3 ; + border-color: #007DA3 ; + color: white ; +} + +.go-button { + background-color: #007DA3; + border-color: #007DA3; + color: white; +} + +.pagination { + margin-bottom: 0; +} \ No newline at end of file