diff --git a/package-lock.json b/package-lock.json index 3a0c3c35..ca66d22c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,10 @@ "packages": { "": { "dependencies": { - "asciidoctor-emoji": "^0.5.0" + "@material-ui/core": "^4.12.4", + "@material-ui/icons": "^4.11.3", + "asciidoctor-emoji": "^0.5.0", + "react-router-dom": "^6.22.1" } }, "node_modules/@asciidoctor/core": { @@ -35,6 +38,221 @@ "node": ">=16" } }, + "node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "node_modules/@material-ui/core": { + "version": "4.12.4", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz", + "integrity": "sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==", + "deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@material-ui/styles": "^4.11.5", + "@material-ui/system": "^4.12.2", + "@material-ui/types": "5.1.0", + "@material-ui/utils": "^4.11.3", + "@types/react-transition-group": "^4.2.0", + "clsx": "^1.0.4", + "hoist-non-react-statics": "^3.3.2", + "popper.js": "1.16.1-lts", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0", + "react-transition-group": "^4.4.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/icons": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.3.tgz", + "integrity": "sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==", + "dependencies": { + "@babel/runtime": "^7.4.4" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@material-ui/core": "^4.0.0", + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/styles": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.5.tgz", + "integrity": "sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==", + "deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@emotion/hash": "^0.8.0", + "@material-ui/types": "5.1.0", + "@material-ui/utils": "^4.11.3", + "clsx": "^1.0.4", + "csstype": "^2.5.2", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.5.1", + "jss-plugin-camel-case": "^10.5.1", + "jss-plugin-default-unit": "^10.5.1", + "jss-plugin-global": "^10.5.1", + "jss-plugin-nested": "^10.5.1", + "jss-plugin-props-sort": "^10.5.1", + "jss-plugin-rule-value-function": "^10.5.1", + "jss-plugin-vendor-prefixer": "^10.5.1", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/system": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.2.tgz", + "integrity": "sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.3", + "csstype": "^2.5.2", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/types": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", + "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/utils": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.3.tgz", + "integrity": "sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==", + "dependencies": { + "@babel/runtime": "^7.4.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz", + "integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/react": { + "version": "17.0.76", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.76.tgz", + "integrity": "sha512-w9Aq+qeszGYoQM0hgFcdsAODGJdogadBDiitPm+zjBFJ0mLymvn2qSXsDaLJUndFRqqXk1FQfa9avHUBk1JhJQ==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react/node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, "node_modules/asciidoctor-emoji": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/asciidoctor-emoji/-/asciidoctor-emoji-0.5.0.tgz", @@ -58,6 +276,42 @@ "balanced-match": "^1.0.0" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "dependencies": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, + "node_modules/csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-helpers/node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -83,6 +337,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -99,6 +371,114 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "peer": true }, + "node_modules/is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz", + "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/jss" + } + }, + "node_modules/jss-plugin-camel-case": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz", + "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-default-unit": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz", + "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-global": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz", + "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-nested": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz", + "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-props-sort": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz", + "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-rule-value-function": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz", + "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-vendor-prefixer": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz", + "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.10.0" + } + }, + "node_modules/jss/node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -111,6 +491,14 @@ "node": ">=10" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -120,6 +508,123 @@ "wrappy": "1" } }, + "node_modules/popper.js": { + "version": "1.16.1-lts", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", + "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/react-router": { + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz", + "integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==", + "dependencies": { + "@remix-run/router": "1.15.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz", + "integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==", + "dependencies": { + "@remix-run/router": "1.15.1", + "react-router": "6.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/unxhr": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/unxhr/-/unxhr-1.2.0.tgz", diff --git a/package.json b/package.json index d5f2efb1..c7801602 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,8 @@ { "dependencies": { - "asciidoctor-emoji": "^0.5.0" + "@material-ui/core": "^4.12.4", + "@material-ui/icons": "^4.11.3", + "asciidoctor-emoji": "^0.5.0", + "react-router-dom": "^6.22.1" } } diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 27466aee..7933cdc3 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -17,7 +17,9 @@ "axios": "^1.6.5", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-scripts": "5.0.1", + "react-icons": "^5.0.1", + "react-router-dom": "^6.22.2", + "react-scripts": "^5.0.1", "web-vitals": "^3.5.1" }, "devDependencies": { @@ -5005,6 +5007,14 @@ "node": ">=12" } }, + "node_modules/@remix-run/router": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.2.tgz", + "integrity": "sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -21996,6 +22006,14 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-icons": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz", + "integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -22009,6 +22027,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz", + "integrity": "sha512-YD3Dzprzpcq+tBMHBS822tCjnWD3iIZbTeSXMY9LPSG541EfoBGyZ3bS25KEnaZjLcmQpw2AVLkFyfgXY8uvcw==", + "dependencies": { + "@remix-run/router": "1.15.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.2.tgz", + "integrity": "sha512-WgqxD2qySEIBPZ3w0sHH+PUAiamDeszls9tzqMPBDA1YYVucTBXLU7+gtRfcSnhe92A3glPnvSxK2dhNoAVOIQ==", + "dependencies": { + "@remix-run/router": "1.15.2", + "react-router": "6.22.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 74e31bee..95e0cfc9 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -12,7 +12,9 @@ "axios": "^1.6.5", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-scripts": "5.0.1", + "react-icons": "^5.0.1", + "react-router-dom": "^6.22.2", + "react-scripts": "^5.0.1", "web-vitals": "^3.5.1" }, "scripts": { diff --git a/webapp/public/help.png b/webapp/public/help.png new file mode 100644 index 00000000..803f4abf Binary files /dev/null and b/webapp/public/help.png differ diff --git a/webapp/public/logo.jpg b/webapp/public/logo.jpg new file mode 100644 index 00000000..27dd9c70 Binary files /dev/null and b/webapp/public/logo.jpg differ diff --git a/webapp/src/App.js b/webapp/src/App.js index 401a3af7..73404053 100644 --- a/webapp/src/App.js +++ b/webapp/src/App.js @@ -1,40 +1,29 @@ -import React, { useState } from 'react'; -import AddUser from './components/AddUser'; -import Login from './components/Login'; -import CssBaseline from '@mui/material/CssBaseline'; +import React from 'react'; +import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; import Container from '@mui/material/Container'; -import Typography from '@mui/material/Typography'; -import Link from '@mui/material/Link'; import QuestionView from './components/questionView/QuestionView'; +import Navbar from './components/fragments/NavBar'; +import Home from './components/home/Home'; +import Login from './components/Login'; +import AddUser from './components/AddUser'; +import Instructions from './components/Instructions'; -function App() { - const [showLogin, setShowLogin] = useState(true); - - const handleToggleView = () => { - setShowLogin(!showLogin); - }; +function App() { return ( - - /* - - - - Welcome to the 2024 edition of the Software Architecture course - - {showLogin ? : } - - {showLogin ? ( - - Don't have an account? Register here. - - ) : ( - - Already have an account? Login here. - - )} - - */ + + + + + } /> + } /> + } /> + } /> + } /> + + + + ); } diff --git a/webapp/src/components/AddUser.js b/webapp/src/components/AddUser.js index 00d522a2..f0feb5c0 100644 --- a/webapp/src/components/AddUser.js +++ b/webapp/src/components/AddUser.js @@ -1,60 +1,93 @@ // src/components/AddUser.js -import React, { useState } from 'react'; -import axios from 'axios'; -import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; - -const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; +import React, { useState } from "react"; +import { FaUser, FaLock } from "react-icons/fa"; +import "./Login.css"; +import { Link } from "react-router-dom"; const AddUser = () => { - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); - const [error, setError] = useState(''); - const [openSnackbar, setOpenSnackbar] = useState(false); - - const addUser = async () => { - try { - await axios.post(`${apiEndpoint}/adduser`, { username, password }); - setOpenSnackbar(true); - } catch (error) { - setError(error.response.data.error); - } - }; - - const handleCloseSnackbar = () => { - setOpenSnackbar(false); - }; - return ( - - - Add User - - setUsername(e.target.value)} - /> - setPassword(e.target.value)} - /> - - - {error && ( - setError('')} message={`Error: ${error}`} /> - )} - +
+
+
+

Register

+
+ + +
+
+ + +
+
+ + +
+ + + + +
+
+
); }; +function LinkLogin() { + return ( + + Do you have an account? Login here. + + ); +} +// const [username, setUsername] = useState(''); +// const [password, setPassword] = useState(''); +// const [error, setError] = useState(''); +// const [openSnackbar, setOpenSnackbar] = useState(false); + +// const addUser = async () => { +// try { +// await axios.post(`${apiEndpoint}/adduser`, { username, password }); +// setOpenSnackbar(true); +// } catch (error) { +// setError(error.response.data.error); +// } +// }; + +// const handleCloseSnackbar = () => { +// setOpenSnackbar(false); +// }; + +// return ( +// +// +// Add User +// +// setUsername(e.target.value)} +// /> +// setPassword(e.target.value)} +// /> +// +// +// {error && ( +// setError('')} message={`Error: ${error}`} /> +// )} +// +// ); +// }; + export default AddUser; diff --git a/webapp/src/components/Home/Home.css b/webapp/src/components/Home/Home.css new file mode 100644 index 00000000..98b8043a --- /dev/null +++ b/webapp/src/components/Home/Home.css @@ -0,0 +1,37 @@ + .wrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + } + + .wrapper button{ + width: 100%; + height: 45px; + background: darkblue; + border: none; + outline: none; + border-radius: 40px; + box-shadow: 0 0 10px black; + cursor:pointer; + font-size: 16px; + color: white; + font-weight: 700; + } + + .wrapper link{ + font-size: 14.5px; + text-align: center; + margin: 20px 0 15px; + } + + + + + + + + + + diff --git a/webapp/src/components/Home/Home.js b/webapp/src/components/Home/Home.js new file mode 100644 index 00000000..fdabeeb1 --- /dev/null +++ b/webapp/src/components/Home/Home.js @@ -0,0 +1,64 @@ +import React from "react"; +import Typography from "@mui/material/Typography"; +import Button from "@mui/material/Button"; +import { Link } from 'react-router-dom'; +import "./Home.css"; + + +import "./Home.css"; + +function Home() { + + return ( +
+

+ Welcome to WIQ! +

+ +

+ {/* Button to the login view */} + +

+ {/* Link to the registration view */} + +

+
+ ); + + +} + + +function ButtonHowToPlay() { + return ( + + + + ); + +} + +function ButtonLogin() { + return ( + + + + ); + +} + +function LinkRegister() { + return ( + + Don't have an account? Register here. + + ); + +} +export default Home; diff --git a/webapp/src/components/Instructions.css b/webapp/src/components/Instructions.css new file mode 100644 index 00000000..e381600b --- /dev/null +++ b/webapp/src/components/Instructions.css @@ -0,0 +1,21 @@ + +main{ + background-color: white; +} + +section { + text-align: justify; + background-color: white; +} + + +article ul p{ + text-align: center; + background-color: lightblue; + font-size: large; +} + +article ul li{ + text-align: justify; + background-color: white; +} \ No newline at end of file diff --git a/webapp/src/components/Instructions.js b/webapp/src/components/Instructions.js new file mode 100644 index 00000000..bee9b261 --- /dev/null +++ b/webapp/src/components/Instructions.js @@ -0,0 +1,62 @@ +import React from 'react'; +import '../components/Instructions.css'; + + + +function Instructions() { + + return ( +
+

WIQ Instructions

+
+
+

    Objetive:

    +
  • + The objective of the game is to answer as many questions correctly as possible. +
  • +
+
+
+

    How to Play:

    +
  • + The game consists of a series of questions. +
  • +
  • + Read each question carefully. +
  • +
  • + Choose the correct answer from the options provided. +
  • +
  • + Click or tap on your selected answer to submit it. +
  • +
+
+
+

    Scoring:

  • + Each correct answer earns you x points.
  • +
  • + Incorrect answers do not deduct points. +
  • +
+
+
+

    Time Limit:

  • + Some game modes may have a time limit for answering each question. Be quick and accurate to maximize your score. +
+
+
+

    Have Fun!:

    +
  • + Enjoy the game and test your knowledge. Good luck! +
  • +
+
+ +
+
+ ); +} + + +export default Instructions; diff --git a/webapp/src/components/Login.css b/webapp/src/components/Login.css new file mode 100644 index 00000000..c65fa58b --- /dev/null +++ b/webapp/src/components/Login.css @@ -0,0 +1,106 @@ + +.wrapper{ + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + background-color: lightblue; +} + +.wrapper2{ + width: 420px; + background-color: blue; + color: white; + border-style: 10px; + padding: 30px 40px; + border-radius: 15%; +} + +.wrapper2 h1{ + font-size: 36px; + text-align: center; +} + +.wrapper2 .input-box{ + position: relative; + width: 100%; + height: 50px; + margin: 30px 0; +} + +.input-box input{ + width: 100%; + height: 100%; + background: lightblue; + border: none; + outline: none; + border: 2px solid gray; + border-radius: 40px; + font-size: 14.5px; + color: black; +} + +.input-box input::placeholder{ + background-color: lightblue; +} + +.input-box .icon{ + position: absolute; + right: 20px; + top: 50%; + transform: translateY(-50%); + font-size: 16px; +} + +.wrapper2 .remember-forgot{ + display: flex; + justify-content: space-between; + font-size: 14.5px; + margin: -15px 0 15px; +} + +.remember-forgot label input{ + accent-color: white; + margin-right: 4px; +} + +.remember-forgot a { + color: white; + text-decoration: none; +} + +.remember-forgot a:hover{ + text-decoration: underline; +} + +.wrapper2 button{ + width: 100%; + height: 45px; + background: white; + border: none; + outline: none; + border-radius: 40px; + box-shadow: 0 0 10px black; + cursor:pointer; + font-size: 16px; + color: black; + font-weight: 700; +} + +.button-register { + color: aliceblue; + } + + .button-login { + color: aliceblue; + } + +.register-link p a { + color: white; + text-decoration: none; + font-weight: 600; +} + +.register-link p a:hover{ + text-decoration: underline; +} \ No newline at end of file diff --git a/webapp/src/components/Login.js b/webapp/src/components/Login.js index 0ad6268e..6a05a02e 100644 --- a/webapp/src/components/Login.js +++ b/webapp/src/components/Login.js @@ -1,80 +1,158 @@ -// src/components/Login.js -import React, { useState } from 'react'; -import axios from 'axios'; -import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; +// import React, { useState } from "react"; +// import axios from "axios"; +import { FaUser, FaLock } from "react-icons/fa"; +import "./Login.css"; +import { Link } from "react-router-dom"; const Login = () => { - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); - const [error, setError] = useState(''); - const [loginSuccess, setLoginSuccess] = useState(false); - const [createdAt, setCreatedAt] = useState(''); - const [openSnackbar, setOpenSnackbar] = useState(false); - const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; + //todo esto de aquí lo dejo por si se necesita en el futuro, es el código base + // const [username, setUsername] = useState(""); + // const [password, setPassword] = useState(""); + // const [error, setError] = useState(""); + // const [loginSuccess, setLoginSuccess] = useState(false); + // const [createdAt, setCreatedAt] = useState(""); + // const [openSnackbar, setOpenSnackbar] = useState(false); + // const apiEndpoint = + // process.env.REACT_APP_API_ENDPOINT || "http://localhost:8000"; - const loginUser = async () => { - try { - const response = await axios.post(`${apiEndpoint}/login`, { username, password }); + // const loginUser = async () => { + // try { + // const response = await axios.post(`${apiEndpoint}/login`, { + // username, + // password, + // }); - // Extract data from the response - const { createdAt: userCreatedAt } = response.data; + // // Extract data from the response + // const { createdAt: userCreatedAt } = response.data; - setCreatedAt(userCreatedAt); - setLoginSuccess(true); + // setCreatedAt(userCreatedAt); + // setLoginSuccess(true); - setOpenSnackbar(true); - } catch (error) { - setError(error.response.data.error); - } - }; - - const handleCloseSnackbar = () => { - setOpenSnackbar(false); - }; + // setOpenSnackbar(true); + // } catch (error) { + // setError(error.response.data.error); + // } + // }; + //empieza return ( - - {loginSuccess ? ( -
- - Hello {username}! - - - Your account was created on {new Date(createdAt).toLocaleDateString()}. - -
- ) : ( -
- - Login - - setUsername(e.target.value)} - /> - setPassword(e.target.value)} - /> - - - {error && ( - setError('')} message={`Error: ${error}`} /> - )} +
+
+
+

Login

+
+ + +
+
+ + +
+ +
+ + Forgot password? +
+ + + +
- )} - +
+
); }; + +function LinkRegister() { + return ( + + Don't you have an account? Register here. + + ); +} export default Login; + +// // src/components/Login.js +// import React, { useState } from 'react'; +// import axios from 'axios'; +// import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; + +// const Login = () => { +// const [username, setUsername] = useState(''); +// const [password, setPassword] = useState(''); +// const [error, setError] = useState(''); +// const [loginSuccess, setLoginSuccess] = useState(false); +// const [createdAt, setCreatedAt] = useState(''); +// const [openSnackbar, setOpenSnackbar] = useState(false); + +// const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; + +// const loginUser = async () => { +// try { +// const response = await axios.post(`${apiEndpoint}/login`, { username, password }); + +// // Extract data from the response +// const { createdAt: userCreatedAt } = response.data; + +// setCreatedAt(userCreatedAt); +// setLoginSuccess(true); + +// setOpenSnackbar(true); +// } catch (error) { +// setError(error.response.data.error); +// } +// }; + +// const handleCloseSnackbar = () => { +// setOpenSnackbar(false); +// }; + +// return ( +// +// {loginSuccess ? ( +//
+// +// Hello {username}! +// +// +// Your account was created on {new Date(createdAt).toLocaleDateString()}. +// +//
+// ) : ( +//
+// +// Login +// +// setUsername(e.target.value)} +// /> +// setPassword(e.target.value)} +// /> +// +// +// {error && ( +// setError('')} message={`Error: ${error}`} /> +// )} +//
+// )} +//
+// ); +// }; + +// export default Login; diff --git a/webapp/src/components/fragments/NavBar.css b/webapp/src/components/fragments/NavBar.css new file mode 100644 index 00000000..4ec0f2c2 --- /dev/null +++ b/webapp/src/components/fragments/NavBar.css @@ -0,0 +1,41 @@ +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + background-color: blue; + width: 100%; + padding: 10px; + box-sizing: border-box; + } + + main { + width: 100%; + } + + .navbar-container img { + width: 40px; + height: 40px; + margin-right: 10px; + } + + .navbar-text { + color: white; + } + + + .help-button { + border: none; + background: none; + + } + + .help-button img { + width: 40px; + height: 40px; + } + + + + + + \ No newline at end of file diff --git a/webapp/src/components/fragments/NavBar.js b/webapp/src/components/fragments/NavBar.js new file mode 100644 index 00000000..2e65ea02 --- /dev/null +++ b/webapp/src/components/fragments/NavBar.js @@ -0,0 +1,31 @@ +// NavBar.js +import React from 'react'; +import Typography from "@mui/material/Typography"; +import { Link } from 'react-router-dom'; +import "./NavBar.css"; + +function Navbar() { + return ( +
+ + + Know and Win! + + +
+ ); +} + +function Profile() { + return App logo; +} + +function Help() { + return ( + + Help + + ); +} + +export default Navbar;